When the non-LL target address is on the link, use the target address as
the source address to prevent server NDP failure. This also consist with
linux kernel behavior

Signed-off-by: Yuxiao Zhang <[email protected]>
---

 net/ndisc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/ndisc.c b/net/ndisc.c
index 641cf6d8385..90460876754 100644
--- a/net/ndisc.c
+++ b/net/ndisc.c
@@ -222,6 +222,10 @@ ip6_send_na(uchar *eth_dst_addr, struct in6_addr 
*neigh_addr,
        __u16 len;
        uchar *pkt;
        unsigned short csum;
+       struct in6_addr *src = target;
+
+       if (ip6_is_unspecified_addr(src))
+               src = &net_link_local_ip6;
 
        debug("sending neighbor advertisement for %pI6c to %pI6c (%pM)\n",
              target, neigh_addr, eth_dst_addr);
@@ -231,7 +235,7 @@ ip6_send_na(uchar *eth_dst_addr, struct in6_addr 
*neigh_addr,
 
        pkt = (uchar *)net_tx_packet;
        pkt += net_set_ether(pkt, eth_dst_addr, PROT_IP6);
-       pkt += ip6_add_hdr(pkt, &net_link_local_ip6, neigh_addr,
+       pkt += ip6_add_hdr(pkt, src, neigh_addr,
                           PROT_ICMPV6, IPV6_NDISC_HOPLIMIT, len);
 
        /* ICMPv6 - NA */
@@ -248,7 +252,7 @@ ip6_send_na(uchar *eth_dst_addr, struct in6_addr 
*neigh_addr,
                            INETHADDRSZ);
 
        /* checksum */
-       csum = csum_ipv6_magic(&net_link_local_ip6,
+       csum = csum_ipv6_magic(src,
                               neigh_addr, len, PROT_ICMPV6,
                               csum_partial((__u8 *)msg, len, 0));
        msg->icmph.icmp6_cksum = csum;
---
base-commit: b4ac71db13a33c4e6532c60a781ddf34b7f4375a
branch: main

-- 
2.55.0.1007.g17ff1f9808-goog

Reply via email to