From 63c3b90e0547aa5a0457f53eadee15e196d1aa8d Mon Sep 17 00:00:00 2001 From: Aaron U'Ren Date: Tue, 20 Jul 2021 13:35:36 -0500 Subject: [PATCH] fact(injectRoute): extract parseBGPPath method to simplify --- .../routing/network_routes_controller.go | 36 ++------------- pkg/controllers/routing/utils.go | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/pkg/controllers/routing/network_routes_controller.go b/pkg/controllers/routing/network_routes_controller.go index 09f60dcd..120abfeb 100644 --- a/pkg/controllers/routing/network_routes_controller.go +++ b/pkg/controllers/routing/network_routes_controller.go @@ -508,39 +508,13 @@ func (nrc *NetworkRoutingController) advertisePodRoute() error { func (nrc *NetworkRoutingController) injectRoute(path *gobgpapi.Path) error { klog.V(2).Infof("injectRoute Path Looks Like: %s", path.String()) - var nextHop net.IP -out: - for _, pAttr := range path.GetPattrs() { - var value ptypes.DynamicAny - if err := ptypes.UnmarshalAny(pAttr, &value); err != nil { - return fmt.Errorf("failed to unmarshal path attribute: %s", err) - } - switch a := value.Message.(type) { - case *gobgpapi.NextHopAttribute: - nextHop = net.ParseIP(a.NextHop).To4() - if nextHop == nil { - if nextHop = net.ParseIP(a.NextHop).To16(); nextHop == nil { - return fmt.Errorf("invalid nextHop address: %s", a.NextHop) - } - } - break out - } - } - if nextHop == nil { - return fmt.Errorf("could not parse next hop received from GoBGP for path: %s", path) - } - nlri := path.GetNlri() - var prefix gobgpapi.IPAddressPrefix - err := ptypes.UnmarshalAny(nlri, &prefix) - if err != nil { - return fmt.Errorf("invalid nlri in advertised path") - } - dst, err := netlink.ParseIPNet(prefix.Prefix + "/" + fmt.Sprint(prefix.PrefixLen)) - if err != nil { - return fmt.Errorf("invalid nlri in advertised path") - } var route *netlink.Route + dst, nextHop, err := parseBGPPath(path) + if err != nil { + return err + } + tunnelName := generateTunnelName(nextHop.String()) sameSubnet := nrc.nodeSubnet.Contains(nextHop) diff --git a/pkg/controllers/routing/utils.go b/pkg/controllers/routing/utils.go index cc6f02b9..8cac7b8b 100644 --- a/pkg/controllers/routing/utils.go +++ b/pkg/controllers/routing/utils.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" + "github.com/golang/protobuf/ptypes" + gobgpapi "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/pkg/packet/bgp" "github.com/vishvananda/netlink" @@ -149,3 +151,47 @@ func validateCommunity(arg string) error { } return fmt.Errorf("failed to parse %s as community", arg) } + +// parseBGPNextHop takes in a GoBGP Path and parses out the destination's next hop from its attributes. If it +// can't parse a next hop IP from the GoBGP Path, it returns an error. +func parseBGPNextHop(path *gobgpapi.Path) (net.IP, error) { + for _, pAttr := range path.GetPattrs() { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(pAttr, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal path attribute: %s", err) + } + switch a := value.Message.(type) { + case *gobgpapi.NextHopAttribute: + nextHop := net.ParseIP(a.NextHop).To4() + if nextHop == nil { + if nextHop = net.ParseIP(a.NextHop).To16(); nextHop == nil { + return nil, fmt.Errorf("invalid nextHop address: %s", a.NextHop) + } + } + return nextHop, nil + } + } + return nil, fmt.Errorf("could not parse next hop received from GoBGP for path: %s", path) +} + +// parseBGPPath takes in a GoBGP Path and parses out the destination subnet and the next hop from its attributes. +// If successful, it will return the destination of the BGP path as a subnet form and the next hop. If it +// can't parse the destination or the next hop IP, it returns an error. +func parseBGPPath(path *gobgpapi.Path) (*net.IPNet, net.IP, error) { + nextHop, err := parseBGPNextHop(path) + if err != nil { + return nil, nil, err + } + + nlri := path.GetNlri() + var prefix gobgpapi.IPAddressPrefix + err = ptypes.UnmarshalAny(nlri, &prefix) + if err != nil { + return nil, nil, fmt.Errorf("invalid nlri in advertised path") + } + dstSubnet, err := netlink.ParseIPNet(prefix.Prefix + "/" + fmt.Sprint(prefix.PrefixLen)) + if err != nil { + return nil, nil, fmt.Errorf("couldn't parse IP subnet from nlri advertised path") + } + return dstSubnet, nextHop, nil +}