summaryrefslogtreecommitdiffhomepage
path: root/docs/sources/zebra-multipath.md
blob: fd71e3b592bfd734efcf99fa68560b0cd163b7fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# Equal Cost Multipath Routing with Zebra

This page explains how GoBGP handles Equal Cost Multipath (ECMP) routes with
Zebra daemon included in [Quagga](http://www.nongnu.org/quagga/) or
[FRRouting](https://frrouting.org/).

## Prerequisites

Assume you finished [Getting Started](getting-started.md) and
[FIB manipulation](zebra.md).

## Contents

- [Configuration](#configuration)
- [Verification](#verification)

## Configuration

**Note:** Before constructing your environment, please confirm your Zebra is
built with "--enable-multipath=ARG" configure option. The APT packaged Quagga
on Ubuntu 16.04 is configured with this option as following.

```bash
$ /usr/lib/quagga/zebra --version
zebra version 0.99.24.1
Copyright 1996-2005 Kunihiro Ishiguro, et al.
configured with:
	--build=x86_64-linux-gnu ...(snip)... --enable-multipath=64 ...(snip)...
```

Here supposes the following topology and demonstrates two ECMP routes which
advertised from R2 and R3 are installed to R1's Kernel routing table via Zebra.

```text
R1: GoBGP + Zebra
R2: GoBGP
R3: GoBGP

    +-------------+                     +-------------+
    | R1          | .1/24         .2/24 | R2          |
    | ID: 1.1.1.1 |---------------------| ID: 2.2.2.2 |
    | AS: 65000   |   192.168.12.0/24   | AS: 65000   |
    +-------------+                     +-------------+
        | .1/24
        |
        | 192.168.13.0/24
        |
        | .3/24
    +-------------+
    | R3          |
    | ID: 3.3.3.3 |
    | AS: 65000   |
    +-------------+
```

To enables ECMP features at GoBGP on R1, please confirm "use-multiple-paths"
option is configured as following. With this option, GoBGP will redistribute BGP
multipath routes to Zebra and Zebra will install them into Kernel routing table.

```toml
# gobgpd.toml on R1

[global.config]
  as = 65000
  router-id = "1.1.1.1"

[global.use-multiple-paths.config]
  enabled = true

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.12.2"
    peer-as = 65000
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.13.3"
    peer-as = 65000
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"

[zebra.config]
  enabled = true
  url = "unix:/var/run/quagga/zserv.api"
  redistribute-route-type-list = ["connect"]
  version = 2
```

```toml
# gobgpd.toml on R2

[global.config]
  as = 65000
  router-id = "2.2.2.2"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.12.1"
    peer-as = 65000
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"
```

```toml
# gobgpd.toml on R3

[global.config]
  as = 65000
  router-id = "3.3.3.3"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.13.1"
    peer-as = 65000
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"
```

## Verification

When connections established between each routers, all routers have only
"connected" routes from Zebra on R1.

```bash
R1> gobgp global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 1.1.1.1/32           0.0.0.0                                   00:00:00   [{Origin: i} {Med: 0}]
*> 192.168.12.0/24      0.0.0.0                                   00:00:00   [{Origin: i} {Med: 0}]
*> 192.168.13.0/24      0.0.0.0                                   00:00:00   [{Origin: i} {Med: 0}]

R2> gobgp global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 1.1.1.1/32           192.168.12.1                              00:00:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 192.168.12.0/24      192.168.12.1                              00:00:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 192.168.13.0/24      192.168.12.1                              00:00:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
```

And only these routes are installed on R1's Kernel routing table.

```bash
R1> ip route
192.168.12.0/24 dev r1-eth1  proto kernel  scope link  src 192.168.12.1
192.168.13.0/24 dev r1-eth2  proto kernel  scope link  src 192.168.13.1
```

Then, let's add new routes destinated to "10.23.1.0/24" on R2 and R3 routes.
These routes should be treated as Multipath routes which have the same cost.

```bash
R2> gobgp global rib -a ipv4 add 10.23.1.0/24
R2> gobgp global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 1.1.1.1/32           192.168.12.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 10.23.1.0/24         0.0.0.0                                   00:00:00   [{Origin: ?}]
*> 192.168.12.0/24      192.168.12.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 192.168.13.0/24      192.168.12.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]

R3> gobgp global rib -a ipv4 add 10.23.1.0/24
R3> gobgp global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 1.1.1.1/32           192.168.13.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 10.23.1.0/24         0.0.0.0                                   00:00:00   [{Origin: ?}]
*> 192.168.12.0/24      192.168.13.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
*> 192.168.13.0/24      192.168.13.1                              00:10:00   [{Origin: i} {Med: 0} {LocalPref: 100}]
```

GoBGP on R1 will receive these routes and install them into R1's Kernel routing
table via Zebra. The following shows that traffic to "10.23.1.0/24" will be
forwarded through the interface r1-eth1 (nexthop is R2) or the interface r1-eth2
(nexthop is R3) with the same weight.

```bash
R1> gobgp global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 1.1.1.1/32           0.0.0.0                                   00:15:00   [{Origin: i} {Med: 0}]
*> 10.23.1.0/24         192.168.12.2                              00:05:00   [{Origin: ?} {LocalPref: 100}]
*  10.23.1.0/24         192.168.13.3                              00:05:00   [{Origin: ?} {LocalPref: 100}]
*> 192.168.12.0/24      0.0.0.0                                   00:15:00   [{Origin: i} {Med: 0}]
*> 192.168.13.0/24      0.0.0.0                                   00:15:00   [{Origin: i} {Med: 0}]

R1> ip route
10.23.1.0/24  proto zebra
	nexthop via 192.168.12.2  dev r1-eth1 weight 1
	nexthop via 192.168.13.3  dev r1-eth2 weight 1
192.168.12.0/24 dev r1-eth1  proto kernel  scope link  src 192.168.12.1
192.168.13.0/24 dev r1-eth2  proto kernel  scope link  src 192.168.13.1
```