adding gwipaddress features in network annotation 03/70703/5
authorKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>
Mon, 10 Aug 2020 04:38:57 +0000 (21:38 -0700)
committerKuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>
Fri, 18 Sep 2020 00:10:02 +0000 (17:10 -0700)
- check defautgateway is true only for one network
- first network with defautgateway is only configured, rest is ignored
- add node network and ovn4nfv0-* route info for eth0 interface

Signed-off-by: Kuralamudhan Ramakrishnan <kuralamudhan.ramakrishnan@intel.com>
Change-Id: I078dee22627b2fa92e34b6cc4fa2ec7c8cd58220

cmd/ovn4nfvk8s-cni/app/helper_linux.go
go.mod
go.sum
internal/pkg/cniserver/cni.go
internal/pkg/network/iface.go
internal/pkg/ovn/ovn.go

index cfcd4e9..21db529 100644 (file)
@@ -8,12 +8,14 @@ import (
        "os/exec"
        "ovn4nfv-k8s-plugin/internal/pkg/config"
        "ovn4nfv-k8s-plugin/internal/pkg/network"
+       "ovn4nfv-k8s-plugin/internal/pkg/ovn"
        "strconv"
        "strings"
 
        "github.com/containernetworking/cni/pkg/types/current"
        "github.com/containernetworking/plugins/pkg/ip"
        "github.com/containernetworking/plugins/pkg/ns"
+       "github.com/prometheus/common/log"
        "github.com/sirupsen/logrus"
        "github.com/vishvananda/netlink"
 )
@@ -96,9 +98,19 @@ func CreateNodeOVSInternalPort(nodeintfipaddr, nodeintfmacaddr, node string) err
        return nil
 }
 
-func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress, gatewayIP, defaultGateway string, idx, mtu int) (*current.Interface, *current.Interface, error) {
+func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress, gatewayIP, defaultGateway string, idx, mtu int, isDefaultGW bool) (*current.Interface, *current.Interface, error) {
        hostIface := &current.Interface{}
        contIface := &current.Interface{}
+       var hostNet string
+
+       if defaultGateway == "false" && isDefaultGW == true && ifName == "eth0" {
+               var err error
+               hostNet, err = network.GetHostNetwork()
+               if err != nil {
+                       log.Error(err, "Failed to get host network")
+                       return nil, nil, fmt.Errorf("failed to get host network: %v", err)
+               }
+       }
 
        var oldHostVethName string
        err := netns.Do(func(hostNS ns.NetNS) error {
@@ -147,6 +159,15 @@ func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress,
                                return err
                        }
                }
+
+               if defaultGateway == "false" && isDefaultGW == true && ifName == "eth0" {
+                       stdout, stderr, err := ovn.RunIP("route", "add", hostNet, "via", gatewayIP)
+                       if err != nil && !strings.Contains(stderr, "RTNETLINK answers: File exists") {
+                               logrus.Errorf("Failed to ip route add stout %s, stderr %s, err %v", stdout, stderr, err)
+                               return fmt.Errorf("Failed to ip route add stout %s, stderr %s, err %v", stdout, stderr, err)
+                       }
+               }
+
                oldHostVethName = hostVeth.Name
 
                return nil
@@ -165,7 +186,7 @@ func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress,
 }
 
 // ConfigureInterface sets up the container interface
-var ConfigureInterface = func(containerNetns, containerID, ifName, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway string, idx, mtu int) ([]*current.Interface, error) {
+var ConfigureInterface = func(containerNetns, containerID, ifName, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway string, idx, mtu int, isDefaultGW bool) ([]*current.Interface, error) {
        netns, err := ns.GetNS(containerNetns)
        if err != nil {
                return nil, fmt.Errorf("failed to open netns %q: %v", containerNetns, err)
@@ -178,9 +199,8 @@ var ConfigureInterface = func(containerNetns, containerID, ifName, namespace, po
        } else {
                ifaceID = fmt.Sprintf("%s_%s", namespace, podName)
                interfaceName = ifName
-               defaultGateway = "true"
        }
-       hostIface, contIface, err := setupInterface(netns, containerID, interfaceName, macAddress, ipAddress, gatewayIP, defaultGateway, idx, mtu)
+       hostIface, contIface, err := setupInterface(netns, containerID, interfaceName, macAddress, ipAddress, gatewayIP, defaultGateway, idx, mtu, isDefaultGW)
        if err != nil {
                return nil, err
        }
diff --git a/go.mod b/go.mod
index ff0bd8f..4c2f46c 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -40,6 +40,7 @@ require (
        github.com/opencontainers/image-spec v1.0.1 // indirect
        github.com/phpdave11/gofpdi v1.0.8 // indirect
        github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 // indirect
+       github.com/prometheus/common v0.2.0
        github.com/rogpeppe/go-charset v0.0.0-20190617161244-0dc95cdf6f31 // indirect
        github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 // indirect
        github.com/sirupsen/logrus v1.4.2
diff --git a/go.sum b/go.sum
index a49ac00..b65e61c 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -63,7 +63,9 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/ajstarks/svgo v0.0.0-20191124160048-bd5c74aaa11c/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@@ -873,6 +875,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
 google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
index 95a41d5..ee848f7 100644 (file)
@@ -107,6 +107,7 @@ func (cr *CNIServerRequest) addMultipleInterfaces(ovnAnnotation, namespace, podN
        var index int
        var result *current.Result
        var dstResult types.Result
+       var isDefaultGW bool
        for _, ovnNet := range ovnAnnotatedMap {
                ipAddress := ovnNet["ip_address"]
                macAddress := ovnNet["mac_address"]
@@ -124,8 +125,23 @@ func (cr *CNIServerRequest) addMultipleInterfaces(ovnAnnotation, namespace, podN
                        klog.Errorf("addMultipleInterfaces: interface can't be null")
                        return nil
                }
+
+               if interfaceName != "*" && defaultGateway == "true" && isDefaultGW == false {
+                       isDefaultGW = true
+               } else if interfaceName != "*" && defaultGateway == "true" {
+                       defaultGateway = "false"
+               }
+
+               if interfaceName == "*" && isDefaultGW == true {
+                       defaultGateway = "false"
+               }
+
+               if interfaceName == "*" && isDefaultGW == false {
+                       defaultGateway = "true"
+               }
+
                klog.Infof("addMultipleInterfaces: ipAddress %v %v", ipAddress, interfaceName)
-               interfacesArray, err = app.ConfigureInterface(cr.Netns, cr.SandboxID, cr.IfName, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway, index, config.Default.MTU)
+               interfacesArray, err = app.ConfigureInterface(cr.Netns, cr.SandboxID, cr.IfName, namespace, podName, macAddress, ipAddress, gatewayIP, interfaceName, defaultGateway, index, config.Default.MTU, isDefaultGW)
                if err != nil {
                        klog.Errorf("Failed to configure interface in pod: %v", err)
                        return nil
index b2a57bd..d49566d 100644 (file)
@@ -27,6 +27,24 @@ func GetDefaultGateway() (string, error) {
        return "", errors.New("Unable to find default route")
 }
 
+//CheckRoute return bool isPresent
+func CheckRoute(dst, gw string) (bool, error) {
+       var isPresent bool
+       routes, err := netlink.RouteList(nil, syscall.AF_INET)
+       if err != nil {
+               return isPresent, err
+       }
+
+       for _, route := range routes {
+               if route.Dst.String() == dst && route.Gw.To4().String() == gw {
+                       isPresent = true
+               }
+       }
+
+       return isPresent, nil
+
+}
+
 // GetDefaultGatewayInterface return default gateway interface link
 func GetDefaultGatewayInterface() (*net.Interface, error) {
        routes, err := netlink.RouteList(nil, syscall.AF_INET)
index 97dc99d..776c534 100644 (file)
@@ -63,6 +63,7 @@ type netInterface struct {
        DefaultGateway string
        IPAddress      string
        MacAddress     string
+       GWIPaddress    string
 }
 
 var ovnCtl *Controller
@@ -159,7 +160,7 @@ func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]int
                        portName = fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
                        ns.Interface = "*"
                }
-               outStr = oc.addLogicalPortWithSwitch(pod, ns.Name, ns.IPAddress, ns.MacAddress, portName)
+               outStr = oc.addLogicalPortWithSwitch(pod, ns.Name, ns.IPAddress, ns.MacAddress, ns.GWIPaddress, portName)
                if outStr == "" {
                        return
                }
@@ -174,7 +175,7 @@ func (oc *Controller) AddLogicalPorts(pod *kapi.Pod, ovnNetObjs []map[string]int
        if defaultInterface == false {
                // Add Default interface
                portName := fmt.Sprintf("%s_%s", pod.Namespace, pod.Name)
-               outStr = oc.addLogicalPortWithSwitch(pod, Ovn4nfvDefaultNw, "", "", portName)
+               outStr = oc.addLogicalPortWithSwitch(pod, Ovn4nfvDefaultNw, "", "", "", portName)
                if outStr == "" {
                        return
                }
@@ -465,7 +466,7 @@ func (oc *Controller) getNodeLogicalPortIPAddr(pod *kapi.Pod) (ipAddress string,
        return ipAddr, nil
 }
 
-func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipAddress, macAddress, portName string) (annotation string) {
+func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipAddress, macAddress, gwipAddress, portName string) (annotation string) {
        var out, stderr string
        var err error
        var isStaticIP bool
@@ -552,10 +553,15 @@ func (oc *Controller) addLogicalPortWithSwitch(pod *kapi.Pod, logicalSwitch, ipA
                return
        }
 
-       gatewayIP, err := oc.getNodeLogicalPortIPAddr(pod)
-       if err != nil {
-               log.Error(err, "Error obtaining gateway address for switch", "logicalSwitch", logicalSwitch)
-               return
+       var gatewayIP string
+       if gwipAddress != "" {
+               gatewayIP = gwipAddress
+       } else {
+               gatewayIP, err = oc.getNodeLogicalPortIPAddr(pod)
+               if err != nil {
+                       log.Error(err, "Error obtaining gateway address for switch", "logicalSwitch", logicalSwitch)
+                       return
+               }
        }
 
        annotation = fmt.Sprintf(`{\"ip_address\":\"%s/%s\", \"mac_address\":\"%s\", \"gateway_ip\": \"%s\"}`, addresses[1], mask, addresses[0], gatewayIP)