Skip to content
Permalink
Browse files

Properly uses default-route in annotation to set the gateway. Fixes n…

…etwork status results.
  • Loading branch information...
dougbtv committed Oct 23, 2019
1 parent 165e23b commit 3a9dd7ed76087062e067866a53ec8e0c9e67cef3
Showing with 99 additions and 9 deletions.
  1. +14 −0 k8sclient/k8sclient.go
  2. +24 −2 multus/multus.go
  3. +61 −5 netutils/netutils.go
  4. +0 −1 types/conf.go
  5. +0 −1 types/types.go
@@ -112,6 +112,20 @@ func SetNetworkStatus(client KubeClient, k8sArgs *types.K8sArgs, netStatus []*ty
if netStatus != nil {
var networkStatus []string
for _, status := range netStatus {
// Clean each empty gateway
// Otherwise we wind up with JSON that's a "default-route": [""]
cleargateway := true
for _, eachgateway := range status.Gateway {
if eachgateway != nil {
cleargateway = false
}
}

if cleargateway {
status.Gateway = nil
}

// Now we can sanely marshal the JSON output
data, err := json.MarshalIndent(status, "", " ")
if err != nil {
return logging.Errorf("SetNetworkStatus: error with Marshal Indent: %v", err)
@@ -251,7 +251,7 @@ func delegateAdd(exec invoke.Exec, ifName string, delegate *types.DelegateNetCon

cniArgs = fmt.Sprintf("%s;MAC=%s", cniArgs, delegate.MacRequest)
logging.Debugf("delegateAdd: set MAC address %q to %q", delegate.MacRequest, ifName)
rt.Args = append(rt.Args, [2]string{ "MAC", delegate.MacRequest })
rt.Args = append(rt.Args, [2]string{"MAC", delegate.MacRequest})
}

if delegate.IPRequest != nil {
@@ -270,7 +270,7 @@ func delegateAdd(exec invoke.Exec, ifName string, delegate *types.DelegateNetCon
ips := strings.Join(delegate.IPRequest, ",")
cniArgs = fmt.Sprintf("%s;IP=%s", cniArgs, ips)
logging.Debugf("delegateAdd: set IP address %q to %q", ips, ifName)
rt.Args = append(rt.Args, [2]string{ "IP", ips })
rt.Args = append(rt.Args, [2]string{"IP", ips})
}
}

@@ -421,13 +421,35 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn
}

// Remove gateway from routing table if the gateway is not used
deletegateway := false
adddefaultgateway := false
if delegate.IsFilterGateway {
deletegateway = true
logging.Debugf("Marked interface %v for gateway deletion", ifName)
} else {
// Otherwise, determine if this interface now gets our default route.
if delegate.GatewayRequest != nil {
deletegateway = true
adddefaultgateway = true
logging.Debugf("Detected gateway override on interface %v to %v", ifName, delegate.GatewayRequest)
}
}

if deletegateway {
tmpResult, err = netutils.DeleteDefaultGW(args, ifName, &tmpResult)
if err != nil {
return nil, logging.Errorf("Multus: Err in deleting gateway: %v", err)
}
}

// Here we'll set the default gateway
if adddefaultgateway {
tmpResult, err = netutils.SetDefaultGW(args, ifName, delegate.GatewayRequest, &tmpResult)
if err != nil {
return nil, logging.Errorf("Multus: Err in setting default gateway: %v", err)
}
}

// Master plugin result is always used if present
if delegate.MasterPlugin || result == nil {
result = tmpResult
@@ -20,23 +20,21 @@ import (
cnitypes "github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"

"github.com/intel/multus-cni/logging"

"github.com/vishvananda/netlink"
"net"
)

// DeleteDefaultGW removes the default gateway from marked interfaces.
func DeleteDefaultGW(args *skel.CmdArgs, ifName string, res *cnitypes.Result) (*current.Result, error) {
logging.Debugf("XXX: DeleteDefaultGW: %s", args.Netns)
result, err := current.NewResultFromResult(*res)
if err != nil {
return nil, logging.Errorf("XXX: %v", err)
return nil, logging.Errorf("DeleteDefaultGW: Error creating new from current CNI result: %v", err)
}

netns, err := ns.GetNS(args.Netns)
if err != nil {
return nil, logging.Errorf("XXX: %v", err)
return nil, logging.Errorf("DeleteDefaultGW: Error getting namespace %v", err)
}
defer netns.Close()

@@ -60,3 +58,61 @@ func DeleteDefaultGW(args *skel.CmdArgs, ifName string, res *cnitypes.Result) (*
result.Routes = newRoutes
return result, err
}

// SetDefaultGW adds a default gateway on a specific interface
func SetDefaultGW(args *skel.CmdArgs, ifName string, gateways []net.IP, res *cnitypes.Result) (*current.Result, error) {

// Use the current CNI result...
result, err := current.NewResultFromResult(*res)
if err != nil {
return nil, logging.Errorf("SetDefaultGW: Error creating new CNI result from current: %v", err)
}

// This ensures we're acting within the net namespace for the pod.
netns, err := ns.GetNS(args.Netns)
if err != nil {
return nil, logging.Errorf("SetDefaultGW: Error getting namespace %v", err)
}
defer netns.Close()

var newResultDefaultRoutes []*cnitypes.Route

// Do this within the net namespace.
err = netns.Do(func(_ ns.NetNS) error {
var err error

// Pick up the link info as we need the index.
link, _ := netlink.LinkByName(ifName)

// Cycle through all the desired gateways.
for _, gw := range gateways {

// Create a new route (note: dst is nil by default)
logging.Debugf("SetDefaultGW: Adding default route on %v (index: %v) to %v", ifName, link.Attrs().Index, gw)
newDefaultRoute := netlink.Route{
LinkIndex: link.Attrs().Index,
Gw: gw,
}

// Build a new element for the results route

// Set a correct CIDR depending on IP type
_, dstipnet, _ := net.ParseCIDR("::0/0")
if gw.To4 != nil {
_, dstipnet, _ = net.ParseCIDR("0.0.0.0/0")
}
newResultDefaultRoutes = append(newResultDefaultRoutes, &cnitypes.Route{Dst: *dstipnet, GW: gw})

// Perform the creation of the default route....
err = netlink.RouteAdd(&newDefaultRoute)
if err != nil {
logging.Errorf("SetDefaultGW: Error adding route: %v", err)
}
}
return err
})

result.Routes = newResultDefaultRoutes
return result, err

}
@@ -204,7 +204,6 @@ func LoadNetworkStatus(r types.Result, netName string, defaultNet bool) (*Networ
logging.Debugf("LoadNetworkStatus: %v, %s, %t", r, netName, defaultNet)
netstatus := &NetworkStatus{}
netstatus.Name = netName
netstatus.Default = defaultNet

// Convert whatever the IPAM result was into the current Result type
result, err := current.NewResultFromResult(r)
@@ -86,7 +86,6 @@ type NetworkStatus struct {
Interface string `json:"interface,omitempty"`
IPs []string `json:"ips,omitempty"`
Mac string `json:"mac,omitempty"`
Default bool `json:"default,omitempty"`
DNS types.DNS `json:"dns,omitempty"`
Gateway []net.IP `json:"default-route,omitempty"`
}

0 comments on commit 3a9dd7e

Please sign in to comment.
You can’t perform that action at this time.