adding gwipaddress features in network annotation
[ovn4nfv-k8s-plugin.git] / cmd / ovn4nfvk8s-cni / app / helper_linux.go
index 1702597..21db529 100644 (file)
@@ -6,13 +6,17 @@ import (
        "fmt"
        "net"
        "os/exec"
+       "ovn4nfv-k8s-plugin/internal/pkg/config"
+       "ovn4nfv-k8s-plugin/internal/pkg/network"
+       "ovn4nfv-k8s-plugin/internal/pkg/ovn"
        "strconv"
        "strings"
 
-       "github.com/sirupsen/logrus"
        "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"
 )
 
@@ -35,9 +39,78 @@ func renameLink(curName, newName string) error {
        return nil
 }
 
-func setupInterface(netns ns.NetNS, containerID, ifName, macAddress, ipAddress, gatewayIP, defaultGateway string, idx, mtu int) (*current.Interface, *current.Interface, error) {
+//Todo Comments
+func CreateNodeOVSInternalPort(nodeintfipaddr, nodeintfmacaddr, node string) error {
+       nodeName := strings.ToLower(node)
+       nodeOVSInternalIntfName := config.GetNodeIntfName(nodeName)
+
+       hwAddr, err := net.ParseMAC(nodeintfmacaddr)
+       if err != nil {
+               logrus.Errorf("Error is converting %q to net hwaddr: %v", nodeOVSInternalIntfName, err)
+               return fmt.Errorf("Error is converting %q to net hwaddr: %v", nodeOVSInternalIntfName, err)
+       }
+
+       ovsArgs := []string{
+               "add-port", "br-int", nodeOVSInternalIntfName, "--", "set",
+               "interface", nodeOVSInternalIntfName, "type=internal",
+               fmt.Sprintf("mac_in_use=%s", strings.ReplaceAll(hwAddr.String(), ":", "\\:")),
+               fmt.Sprintf("mac=%s", strings.ReplaceAll(hwAddr.String(), ":", "\\:")),
+               fmt.Sprintf("external_ids:iface-id=%s", nodeOVSInternalIntfName),
+       }
+       logrus.Infof("ovs-vsctl args - %v", ovsArgs)
+
+       //var out []byte
+       out, err := exec.Command("ovs-vsctl", ovsArgs...).CombinedOutput()
+       if err != nil {
+               logrus.Errorf("failure in creating Node OVS internal port - %s: %v - %q", nodeOVSInternalIntfName, err, string(out))
+               return fmt.Errorf("failure in creating Node OVS internal port - %s: %v - %q", nodeOVSInternalIntfName, err, string(out))
+       }
+       logrus.Infof("ovs-vsctl args - %v output:%v", ovsArgs, string(out))
+
+       link, err := netlink.LinkByName(nodeOVSInternalIntfName)
+       if err != nil {
+               logrus.Errorf("failed to get netlink for Node OVS internal port %s: %v", nodeOVSInternalIntfName, err)
+               return fmt.Errorf("failed to get netlink for Node OVS internal port %s: %v", nodeOVSInternalIntfName, err)
+       }
+
+       if err := netlink.LinkSetUp(link); err != nil {
+               logrus.Errorf("failed to set up netlink for Node OVS internal port %s: %v", nodeOVSInternalIntfName, err)
+               return fmt.Errorf("failed to set up netlink for Node OVS internal port %s: %v", nodeOVSInternalIntfName, err)
+       }
+
+       addr, err := netlink.ParseAddr(nodeintfipaddr)
+       if err != nil {
+               logrus.Errorf("failed to parse IP addr %s: %v", nodeintfipaddr, err)
+               return fmt.Errorf("failed to parse IP addr %s: %v", nodeintfipaddr, err)
+       }
+       err = netlink.AddrAdd(link, addr)
+       if err != nil {
+               logrus.Errorf("failed to parse IP addr %s: %v", nodeintfipaddr, err)
+               return fmt.Errorf("failed to add IP addr %s to %s: %v", nodeintfipaddr, nodeOVSInternalIntfName, err)
+       }
+
+       err = network.SetupAndEnsureIPTables(network.MasqRules(nodeOVSInternalIntfName))
+       if err != nil {
+               logrus.Errorf("failed to apply snat rule for %s: %v", nodeOVSInternalIntfName, err)
+               return fmt.Errorf("failed to apply snat rule for %s: %v", nodeOVSInternalIntfName, err)
+       }
+
+       return nil
+}
+
+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 {
@@ -86,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
@@ -104,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)
@@ -117,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
        }