]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
addons: link: porting 'veth-peer-name' attribute to python3 branch 3.0.0-1
authorJulien Fortin <julien@cumulusnetworks.com>
Thu, 14 May 2020 02:03:44 +0000 (04:03 +0200)
committerJulien Fortin <julien@cumulusnetworks.com>
Thu, 14 May 2020 02:08:04 +0000 (04:08 +0200)
original commit ported to the python3 branch:

commit bffa619b11ae7aa9e567c26c255c17ac6df2c495
Author: Maximilian Wilhelm <max@rfc2324.org>
Date:   Sat Jan 14 19:08:01 2017 +0100

    Add option 'veth-peer-name' to veth links and ensure proper configuration.

      The option »veth-peer-name« forces an veth peer link to be created with
      a specific interface name. As the interface name of the "local" part of
      the veth link pair already is defined by the name of the interface stanza
      this option is added to, now both sides are clearly named.

      As there is a bidirectional dependency of both link pairs - both cannot
      exist without the other - this presents a problem when setting up all
      interfaces. Depending on which interface is set up first there might be
      a problem when only on dependency is specified. Therefore adding the
      »veth-peer-name« option to both interface of the veth link pair ensures
      that regardless of which side is configured first the peer name will be
      set correctly. This intentionally creates a circular dependency which is
      handled accordingly.

      Fixing the config check for veth link-type while at it :)

Signed-off-by: Maximilian Wilhelm <max@rfc2324.org>
Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
debian/changelog
ifupdown2/addons/link.py
ifupdown2/ifupdown/ifupdownmain.py
ifupdown2/lib/iproute2.py

index a9e1660af11d81ff932d2690b820705857bc327a..0fc213d9d8c18fbfc304041be4920e657a181235 100644 (file)
@@ -5,6 +5,7 @@ ifupdown2 (3.0.0-1) unstable; urgency=medium
    * New: bridge-always-up attribute
    * New: set bridge mtu with policy default
    * New: ES bond with "es-sys-mac" attribute
+   * New: support for "veth-peer-name" attribute
    * New: dhcp policy: dhclient_retry_on_failure
    * New: support for marking interfaces as mgmt interfaces
    * New: bridge-vlan-vni-map attribute (single vxlan device)
index 1832014136170275d6a9b59a8ca51a3b1cd63c6e..a7923915ee4735cb55d951bd96a10d2e7ce01e59 100644 (file)
@@ -43,6 +43,11 @@ class link(Addon, moduleBase):
                 "example": ["link-down yes/no"],
                 "default": "no",
                 "validvals": ["yes", "no"]
+            },
+            "veth-peer-name": {
+                "help": "Name of the veth peer interface.",
+                "validvals": "<interface>",
+                "example": ["veth-peer-name veth_ext2int"]
             }
         }
     }
@@ -75,9 +80,26 @@ class link(Addon, moduleBase):
         if ifaceobj.get_attr_value_first('link-type'):
             ifaceobj.link_kind = ifaceLinkKind.OTHER
 
+        link_type = ifaceobj.get_attr_value_first("link-type")
+        # If this interface is one side of a veth link pair and a name for
+        # the peer interface if given, pass it to the link_create call.
+        if link_type == "veth" and ifaceobj.get_attr_value_first("veth-peer-name"):
+            return [ifaceobj.get_attr_value_first("veth-peer-name")]
+
+        return None
+
     def _up(self, ifaceobj):
-        link_type = ifaceobj.get_attr_value_first('link-type')
-        if link_type:
+        link_type = ifaceobj.get_attr_value_first("link-type")
+
+        # If this interface is one side of a veth link pair and a name for
+        # the peer interface if given, pass it to the link_create call.
+        if link_type == "veth":
+            peer_name = ifaceobj.get_attr_value_first("veth-peer-name")
+
+            if peer_name and not self.cache.link_exists(ifaceobj.name):
+                self.iproute2.link_add_veth(ifaceobj.name, peer_name)
+
+        elif link_type:
             self.netlink.link_add(ifname=ifaceobj.name, kind=link_type)
 
     def _down(self, ifaceobj):
index fa67000e77e20c6f571c1398c7ab8c247e26db3d..04dd6d79c47314efda4602c3179433e1f4a7ef25 100644 (file)
@@ -741,6 +741,32 @@ class ifupdownMain:
             if ulist: ret_ulist.extend(ulist)
         return list(set(ret_ulist))
 
+    def _remove_circular_veth_dependencies(self, ifaceobj, dlist):
+        # if ifaceobj isn't a veth link, ignore it.
+        if ifaceobj.get_attr_value_first('link-type') != "veth":
+            return
+
+        for diface in dlist:
+            difaceobj = self.get_ifaceobj_first(diface)
+            # If the dependent iface isn't a veth link - which shouldn't
+            # happen - ignore it to be save.
+            if difaceobj and difaceobj.get_attr_value_first('link-type') != "veth":
+                continue
+
+            # If the peer has a desired peer name set and this is us,
+            # see if the peer has a dependency to us too and remove our
+            # redundant dependency to the peer.
+            diface_peer_name = difaceobj.get_attr_value_first('veth-peer-name')
+            if diface_peer_name and diface_peer_name == ifaceobj.name:
+                peer_dlist = difaceobj.lowerifaces
+                if not peer_dlist:
+                    # Not list of dependent interface on the peer.
+                    continue
+
+                # We aleady are in the peers dlist, don't add dependcy from us to peer
+                if ifaceobj.name in peer_dlist:
+                    dlist.remove(difaceobj.name)
+
     def populate_dependency_info(self, ops, ifacenames=None):
         """ recursive function to generate iface dependency info """
 
@@ -774,6 +800,7 @@ class ifupdownMain:
             if dependents_processed:
                 continue
             if dlist:
+                self._remove_circular_veth_dependencies(ifaceobj, dlist)
                 self.preprocess_dependency_list(ifaceobj,
                                                 dlist, ops)
                 ifaceobj.lowerifaces = dlist
index 2b960a6c1391a34be55401acb9e142737f77c4e1..ee26c36c5d44c3c3dd027a9d8a8819794fdc0bb8 100644 (file)
@@ -269,6 +269,14 @@ class IPRoute2(Cache, Requirements):
 
     ###
 
+    def link_add_veth(self, ifname, peer_name):
+        utils.exec_command(
+            "%s link add %s type veth peer name %s"
+            % (utils.ip_cmd, ifname, peer_name)
+        )
+
+    ###
+
     def link_add_single_vxlan(self, ifname, ip, port):
         self.logger.info("creating single vxlan device: %s" % ifname)