diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-12-18 11:06:33 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-12-30 20:33:37 +0900 |
commit | 06be3c5c2637aebca8a887d9f8d87cc1e9a7692a (patch) | |
tree | 27593ebaa548430f756fc3c6ad6ab647ebdbbfe3 | |
parent | 577662422ee02622e4a8277ad570d501e0cf7ebc (diff) |
cli: Support EVPN Default Gateway Extended Community
This patch enables to support the Default Gateway Extended Community on
the EVPN MAC/IP Advertisement route.
Usage Example:
$ gobgp global rib -a evpn add macadv aa:bb:cc:dd:ee:ff 10.0.0.1 etag 10 label 20,30 rd 1.1.1.1:65000 default-gateway
$ gobgp global rib -a evpn
Network Labels Next Hop AS_PATH Age Attrs
*> [type:macadv][rd:1.1.1.1:65000][etag:10][mac:aa:bb:cc:dd:ee:ff][ip:10.0.0.1] [20,30] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [default-gateway]} [ESI: single-homed]]
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r-- | docs/sources/evpn.md | 6 | ||||
-rw-r--r-- | gobgp/cmd/global.go | 108 | ||||
-rw-r--r-- | packet/bgp/bgp.go | 15 |
3 files changed, 83 insertions, 46 deletions
diff --git a/docs/sources/evpn.md b/docs/sources/evpn.md index fb943f1d..e457242c 100644 --- a/docs/sources/evpn.md +++ b/docs/sources/evpn.md @@ -50,7 +50,7 @@ $ gobgp global rib -a evpn del a-d esi LACP aa:bb:cc:dd:ee:ff 100 etag 200 label ```bash # Add a route -$ gobgp global rib -a evpn add macadv <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] +$ gobgp global rib -a evpn add macadv <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway] # Show routes $ gobgp global rib -a evpn [macadv] @@ -70,10 +70,10 @@ $ gobgp global rib -a evpn $ gobgp global rib -a evpn del macadv aa:bb:cc:dd:ee:ff 10.0.0.1 etag 100 label 200,300 rd 1.1.1.1:65000 # With optionals -$ gobgp global rib -a evpn add macadv aa:bb:cc:dd:ee:ff 10.0.0.1 esi AS 65000 100 etag 200 label 300 rd 1.1.1.1:65000 rt 65000:400 encap vxlan +$ gobgp global rib -a evpn add macadv aa:bb:cc:dd:ee:ff 10.0.0.1 esi AS 65000 100 etag 200 label 300 rd 1.1.1.1:65000 rt 65000:400 encap vxlan default-gateway $ gobgp global rib -a evpn macadv Network Labels Next Hop AS_PATH Age Attrs -*> [type:macadv][rd:1.1.1.1:65000][etag:200][mac:aa:bb:cc:dd:ee:ff][ip:10.0.0.1] [300] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [65000:400], [VXLAN]} [ESI: ESI_AS | as 65000, local discriminator 100]] +*> [type:macadv][rd:1.1.1.1:65000][etag:200][mac:aa:bb:cc:dd:ee:ff][ip:10.0.0.1] [300] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [65000:400], [VXLAN], [default-gateway]} [ESI: ESI_AS | as 65000, local discriminator 100]] $ gobgp global rib -a evpn del macadv aa:bb:cc:dd:ee:ff 10.0.0.1 esi AS 65000 100 etag 200 label 300 rd 1.1.1.1:65000 ``` diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go index 3e9f3671..45ee5614 100644 --- a/gobgp/cmd/global.go +++ b/gobgp/cmd/global.go @@ -45,41 +45,44 @@ const ( ENCAP ESI_LABEL ROUTER_MAC + DEFAULT_GATEWAY VALID NOT_FOUND INVALID ) var ExtCommNameMap = map[ExtCommType]string{ - ACCEPT: "accept", - DISCARD: "discard", - RATE: "rate-limit", - REDIRECT: "redirect", - MARK: "mark", - ACTION: "action", - RT: "rt", - ENCAP: "encap", - ESI_LABEL: "esi-label", - ROUTER_MAC: "router-mac", - VALID: "valid", - NOT_FOUND: "not-found", - INVALID: "invalid", + ACCEPT: "accept", + DISCARD: "discard", + RATE: "rate-limit", + REDIRECT: "redirect", + MARK: "mark", + ACTION: "action", + RT: "rt", + ENCAP: "encap", + ESI_LABEL: "esi-label", + ROUTER_MAC: "router-mac", + DEFAULT_GATEWAY: "default-gateway", + VALID: "valid", + NOT_FOUND: "not-found", + INVALID: "invalid", } var ExtCommValueMap = map[string]ExtCommType{ - ExtCommNameMap[ACCEPT]: ACCEPT, - ExtCommNameMap[DISCARD]: DISCARD, - ExtCommNameMap[RATE]: RATE, - ExtCommNameMap[REDIRECT]: REDIRECT, - ExtCommNameMap[MARK]: MARK, - ExtCommNameMap[ACTION]: ACTION, - ExtCommNameMap[RT]: RT, - ExtCommNameMap[ENCAP]: ENCAP, - ExtCommNameMap[ESI_LABEL]: ESI_LABEL, - ExtCommNameMap[ROUTER_MAC]: ROUTER_MAC, - ExtCommNameMap[VALID]: VALID, - ExtCommNameMap[NOT_FOUND]: NOT_FOUND, - ExtCommNameMap[INVALID]: INVALID, + ExtCommNameMap[ACCEPT]: ACCEPT, + ExtCommNameMap[DISCARD]: DISCARD, + ExtCommNameMap[RATE]: RATE, + ExtCommNameMap[REDIRECT]: REDIRECT, + ExtCommNameMap[MARK]: MARK, + ExtCommNameMap[ACTION]: ACTION, + ExtCommNameMap[RT]: RT, + ExtCommNameMap[ENCAP]: ENCAP, + ExtCommNameMap[ESI_LABEL]: ESI_LABEL, + ExtCommNameMap[ROUTER_MAC]: ROUTER_MAC, + ExtCommNameMap[DEFAULT_GATEWAY]: DEFAULT_GATEWAY, + ExtCommNameMap[VALID]: VALID, + ExtCommNameMap[NOT_FOUND]: NOT_FOUND, + ExtCommNameMap[INVALID]: INVALID, } func rateLimitParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { @@ -247,6 +250,18 @@ func routerMacParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { return []bgp.ExtendedCommunityInterface{o}, nil } +func defaultGatewayParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { + if len(args) < 1 || args[0] != ExtCommNameMap[DEFAULT_GATEWAY] { + return nil, fmt.Errorf("invalid default-gateway") + } + o := &bgp.OpaqueExtended{ + IsTransitive: true, + Value: &bgp.DefaultGatewayExtended{}, + SubType: bgp.EC_SUBTYPE_DEFAULT_GATEWAY, + } + return []bgp.ExtendedCommunityInterface{o}, nil +} + func validationParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { if len(args) < 1 { return nil, fmt.Errorf("invalid validation state") @@ -269,19 +284,20 @@ func validationParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { } var ExtCommParserMap = map[ExtCommType]func([]string) ([]bgp.ExtendedCommunityInterface, error){ - ACCEPT: nil, - DISCARD: rateLimitParser, - RATE: rateLimitParser, - REDIRECT: redirectParser, - MARK: markParser, - ACTION: actionParser, - RT: rtParser, - ENCAP: encapParser, - ESI_LABEL: esiLabelParser, - ROUTER_MAC: routerMacParser, - VALID: validationParser, - NOT_FOUND: validationParser, - INVALID: validationParser, + ACCEPT: nil, + DISCARD: rateLimitParser, + RATE: rateLimitParser, + REDIRECT: redirectParser, + MARK: markParser, + ACTION: actionParser, + RT: rtParser, + ENCAP: encapParser, + ESI_LABEL: esiLabelParser, + ROUTER_MAC: routerMacParser, + DEFAULT_GATEWAY: defaultGatewayParser, + VALID: validationParser, + NOT_FOUND: validationParser, + INVALID: validationParser, } func ParseExtendedCommunities(args []string) ([]bgp.ExtendedCommunityInterface, error) { @@ -443,11 +459,11 @@ 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>] + // <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway] // or - // <mac address> <ip address> <etag> [esi <esi>] label <label> rd <rd> [rt <rt>...] [encap <encap type>] + // <mac address> <ip address> <etag> [esi <esi>] label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway] // or - // <mac address> <ip address> <etag> <label> [esi <esi>] rd <rd> [rt <rt>...] [encap <encap type>] + // <mac address> <ip address> <etag> <label> [esi <esi>] rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway] req := 6 if len(args) < req { return nil, nil, fmt.Errorf("%d args required at least, but got %d", req, len(args)) @@ -529,6 +545,12 @@ func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, []string, erro if len(m["encap"]) > 0 { extcomms = append(extcomms, "encap", m["encap"][0]) } + for _, a := range args { + if a == "default-gateway" { + extcomms = append(extcomms, "default-gateway") + break + } + } r := &bgp.EVPNMacIPAdvertisementRoute{ RD: rd, @@ -1320,7 +1342,7 @@ usage: %s rib -a %%s %s%%s match <MATCH> then <THEN>%%s%%s%%s helpErrMap[bgp.RF_FS_L2_VPN] = fmt.Errorf(fsHelpMsgFmt, "l2vpn-flowspec", " rd <RD>", " [rt <RT>]", rdHelpMsgFmt, l2vpnFsMatchExpr) helpErrMap[bgp.RF_EVPN] = fmt.Errorf(`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>] + <MACADV> : <mac address> <ip address> [esi <esi>] etag <etag> label <label> rd <rd> [rt <rt>...] [encap <encap type>] [default-gateway] <MULTICAST> : <ip address> etag <etag> rd <rd> [rt <rt>...] [encap <encap type>] <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>]`, cmdstr, modtype) diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index 66e5ff30..28d47cfd 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -6470,6 +6470,19 @@ func (e *EncapExtended) String() string { } } +type DefaultGatewayExtended struct { +} + +func (e *DefaultGatewayExtended) Serialize() ([]byte, error) { + buf := make([]byte, 7) + buf[0] = byte(EC_SUBTYPE_DEFAULT_GATEWAY) + return buf, nil +} + +func (e *DefaultGatewayExtended) String() string { + return "default-gateway" +} + type OpaqueExtended struct { IsTransitive bool Value OpaqueExtendedValueInterface @@ -6494,6 +6507,8 @@ func (e *OpaqueExtended) DecodeFromBytes(data []byte) error { e.Value = &EncapExtended{ TunnelType: t, } + case EC_SUBTYPE_DEFAULT_GATEWAY: + e.Value = &DefaultGatewayExtended{} default: e.Value = &DefaultOpaqueExtendedValue{ Value: data, //7byte |