From 9e8aa85aec3bb12ae28dd4b18128237828f63377 Mon Sep 17 00:00:00 2001 From: IWASE Yusuke Date: Tue, 14 Nov 2017 13:55:55 +0900 Subject: [PATCH] cli: EVPN Ethernet Segment Route advertisement This patch enables to add route for EVPN Ethernet Segment Route via "gobgp" command. Example: $ gobgp global rib -a evpn add esi 10.0.0.1 esi 0 rd 65000:100 $ gobgp global rib -a evpn Network Labels Next Hop AS_PATH Age Attrs *> [type:esi][rd:65000:100][esi:single-homed][ip:10.0.0.1] 0.0.0.0 hh:mm:ss [{Origin: ?}] Signed-off-by: IWASE Yusuke --- gobgp/cmd/global.go | 62 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go index 3bae70564..708a5f625 100644 --- a/gobgp/cmd/global.go +++ b/gobgp/cmd/global.go @@ -542,6 +542,63 @@ func ParseEvpnMulticastArgs(args []string) (bgp.AddrPrefixInterface, []string, e return bgp.NewEVPNNLRI(bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, 0, r), extcomms, nil } +func ParseEvpnEthernetSegmentArgs(args []string) (bgp.AddrPrefixInterface, []string, error) { + // Format: + // esi rd [rt ...] [encap ] + req := 5 + if len(args) < req { + return nil, nil, fmt.Errorf("%d args required at least, but got %d", req, len(args)) + } + m := extractReserved(args, []string{"esi", "rd", "rt", "encap"}) + if len(m[""]) < 1 { + return nil, nil, fmt.Errorf("specify ip address") + } + for _, f := range []string{"esi", "rd"} { + for len(m[f]) == 0 { + return nil, nil, fmt.Errorf("specify %s", f) + } + } + + ip := net.ParseIP(m[""][0]) + ipLen := 0 + if ip == nil { + return nil, nil, fmt.Errorf("invalid ip address: %s", m[""][0]) + } else if ip.IsUnspecified() { + ip = nil + } else if ip.To4() != nil { + ipLen = net.IPv4len * 8 + } else { + ipLen = net.IPv6len * 8 + } + + esi, err := bgp.ParseEthernetSegmentIdentifier(m["esi"]) + if err != nil { + return nil, nil, err + } + + rd, err := bgp.ParseRouteDistinguisher(m["rd"][0]) + if err != nil { + return nil, nil, err + } + + extcomms := make([]string, 0) + if len(m["rt"]) > 0 { + extcomms = append(extcomms, "rt") + extcomms = append(extcomms, m["rt"]...) + } + if len(m["encap"]) > 0 { + extcomms = append(extcomms, "encap", m["encap"][0]) + } + + r := &bgp.EVPNEthernetSegmentRoute{ + RD: rd, + ESI: esi, + IPAddressLength: uint8(ipLen), + IPAddress: ip, + } + return bgp.NewEVPNNLRI(bgp.EVPN_ETHERNET_SEGMENT_ROUTE, 0, r), extcomms, nil +} + func ParseEvpnIPPrefixArgs(args []string) (bgp.AddrPrefixInterface, []string, error) { // Format: // [gw ] etag [label