diff options
author | JieJhih Jhang <aawer12345tw@yahoo.com.tw> | 2019-03-29 17:12:10 +0800 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@gmail.com> | 2019-04-11 07:30:35 +0900 |
commit | 42feaea2a0bfc3deb1becdc8c06e4bad44a4b52c (patch) | |
tree | 963e4c813a0686ef44acf2a593ea6b33cf1be355 /cmd | |
parent | fa5878f6f306e1f8abfc58c4e421a55ead51854d (diff) |
cmd/gobgp: Parse evpn IPMSI parameter
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/gobgp/global.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/cmd/gobgp/global.go b/cmd/gobgp/global.go index fe53242f..9017c0d3 100644 --- a/cmd/gobgp/global.go +++ b/cmd/gobgp/global.go @@ -829,6 +829,60 @@ func parseEvpnIPPrefixArgs(args []string) (bgp.AddrPrefixInterface, []string, er return bgp.NewEVPNNLRI(bgp.EVPN_IP_PREFIX, r), extcomms, nil } +func parseEvpnIPMSIArgs(args []string) (bgp.AddrPrefixInterface, []string, error) { + // Format: + // etag <etag> rd <rd> [rt <rt>...] [encap <encap type>] + req := 4 + 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{ + "etag": paramSingle, + "rd": paramSingle, + "rt": paramSingle, + "encap": paramSingle}) + if err != nil { + return nil, nil, err + } + for _, f := range []string{"etag", "rd"} { + for len(m[f]) == 0 { + return nil, nil, fmt.Errorf("specify %s", f) + } + } + + rd, err := bgp.ParseRouteDistinguisher(m["rd"][0]) + if err != nil { + return nil, nil, err + } + + e, err := strconv.ParseUint(m["etag"][0], 10, 32) + if err != nil { + return nil, nil, fmt.Errorf("invalid etag: %s: %s", m["etag"][0], err) + } + etag := uint32(e) + + extcomms := make([]string, 0) + if len(m["rt"]) > 0 { + extcomms = append(extcomms, "rt") + extcomms = append(extcomms, m["rt"]...) + } + ec, err := bgp.ParseExtendedCommunity(bgp.EC_SUBTYPE_SOURCE_AS, m["rt"][0]) + if err != nil { + return nil, nil, fmt.Errorf("route target parse failed") + } + + if len(m["encap"]) > 0 { + extcomms = append(extcomms, "encap", m["encap"][0]) + } + + r := &bgp.EVPNIPMSIRoute{ + RD: rd, + ETag: etag, + EC: ec, + } + return bgp.NewEVPNNLRI(bgp.EVPN_I_PMSI, r), extcomms, nil +} + func parseEvpnArgs(args []string) (bgp.AddrPrefixInterface, []string, error) { if len(args) < 1 { return nil, nil, fmt.Errorf("lack of args. need 1 but %d", len(args)) @@ -846,6 +900,8 @@ func parseEvpnArgs(args []string) (bgp.AddrPrefixInterface, []string, error) { return parseEvpnEthernetSegmentArgs(args) case "prefix": return parseEvpnIPPrefixArgs(args) + case "i-pmsi": + return parseEvpnIPMSIArgs(args) } return nil, nil, fmt.Errorf("invalid subtype. expect [macadv|multicast|prefix] but %s", subtype) } |