Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: neighbour: Add mcast_resolicit to configure the number of multicast resolicitations in PROBE state.

We send unicast neighbor (ARP or NDP) solicitations ucast_probes
times in PROBE state. Zhu Yanjun reported that some implementation
does not reply against them and the entry will become FAILED, which
is undesirable.

We had been dealt with such nodes by sending multicast probes mcast_
solicit times after unicast probes in PROBE state. In 2003, I made
a change not to send them to improve compatibility with IPv6 NDP.

Let's introduce per-protocol per-interface sysctl knob "mcast_
reprobe" to configure the number of multicast (re)solicitation for
reconfirmation in PROBE state. The default is 0, since we have
been doing so for 10+ years.

Reported-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
CC: Ulf Samuelsson <ulf.samuelsson@ericsson.com>
Signed-off-by: YOSHIFUJI Hideaki <hideaki.yoshifuji@miraclelinux.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

YOSHIFUJI Hideaki/吉藤英明 and committed by
David S. Miller
8da86466 fc300dc3

+13 -4
+1
include/net/neighbour.h
··· 42 42 NEIGH_VAR_MCAST_PROBES, 43 43 NEIGH_VAR_UCAST_PROBES, 44 44 NEIGH_VAR_APP_PROBES, 45 + NEIGH_VAR_MCAST_REPROBES, 45 46 NEIGH_VAR_RETRANS_TIME, 46 47 NEIGH_VAR_BASE_REACHABLE_TIME, 47 48 NEIGH_VAR_DELAY_PROBE_TIME,
+1
include/uapi/linux/neighbour.h
··· 126 126 NDTPA_PROXY_QLEN, /* u32 */ 127 127 NDTPA_LOCKTIME, /* u64, msecs */ 128 128 NDTPA_QUEUE_LENBYTES, /* u32 */ 129 + NDTPA_MCAST_REPROBES, /* u32 */ 129 130 __NDTPA_MAX 130 131 }; 131 132 #define NDTPA_MAX (__NDTPA_MAX - 1)
+11 -4
net/core/neighbour.c
··· 817 817 static __inline__ int neigh_max_probes(struct neighbour *n) 818 818 { 819 819 struct neigh_parms *p = n->parms; 820 - int max_probes = NEIGH_VAR(p, UCAST_PROBES) + NEIGH_VAR(p, APP_PROBES); 821 - if (!(n->nud_state & NUD_PROBE)) 822 - max_probes += NEIGH_VAR(p, MCAST_PROBES); 823 - return max_probes; 820 + return NEIGH_VAR(p, UCAST_PROBES) + NEIGH_VAR(p, APP_PROBES) + 821 + (n->nud_state & NUD_PROBE ? NEIGH_VAR(p, MCAST_REPROBES) : 822 + NEIGH_VAR(p, MCAST_PROBES)); 824 823 } 825 824 826 825 static void neigh_invalidate(struct neighbour *neigh) ··· 1741 1742 NEIGH_VAR(parms, UCAST_PROBES)) || 1742 1743 nla_put_u32(skb, NDTPA_MCAST_PROBES, 1743 1744 NEIGH_VAR(parms, MCAST_PROBES)) || 1745 + nla_put_u32(skb, NDTPA_MCAST_REPROBES, 1746 + NEIGH_VAR(parms, MCAST_REPROBES)) || 1744 1747 nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time) || 1745 1748 nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME, 1746 1749 NEIGH_VAR(parms, BASE_REACHABLE_TIME)) || ··· 1902 1901 [NDTPA_APP_PROBES] = { .type = NLA_U32 }, 1903 1902 [NDTPA_UCAST_PROBES] = { .type = NLA_U32 }, 1904 1903 [NDTPA_MCAST_PROBES] = { .type = NLA_U32 }, 1904 + [NDTPA_MCAST_REPROBES] = { .type = NLA_U32 }, 1905 1905 [NDTPA_BASE_REACHABLE_TIME] = { .type = NLA_U64 }, 1906 1906 [NDTPA_GC_STALETIME] = { .type = NLA_U64 }, 1907 1907 [NDTPA_DELAY_PROBE_TIME] = { .type = NLA_U64 }, ··· 2001 1999 break; 2002 2000 case NDTPA_MCAST_PROBES: 2003 2001 NEIGH_VAR_SET(p, MCAST_PROBES, 2002 + nla_get_u32(tbp[i])); 2003 + break; 2004 + case NDTPA_MCAST_REPROBES: 2005 + NEIGH_VAR_SET(p, MCAST_REPROBES, 2004 2006 nla_get_u32(tbp[i])); 2005 2007 break; 2006 2008 case NDTPA_BASE_REACHABLE_TIME: ··· 2993 2987 NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_PROBES, "mcast_solicit"), 2994 2988 NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(UCAST_PROBES, "ucast_solicit"), 2995 2989 NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(APP_PROBES, "app_solicit"), 2990 + NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_REPROBES, "mcast_resolicit"), 2996 2991 NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(RETRANS_TIME, "retrans_time"), 2997 2992 NEIGH_SYSCTL_JIFFIES_ENTRY(BASE_REACHABLE_TIME, "base_reachable_time"), 2998 2993 NEIGH_SYSCTL_JIFFIES_ENTRY(DELAY_PROBE_TIME, "delay_first_probe_time"),