summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/sources/evpn.md71
-rw-r--r--gobgp/cmd/global.go30
2 files changed, 91 insertions, 10 deletions
diff --git a/docs/sources/evpn.md b/docs/sources/evpn.md
index ab53fea1..db139231 100644
--- a/docs/sources/evpn.md
+++ b/docs/sources/evpn.md
@@ -12,6 +12,8 @@ still very experimental.
- [Inclusive Multicast Ethernet Tag Route](#inclusive-multicast-ethernet-tag-route)
- [Ethernet Segment Route](#ethernet-segment-route)
- [IP Prefix Route](#ip-prefix-route)
+- [Reference](#reference)
+ - [Router's MAC Option](#routers-mac-option)
- [BaGPipe](#bagpipe)
- [Configuration](#configuration)
- [Advertising EVPN route](#advertising-evpn-route)
@@ -237,6 +239,75 @@ $ gobgp global rib -a evpn prefix
$ gobgp global rib -a evpn del prefix 10.0.0.0/24 172.16.0.1 esi MSTP aa:aa:aa:aa:aa:aa 100 etag 200 label 300 rd 1.1.1.1:65000
```
+## Reference
+
+### Router's MAC Option
+
+The `router-mac` option in `gobgp` CLI allows sending Router's
+MAC Extended Community via BGP EVPN Type 2 and Type 5 advertisements.
+
+As explained in below RFC draft, this community is used to carry the
+MAC address of the VTEP where MAC-IP pair resides.
+
+For example, GoBGP router (R1) peers with Cisco router (R2).
+R1 is used by an orchestraction platform, e.g. OpenStack, Docker Swarm,
+etc., to advertise container MAC-IP bindings. When R1 advertises the
+binding it also sets next hop for the route as the host where the MAC-IP
+binding (i.e. container) resides. When R2 receives the route, it will
+not install it unless Router's MAC Extended Community is present. R2
+will use the MAC address in the community to create an entry in MAC
+address table of R2 pointint to NVE interface.
+
+```bash
+gobgp global rib -a evpn add macadv e9:72:d7:aa:1f:b4 \
+ 172.16.100.100 etag 0 label 34567 rd 10.1.1.1:100 \
+ rt 65001:100 encap vxlan nexthop 10.10.10.10 \
+ origin igp router-mac e9:72:d7:aa:1f:b4
+
+gobgp global rib -a evpn add nexthop 10.10.10.10 origin igp \
+ prefix 172.16.100.100/32 esi 0 etag 0 rd 10.1.1.1:100 \
+ rt 65001:100 gw 10.10.10.10 label 34567 encap vxlan \
+ router-mac e9:72:d7:aa:1f:b4
+```
+
+In the above example, a host with IP of `10.10.10.10` runs a
+container connected to an Open vSwitch instance. The container's IP
+address is `172.16.100.100` and MAC address `e9:72:d7:aa:1f:b4`.
+The Open vSwitch is VTEP with `tunnel_key=34567`, i.e. VNID `34567`.
+
+GoBGP (R1) and Cisco (R2) routers are in BGP AS 65001. R1's IP is
+`10.1.1.1`. R2 used RT of `65001:100` to import routes and place
+them into appropriate VRF. In this case the VRF is associated with
+L2VNI from VLAN 300. Upon the receipt of the above BGP EVPN
+Type 2 and Type 5 routes, R2 will create create a MAC address
+entry pointing to it's NVE interface with destination IP address
+of `10.10.10.10`.
+
+```bash
+Legend:
+ * - primary entry, G - Gateway MAC, (R) - Routed MAC, O - Overlay MAC
+ age - seconds since last seen,+ - primary entry using vPC Peer-Link,
+ (T) - True, (F) - False, C - ControlPlane MAC
+ VLAN MAC Address Type age Secure NTFY Ports
+---------+-----------------+--------+---------+------+----+------------------
+* 300 e972.d7aa.1fb4 static - F F nve1(10.10.10.10)
+```
+
+The R2 will use the `router-mac e9:72:d7:aa:1f:b4` as the destination MAC
+address of the inner VXLAN packet. For example, an underlay host `20.20.20.20`
+ping the container. The inner VXLAN L2 destination address is
+`e9:72:d7:aa:1f:b4`. The inner VXLAN L2 source address is R2's MAC. The outer
+VXLAN L3 source address, i.e. `10.2.2.2` is R2' NVE address.
+
+```bash
+OUTER VXLAN L2: 10:20:08:d0:ff:23 > b2:0e:19:6a:8d:51
+OUTER VXLAN L3: 10.2.2.2.45532 > 10.10.10.10.4789: VXLAN, flags [I] (0x08), vni 34567
+INNER VXLAN L2: 4e:f4:ca:aa:f6:7b > e9:72:d7:aa:1f:b4
+INNER VXLAN L3: 20.20.20.20 > 172.16.100.100: ICMP echo reply, id 66, seq 1267, length 64
+```
+
+See also: [Integrated Routing and Bridging in EVPN](https://tools.ietf.org/html/draft-ietf-bess-evpn-inter-subnet-forwarding-03#section-6.1)
+
## BaGPipe
This example uses [BaGPipe](https://github.com/openstack/networking-bagpipe). GoBGP receives
diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go
index c9be51bc..b5851929 100644
--- a/gobgp/cmd/global.go
+++ b/gobgp/cmd/global.go
@@ -465,22 +465,23 @@ func ParseEvpnEthernetAutoDiscoveryArgs(args []string) (bgp.AddrPrefixInterface,
func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
// Format:
- // <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway]
+ // <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [router-mac <mac address>] [default-gateway]
// or
- // <mac address> <ip address> <etag> [esi <esi>] label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway]
+ // <mac address> <ip address> <etag> [esi <esi>] label <label> rd <rd> [rt <rt>...] [encap <encap type>] [router-mac <mac address>] [default-gateway]
// or
- // <mac address> <ip address> <etag> <label> [esi <esi>] rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway]
+ // <mac address> <ip address> <etag> <label> [esi <esi>] rd <rd> [rt <rt>...] [encap <encap type>] [router-mac <mac address>] [default-gateway]
req := 6
if len(args) < req {
return nil, nil, fmt.Errorf("%d args required at least, but got %d", req, len(args))
}
m, err := extractReserved(args, map[string]int{
- "esi": PARAM_LIST,
- "etag": PARAM_SINGLE,
- "label": PARAM_SINGLE,
- "rd": PARAM_SINGLE,
- "rt": PARAM_LIST,
- "encap": PARAM_SINGLE})
+ "esi": PARAM_LIST,
+ "etag": PARAM_SINGLE,
+ "label": PARAM_SINGLE,
+ "rd": PARAM_SINGLE,
+ "rt": PARAM_LIST,
+ "encap": PARAM_SINGLE,
+ "router-mac": PARAM_SINGLE})
if err != nil {
return nil, nil, err
}
@@ -560,6 +561,15 @@ func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, []string, erro
if len(m["encap"]) > 0 {
extcomms = append(extcomms, "encap", m["encap"][0])
}
+
+ if len(m["router-mac"]) != 0 {
+ _, err := net.ParseMAC(m["router-mac"][0])
+ if err != nil {
+ return nil, nil, fmt.Errorf("invalid router-mac address: %s", m["router-mac"][0])
+ }
+ extcomms = append(extcomms, "router-mac", m["router-mac"][0])
+ }
+
for _, a := range args {
if a == "default-gateway" {
extcomms = append(extcomms, "default-gateway")
@@ -1422,7 +1432,7 @@ usage: %s rib -a %%s %s%%s match <MATCH> then <THEN>%%s%%s%%s
helpErrMap[bgp.RF_EVPN] = fmt.Errorf(`error: %s
usage: %s rib %s { a-d <A-D> | macadv <MACADV> | multicast <MULTICAST> | esi <ESI> | prefix <PREFIX> } -a evpn
<A-D> : esi <esi> etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [esi-label <esi-label> [single-active | all-active]]
- <MACADV> : <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway]
+ <MACADV> : <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [router-mac <mac address>] [default-gateway]
<MULTICAST> : <ip address> etag <etag> rd <rd> [rt <rt>...] [encap <encap type>] [pmsi <type> [leaf-info-required] <label> <tunnel-id>]
<ESI> : <ip address> esi <esi> rd <rd> [rt <rt>...] [encap <encap type>]
<PREFIX> : <ip prefix> [gw <gateway>] [esi <esi>] etag <etag> [label <label>] rd <rd> [rt <rt>...] [encap <encap type>] [router-mac <mac address>]`,