summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2018-02-08 14:45:12 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-02-16 11:28:02 +0900
commit421a3840e00b4508567c040b5241b3e74cf711e8 (patch)
tree8376d27ad9b64da857718672436f82dfe11776b6
parent9fbec19c4c2624df842ab33bb91943bd9befdffa (diff)
cli: Support to advertise PMSI Tunnel Attribute
This patch enables "gobgp" command to advertise the PMSI Tunnel Attribute which is appended to the EVPN Inclusive Multicast Ethernet Tag routes for example. Usage Example: $ gobgp global rib -a evpn add multicast 10.0.0.1 etag 10 rd 65000:100 pmsi ingress-repl 100 1.1.1.1 $ gobgp global rib -a evpn Network Labels Next Hop AS_PATH Age Attrs *> [type:multicast][rd:65000:100][etag:10][ip:10.0.0.1] 0.0.0.0 00:00:00 [{Origin: ?} {Pmsi: type: ingress-repl, label: 100, tunnel-id: 1.1.1.1}] Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r--docs/sources/evpn.md7
-rw-r--r--gobgp/cmd/global.go35
-rw-r--r--packet/bgp/bgp.go47
3 files changed, 76 insertions, 13 deletions
diff --git a/docs/sources/evpn.md b/docs/sources/evpn.md
index 176dca3c..ddf80376 100644
--- a/docs/sources/evpn.md
+++ b/docs/sources/evpn.md
@@ -149,7 +149,7 @@ $ gobgp global rib -a evpn del macadv aa:bb:cc:dd:ee:ff 10.0.0.1 esi AS 65000 10
```bash
# Add a route
-$ gobgp global rib -a evpn add multicast <ip address> etag <etag> rd <rd> [rt <rt>...] [encap <encap type>]
+$ gobgp global rib -a evpn add multicast <ip address> etag <etag> rd <rd> [rt <rt>...] [encap <encap type>] [pmsi <type> [leaf-info-required] <label> <tunnel-id>]
# Show routes
$ gobgp global rib -a evpn [multicast]
@@ -169,11 +169,10 @@ $ gobgp global rib -a evpn
$ gobgp global rib -a evpn del multicast 10.0.0.1 etag 100 rd 1.1.1.1:65000
# With optionals
-$ gobgp global rib -a evpn add multicast 10.0.0.1 etag 100 rd 1.1.1.1:65000 rt 65000:200 encap vxlan
+$ gobgp global rib -a evpn add multicast 10.0.0.1 etag 100 rd 1.1.1.1:65000 rt 65000:200 encap vxlan pmsi ingress-repl 100 1.1.1.1
$ gobgp global rib -a evpn multicast
Network Labels Next Hop AS_PATH Age Attrs
-*> [type:multicast][rd:1.1.1.1:65000][etag:100][ip:10.0.0.1] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [65000:200], [VXLAN]}]
-$ gobgp global rib -a evpn del multicast 10.0.0.1 etag 100 rd 1.1.1.1:65000
+*> [type:multicast][rd:1.1.1.1:65000][etag:100][ip:10.0.0.1] 0.0.0.0 00:00:00 [{Origin: ?} {Pmsi: type: ingress-repl, label: 100, tunnel-id: 1.1.1.1} {Extcomms: [65000:200], [VXLAN]}]
```
### Ethernet Segment Route
diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go
index 2c7a71d6..81506802 100644
--- a/gobgp/cmd/global.go
+++ b/gobgp/cmd/global.go
@@ -961,6 +961,22 @@ func extractLargeCommunity(args []string) ([]string, bgp.PathAttributeInterface,
return args, nil, nil
}
+func extractPmsiTunnel(args []string) ([]string, bgp.PathAttributeInterface, error) {
+ for idx, arg := range args {
+ if arg == "pmsi" {
+ pmsi, err := bgp.ParsePmsiTunnel(args[idx+1:])
+ if err != nil {
+ return nil, nil, err
+ }
+ if pmsi.IsLeafInfoRequired {
+ return append(args[:idx], args[idx+5:]...), pmsi, nil
+ }
+ return append(args[:idx], args[idx+4:]...), pmsi, nil
+ }
+ }
+ return args, nil, nil
+}
+
func extractAigp(args []string) ([]string, bgp.PathAttributeInterface, error) {
for idx, arg := range args {
if arg == "aigp" {
@@ -1028,14 +1044,15 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*table.Path, error) {
attrs := table.PathAttrs(make([]bgp.PathAttributeInterface, 0, 1))
fns := []func([]string) ([]string, bgp.PathAttributeInterface, error){
- extractAsPath,
- extractOrigin,
- extractMed,
- extractLocalPref,
- extractCommunity,
- extractAigp,
- extractAggregator,
- extractLargeCommunity,
+ extractOrigin, // 1 ORIGIN
+ extractAsPath, // 2 AS_PATH
+ extractMed, // 4 MULTI_EXIT_DISC
+ extractLocalPref, // 5 LOCAL_PREF
+ extractAggregator, // 7 AGGREGATOR
+ extractCommunity, // 8 COMMUNITY
+ extractPmsiTunnel, // 22 PMSI_TUNNEL
+ extractAigp, // 26 AIGP
+ extractLargeCommunity, // 32 LARGE_COMMUNITY
}
for _, fn := range fns {
@@ -1351,7 +1368,7 @@ usage: %s rib -a %%s %s%%s match <MATCH> then <THEN>%%s%%s%%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]
- <MULTICAST> : <ip address> etag <etag> rd <rd> [rt <rt>...] [encap <encap type>]
+ <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>]`,
err,
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index df2e1571..8e9288e0 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -7927,6 +7927,53 @@ func NewPathAttributePmsiTunnel(typ PmsiTunnelType, isLeafInfoRequired bool, lab
}
}
+func ParsePmsiTunnel(args []string) (*PathAttributePmsiTunnel, error) {
+ // Format:
+ // "<type>" ["leaf-info-required"] "<label>" "<tunnel-id>"
+ if len(args) < 3 {
+ return nil, fmt.Errorf("invalid pmsi tunnel arguments: %s", args)
+ }
+
+ pmsi := NewPathAttributePmsiTunnel(0, false, 0, nil)
+
+ switch args[0] {
+ case "ingress-repl":
+ pmsi.TunnelType = PMSI_TUNNEL_TYPE_INGRESS_REPL
+ default:
+ typ, err := strconv.ParseUint(args[0], 10, 8)
+ if err != nil {
+ return nil, fmt.Errorf("invalid pmsi tunnel type: %s", args[0])
+ }
+ pmsi.TunnelType = PmsiTunnelType(typ)
+ }
+
+ indx := 1
+ if args[indx] == "leaf-info-required" {
+ pmsi.IsLeafInfoRequired = true
+ indx++
+ }
+
+ label, err := strconv.ParseUint(args[indx], 10, 32)
+ if err != nil {
+ return nil, fmt.Errorf("invalid pmsi tunnel label: %s", args[indx])
+ }
+ pmsi.Label = uint32(label)
+ indx++
+
+ switch pmsi.TunnelType {
+ case PMSI_TUNNEL_TYPE_INGRESS_REPL:
+ ip := net.ParseIP(args[indx])
+ if ip == nil {
+ return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", args[indx])
+ }
+ pmsi.TunnelID = &IngressReplTunnelID{Value: ip}
+ default:
+ pmsi.TunnelID = &DefaultPmsiTunnelID{Value: []byte(args[indx])}
+ }
+
+ return pmsi, nil
+}
+
type AigpTLVType uint8
const (