fact(injectRoute): extract parseBGPPath method to simplify

This commit is contained in:
Aaron U'Ren 2021-07-20 13:35:36 -05:00
parent e9be04ef2f
commit 63c3b90e05
2 changed files with 51 additions and 31 deletions

View File

@ -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)

View File

@ -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
}