diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-12-15 14:02:18 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-12-21 08:23:14 +0900 |
commit | 41f97f11056b097ab25b147abbd80a582e3ec019 (patch) | |
tree | a3c99463e7ae80742f0a1a5f15574efa08abd263 | |
parent | eaef2a30aa9720848387819fc9daf21ec1f2b8f0 (diff) |
cli: Enable to filter EVPN routes by Route Type
Currently, "gobgp" command supports only to display all routes on RIBs,
but with huge RIBs, it is convenient to select routes by a part of NLRI
fields.
This patch enables to filter routes by EVPN Route Type.
For example, when 5 routes for each route type;
$ gobgp global rib -a evpn
Network Labels Next Hop AS_PATH Age Attrs
*> [type:A-D][rd:65000:100][esi:single-homed][etag:10] [10] 0.0.0.0 00:01:09 [{Origin: ?}]
*> [type:Prefix][rd:65000:100][etag:10][prefix:10.0.0.0/24] [0] 0.0.0.0 00:00:04 [{Origin: ?} [ESI: single-homed] [GW: 0.0.0.0]]
*> [type:esi][rd:65000:100][esi:single-homed][ip:10.0.0.1] 0.0.0.0 00:00:19 [{Origin: ?}]
*> [type:macadv][rd:65000:100][etag:10][mac:aa:bb:cc:dd:ee:ff][ip:10.0.0.1] [20,30] 0.0.0.0 00:00:54 [{Origin: ?} [ESI: single-homed]]
*> [type:multicast][rd:65000:100][etag:10][ip:10.0.0.1] 0.0.0.0 00:00:33 [{Origin: ?}]
You can select multicast route as following;
$ gobgp global rib -a evpn multicast
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:03:02 [{Origin: ?}]
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r-- | gobgp/cmd/neighbor.go | 9 | ||||
-rw-r--r-- | table/table.go | 51 |
2 files changed, 57 insertions, 3 deletions
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index fb4b68f5..2f0f21a4 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -714,8 +714,13 @@ func showNeighborRib(r string, name string, args []string) error { var filter []*table.LookupPrefix if len(args) > 0 { target := args[0] - if _, _, err = parseCIDRorIP(args[0]); err != nil { - return err + switch family { + case bgp.RF_EVPN: + // Uses target as EVPN Route Type string + default: + if _, _, err = parseCIDRorIP(target); err != nil { + return err + } } var option table.LookupOption args = args[1:] diff --git a/table/table.go b/table/table.go index 01bf6349..893c9343 100644 --- a/table/table.go +++ b/table/table.go @@ -19,6 +19,7 @@ import ( "fmt" "net" "sort" + "strings" "github.com/armon/go-radix" "github.com/osrg/gobgp/packet/bgp" @@ -284,6 +285,41 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error) return results, nil } +func (t *Table) GetEvpnDestinationsWithRouteType(typ string) ([]*Destination, error) { + var routeType uint8 + switch strings.ToLower(typ) { + case "a-d": + routeType = bgp.EVPN_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY + case "macadv": + routeType = bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT + case "multicast": + routeType = bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG + case "esi": + routeType = bgp.EVPN_ETHERNET_SEGMENT_ROUTE + case "prefix": + routeType = bgp.EVPN_IP_PREFIX + default: + return nil, fmt.Errorf("unsupported evpn route type: %s", typ) + } + destinations := t.GetDestinations() + results := make([]*Destination, 0, len(destinations)) + switch t.routeFamily { + case bgp.RF_EVPN: + for _, dst := range destinations { + if nlri, ok := dst.nlri.(*bgp.EVPNNLRI); !ok { + return nil, fmt.Errorf("invalid evpn nlri type detected: %T", dst.nlri) + } else if nlri.RouteType == routeType { + results = append(results, dst) + } + } + default: + for _, dst := range destinations { + results = append(results, dst) + } + } + return results, nil +} + func (t *Table) setDestination(key string, dest *Destination) { t.destinations[key] = dest } @@ -400,8 +436,21 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) { } } } + case bgp.RF_EVPN: + for _, p := range prefixes { + // Uses LookupPrefix.Prefix as EVPN Route Type string + ds, err := t.GetEvpnDestinationsWithRouteType(p.Prefix) + if err != nil { + return nil, err + } + for _, dst := range ds { + if d := dst.Select(dOption); d != nil { + dsts[dst.GetNlri().String()] = d + } + } + } default: - return nil, fmt.Errorf("route filtering is only supported for IPv4/IPv6 unicast/mpls routes") + return nil, fmt.Errorf("route filtering is not supported for this family") } } else { for k, dst := range t.GetDestinations() { |