Skip to content

Commit

Permalink
cli: Support EVPN Default Gateway Extended Community
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
iwaseyusuke authored and fujita committed Dec 30, 2017
1 parent 5776624 commit 06be3c5
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 46 deletions.
6 changes: 3 additions & 3 deletions docs/sources/evpn.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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
```
Expand Down
108 changes: 65 additions & 43 deletions gobgp/cmd/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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")
Expand All @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions packet/bgp/bgp.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 06be3c5

Please sign in to comment.