<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/drivers/net/vxlan, branch master</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>vxlan: Stop rejecting dynamic FDB entries with a nexthop ID</title>
<updated>2026-11-02T16:07:43+00:00</updated>
<author>
<name>Ido Schimmel</name>
<email>idosch@nvidia.com</email>
</author>
<published>2026-10-30T13:37:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7308ef8b4a6779a39f68d053c19b53a5c584a663'/>
<id>7308ef8b4a6779a39f68d053c19b53a5c584a663</id>
<content type='text'>
Commit 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a
nexthop id") started rejecting FDB entries that point to FDB nexthops
unless they are configured as "permanent" or "static". The intent was to
prevent such entries from being aged out by vxlan_cleanup(), which runs
without RTNL and can therefore race with other VXLAN devices that modify
the same per-nexthop FDB list.

However, FRR installs remote MACs that are behind a multihomed Ethernet
Segment (EVPN-MH) as dynamic FDB entries that point to an FDB nexthop
group. Since the above commit, these entries are rejected and traffic
towards the corresponding MACs is flooded to all the remote VTEPs.

These entries are also marked as externally learned ("extern_learn")
and are therefore skipped by vxlan_cleanup(), but exempting externally
learned entries from the checks is not enough: vxlan_cleanup() reads
the state and flags of an entry without the hash lock, so an entry that
is concurrently changed from dynamic and externally learned to static
can still be aged out.

Instead, remove the checks added by the above commit and make
vxlan_cleanup() skip FDB entries that point to FDB nexthops. Such
entries can only be configured from user space, cannot be learned and
cannot roam, so there is no reason to age them out. The nexthop pointer
of an FDB entry is set before the entry is linked and is only cleared
after it was unlinked and an RCU grace period has passed, so it can be
checked without the hash lock.

Adjust the test cases added by the above commit and add a test case
that checks that dynamic FDB entries that point to FDB nexthops are not
aged out. Without the fix:

 # ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"

 IPv4 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [FAIL]
 TEST: Fdb mac add with nexthop group and extern_learn               [FAIL]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [FAIL]
 [...]

 IPv6 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [FAIL]
 TEST: Fdb mac add with nexthop group and extern_learn               [FAIL]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [FAIL]
 [...]

 Tests passed:  44
 Tests failed:   6
 Tests skipped:  0

With the fix:

 # ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"

 IPv4 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [ OK ]
 TEST: Fdb mac add with nexthop group and extern_learn               [ OK ]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [ OK ]
 [...]

 IPv6 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [ OK ]
 TEST: Fdb mac add with nexthop group and extern_learn               [ OK ]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [ OK ]
 [...]

 Tests passed:  50
 Tests failed:   0
 Tests skipped:  0

Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Fixes: 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a nexthop id")
Cc: stable@vger.kernel.org
Reported-by: Sascha Frey &lt;sf@techfak.net&gt;
Closes: https://lore.kernel.org/netdev/20261028142928.GA8406@techfak.de/
Tested-by: Sascha Frey &lt;sf@techfak.net&gt;
Signed-off-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Reviewed-by: Nikolay Aleksandrov &lt;razor@blackwall.org&gt;
Link: https://patch.msgid.link/20261030133750.28668-1-idosch@nvidia.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a
nexthop id") started rejecting FDB entries that point to FDB nexthops
unless they are configured as "permanent" or "static". The intent was to
prevent such entries from being aged out by vxlan_cleanup(), which runs
without RTNL and can therefore race with other VXLAN devices that modify
the same per-nexthop FDB list.

However, FRR installs remote MACs that are behind a multihomed Ethernet
Segment (EVPN-MH) as dynamic FDB entries that point to an FDB nexthop
group. Since the above commit, these entries are rejected and traffic
towards the corresponding MACs is flooded to all the remote VTEPs.

These entries are also marked as externally learned ("extern_learn")
and are therefore skipped by vxlan_cleanup(), but exempting externally
learned entries from the checks is not enough: vxlan_cleanup() reads
the state and flags of an entry without the hash lock, so an entry that
is concurrently changed from dynamic and externally learned to static
can still be aged out.

Instead, remove the checks added by the above commit and make
vxlan_cleanup() skip FDB entries that point to FDB nexthops. Such
entries can only be configured from user space, cannot be learned and
cannot roam, so there is no reason to age them out. The nexthop pointer
of an FDB entry is set before the entry is linked and is only cleared
after it was unlinked and an RCU grace period has passed, so it can be
checked without the hash lock.

Adjust the test cases added by the above commit and add a test case
that checks that dynamic FDB entries that point to FDB nexthops are not
aged out. Without the fix:

 # ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"

 IPv4 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [FAIL]
 TEST: Fdb mac add with nexthop group and extern_learn               [FAIL]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [FAIL]
 [...]

 IPv6 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [FAIL]
 TEST: Fdb mac add with nexthop group and extern_learn               [FAIL]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [FAIL]
 [...]

 Tests passed:  44
 Tests failed:   6
 Tests skipped:  0

With the fix:

 # ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"

 IPv4 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [ OK ]
 TEST: Fdb mac add with nexthop group and extern_learn               [ OK ]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [ OK ]
 [...]

 IPv6 fdb groups functional
 --------------------------
 [...]
 TEST: Fdb mac add with nexthop group and dynamic state              [ OK ]
 TEST: Fdb mac add with nexthop group and extern_learn               [ OK ]
 TEST: Fdb mac without nexthop group aged out                        [ OK ]
 TEST: Fdb mac with nexthop group not aged out                       [ OK ]
 [...]

 Tests passed:  50
 Tests failed:   0
 Tests skipped:  0

Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Fixes: 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a nexthop id")
Cc: stable@vger.kernel.org
Reported-by: Sascha Frey &lt;sf@techfak.net&gt;
Closes: https://lore.kernel.org/netdev/20261028142928.GA8406@techfak.de/
Tested-by: Sascha Frey &lt;sf@techfak.net&gt;
Signed-off-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Reviewed-by: Nikolay Aleksandrov &lt;razor@blackwall.org&gt;
Link: https://patch.msgid.link/20261030133750.28668-1-idosch@nvidia.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: keep reserved_bits across changelink</title>
<updated>2026-10-27T10:36:05+00:00</updated>
<author>
<name>Hannes Laimer</name>
<email>h.laimer@proxmox.com</email>
</author>
<published>2026-10-23T11:14:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=e3a629477d52a9f49d50d72903be06a4d1f4aa58'/>
<id>e3a629477d52a9f49d50d72903be06a4d1f4aa58</id>
<content type='text'>
vxlan_nl2conf() derives reserved_bits from the extension attributes
set in the netlink message if IFLA_VXLAN_RESERVED_BITS is absent. A
changelink having it set is rejected, so this means that every
changelink will reset all extension bits and reserve them again.
vxlan_nl2flag() rejects setting a flag on an attribute that is
create-only on changelink. So also setting an extension attribute will
fail before it can un-reserve its fields.

The extension's header bits being reserved again then makes
vxlan_rcv() drop frames that have them set in their header as invalid.
The device still reports the extension as enabled, because only the
reserved_bits are rebuilt and the flags are just copied.

A simple reproducer is

    ip link add vxgbp type vxlan id 1 dstport 4789 local 10.0.0.1 gbp
    ip link set dev vxgbp type vxlan ageing 300

After setting the unrelated ageing, incoming packets with the GBP bit
set in the header start getting dropped.

Keeping the reserved_bits on changelink is safe because anything a
changelink accepts leaves the header bits enabled extensions use
unchanged.

Ran into this when adding support for the GBP flag in ifupdown2, see
link below. The device kept dropping packets after some time, it
turned out it always started after a changelink.

Tested this by changing ageing by hand on a vxlan device that was
created by ifupdown2 with the gbp flag, and checking the reserved bits
using

    ip -d link show vxgbp | grep -o 'reserved_bits 0x[0-9a-f]*'

Without the fix I got 0xf7ffffff000000ff after the changelink, and
with the fix it stayed 0x77000000000000ff. The following patch
contains a selftest that fails without the fix and passes with it.

Fixes: e4f8647767cf ("vxlan: Track reserved bits explicitly as part of the configuration")
Link: https://lore.proxmox.com/pve-devel/20260828134708.692354-1-h.laimer@proxmox.com/
Signed-off-by: Hannes Laimer &lt;h.laimer@proxmox.com&gt;
Reviewed-by: Nikolay Aleksandrov &lt;razor@blackwall.org&gt;
Reviewed-by: Petr Machata &lt;petrm@nvidia.com&gt;
Link: https://patch.msgid.link/20261023-b4-vxlan-changelink-gbp-v1-1-f0d13951c09b@proxmox.com
Tested-by: Gabriel Goller &lt;g.goller@proxmox.com&gt;
Reviewed-by: Gabriel Goller &lt;g.goller@proxmox.com&gt;
Reviewed-by: Hangbin Liu &lt;liuhangbin@kylinos.cn&gt;
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
vxlan_nl2conf() derives reserved_bits from the extension attributes
set in the netlink message if IFLA_VXLAN_RESERVED_BITS is absent. A
changelink having it set is rejected, so this means that every
changelink will reset all extension bits and reserve them again.
vxlan_nl2flag() rejects setting a flag on an attribute that is
create-only on changelink. So also setting an extension attribute will
fail before it can un-reserve its fields.

The extension's header bits being reserved again then makes
vxlan_rcv() drop frames that have them set in their header as invalid.
The device still reports the extension as enabled, because only the
reserved_bits are rebuilt and the flags are just copied.

A simple reproducer is

    ip link add vxgbp type vxlan id 1 dstport 4789 local 10.0.0.1 gbp
    ip link set dev vxgbp type vxlan ageing 300

After setting the unrelated ageing, incoming packets with the GBP bit
set in the header start getting dropped.

Keeping the reserved_bits on changelink is safe because anything a
changelink accepts leaves the header bits enabled extensions use
unchanged.

Ran into this when adding support for the GBP flag in ifupdown2, see
link below. The device kept dropping packets after some time, it
turned out it always started after a changelink.

Tested this by changing ageing by hand on a vxlan device that was
created by ifupdown2 with the gbp flag, and checking the reserved bits
using

    ip -d link show vxgbp | grep -o 'reserved_bits 0x[0-9a-f]*'

Without the fix I got 0xf7ffffff000000ff after the changelink, and
with the fix it stayed 0x77000000000000ff. The following patch
contains a selftest that fails without the fix and passes with it.

Fixes: e4f8647767cf ("vxlan: Track reserved bits explicitly as part of the configuration")
Link: https://lore.proxmox.com/pve-devel/20260828134708.692354-1-h.laimer@proxmox.com/
Signed-off-by: Hannes Laimer &lt;h.laimer@proxmox.com&gt;
Reviewed-by: Nikolay Aleksandrov &lt;razor@blackwall.org&gt;
Reviewed-by: Petr Machata &lt;petrm@nvidia.com&gt;
Link: https://patch.msgid.link/20261023-b4-vxlan-changelink-gbp-v1-1-f0d13951c09b@proxmox.com
Tested-by: Gabriel Goller &lt;g.goller@proxmox.com&gt;
Reviewed-by: Gabriel Goller &lt;g.goller@proxmox.com&gt;
Reviewed-by: Hangbin Liu &lt;liuhangbin@kylinos.cn&gt;
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: vnifilter: validate the VXLAN_VNIFILTER_ENTRY nest</title>
<updated>2026-10-21T00:35:04+00:00</updated>
<author>
<name>Ali Firas</name>
<email>alishmery18@gmail.com</email>
</author>
<published>2026-10-14T12:38:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=599d0e97610f09162d84c4ede4164628c066921e'/>
<id>599d0e97610f09162d84c4ede4164628c066921e</id>
<content type='text'>
vxlan_vnifilter_process() parses the message with vni_filter_policy,
whose VXLAN_VNIFILTER_ENTRY is a bare NLA_NESTED with no nested policy
attached. The entry attributes are therefore validated only later, one
entry at a time, by the nla_parse_nested() inside
vxlan_process_vni_filter(). Entries are parsed as they are dispatched:
in a message whose first entry is valid and whose second is not, the
first entry is applied and its RTM_NEWTUNNEL notification sent before
the second is rejected.

Link the nest to vni_filter_entry_policy with NLA_POLICY_NESTED() so
every entry is checked against the entry policy up front, before any
entry is acted on. A message whose entry the policy rejects -- a
malformed attribute, or, with the next patch, an out-of-range endpoint
-- is now refused as a unit and installs nothing. Faults the policy does
not cover, such as a device or handler error raised on a later entry,
are unchanged: entries are still dispatched and applied one at a time.

This reorders two faults. The nest is validated before the device is
looked up and before the vnifilter flag is checked, so a request
rejected by the entry policy, aimed at a missing or non-vnifilter
device, now returns that policy error where it previously returned
-ENODEV or -EOPNOTSUPP. The request was invalid either way; only the
errno an operator sees changes.

The nla_parse_nested() in vxlan_process_vni_filter() stays: it is what
fills the per-entry attribute table the handler reads. It can no longer
fail on a message that has reached it.

Suggested-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
Link: https://lore.kernel.org/netdev/20260921150904.65a704eb@kernel.org/
Signed-off-by: Ali Firas &lt;alishmery18@gmail.com&gt;
Link: https://patch.msgid.link/20261014123814.388557-2-alishmery18@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
vxlan_vnifilter_process() parses the message with vni_filter_policy,
whose VXLAN_VNIFILTER_ENTRY is a bare NLA_NESTED with no nested policy
attached. The entry attributes are therefore validated only later, one
entry at a time, by the nla_parse_nested() inside
vxlan_process_vni_filter(). Entries are parsed as they are dispatched:
in a message whose first entry is valid and whose second is not, the
first entry is applied and its RTM_NEWTUNNEL notification sent before
the second is rejected.

Link the nest to vni_filter_entry_policy with NLA_POLICY_NESTED() so
every entry is checked against the entry policy up front, before any
entry is acted on. A message whose entry the policy rejects -- a
malformed attribute, or, with the next patch, an out-of-range endpoint
-- is now refused as a unit and installs nothing. Faults the policy does
not cover, such as a device or handler error raised on a later entry,
are unchanged: entries are still dispatched and applied one at a time.

This reorders two faults. The nest is validated before the device is
looked up and before the vnifilter flag is checked, so a request
rejected by the entry policy, aimed at a missing or non-vnifilter
device, now returns that policy error where it previously returned
-ENODEV or -EOPNOTSUPP. The request was invalid either way; only the
errno an operator sees changes.

The nla_parse_nested() in vxlan_process_vni_filter() stays: it is what
fills the per-entry attribute table the handler reads. It can no longer
fail on a message that has reached it.

Suggested-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
Link: https://lore.kernel.org/netdev/20260921150904.65a704eb@kernel.org/
Signed-off-by: Ali Firas &lt;alishmery18@gmail.com&gt;
Link: https://patch.msgid.link/20261014123814.388557-2-alishmery18@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: report a circular route as SKB_DROP_REASON_RECURSION_LIMIT</title>
<updated>2026-10-08T02:45:44+00:00</updated>
<author>
<name>Anton Danilov</name>
<email>littlesmilingcloud@gmail.com</email>
</author>
<published>2026-10-05T20:14:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=d476bb7c0efd56aa3d579114802305e4500bec85'/>
<id>d476bb7c0efd56aa3d579114802305e4500bec85</id>
<content type='text'>
udp_tunnel_dst_lookup() and udp_tunnel6_dst_lookup() return -ELOOP
when the route to the remote end goes out of the vxlan device itself,
and vxlan_xmit_one() counts that in collisions, apart from the
-ENETUNREACH of a failed lookup. The drop reason does not tell them
apart: both are reported as SKB_DROP_REASON_IP_OUTNOROUTES, which
describes a failed route lookup.

Such a route would send the encapsulated packet back into the device
it leaves, which is the dead loop on a virtual device that
SKB_DROP_REASON_RECURSION_LIMIT describes. Report the -ELOOP case with
that reason, and add the tunnel case to the description of the reason
as an example. ip_tunnel and ip6_tunnel make the same check,
rt-&gt;dst.dev == dev in ip_tunnel_xmit() and ip_md_tunnel_xmit() and
tdev == dev in ip6_tnl_xmit(), and can report it with the same reason.

Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-5-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
udp_tunnel_dst_lookup() and udp_tunnel6_dst_lookup() return -ELOOP
when the route to the remote end goes out of the vxlan device itself,
and vxlan_xmit_one() counts that in collisions, apart from the
-ENETUNREACH of a failed lookup. The drop reason does not tell them
apart: both are reported as SKB_DROP_REASON_IP_OUTNOROUTES, which
describes a failed route lookup.

Such a route would send the encapsulated packet back into the device
it leaves, which is the dead loop on a virtual device that
SKB_DROP_REASON_RECURSION_LIMIT describes. Report the -ELOOP case with
that reason, and add the tunnel case to the description of the reason
as an example. ip_tunnel and ip6_tunnel make the same check,
rt-&gt;dst.dev == dev in ip_tunnel_xmit() and ip_md_tunnel_xmit() and
tdev == dev in ip6_tnl_xmit(), and can report it with the same reason.

Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-5-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: report the drop reason of __iptunnel_pull_header()</title>
<updated>2026-10-08T02:45:44+00:00</updated>
<author>
<name>Anton Danilov</name>
<email>littlesmilingcloud@gmail.com</email>
</author>
<published>2026-10-05T20:14:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=0518c33e1d7e5600e441027100079aaf9c0dda74'/>
<id>0518c33e1d7e5600e441027100079aaf9c0dda74</id>
<content type='text'>
vxlan_rcv() reports SKB_DROP_REASON_NOMEM whenever
__iptunnel_pull_header() fails, as the helper used to return -ENOMEM
for any failure. The VXLAN header is already in the linear area at this
point, but the inner Ethernet header of a packet without GPE may not
be, so a packet whose inner frame is shorter than an Ethernet header is
reported as an out of memory condition.

Report the reason __iptunnel_pull_header() now returns instead:
PKT_TOO_SMALL for such a packet, NOMEM when an allocation fails.

Suggested-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-4-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
vxlan_rcv() reports SKB_DROP_REASON_NOMEM whenever
__iptunnel_pull_header() fails, as the helper used to return -ENOMEM
for any failure. The VXLAN header is already in the linear area at this
point, but the inner Ethernet header of a packet without GPE may not
be, so a packet whose inner frame is shorter than an Ethernet header is
reported as an out of memory condition.

Report the reason __iptunnel_pull_header() now returns instead:
PKT_TOO_SMALL for such a packet, NOMEM when an allocation fails.

Suggested-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-4-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: rename the drop reasons for use by other tunnels</title>
<updated>2026-10-08T02:45:43+00:00</updated>
<author>
<name>Anton Danilov</name>
<email>littlesmilingcloud@gmail.com</email>
</author>
<published>2026-10-05T20:14:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7629d6db839f196f108504662f1ad3b2fa822d0d'/>
<id>7629d6db839f196f108504662f1ad3b2fa822d0d</id>
<content type='text'>
VXLAN_INVALID_HDR and VXLAN_VNI_NOT_FOUND describe conditions that are
not specific to vxlan: a malformed tunnel header, and a packet for
which no tunnel device is found. The GRE receive paths drop packets
for the same two conditions, and can report them with the same reasons
once they are converted to drop reasons.

Rename them to TUNNEL_INVALID_HDR and TUNNEL_NOT_FOUND and reword their
descriptions, the way VXLAN_NO_REMOTE became NO_TX_TARGET in commit
46e0ccfb88f0 ("net: vxlan: rename SKB_DROP_REASON_VXLAN_NO_REMOTE").
The numeric values stay the same; the names that the skb:kfree_skb
tracepoint and drop_monitor report change.

Suggested-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-2-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
VXLAN_INVALID_HDR and VXLAN_VNI_NOT_FOUND describe conditions that are
not specific to vxlan: a malformed tunnel header, and a packet for
which no tunnel device is found. The GRE receive paths drop packets
for the same two conditions, and can report them with the same reasons
once they are converted to drop reasons.

Rename them to TUNNEL_INVALID_HDR and TUNNEL_NOT_FOUND and reword their
descriptions, the way VXLAN_NO_REMOTE became NO_TX_TARGET in commit
46e0ccfb88f0 ("net: vxlan: rename SKB_DROP_REASON_VXLAN_NO_REMOTE").
The numeric values stay the same; the names that the skb:kfree_skb
tracepoint and drop_monitor report change.

Suggested-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Signed-off-by: Anton Danilov &lt;littlesmilingcloud@gmail.com&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261005201417.906344-2-littlesmilingcloud@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ipv4: Use ipv4_neigh_lookup() and friends.</title>
<updated>2026-10-07T23:07:04+00:00</updated>
<author>
<name>Kuniyuki Iwashima</name>
<email>kuniyu@google.com</email>
</author>
<published>2026-10-03T21:23:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=f2f25d59f56a0a225447af203d73e51b4f7f92f5'/>
<id>f2f25d59f56a0a225447af203d73e51b4f7f92f5</id>
<content type='text'>
It is error-prone to require callers to fetch netns and
neigh_table and pass it with dev to neigh_lookup(), etc.

Let's replace neigh_lookup() and friends with IPv4 helpers.

Note that __neigh_lookup(create=false) is replaced with
ipv4_neigh_lookup() and __neigh_lookup(create=true) and
__neigh_lookup_errno() are split into ipv4_neigh_lookup()
and ipv4_neigh_create().

Fixes: 2430df635a59 ("ipv4: Replace &amp;arp_tbl with arp_table(net).")
Signed-off-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Reviewed-by: Fernando Fernandez Mancera &lt;fmancera@suse.de&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261003212336.1304988-8-kuniyu@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It is error-prone to require callers to fetch netns and
neigh_table and pass it with dev to neigh_lookup(), etc.

Let's replace neigh_lookup() and friends with IPv4 helpers.

Note that __neigh_lookup(create=false) is replaced with
ipv4_neigh_lookup() and __neigh_lookup(create=true) and
__neigh_lookup_errno() are split into ipv4_neigh_lookup()
and ipv4_neigh_create().

Fixes: 2430df635a59 ("ipv4: Replace &amp;arp_tbl with arp_table(net).")
Signed-off-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Reviewed-by: Fernando Fernandez Mancera &lt;fmancera@suse.de&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261003212336.1304988-8-kuniyu@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ipv6: Use ipv6_neigh_lookup() and friends.</title>
<updated>2026-10-07T23:07:03+00:00</updated>
<author>
<name>Kuniyuki Iwashima</name>
<email>kuniyu@google.com</email>
</author>
<published>2026-10-03T21:23:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=0e59523b440c90ed1899476f32ad4e949282f43e'/>
<id>0e59523b440c90ed1899476f32ad4e949282f43e</id>
<content type='text'>
syzbot reported the splat below in neigh_mark_dead() [0]
where tbl-&gt;lock was not held while neigh_ifdown() should
have acquired one.

This only happens when a neigh_table accidentally has a
neighbour from a different netns.

In ip6_finish_output2(), the net argument is the caller's and
does not always match dev_net(dev) fetched from dst. (e.g. xfrm)

It is error-prone to require callers to fetch netns and
neigh_table and pass it with dev to neigh_lookup(), etc.

Let's replace neigh_lookup() and friends with IPv6 helpers.

Note that __neigh_lookup() is split into ipv6_neigh_lookup()
and ipv6_neigh_create().

[0]:
debug_locks &amp;&amp; !(lock_is_held(&amp;(&amp;n-&gt;tbl-&gt;lock)-&gt;dep_map) != 0)
WARNING: net/core/neighbour.c:154 at neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154, CPU#0: syz.0.857/9765
Modules linked in:
CPU: 0 UID: 0 PID: 9765 Comm: syz.0.857 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154
Code: e8 03 42 80 3c 28 00 74 08 48 89 df e8 ee 9a 80 f8 4c 89 33 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc e8 86 95 10 f8 90 &lt;0f&gt; 0b 90 e9 8f fd ff ff 48 c7 c1 80 9a 7a 90 80 e1 07 80 c1 03 38
RSP: 0018:ffffc90003726600 EFLAGS: 00010287
RAX: ffffffff89b7467a RBX: ffff888022e86000 RCX: 0000000000080000
RDX: ffffc900047fa000 RSI: 0000000000003e08 RDI: 0000000000003e09
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000004
R10: dffffc0000000000 R11: fffff520006e4cb8 R12: ffff888022e8613c
R13: dffffc0000000000 R14: ffff888022e86020 R15: ffff888022e86000
FS:  00007f9c30f046c0(0000) GS:ffff888124cc6000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000076c56000 CR4: 00000000003526f0
Call Trace:
 &lt;TASK&gt;
 neigh_flush_one+0x27c/0x5a0 net/core/neighbour.c:388
 neigh_flush_dev net/core/neighbour.c:432 [inline]
 __neigh_ifdown+0x1fb/0xc70 net/core/neighbour.c:465
 neigh_ifdown+0x1f/0x30 net/core/neighbour.c:487
 rt6_disable_ip+0x751/0x7e0 net/ipv6/route.c:5058
 addrconf_ifdown+0x155/0x1ad0 net/ipv6/addrconf.c:3892
 addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
 notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85
 call_netdevice_notifiers_mtu net/core/dev.c:2350 [inline]
 netif_set_mtu_ext+0x5ac/0x830 net/core/dev.c:9963
 do_setlink+0xa81/0x47a0 net/core/rtnetlink.c:3247
 rtnl_setlink+0x578/0x820 net/core/rtnetlink.c:3623
 rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7159
 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
 netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
 netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
 sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
 __sock_sendmsg net/socket.c:815 [inline]
 sock_write_iter+0x2de/0x3e0 net/socket.c:1266
 do_iter_readv_writev+0x612/0x8c0 fs/read_write.c:-1
 vfs_writev+0x343/0x990 fs/read_write.c:1058
 do_writev+0x154/0x2e0 fs/read_write.c:1104
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9c2ff9e159
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 &lt;48&gt; 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9c30f04028 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
RAX: ffffffffffffffda RBX: 00007f9c30225fa0 RCX: 00007f9c2ff9e159
RDX: 0000000000000001 RSI: 00002000000003c0 RDI: 0000000000000004
RBP: 00007f9c3003506b R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f9c30226038 R14: 00007f9c30225fa0 R15: 00007ffed3c74808
 &lt;/TASK&gt;

Fixes: df5f4f372de5 ("ipv6: Replace &amp;nd_tbl with nd_table(net).")
Reported-by: syzbot+5a8857f0b4a0a7b12c62@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6abd69a9.80e1c6cc.22483f.0005.GAE@google.com/
Signed-off-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Reviewed-by: Fernando Fernandez Mancera &lt;fmancera@suse.de&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261003212336.1304988-7-kuniyu@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
syzbot reported the splat below in neigh_mark_dead() [0]
where tbl-&gt;lock was not held while neigh_ifdown() should
have acquired one.

This only happens when a neigh_table accidentally has a
neighbour from a different netns.

In ip6_finish_output2(), the net argument is the caller's and
does not always match dev_net(dev) fetched from dst. (e.g. xfrm)

It is error-prone to require callers to fetch netns and
neigh_table and pass it with dev to neigh_lookup(), etc.

Let's replace neigh_lookup() and friends with IPv6 helpers.

Note that __neigh_lookup() is split into ipv6_neigh_lookup()
and ipv6_neigh_create().

[0]:
debug_locks &amp;&amp; !(lock_is_held(&amp;(&amp;n-&gt;tbl-&gt;lock)-&gt;dep_map) != 0)
WARNING: net/core/neighbour.c:154 at neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154, CPU#0: syz.0.857/9765
Modules linked in:
CPU: 0 UID: 0 PID: 9765 Comm: syz.0.857 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:neigh_mark_dead+0x2fb/0x340 net/core/neighbour.c:154
Code: e8 03 42 80 3c 28 00 74 08 48 89 df e8 ee 9a 80 f8 4c 89 33 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc e8 86 95 10 f8 90 &lt;0f&gt; 0b 90 e9 8f fd ff ff 48 c7 c1 80 9a 7a 90 80 e1 07 80 c1 03 38
RSP: 0018:ffffc90003726600 EFLAGS: 00010287
RAX: ffffffff89b7467a RBX: ffff888022e86000 RCX: 0000000000080000
RDX: ffffc900047fa000 RSI: 0000000000003e08 RDI: 0000000000003e09
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000004
R10: dffffc0000000000 R11: fffff520006e4cb8 R12: ffff888022e8613c
R13: dffffc0000000000 R14: ffff888022e86020 R15: ffff888022e86000
FS:  00007f9c30f046c0(0000) GS:ffff888124cc6000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000076c56000 CR4: 00000000003526f0
Call Trace:
 &lt;TASK&gt;
 neigh_flush_one+0x27c/0x5a0 net/core/neighbour.c:388
 neigh_flush_dev net/core/neighbour.c:432 [inline]
 __neigh_ifdown+0x1fb/0xc70 net/core/neighbour.c:465
 neigh_ifdown+0x1f/0x30 net/core/neighbour.c:487
 rt6_disable_ip+0x751/0x7e0 net/ipv6/route.c:5058
 addrconf_ifdown+0x155/0x1ad0 net/ipv6/addrconf.c:3892
 addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
 notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85
 call_netdevice_notifiers_mtu net/core/dev.c:2350 [inline]
 netif_set_mtu_ext+0x5ac/0x830 net/core/dev.c:9963
 do_setlink+0xa81/0x47a0 net/core/rtnetlink.c:3247
 rtnl_setlink+0x578/0x820 net/core/rtnetlink.c:3623
 rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7159
 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
 netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
 netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
 sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
 __sock_sendmsg net/socket.c:815 [inline]
 sock_write_iter+0x2de/0x3e0 net/socket.c:1266
 do_iter_readv_writev+0x612/0x8c0 fs/read_write.c:-1
 vfs_writev+0x343/0x990 fs/read_write.c:1058
 do_writev+0x154/0x2e0 fs/read_write.c:1104
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9c2ff9e159
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 &lt;48&gt; 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9c30f04028 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
RAX: ffffffffffffffda RBX: 00007f9c30225fa0 RCX: 00007f9c2ff9e159
RDX: 0000000000000001 RSI: 00002000000003c0 RDI: 0000000000000004
RBP: 00007f9c3003506b R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f9c30226038 R14: 00007f9c30225fa0 R15: 00007ffed3c74808
 &lt;/TASK&gt;

Fixes: df5f4f372de5 ("ipv6: Replace &amp;nd_tbl with nd_table(net).")
Reported-by: syzbot+5a8857f0b4a0a7b12c62@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6abd69a9.80e1c6cc.22483f.0005.GAE@google.com/
Signed-off-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Reviewed-by: Fernando Fernandez Mancera &lt;fmancera@suse.de&gt;
Reviewed-by: Ido Schimmel &lt;idosch@nvidia.com&gt;
Link: https://patch.msgid.link/20261003212336.1304988-7-kuniyu@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: no longer rely on RTNL in vxlan_fill_info()</title>
<updated>2026-09-28T23:48:39+00:00</updated>
<author>
<name>Eric Dumazet</name>
<email>edumazet@google.com</email>
</author>
<published>2026-09-22T18:11:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=4b74deb12948aa4057da966e34fe23db3c9877af'/>
<id>4b74deb12948aa4057da966e34fe23db3c9877af</id>
<content type='text'>
Now that vxlan-&gt;cfg is RCU-protected, we can update vxlan_fill_info()
to run under RCU read lock instead of relying on RTNL.

This completes the transition to RTNL-less link info dumping for VXLAN.

Signed-off-by: Eric Dumazet &lt;edumazet@google.com&gt;
Reviewed-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Link: https://patch.msgid.link/20260922181102.3989489-9-edumazet@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now that vxlan-&gt;cfg is RCU-protected, we can update vxlan_fill_info()
to run under RCU read lock instead of relying on RTNL.

This completes the transition to RTNL-less link info dumping for VXLAN.

Signed-off-by: Eric Dumazet &lt;edumazet@google.com&gt;
Reviewed-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Link: https://patch.msgid.link/20260922181102.3989489-9-edumazet@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>vxlan: remove default_dst and use vxlan_config and lowerdev</title>
<updated>2026-09-28T23:48:35+00:00</updated>
<author>
<name>Eric Dumazet</name>
<email>edumazet@google.com</email>
</author>
<published>2026-09-22T18:11:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7e9e6844befcbbed3b576c16e75d5348639774ff'/>
<id>7e9e6844befcbbed3b576c16e75d5348639774ff</id>
<content type='text'>
Now that vxlan-&gt;cfg is an RCU-protected pointer, storing default
destination attributes (remote_ip, remote_vni, remote_ifindex) in
vxlan-&gt;default_dst is redundant and creates potential data races for
lockless readers.

Furthermore, several fields of struct vxlan_rdst (remote_port,
offloaded, list, rcu, dst_cache) in default_dst were completely unused.
The remaining one, remote_dev, only tracked the lower device, a role
now taken by vxlan-&gt;lowerdev, so drop it from struct vxlan_rdst.

Replace vxlan-&gt;default_dst with a 'struct net_device *lowerdev' pointer
in struct vxlan_dev to track adjacent upper/lower netdev topology under
RTNL, and switch all remaining users over to reading configuration
attributes from vxlan-&gt;cfg.

Also update mlx5e_tc_tun_get_remote_ifindex() to read remote_ifindex
from vxlan-&gt;cfg under rcu_read_lock().

In vxlan_changelink(), pass lowerdev to vxlan_config_apply() to preserve
needed_headroom and needed_tailroom. The mtu is still only reconsidered
when the lower device changes, so that an unrelated changelink can not
shrink it.

cfg-&gt;remote_ifindex is now committed unconditionally, where
default_dst.remote_ifindex was left untouched when IFLA_VXLAN_LINK was
cleared, so a changelink dropping the lower device no longer leaves a
stale ifindex behind. For the same reason vxlan_changelink() no longer
needs to compute the ifindex that will actually be committed.

Setting IFLA_VXLAN_LINK to 0 now also tears down the upper/lower
adjacency, which netdev_adjacent_change_commit() used to skip for a NULL
new device, resets needed_tailroom, and is rejected if per-VNI multicast
groups are configured.

Signed-off-by: Eric Dumazet &lt;edumazet@google.com&gt;
Reviewed-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Link: https://patch.msgid.link/20260922181102.3989489-8-edumazet@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now that vxlan-&gt;cfg is an RCU-protected pointer, storing default
destination attributes (remote_ip, remote_vni, remote_ifindex) in
vxlan-&gt;default_dst is redundant and creates potential data races for
lockless readers.

Furthermore, several fields of struct vxlan_rdst (remote_port,
offloaded, list, rcu, dst_cache) in default_dst were completely unused.
The remaining one, remote_dev, only tracked the lower device, a role
now taken by vxlan-&gt;lowerdev, so drop it from struct vxlan_rdst.

Replace vxlan-&gt;default_dst with a 'struct net_device *lowerdev' pointer
in struct vxlan_dev to track adjacent upper/lower netdev topology under
RTNL, and switch all remaining users over to reading configuration
attributes from vxlan-&gt;cfg.

Also update mlx5e_tc_tun_get_remote_ifindex() to read remote_ifindex
from vxlan-&gt;cfg under rcu_read_lock().

In vxlan_changelink(), pass lowerdev to vxlan_config_apply() to preserve
needed_headroom and needed_tailroom. The mtu is still only reconsidered
when the lower device changes, so that an unrelated changelink can not
shrink it.

cfg-&gt;remote_ifindex is now committed unconditionally, where
default_dst.remote_ifindex was left untouched when IFLA_VXLAN_LINK was
cleared, so a changelink dropping the lower device no longer leaves a
stale ifindex behind. For the same reason vxlan_changelink() no longer
needs to compute the ifindex that will actually be committed.

Setting IFLA_VXLAN_LINK to 0 now also tears down the upper/lower
adjacency, which netdev_adjacent_change_commit() used to skip for a NULL
new device, resets needed_tailroom, and is rejected if per-VNI multicast
groups are configured.

Signed-off-by: Eric Dumazet &lt;edumazet@google.com&gt;
Reviewed-by: Kuniyuki Iwashima &lt;kuniyu@google.com&gt;
Link: https://patch.msgid.link/20260922181102.3989489-8-edumazet@google.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
