Skip to content

Commit

Permalink
Merge pull request openshift#1131 from trozet/bz2092501
Browse files Browse the repository at this point in the history
Bug 2092501: Fixes finding default gateway for configured GW interface

Signed-off-by: Patryk Diak <pdiak@redhat.com>
  • Loading branch information
openshift-ci[bot] authored and kyrtapz committed Jun 22, 2022
2 parents 42c8f75 + 5cd68fd commit 1075990
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
2 changes: 1 addition & 1 deletion go-controller/pkg/node/gateway_init.go
Expand Up @@ -138,7 +138,7 @@ func getGatewayNextHops() ([]net.IP, string, error) {
}
gatewayIntf := config.Gateway.Interface
if needIPv4NextHop || needIPv6NextHop || gatewayIntf == "" {
defaultGatewayIntf, defaultGatewayNextHops, err := getDefaultGatewayInterfaceDetails()
defaultGatewayIntf, defaultGatewayNextHops, err := getDefaultGatewayInterfaceDetails(gatewayIntf)
if err != nil {
return nil, "", err
}
Expand Down
9 changes: 9 additions & 0 deletions go-controller/pkg/node/gateway_init_linux_test.go
Expand Up @@ -994,6 +994,15 @@ var _ = Describe("Gateway Init Operations", func() {
It("sets up a shared interface gateway with tagged VLAN", func() {
shareGatewayInterfaceTest(app, testNS, eth0Name, eth0MAC, eth0IP, eth0GWIP, eth0CIDR, 3000)
})

config.Gateway.Interface = eth0Name
It("sets up a shared interface gateway with predetermined gateway interface", func() {
shareGatewayInterfaceTest(app, testNS, eth0Name, eth0MAC, eth0IP, eth0GWIP, eth0CIDR, 0)
})

It("sets up a shared interface gateway with tagged VLAN + predetermined gateway interface", func() {
shareGatewayInterfaceTest(app, testNS, eth0Name, eth0MAC, eth0IP, eth0GWIP, eth0CIDR, 3000)
})
})
})

Expand Down
56 changes: 47 additions & 9 deletions go-controller/pkg/node/helper_linux.go
Expand Up @@ -16,13 +16,14 @@ import (

// getDefaultGatewayInterfaceDetails returns the interface name on
// which the default gateway (for route to 0.0.0.0) is configured.
// optionally pass the pre-determined gateway interface
// It also returns the default gateways themselves.
func getDefaultGatewayInterfaceDetails() (string, []net.IP, error) {
func getDefaultGatewayInterfaceDetails(gwIface string) (string, []net.IP, error) {
var intfName string
var gatewayIPs []net.IP

if config.IPv4Mode {
intfIPv4Name, gw, err := getDefaultGatewayInterfaceByFamily(netlink.FAMILY_V4)
intfIPv4Name, gw, err := getDefaultGatewayInterfaceByFamily(netlink.FAMILY_V4, gwIface)
if err != nil {
return "", gatewayIPs, err
}
Expand All @@ -31,7 +32,7 @@ func getDefaultGatewayInterfaceDetails() (string, []net.IP, error) {
}

if config.IPv6Mode {
intfIPv6Name, gw, err := getDefaultGatewayInterfaceByFamily(netlink.FAMILY_V6)
intfIPv6Name, gw, err := getDefaultGatewayInterfaceByFamily(netlink.FAMILY_V6, gwIface)
if err != nil {
return "", gatewayIPs, err
}
Expand All @@ -50,10 +51,29 @@ func getDefaultGatewayInterfaceDetails() (string, []net.IP, error) {
return intfName, gatewayIPs, nil
}

func getDefaultGatewayInterfaceByFamily(family int) (string, net.IP, error) {
// uses netlink to do a route lookup for default gateway
// takes IP address family and optional name of a pre-determined gateway interface
// returns name of default gateway interface, the default gateway ip, and any error
func getDefaultGatewayInterfaceByFamily(family int, gwIface string) (string, net.IP, error) {
// filter the default route to obtain the gateway
filter := &netlink.Route{Dst: nil}
routes, err := netlink.RouteListFiltered(family, filter, netlink.RT_FILTER_DST)
mask := netlink.RT_FILTER_DST
// gw interface provided
if len(gwIface) > 0 {
link, err := netlink.LinkByName(gwIface)
if err != nil {
return "", nil, fmt.Errorf("error looking up gw interface: %q, error: %w", gwIface, err)
}
if link.Attrs() == nil {
return "", nil, fmt.Errorf("no attributes found for link: %#v", link)
}
gwIfIdx := link.Attrs().Index
klog.Infof("Provided gateway interface %q, found as index: %d", gwIface, gwIfIdx)
filter.LinkIndex = gwIfIdx
mask = mask | netlink.RT_FILTER_OIF
}

routes, err := netlink.RouteListFiltered(family, filter, mask)
if err != nil {
return "", nil, errors.Wrapf(err, "failed to get routing table in node")
}
Expand All @@ -70,8 +90,17 @@ func getDefaultGatewayInterfaceByFamily(family int) (string, net.IP, error) {
klog.Warningf("Failed to get gateway for route %v : %v", r, err)
continue
}
klog.Infof("Found default gateway interface %s %s", intfLink.Attrs().Name, r.Gw.String())
return intfLink.Attrs().Name, r.Gw, nil
if intfLink.Attrs() == nil {
return "", nil, fmt.Errorf("no attributes found for link: %#v", intfLink.Attrs())
}
foundIfName := intfLink.Attrs().Name
klog.Infof("Found default gateway interface %s %s", foundIfName, r.Gw.String())
if len(gwIface) > 0 && gwIface != foundIfName {
// this should not happen, but if it did, indicates something broken with our use of the netlink lib
return "", nil, fmt.Errorf("mistmaching provided gw interface: %s and gateway found: %s",
gwIface, foundIfName)
}
return foundIfName, r.Gw, nil
}

// multipath, use the first valid entry
Expand All @@ -87,8 +116,17 @@ func getDefaultGatewayInterfaceByFamily(family int) (string, net.IP, error) {
klog.Warningf("Failed to get gateway for multipath route %v : %v", nh, err)
continue
}
klog.Infof("Found default gateway interface %s %s", intfLink.Attrs().Name, nh.Gw.String())
return intfLink.Attrs().Name, nh.Gw, nil
if intfLink.Attrs() == nil {
return "", nil, fmt.Errorf("no attributes found for link: %#v", intfLink.Attrs())
}
foundIfName := intfLink.Attrs().Name
klog.Infof("Found default gateway interface %s %s", foundIfName, nh.Gw.String())
if len(gwIface) > 0 && gwIface != foundIfName {
// this should not happen, but if it did, indicates something broken with our use of the netlink lib
return "", nil, fmt.Errorf("mistmaching provided gw interface: %q and gateway found: %q",
gwIface, foundIfName)
}
return foundIfName, nh.Gw, nil
}
}
return "", net.IP{}, fmt.Errorf("failed to get default gateway interface")
Expand Down
3 changes: 2 additions & 1 deletion go-controller/pkg/ovn/master.go
Expand Up @@ -1474,7 +1474,8 @@ func (oc *Controller) syncNodesRetriable(nodes []interface{}) error {

knownChassisNames := sets.NewString()
chassisDeleteList := []*sbdb.Chassis{}
for _, chassis := range chassisList {
for i, _ := range chassisList {
chassis := chassisList[i]
knownChassisNames.Insert(chassis.Name)
// skip chassis that have a corresponding node
if foundNodes.Has(chassis.Hostname) {
Expand Down

0 comments on commit 1075990

Please sign in to comment.