public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH ifupdown2] d/patches: add patch for adding IPv6 vxlan-local-tunnelip
@ 2025-10-14 13:00 Christoph Heiss
  2025-10-14 14:14 ` Gabriel Goller
  0 siblings, 1 reply; 2+ messages in thread
From: Christoph Heiss @ 2025-10-14 13:00 UTC (permalink / raw)
  To: pve-devel

Fixes #5398 [0].

This patch makes it possible to use an IPv6 address for the local VXLAN
tunnel address, in addition to IPv4 addresses. With this change it's
possible to use IPv6 as the underlay for a VXLAN based network without
the need for IPv4.

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=5398

Upstream-Link: https://github.com/CumulusNetworks/ifupdown2/pull/315
Suggested-by: Stefan Hanreich <s.hanreich@proxmox.com>
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Stefan suggested the inclusion of this patch, as it's been a fairly
requested features.

Marked it as RFC tho, as it is untested (Gabriel volunteered for this,
as he has a setup for that) and upstream still doesn't seem to have
decided if the attribute should be renamed to `vxlan-local-tunnelip6`.

Pulling it in now would mean that we're "stuck" with that name, if we
don't want to break users later on, if the attribute is really renamed -
or we could also support both styles in that case.

 debian/patches/series                         |   1 +
 ...upport-for-IPv6-vxlan-local-tunnelip.patch | 134 ++++++++++++++++++
 2 files changed, 135 insertions(+)
 create mode 100644 debian/patches/upstream/0002-vxlan-Add-support-for-IPv6-vxlan-local-tunnelip.patch

diff --git a/debian/patches/series b/debian/patches/series
index 266f57d..d045d1f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -13,4 +13,5 @@ pve/0012-addons-nlcache-set-interface-mtu-through-netlink-ins.patch
 pve/0013-addons-nlcache-set-interface-alias-through-netlink-i.patch
 upstream/0001-add-ipv6-slaac-support-inet6-auto-and-accept_ra.patch
 upstream/0001-use-raw-strings-for-regex-to-fix-backslash-interpret.patch
+upstream/0002-vxlan-Add-support-for-IPv6-vxlan-local-tunnelip.patch
 pve/0014-nlmanager-read-ipv6-devconf-disable_ipv6-attribute-t.patch
diff --git a/debian/patches/upstream/0002-vxlan-Add-support-for-IPv6-vxlan-local-tunnelip.patch b/debian/patches/upstream/0002-vxlan-Add-support-for-IPv6-vxlan-local-tunnelip.patch
new file mode 100644
index 0000000..eec26f1
--- /dev/null
+++ b/debian/patches/upstream/0002-vxlan-Add-support-for-IPv6-vxlan-local-tunnelip.patch
@@ -0,0 +1,134 @@
+From d085fb18a45c7b5d69ffbfa54be91f31c2d396a8 Mon Sep 17 00:00:00 2001
+From: Christoph Heiss <c.heiss@proxmox.com>
+Date: Thu, 17 Jul 2025 14:13:01 +0200
+Subject: [PATCH] vxlan: Add support for IPv6 vxlan-local-tunnelip
+
+This commit adds the option to pass an IPv6 address instead of an IPv4 address to use as
+local tunnel IP address. With this change it's possible to use IPv6 as the underlay for
+a VXLAN based network without the need for IPv4.
+
+Upstream-Link: https://github.com/CumulusNetworks/ifupdown2/pull/315
+Authored-by: Wido den Hollander <wido@widodh.nl>
+  [ CH: rebased on our tree, added appropriate logging in iproute2 module ]
+Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
+---
+ ifupdown2/addons/vxlan.py | 12 +++++++-----
+ ifupdown2/lib/iproute2.py | 26 +++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/ifupdown2/addons/vxlan.py b/ifupdown2/addons/vxlan.py
+index cc8d3b3..250a462 100644
+--- a/ifupdown2/addons/vxlan.py
++++ b/ifupdown2/addons/vxlan.py
+@@ -51,7 +51,7 @@ class vxlan(Vxlan, moduleBase):
+             },
+             "vxlan-local-tunnelip": {
+                 "help": "vxlan local tunnel ip",
+-                "validvals": ["<ipv4>"],
++                "validvals": ["<ipv4>", "<ipv6>"],
+                 "example": ["vxlan-local-tunnelip 172.16.20.103"]
+             },
+             "vxlan-svcnodeip": {
+@@ -547,7 +547,7 @@ class vxlan(Vxlan, moduleBase):
+ 
+         if local:
+             try:
+-                local = ipnetwork.IPv4Address(local)
++                local = ipnetwork.IPAddress(local)
+ 
+                 if local.initialized_with_prefixlen:
+                     self.logger.warning("%s: vxlan-local-tunnelip %s: netmask ignored" % (ifname, local))
+@@ -1173,7 +1173,8 @@ class vxlan(Vxlan, moduleBase):
+                         vxlan_physdev,
+                         user_request_vxlan_info_data.get(Link.IFLA_VXLAN_PORT),
+                         vxlan_vnifilter,
+-                        vxlan_ttl
++                        vxlan_ttl,
++                        local.version
+                     )
+                 elif ifaceobj.link_privflags & ifaceLinkPrivFlags.L3VXI:
+                     self.iproute2.link_add_l3vxi(
+@@ -1183,7 +1184,8 @@ class vxlan(Vxlan, moduleBase):
+                         group.ip if group else None,
+                         vxlan_physdev,
+                         user_request_vxlan_info_data.get(Link.IFLA_VXLAN_PORT),
+-                        vxlan_ttl
++                        vxlan_ttl,
++                        local.version
+                     )
+                 else:
+                     try:
+@@ -1235,7 +1237,7 @@ class vxlan(Vxlan, moduleBase):
+         if remoteips:
+             try:
+                 for remoteip in remoteips:
+-                    ipnetwork.IPv4Address(remoteip)
++                    ipnetwork.IPAddress(remoteip)
+             except Exception as e:
+                 self.log_error('%s: vxlan-remoteip: %s' % (ifaceobj.name, str(e)))
+ 
+diff --git a/ifupdown2/lib/iproute2.py b/ifupdown2/lib/iproute2.py
+index bbbfb43..b8ab7a1 100644
+--- a/ifupdown2/lib/iproute2.py
++++ b/ifupdown2/lib/iproute2.py
+@@ -280,17 +280,22 @@ class IPRoute2(Cache, Requirements):
+ 
+     ###
+ 
+-    def link_add_single_vxlan(self, link_exists, ifname, ip, group, physdev, port, vnifilter="off", ttl=None):
+-        self.logger.info("creating single vxlan device: %s" % ifname)
++    def link_add_single_vxlan(self, link_exists, ifname, ip, group, physdev, port, vnifilter="off", ttl=None, ipversion=4):
++        cmd = []
++
++        if ipversion == 6:
++            cmd.append("-6")
+ 
+         if link_exists:
++            self.logger.info("updating single vxlan device: %s" % ifname)
+             # When updating an SVD we need to use `ip link set` and we have to
+             # drop the external keyword:
+             # $ ip link set dev vxlan0 type vxlan external local 27.0.0.242 dev ipmr-lo
+             # Error: vxlan: cannot change COLLECT_METADATA flag.
+-            cmd = ["link set dev %s type vxlan" % ifname]
++            cmd.append("link set dev %s type vxlan" % ifname)
+         else:
+-            cmd = ["link add dev %s type vxlan external" % ifname]
++            self.logger.info("creating single vxlan device: %s" % ifname)
++            cmd.append("link add dev %s type vxlan external" % ifname)
+ 
+             # when changing local ip, if we specify vnifilter we get:
+             # Error: vxlan: cannot change flag.
+@@ -316,20 +321,27 @@ class IPRoute2(Cache, Requirements):
+         self.__execute_or_batch(utils.ip_cmd, " ".join(cmd))
+         self.__update_cache_after_link_creation(ifname, "vxlan")
+ 
+-    def link_add_l3vxi(self, link_exists, ifname, ip, group, physdev, port, ttl=None):
++    def link_add_l3vxi(self, link_exists, ifname, ip, group, physdev, port, ttl=None, ipversion=4):
+         self.logger.info("creating l3vxi device: %s" % ifname)
+ 
++        cmd = []
++
++        if ipversion == 6:
++            cmd.append("-6")
++
+         if link_exists:
++            self.logger.info("updating l3vxi device: %s" % ifname)
+             # When updating an SVD we need to use `ip link set` and we have to
+             # drop the external keyword:
+             # $ ip link set dev vxlan0 type vxlan external local 27.0.0.242 dev ipmr-lo
+             # Error: vxlan: cannot change COLLECT_METADATA flag.
+-            cmd = ["link set dev %s type vxlan" % ifname]
++            cmd.append("link set dev %s type vxlan" % ifname)
+         else:
+-            cmd = ["link add dev %s type vxlan external vnifilter" % ifname]
++            self.logger.info("creating l3vxi device: %s" % ifname)
+             # when changing local ip, if we specify vnifilter we get:
+             # Error: vxlan: cannot change flag.
+             # So we are only setting this attribute on vxlan creation
++            cmd.append("link add dev %s type vxlan external vnifilter" % ifname)
+ 
+         if ip:
+             cmd.append("local %s" % ip)
+-- 
+2.49.0
+
-- 
2.51.0



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [pve-devel] [PATCH ifupdown2] d/patches: add patch for adding IPv6 vxlan-local-tunnelip
  2025-10-14 13:00 [pve-devel] [PATCH ifupdown2] d/patches: add patch for adding IPv6 vxlan-local-tunnelip Christoph Heiss
@ 2025-10-14 14:14 ` Gabriel Goller
  0 siblings, 0 replies; 2+ messages in thread
From: Gabriel Goller @ 2025-10-14 14:14 UTC (permalink / raw)
  To: Christoph Heiss; +Cc: pve-devel

Just to keep the mailing list in the loop:

* when installing the packet the following error is visible: 

     find: ‘/var/lib/dhcp/’: No such file or directory

     but I didn't notice anything off, so probably a debian packaging
     thingy.

* when using a vxlan interface with a ipv6 tunnelip the reload fails:
     config:

     auto vrfvx_zone
     iface vrfvx_zone
             vxlan-id 101
             vxlan-local-tunnelip fc00:10::2
             bridge-learning off
             bridge-arp-nd-suppress on
             mtu 1450

     error:

     info: vrfvx_zone: netlink: ip link add dev vrfvx_zone type vxlan id 101 (with attributes)
     debug: attributes: {1: 101, 7: True, 15: 4789, 5: 0, 4: fc00:10::2}
     debug:   File "/usr/sbin/ifreload", line 139, in <module>
         sys.exit(main())
        File "/usr/sbin/ifreload", line 127, in main
         return stand_alone()
        File "/usr/sbin/ifreload", line 106, in stand_alone
         status = ifupdown2.main()
        File "/usr/share/ifupdown2/ifupdown/main.py", line 76, in main
         self.handlers.get(self.op)(self.args)
        File "/usr/share/ifupdown2/ifupdown/main.py", line 283, in run_reload
         ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
        File "/usr/share/ifupdown2/ifupdown/ifupdownmain.py", line 2460, in reload
         self._reload_default(*args, **kargs)
        File "/usr/share/ifupdown2/ifupdown/ifupdownmain.py", line 2438, in _reload_default
         ret = self._sched_ifaces(new_filtered_ifacenames, upops,
        File "/usr/share/ifupdown2/ifupdown/ifupdownmain.py", line 1576, in _sched_ifaces
         ifaceScheduler.sched_ifaces(self, ifacenames, ops,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 595, in sched_ifaces
         cls.run_iface_list(ifupdownobj, run_queue, ops,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 325, in run_iface_list
         cls.run_iface_graph(ifupdownobj, ifacename, ops, parent,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 302, in run_iface_graph
         cls.run_iface_list(ifupdownobj, dlist, ops,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 325, in run_iface_list
         cls.run_iface_graph(ifupdownobj, ifacename, ops, parent,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 302, in run_iface_graph
         cls.run_iface_list(ifupdownobj, dlist, ops,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 325, in run_iface_list
         cls.run_iface_graph(ifupdownobj, ifacename, ops, parent,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 315, in run_iface_graph
         cls.run_iface_list_ops(ifupdownobj, ifaceobjs, ops)
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 188, in run_iface_list_ops
         cls.run_iface_op(ifupdownobj, ifaceobj, op,
        File "/usr/share/ifupdown2/ifupdown/scheduler.py", line 106, in run_iface_op
         m.run(ifaceobj, op,
        File "/usr/share/ifupdown2/addons/vxlan.py", line 1761, in run
         op_handler(self, ifaceobj)
        File "/usr/share/ifupdown2/addons/vxlan.py", line 1204, in _up
         self.log_error("%s: vxlan creation failed: %s" % (ifname, str(e)), ifaceobj)
        File "/usr/share/ifupdown2/ifupdownaddons/modulebase.py", line 121, in log_error
         stack = traceback.format_stack()
     debug: Traceback (most recent call last):
       File "/usr/share/ifupdown2/addons/vxlan.py", line 1196, in _up
         self.netlink.link_add_vxlan_with_info_data(ifname, user_request_vxlan_info_data)
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       File "/usr/share/ifupdown2/lib/nlcache.py", line 3231, in link_add_vxlan_with_info_data
         link.build_message(next(self.sequence), self.pid)
         ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       File "/usr/share/ifupdown2/nlmanager/nlpacket.py", line 3908, in build_message
         attrs += attr.encode()
                  ~~~~~~~~~~~^^
       File "/usr/share/ifupdown2/nlmanager/nlpacket.py", line 3130, in encode
         raw = pack(pack_layout, *payload)
     struct.error: pack expected 25 items for packing (got 37)
     error: vrfvx_zone: vxlan creation failed: pack expected 25 items for packing (got 37)


Thanks for rebasing this!


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-10-14 14:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-14 13:00 [pve-devel] [PATCH ifupdown2] d/patches: add patch for adding IPv6 vxlan-local-tunnelip Christoph Heiss
2025-10-14 14:14 ` Gabriel Goller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal