* [net] ipv6: honor per-interface proxy_ndp in forward and NA paths
@ 2026-06-23 8:56 Chenguang Zhao
2026-06-25 7:53 ` Ido Schimmel
2026-06-29 6:18 ` [PATCH net-next v2] " Chenguang Zhao
0 siblings, 2 replies; 6+ messages in thread
From: Chenguang Zhao @ 2026-06-23 8:56 UTC (permalink / raw)
To: David Ahern, Ido Schimmel, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: Chenguang Zhao, Simon Horman, netdev
ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
global setting.
Honor per-interface proxy_ndp in both places to match the NS path and
allow setups that only enable proxy_ndp on specific interfaces.
Fixes: fbea49e1e240 ("[IPV6] NDISC: Add proxy_ndp sysctl.")
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
net/ipv6/ip6_output.c | 4 ++--
net/ipv6/ndisc.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 368e4fa3b43c..c4ca4a813479 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
return -ETIMEDOUT;
}
- /* XXX: idev->cnf.proxy_ndp? */
- if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
+ if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
+ (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev)) {
int proxied = ip6_forward_proxy_check(skb);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f867ec8d3d90..e03e94681738 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1096,9 +1096,9 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
*/
if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
READ_ONCE(net->ipv6.devconf_all->forwarding) &&
- READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
+ (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
+ (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
pneigh_lookup(&nd_tbl, net, &msg->target, dev)) {
- /* XXX: idev->cnf.proxy_ndp */
goto out;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [net] ipv6: honor per-interface proxy_ndp in forward and NA paths
2026-06-23 8:56 [net] ipv6: honor per-interface proxy_ndp in forward and NA paths Chenguang Zhao
@ 2026-06-25 7:53 ` Ido Schimmel
2026-06-29 6:18 ` [PATCH net-next v2] " Chenguang Zhao
1 sibling, 0 replies; 6+ messages in thread
From: Ido Schimmel @ 2026-06-25 7:53 UTC (permalink / raw)
To: Chenguang Zhao
Cc: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, netdev
Subject prefix is incorrect. See:
https://docs.kernel.org/process/maintainer-netdev.html
On Tue, Jun 23, 2026 at 04:56:00PM +0800, Chenguang Zhao wrote:
> ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
> proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
> global setting.
>
> Honor per-interface proxy_ndp in both places to match the NS path and
> allow setups that only enable proxy_ndp on specific interfaces.
>
> Fixes: fbea49e1e240 ("[IPV6] NDISC: Add proxy_ndp sysctl.")
> Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
Given that this never worked and that the patch changes a 20 years old
user-visible behavior, I prefer that you target it at net-next (without
the Fixes tag) when it opens next week.
Also, did you look into why these "XXX" comments were added in the
original commit from 2006? I *assume* that it's because back then both
ndisc_recv_na() and ip6_forward() were missing an idev, unlike
ndisc_recv_ns().
> ---
> net/ipv6/ip6_output.c | 4 ++--
> net/ipv6/ndisc.c | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index 368e4fa3b43c..c4ca4a813479 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
> return -ETIMEDOUT;
> }
>
> - /* XXX: idev->cnf.proxy_ndp? */
> - if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
> + if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
> + (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
> pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev)) {
Note that idev doesn't necessarily correspond to the device with which
the neighbour lookup is performed (skb->dev). See 0857d6f8c759d.
vrf_ip6_rcv() does not modify skb->dev for neighbour discovery packets,
so this happens to be OK in this case, but you need to explain this in
the commit message.
> int proxied = ip6_forward_proxy_check(skb);
>
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index f867ec8d3d90..e03e94681738 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -1096,9 +1096,9 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
> */
> if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
> READ_ONCE(net->ipv6.devconf_all->forwarding) &&
> - READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
> + (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
> + (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
> pneigh_lookup(&nd_tbl, net, &msg->target, dev)) {
> - /* XXX: idev->cnf.proxy_ndp */
> goto out;
> }
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next v2] ipv6: honor per-interface proxy_ndp in forward and NA paths
2026-06-23 8:56 [net] ipv6: honor per-interface proxy_ndp in forward and NA paths Chenguang Zhao
2026-06-25 7:53 ` Ido Schimmel
@ 2026-06-29 6:18 ` Chenguang Zhao
2026-06-29 13:59 ` Nicolas Dichtel
1 sibling, 1 reply; 6+ messages in thread
From: Chenguang Zhao @ 2026-06-29 6:18 UTC (permalink / raw)
To: dsahern, idosch, davem, edumazet, kuba, pabeni
Cc: horms, netdev, Chenguang Zhao, Chenguang Zhao
ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
global setting. The original commit left XXX comments in these paths
likely because idev was not available there at the time; ip6_forward()
now obtains idev from IP6CB(skb)->iif.
Honor per-interface proxy_ndp in both places to match the NS path and
allow setups that only enable proxy_ndp on specific interfaces.
In ip6_forward(), idev is looked up via the ingress interface (iif) while
pneigh_lookup() uses skb->dev. For ND packets this is correct because
vrf_ip6_rcv() does not modify skb->dev for neighbour discovery frames,
so both refer to the ingress interface.
Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
---
v2:
Per Ido's review, the following changes were made in v2:
- Target net-next instead of net
- Drop Fixes tag
- Expand commit message: XXX comment history, idev vs skb->dev for ND packets
- Fix subject prefix
v1:
- https://lore.kernel.org/all/20260623085600.396401-1-zhaochenguang@kylinos.cn/
net/ipv6/ip6_output.c | 4 ++--
net/ipv6/ndisc.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 368e4fa3b43c..c4ca4a813479 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
return -ETIMEDOUT;
}
- /* XXX: idev->cnf.proxy_ndp? */
- if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
+ if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
+ (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev)) {
int proxied = ip6_forward_proxy_check(skb);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f867ec8d3d90..e03e94681738 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1096,9 +1096,9 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
*/
if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
READ_ONCE(net->ipv6.devconf_all->forwarding) &&
- READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
+ (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
+ (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
pneigh_lookup(&nd_tbl, net, &msg->target, dev)) {
- /* XXX: idev->cnf.proxy_ndp */
goto out;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v2] ipv6: honor per-interface proxy_ndp in forward and NA paths
2026-06-29 6:18 ` [PATCH net-next v2] " Chenguang Zhao
@ 2026-06-29 13:59 ` Nicolas Dichtel
2026-06-29 22:46 ` Jakub Kicinski
0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Dichtel @ 2026-06-29 13:59 UTC (permalink / raw)
To: Chenguang Zhao, dsahern, idosch, davem, edumazet, kuba, pabeni
Cc: horms, netdev, Chenguang Zhao
Le 29/06/2026 à 08:18, Chenguang Zhao a écrit :
> ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
> proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
> global setting. The original commit left XXX comments in these paths
> likely because idev was not available there at the time; ip6_forward()
> now obtains idev from IP6CB(skb)->iif.
>
> Honor per-interface proxy_ndp in both places to match the NS path and
> allow setups that only enable proxy_ndp on specific interfaces.
>
> In ip6_forward(), idev is looked up via the ingress interface (iif) while
> pneigh_lookup() uses skb->dev. For ND packets this is correct because
> vrf_ip6_rcv() does not modify skb->dev for neighbour discovery frames,
> so both refer to the ingress interface.
>
> Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
> ---
> v2:
> Per Ido's review, the following changes were made in v2:
> - Target net-next instead of net
> - Drop Fixes tag
> - Expand commit message: XXX comment history, idev vs skb->dev for ND packets
> - Fix subject prefix
>
> v1:
> - https://lore.kernel.org/all/20260623085600.396401-1-zhaochenguang@kylinos.cn/
>
> net/ipv6/ip6_output.c | 4 ++--
> net/ipv6/ndisc.c | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index 368e4fa3b43c..c4ca4a813479 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
> return -ETIMEDOUT;
> }
>
> - /* XXX: idev->cnf.proxy_ndp? */
> - if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
> + if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
> + (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
As stated by Ido, this changes a 20 years old user-visible behavior. It suddenly
may enable proxy NDP on a system.
I was thinking that this kind of change was prohibited.
Regards,
Nicolas
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v2] ipv6: honor per-interface proxy_ndp in forward and NA paths
2026-06-29 13:59 ` Nicolas Dichtel
@ 2026-06-29 22:46 ` Jakub Kicinski
2026-07-13 12:27 ` Chenguang Zhao
0 siblings, 1 reply; 6+ messages in thread
From: Jakub Kicinski @ 2026-06-29 22:46 UTC (permalink / raw)
To: Chenguang Zhao, Chenguang Zhao
Cc: Nicolas Dichtel, dsahern, idosch, davem, edumazet, pabeni, horms,
netdev
On Mon, 29 Jun 2026 15:59:00 +0200 Nicolas Dichtel wrote:
> Le 29/06/2026 à 08:18, Chenguang Zhao a écrit :
> > ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
> > proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
> > global setting. The original commit left XXX comments in these paths
> > likely because idev was not available there at the time; ip6_forward()
> > now obtains idev from IP6CB(skb)->iif.
> >
> > Honor per-interface proxy_ndp in both places to match the NS path and
> > allow setups that only enable proxy_ndp on specific interfaces.
> >
> > In ip6_forward(), idev is looked up via the ingress interface (iif) while
> > pneigh_lookup() uses skb->dev. For ND packets this is correct because
> > vrf_ip6_rcv() does not modify skb->dev for neighbour discovery frames,
> > so both refer to the ingress interface.
> >
> > Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
> > ---
> > v2:
> > Per Ido's review, the following changes were made in v2:
> > - Target net-next instead of net
> > - Drop Fixes tag
> > - Expand commit message: XXX comment history, idev vs skb->dev for ND packets
> > - Fix subject prefix
> >
> > v1:
> > - https://lore.kernel.org/all/20260623085600.396401-1-zhaochenguang@kylinos.cn/
> >
> > net/ipv6/ip6_output.c | 4 ++--
> > net/ipv6/ndisc.c | 4 ++--
> > 2 files changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> > index 368e4fa3b43c..c4ca4a813479 100644
> > --- a/net/ipv6/ip6_output.c
> > +++ b/net/ipv6/ip6_output.c
> > @@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
> > return -ETIMEDOUT;
> > }
> >
> > - /* XXX: idev->cnf.proxy_ndp? */
> > - if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
> > + if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
> > + (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
> As stated by Ido, this changes a 20 years old user-visible behavior. It suddenly
> may enable proxy NDP on a system.
> I was thinking that this kind of change was prohibited.
Chenguang Zhao, is this a change you find useful or are you just
acting on an AI-generated port about inconsistency in behavior?
Could you please explain your use case / deployment scenario?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next v2] ipv6: honor per-interface proxy_ndp in forward and NA paths
2026-06-29 22:46 ` Jakub Kicinski
@ 2026-07-13 12:27 ` Chenguang Zhao
0 siblings, 0 replies; 6+ messages in thread
From: Chenguang Zhao @ 2026-07-13 12:27 UTC (permalink / raw)
To: Jakub Kicinski, Chenguang Zhao
Cc: Nicolas Dichtel, dsahern, idosch, davem, edumazet, pabeni, horms,
netdev, chenguang.zhao
Thanks for the question.
Yes, I do find this useful; it is not only about cleaning up an
inconsistency found by tooling.
The common deployment for proxy NDP is to enable it only on the
upstream/WAN interface, not globally, for example:
# host with eth0 (WAN) and eth1 (LAN / containers / VPN)
sysctl -w net.ipv6.conf.eth0.proxy_ndp=1
ip -6 neigh add proxy 2001:db8::10 dev eth0
This is what Documentation and most guides describe (ndppd, Docker
IPv6, VPN/VPS setups that need to answer NS for addresses that live
behind another interface). Operators usually avoid
net.ipv6.conf.all.proxy_ndp=1 so proxying is not enabled on every
interface.
With that setup today:
- ndisc_recv_ns() already honors idev->cnf.proxy_ndp, so NS replies
work as expected;
- ip6_forward() / ndisc_recv_na() only look at
net->ipv6.devconf_all->proxy_ndp, so the forward/local-delivery
and NA handling for proxied addresses still require the global
knob.
So per-interface proxy_ndp is only half-effective unless
all.proxy_ndp is also set. The XXX comments look like that gap was
known when proxy_ndp was introduced; idev is available on these paths
now, so I want the remaining paths to match the NS path and the
documented per-interface usage.
I did use code review assistance while looking at IPv6 NDP, but the
motivation for sending the patch is the incomplete per-interface
behavior above, not just "make the checks look the same".
Applying this patch only adds per-interface control for IPv6 proxy NDP
to enable finer-grained configuration, and it should have negligible
impact on existing systems with the global IPv6 proxy NDP enabled.
Chenguang
Thanks
在 2026/6/30 06:46, Jakub Kicinski 写道:
> On Mon, 29 Jun 2026 15:59:00 +0200 Nicolas Dichtel wrote:
>> Le 29/06/2026 à 08:18, Chenguang Zhao a écrit :
>>> ndisc_recv_ns() has always checked both devconf_all and idev->cnf for
>>> proxy_ndp, but ip6_forward() and ndisc_recv_na() only looked at the
>>> global setting. The original commit left XXX comments in these paths
>>> likely because idev was not available there at the time; ip6_forward()
>>> now obtains idev from IP6CB(skb)->iif.
>>>
>>> Honor per-interface proxy_ndp in both places to match the NS path and
>>> allow setups that only enable proxy_ndp on specific interfaces.
>>>
>>> In ip6_forward(), idev is looked up via the ingress interface (iif) while
>>> pneigh_lookup() uses skb->dev. For ND packets this is correct because
>>> vrf_ip6_rcv() does not modify skb->dev for neighbour discovery frames,
>>> so both refer to the ingress interface.
>>>
>>> Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
>>> ---
>>> v2:
>>> Per Ido's review, the following changes were made in v2:
>>> - Target net-next instead of net
>>> - Drop Fixes tag
>>> - Expand commit message: XXX comment history, idev vs skb->dev for ND packets
>>> - Fix subject prefix
>>>
>>> v1:
>>> - https://lore.kernel.org/all/20260623085600.396401-1-zhaochenguang@kylinos.cn/
>>>
>>> net/ipv6/ip6_output.c | 4 ++--
>>> net/ipv6/ndisc.c | 4 ++--
>>> 2 files changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
>>> index 368e4fa3b43c..c4ca4a813479 100644
>>> --- a/net/ipv6/ip6_output.c
>>> +++ b/net/ipv6/ip6_output.c
>>> @@ -579,8 +579,8 @@ int ip6_forward(struct sk_buff *skb)
>>> return -ETIMEDOUT;
>>> }
>>>
>>> - /* XXX: idev->cnf.proxy_ndp? */
>>> - if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) &&
>>> + if ((READ_ONCE(net->ipv6.devconf_all->proxy_ndp) ||
>>> + (idev && READ_ONCE(idev->cnf.proxy_ndp))) &&
>> As stated by Ido, this changes a 20 years old user-visible behavior. It suddenly
>> may enable proxy NDP on a system.
>> I was thinking that this kind of change was prohibited.
> Chenguang Zhao, is this a change you find useful or are you just
> acting on an AI-generated port about inconsistency in behavior?
> Could you please explain your use case / deployment scenario?
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-13 12:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-23 8:56 [net] ipv6: honor per-interface proxy_ndp in forward and NA paths Chenguang Zhao
2026-06-25 7:53 ` Ido Schimmel
2026-06-29 6:18 ` [PATCH net-next v2] " Chenguang Zhao
2026-06-29 13:59 ` Nicolas Dichtel
2026-06-29 22:46 ` Jakub Kicinski
2026-07-13 12:27 ` Chenguang Zhao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox