From: Kuralamudhan Ramakrishnan Date: Mon, 10 Aug 2020 04:38:57 +0000 (-0700) Subject: adding gwipaddress features in network annotation X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=commitdiff_plain;h=69b6bceec76caea07f95ba5cc372205c16e0e11b;p=ovn4nfv-k8s-plugin.git adding gwipaddress features in network annotation - 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 Change-Id: I078dee22627b2fa92e34b6cc4fa2ec7c8cd58220 --- diff --git a/cmd/ovn4nfvk8s-cni/app/helper_linux.go b/cmd/ovn4nfvk8s-cni/app/helper_linux.go index cfcd4e9..21db529 100644 --- a/cmd/ovn4nfvk8s-cni/app/helper_linux.go +++ b/cmd/ovn4nfvk8s-cni/app/helper_linux.go @@ -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 := ¤t.Interface{} contIface := ¤t.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 --- 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 --- 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= diff --git a/internal/pkg/cniserver/cni.go b/internal/pkg/cniserver/cni.go index 95a41d5..ee848f7 100644 --- a/internal/pkg/cniserver/cni.go +++ b/internal/pkg/cniserver/cni.go @@ -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 diff --git a/internal/pkg/network/iface.go b/internal/pkg/network/iface.go index b2a57bd..d49566d 100644 --- a/internal/pkg/network/iface.go +++ b/internal/pkg/network/iface.go @@ -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) diff --git a/internal/pkg/ovn/ovn.go b/internal/pkg/ovn/ovn.go index 97dc99d..776c534 100644 --- a/internal/pkg/ovn/ovn.go +++ b/internal/pkg/ovn/ovn.go @@ -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)