Skip to content

Commit

Permalink
CLI VPNv4/VPNv6 filtering
Browse files Browse the repository at this point in the history
gobgp CLI can filter VPNv4/VPNv6 prefixes with or without rd.
  • Loading branch information
horseinthesky authored and Kirill 'horseinthesky' Pletnev committed Sep 6, 2023
1 parent 002690b commit 35bfc96
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 162 deletions.
13 changes: 11 additions & 2 deletions api/gobgp.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/gobgp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ message TableLookupPrefix {
enum Type { EXACT = 0; LONGER = 1; SHORTER = 2; }
string prefix = 1;
Type type = 2;
string rd = 3;
}

message ListPathRequest {
Expand Down
38 changes: 21 additions & 17 deletions api/gobgp_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions cmd/gobgp/neighbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ func showNeighborRib(r string, name string, args []string) error {
showMUP := false
showIdentifier := bgp.BGP_ADD_PATH_NONE
validationTarget := ""
rd := ""

def := addr2AddressFamily(net.ParseIP(name))
switch r {
Expand Down Expand Up @@ -889,6 +890,25 @@ func showNeighborRib(r string, name string, args []string) error {
option = api.TableLookupPrefix_LONGER
} else if args[0] == "shorter-prefixes" {
option = api.TableLookupPrefix_SHORTER
} else if args[0] == "rd" {
switch rf {
case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN:
case bgp.RF_EVPN:
return fmt.Errorf("route distinguisher option for %q family is not implemented yet", rf)
default:
return fmt.Errorf("route distinguisher is not applicable to %q family", rf)
}

if len(args) < 2 {
return fmt.Errorf("no route distinguisher value specified")
}
args = args[1:]

rd := args[0]
_, err = bgp.ParseRouteDistinguisher(rd)
if err != nil {
return err
}
} else if args[0] == "validation" {
if r != cmdAdjIn {
return fmt.Errorf("RPKI information is supported for only adj-in")
Expand All @@ -901,6 +921,7 @@ func showNeighborRib(r string, name string, args []string) error {
}
filter = []*api.TableLookupPrefix{{
Prefix: target,
Rd: rd,
Type: option,
},
}
Expand Down
4 changes: 2 additions & 2 deletions docs/sources/cli-command-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ gobgp has the following subcommands.
# show all Route information
% gobgp global rib [-a <address family>]
# show a specific route information
% gobgp global rib [<prefix>|<host>] [longer-prefixes|shorter-prefixes] [-a <address family>]
% gobgp global rib [<prefix>|<host>] [rd <rd>] [longer-prefixes|shorter-prefixes] [-a <address family>]
# show table summary
% gobgp global rib summary [-a <address family>]
```
Expand Down Expand Up @@ -154,7 +154,7 @@ The following options can be specified in the neighbor subcommand:
# show all routes in [local|adj-in|adj-out] table
% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [-a <address family>]
# show a specific route in [local|adj-in|adj-out] table
% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [<prefix>|<host>] [longer-prefixes|shorter-prefixes] [-a <address family>]
% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [<prefix>|<host>] [rd <rd>] [longer-prefixes|shorter-prefixes] [-a <address family>]
# show table summary
% gobgp neighbor <neighbor address> [local|adj-in|adj-out] summary [-a <address family>]
# show RPKI detailed information in adj-in table
Expand Down
58 changes: 53 additions & 5 deletions internal/pkg/table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (

type LookupPrefix struct {
Prefix string
RD string
LookupOption
}

Expand Down Expand Up @@ -251,7 +252,6 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)
if err != nil {
return nil, err
}

ones, bits := network.Mask.Size()

r := critbitgo.NewNet()
Expand All @@ -270,16 +270,19 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)

r.Add(nlriToIPNet(dst.nlri), dst)
}

p := &net.IPNet{
IP: network.IP,
Mask: net.CIDRMask((ones>>3)<<3, bits),
}

mask := 0
div := 0
if ones%8 != 0 {
mask = 8 - ones&0x7
div = ones >> 3
}

r.WalkPrefix(p, func(n *net.IPNet, v interface{}) bool {
if mask != 0 && n.IP[div]>>mask != p.IP[div]>>mask {
return true
Expand Down Expand Up @@ -548,23 +551,57 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
for _, p := range prefixes {
switch p.LookupOption {
case LOOKUP_LONGER:
ds, err := t.GetLongerPrefixDestinations(p.Prefix)
_, prefix, err := net.ParseCIDR(p.Prefix)
if err != nil {
return nil, err
}

if p.RD == "" {
for _, dst := range t.GetDestinations() {
tablePrefix := nlriToIPNet(dst.nlri)

if bgp.ContainsCIDR(prefix, tablePrefix) {
r.setDestination(dst)
}
}

return r, nil
}

ds, err := t.GetLongerPrefixDestinations(p.RD + ":" + p.Prefix)
if err != nil {
return nil, err
}

for _, dst := range ds {
if d := dst.Select(dOption); d != nil {
r.setDestination(d)
}
}
case LOOKUP_SHORTER:
rd, addr, network, err := bgp.ParseVPNPrefix(p.Prefix)
addr, prefix, err := net.ParseCIDR(p.Prefix)
if err != nil {
return nil, err
}

ones, _ := network.Mask.Size()
if p.RD == "" {
for _, dst := range t.GetDestinations() {
tablePrefix := nlriToIPNet(dst.nlri)

if bgp.ContainsCIDR(tablePrefix, prefix) {
r.setDestination(dst)
}
}

return r, nil
}

rd, err := bgp.ParseRouteDistinguisher(p.RD)
if err != nil {
return nil, err
}

ones, _ := prefix.Mask.Size()
for i := ones; i >= 0; i-- {
_, prefix, _ := net.ParseCIDR(addr.String() + "/" + strconv.Itoa(i))

Expand All @@ -574,7 +611,18 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
}
}
default:
err := f(p.Prefix)
if p.RD == "" {
for _, dst := range t.GetDestinations() {
net := nlriToIPNet(dst.nlri)
if net.String() == p.Prefix {
r.setDestination(dst)
}
}

return r, nil
}

err := f(p.RD + ":" + p.Prefix)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 35bfc96

Please sign in to comment.