summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-12-18 11:06:33 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-12-30 20:33:37 +0900
commit06be3c5c2637aebca8a887d9f8d87cc1e9a7692a (patch)
tree27593ebaa548430f756fc3c6ad6ab647ebdbbfe3
parent577662422ee02622e4a8277ad570d501e0cf7ebc (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.md6
-rw-r--r--gobgp/cmd/global.go108
-rw-r--r--packet/bgp/bgp.go15
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