Bug 1445054
| Summary: | Setting ipv6.disable=1 prevents both IPv4 and IPv6 socket opening for VXLAN tunnels | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Robb Manes <rmanes> | |
| Component: | kernel | Assignee: | Jiri Benc <jbenc> | |
| kernel sub component: | Tunnel | QA Contact: | Jan Tluka <jtluka> | |
| Status: | CLOSED ERRATA | Docs Contact: | ||
| Severity: | medium | |||
| Priority: | urgent | CC: | dhoward, jbenc, jreznik, martinbj2008, misalunk, mleitner, network-qe, rmanes, sdodson, stwalter, tatanaka | |
| Version: | 7.3 | Keywords: | ZStream | |
| Target Milestone: | rc | |||
| Target Release: | --- | |||
| Hardware: | Unspecified | |||
| OS: | Unspecified | |||
| Whiteboard: | ||||
| Fixed In Version: | kernel-3.10.0-668.el7 | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | ||
| Clone Of: | ||||
| : | 1454636 (view as bug list) | Environment: | ||
| Last Closed: | 2017-08-02 06:13:10 UTC | Type: | Bug | |
| Regression: | --- | Mount Type: | --- | |
| Documentation: | --- | CRM: | ||
| Verified Versions: | Category: | --- | ||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
| Cloudforms Team: | --- | Target Upstream Version: | ||
| Embargoed: | ||||
| Bug Depends On: | ||||
| Bug Blocks: | 1323132, 1454636 | |||
Valid workaround is to remove ipv6.disable=1, which will open both sockets.
Full reproduction steps:
- Configure two individual hosts on the same subnet, using 192.168.1.2 and 192.168.1.3 as an example.
- On each host (two separate hosts):
- Add an internal OpenVSwitch bridge to the host:
# ovs-vsctl add-br br-int
- Add a VXLAN port to the br-int device with the remote_ip address the peer system:
# ovs-vsctl add-port br-int vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.1.2
||OR||
# ovs-vsctl add-port br-int vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.1.3
- Add a veth pair to the OVS bridge and attach one end to the bridge, and provide it with a separate network address (10.10.10.2 and 10.10.10.3 on each host used in this example):
# ip link set type veth
# ip link set veth0 up
# ip link set veth1 up
# ovs-vsctl add-port br-int veth1
# ip addr add 10.10.10.2/24 dev veth0
||OR||
# ip addr add 10.10.10.3/24 dev veth0
Both sides should be able to ping 10.10.10.* devices on the vxlan tunnel to their respective peer. After adding ipv6.disable=1 to the /etc/sysconfig/grub line "GRUB_CMDLINE_LINUX" rebuild GRUB2 configuration:
- grub2-mkconfig -o /boot/grub2/grub.cfg
Reboot, and VXLAN should no longer function. Applying the patch in #1 will resolve the problem.
Hi Jiri. I believe this is a follow-up for b1be00a6c39f ("vxlan: support both IPv4 and IPv6 sockets in a single vxlan device").
The patch above will cause it log an error for ipv6 socket while it will be silent for ipv4 if it works. That doesn't seem very friendly, but the admin did disable ipv6 for that interface, so maybe that's okay.
Patches submitted upstream: http://patchwork.ozlabs.org/patch/756113/ http://patchwork.ozlabs.org/patch/756114/ *** Bug 1437778 has been marked as a duplicate of this bug. *** Patch(es) committed on kernel repository and an interim kernel build is undergoing testing Patch(es) available on kernel-3.10.0-668.el7 *** Bug 1452611 has been marked as a duplicate of this bug. *** Reproduced on 3.10.0-632.el7 kernel using script in comment 1. Adding ip6_disable=1 to kernel cmdline made vxlan not working. Verified on 3.10.0-668.el7 kernel. The vxlan works with or without ip6_disable=1 on kernel cmdline. *** Bug 1467387 has been marked as a duplicate of this bug. *** Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2017:1842 |
Description of problem: When booting with ipv6.disable=1, vxlan will fail to initialize with the error "vxlan: Cannot bind port 4789, err=-97" which is EAFNOSUPPORT. This is normally fine, except that should this IPv6 check fail due to EAFNOSUPPORT on the first call of __vxlan_sock_add(), the second non-IPv6 call of __vxlan_sock_add() will not occur. This is due to the check done in vxlan_add_sock(): When __vxlan_add_sock() will return failure due to EAFNOSUPPORT via vxlan_sock_add->__vxlan_sock_add->vxlan_create_sock->udp_sock_create() refusing the AF_INET6 address, the first check fails and the second will never retry, so no vxlan socket is made. static int vxlan_sock_add(struct vxlan_dev *vxlan) { bool ipv6 = vxlan->flags & VXLAN_F_IPV6; bool metadata = vxlan->flags & VXLAN_F_COLLECT_METADATA; int ret = 0; RCU_INIT_POINTER(vxlan->vn4_sock, NULL); #if IS_ENABLED(CONFIG_IPV6) RCU_INIT_POINTER(vxlan->vn6_sock, NULL); if (ipv6 || metadata) ret = __vxlan_sock_add(vxlan, true); #endif if ((!ret || ret == -EAFNOSUPPORT) && (!ipv6 || metadata)) ret = __vxlan_sock_add(vxlan, false); if (ret < 0) vxlan_sock_release(vxlan); return ret; } Fix, as authored by Marcelo Leitner, is as below: diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ebc98bb..2dfeda8 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2832,7 +2832,7 @@ static int vxlan_sock_add(struct vxlan_dev *vxlan) if (ipv6 || metadata) ret = __vxlan_sock_add(vxlan, true); #endif - if (!ret && (!ipv6 || metadata)) + if ((!ret || ret == -EAFNOSUPPORT) && (!ipv6 || metadata)) ret = __vxlan_sock_add(vxlan, false); if (ret < 0) vxlan_sock_release(vxlan); We now track to see if EAFNOSUPPORT is returned, and if it is we will fall through to an IPv4 socket using __vxlan_sock_add(). Version-Release number of selected component (if applicable): Occurs in latest net-next and affects RHEL7 by proxy. How reproducible: Every time. Steps to Reproduce: 1. Configure vxlan tunnel (I used an OVS bridge) on a host and attach a tap or veth to it: # ovs-vsctl add-br vxlan-br vx1 # ovs-vsctl add-port vxlan-br vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.222.21 # ovs-vsctl add-port vxlan-br $TAP/VETH 2. Attach a seperate network to the IP of the tap or veth device. 3. Reboot with ipv6.disable=1 as a command line option, vxlan tunnel will no longer function. Actual results: vxlan socket is not created for IPv4 despite only IPv6 being disabled Expected results: Only IPv6 socket should not be created, IPv4 socket should also be made.