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
