From: Jon Maloy <jmaloy@redhat.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: sbrivio@redhat.com, dgibson@redhat.com, passt-dev@passt.top
Subject: Re: [PATCH v9 9/9] arp/ndp: send gratuitous ARP / unsolicitated NA when MAC cache entry added
Date: Fri, 26 Sep 2025 19:25:33 -0400 [thread overview]
Message-ID: <2cf5fd66-a5f5-45b0-8e4d-57ab56bf874c@redhat.com> (raw)
In-Reply-To: <aNNj_gE_o_xCJGrQ@zatzit>
On 2025-09-23 23:22, David Gibson wrote:
> On Tue, Sep 23, 2025 at 09:13:30PM -0400, Jon Maloy wrote:
>> Gratuitious ARP and unsolicitated NA should be handled with caution
>> because of the risk of malignant users emitting them to disturb
>> network communication.
>>
[...]
>> + req.ah.ar_op = htons(ARPOP_REPLY);
>> + req.ah.ar_hrd = htons(ARPHRD_ETHER);
>> + req.ah.ar_pro = htons(ETH_P_IP);
>> + req.ah.ar_hln = ETH_ALEN;
>> + req.ah.ar_pln = 4;
>> +
>> + /* ARP message */
>> + memcpy(req.am.sha, mac, sizeof(req.am.sha));
>> + memcpy(req.am.sip, &ip, sizeof(req.am.sip));
>> + memcpy(req.am.tha, MAC_BROADCAST, sizeof(req.am.tha));
>> + memcpy(req.am.tip, &ip, sizeof(req.am.tip));
>
> So, I was trying to check if it made sense to use the same IP for both
> source and target here, and came across
> https://www.rfc-editor.org/rfc/rfc5227#section-3
>
> Which suggests we should (counter intuitively) be using ARP requests,
> not ARP replies for announcements.
I have now read through it, and it seems to come to the conclusion
that this is not advisable. In principle it should work, if all
implementations stick to standard, but there might be stacks which are
not stateless in this regard, i.e., they only accepts ARP replies as a
response to a sent request.
In short, I think I will stick to my current approach, since it is
evidently harmless and is proven to work.
///jon
>
>> + inet_ntop(AF_INET, &ip, ip_str, sizeof(ip_str));
>> + debug("Sending gratuitous ARP for %s", ip_str);
>> + tap_send_single(c, &req, sizeof(req));
>> +}
>> diff --git a/arp.h b/arp.h
>> index d5ad0e1..b0dbb56 100644
>> --- a/arp.h
>> +++ b/arp.h
>> @@ -22,5 +22,7 @@ struct arpmsg {
>>
>> int arp(const struct ctx *c, struct iov_tail *data);
>> void arp_send_init_req(const struct ctx *c);
>> +void arp_send_gratuitous(const struct ctx *c, struct in_addr ip,
>> + const unsigned char *mac);
>>
>> #endif /* ARP_H */
>> diff --git a/fwd.c b/fwd.c
>> index c6348ab..879a351 100644
>> --- a/fwd.c
>> +++ b/fwd.c
>> @@ -26,6 +26,8 @@
>> #include "passt.h"
>> #include "lineread.h"
>> #include "flow_table.h"
>> +#include "arp.h"
>> +#include "ndp.h"
>>
>> /* Empheral port range: values from RFC 6335 */
>> static in_port_t fwd_ephemeral_min = (1 << 15) + (1 << 14);
>> @@ -129,6 +131,15 @@ void fwd_neigh_mac_cache_alloc(const struct ctx *c,
>>
>> memcpy(&e->addr, addr, sizeof(*addr));
>> memcpy(e->mac, mac, ETH_ALEN);
>> +
>> + /* Send gratuitous ARP / unsolicited NA for the new mapping */
>
> AFAICT this doesn't actually implement what the commit message
> describes - it seems to always send an ARP/NA when the neighbour table
> is updated.
>
>> + if (inany_v4(addr)) {
>> + struct in_addr ip4 = *inany_v4(addr);
>> +
>> + arp_send_gratuitous(c, ip4, e->mac);
>> + } else {
>> + ndp_send_unsolicited_na(c, &addr->a6);
>> + }
>> }
>>
>> /**
>> diff --git a/ndp.c b/ndp.c
>> index 70b68aa..8914f31 100644
>> --- a/ndp.c
>> +++ b/ndp.c
>> @@ -226,6 +226,16 @@ static void ndp_na(const struct ctx *c, const struct in6_addr *dst,
>> ndp_send(c, dst, &na, sizeof(na));
>> }
>>
>> +/**
>> + * ndp_send_unsolicited_na() - Send unsolicited NA
>> + * @c: Execution context
>> + * @addr: IPv6 address to advertise
>> + */
>> +void ndp_send_unsolicited_na(const struct ctx *c, const struct in6_addr *addr)
>> +{
>> + ndp_na(c, &in6addr_ll_all_nodes, addr);
>> +}
>> +
>> /**
>> * ndp_ra() - Send an NDP Router Advertisement (RA) message
>> * @c: Execution context
>> diff --git a/ndp.h b/ndp.h
>> index 781ea86..320009c 100644
>> --- a/ndp.h
>> +++ b/ndp.h
>> @@ -12,5 +12,6 @@ int ndp(const struct ctx *c, const struct in6_addr *saddr,
>> struct iov_tail *data);
>> void ndp_timer(const struct ctx *c, const struct timespec *now);
>> void ndp_send_init_req(const struct ctx *c);
>> +void ndp_send_unsolicited_na(const struct ctx *c, const struct in6_addr *addr);
>>
>> #endif /* NDP_H */
>> --
>> 2.50.1
>>
>
next prev parent reply other threads:[~2025-09-26 23:25 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-24 1:13 [PATCH v9 0/9] Use true MAC address of LAN local remote hosts Jon Maloy
2025-09-24 1:13 ` [PATCH v9 1/9] netlink: add subsciption on changes in NDP/ARP table Jon Maloy
2025-09-24 2:47 ` David Gibson
2025-09-24 3:34 ` David Gibson
2025-09-24 18:40 ` Jon Maloy
2025-09-25 6:42 ` David Gibson
2025-09-24 1:13 ` [PATCH v9 2/9] fwd: Add cache table for ARP/NDP contents Jon Maloy
2025-09-24 3:03 ` David Gibson
2025-09-24 18:54 ` Jon Maloy
2025-09-24 1:13 ` [PATCH v9 3/9] arp/ndp: respond with true MAC address of LAN local remote hosts Jon Maloy
2025-09-24 1:13 ` [PATCH v9 4/9] flow: add MAC address of LAN local remote hosts to flow Jon Maloy
2025-09-24 1:13 ` [PATCH v9 5/9] udp: forward external source MAC address through tap interface Jon Maloy
2025-09-24 1:13 ` [PATCH v9 6/9] tcp: " Jon Maloy
2025-09-24 1:13 ` [PATCH v9 7/9] tap: change signature of function tap_push_l2h() Jon Maloy
2025-09-24 1:13 ` [PATCH v9 8/9] icmp: let icmp use mac address from flowside structure Jon Maloy
2025-09-24 1:13 ` [PATCH v9 9/9] arp/ndp: send gratuitous ARP / unsolicitated NA when MAC cache entry added Jon Maloy
2025-09-24 3:22 ` David Gibson
2025-09-24 22:18 ` Jon Maloy
2025-09-24 23:32 ` Jon Maloy
2025-09-25 6:38 ` David Gibson
2025-09-25 12:48 ` Jon Maloy
2025-09-26 0:47 ` David Gibson
2025-09-26 22:59 ` Jon Maloy
2025-09-29 4:03 ` David Gibson
2025-09-25 6:36 ` David Gibson
2025-09-25 13:14 ` Jon Maloy
2025-09-26 0:55 ` David Gibson
2025-09-26 23:05 ` Jon Maloy
2025-09-29 4:04 ` David Gibson
2025-09-26 23:25 ` Jon Maloy [this message]
2025-09-27 19:32 ` Jon Maloy
2025-09-29 4:08 ` David Gibson
2025-09-29 22:23 ` Stefano Brivio
2025-09-30 0:15 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2cf5fd66-a5f5-45b0-8e4d-57ab56bf874c@redhat.com \
--to=jmaloy@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=dgibson@redhat.com \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).