summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-12-15 14:02:18 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-12-21 08:23:14 +0900
commit41f97f11056b097ab25b147abbd80a582e3ec019 (patch)
treea3c99463e7ae80742f0a1a5f15574efa08abd263
parenteaef2a30aa9720848387819fc9daf21ec1f2b8f0 (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.go9
-rw-r--r--table/table.go51
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() {