[PATCH net-next 05/13] amt: match the Membership Update tunnel by outer family

From: Omar Ramadan

Date: Fri Oct 09 2026 - 08:34:15 EST


amt_update_handler() finds the gateway's tunnel by comparing
tunnel->addr.ip4 with ip_hdr(skb)->saddr, which on an IPv6 outer header
reads bytes 4-7 of the source address as an IPv4 address, so an IPv6
relay never accepts a Membership Update.

Take the outer source with amt_outer_saddr() on entry, by value, before
pskb_may_pull() and iptunnel_pull_header() can reallocate the header.
Match the tunnel with amt_addr_equal(), as amt_request_handler() does,
so the tunnel a Request created is the one its Updates find in both
families. The inner report parsing is unchanged.

Assisted-by: LLM
Signed-off-by: Omar Ramadan <omar@xxxxxxxxxxxxx>
---
drivers/net/amt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 5e8a74c..b977b00 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -2620,14 +2620,14 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
{
struct amt_header_membership_update *amtmu;
struct amt_tunnel_list *tunnel;
+ union amt_addr saddr;
struct ethhdr *eth;
struct iphdr *iph;
int len, hdr_size;
u64 response_mac;
- __be32 saddr;
__be32 nonce;

- saddr = ip_hdr(skb)->saddr;
+ amt_outer_saddr(amt, skb, &saddr);

hdr_size = sizeof(*amtmu) + sizeof(struct udphdr);
if (!pskb_may_pull(skb, hdr_size))
@@ -2646,7 +2646,7 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
skb_reset_network_header(skb);

list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
- if (tunnel->addr.ip4 == saddr) {
+ if (amt_addr_equal(&tunnel->addr, &saddr)) {
if ((nonce == tunnel->nonce &&
response_mac == tunnel->mac)) {
mod_delayed_work(amt_wq, &tunnel->gc_wq,
--
2.43.0