@@ -112,6 +112,7 @@ enum {
NDTPA_APP_PROBES, /* u32 */
NDTPA_UCAST_PROBES, /* u32 */
NDTPA_MCAST_PROBES, /* u32 */
+ NDTPA_MCAST_REPROBES, /* u32 */
NDTPA_ANYCAST_DELAY, /* u64, msecs */
NDTPA_PROXY_DELAY, /* u64, msecs */
NDTPA_PROXY_QLEN, /* u32 */
@@ -63,6 +63,7 @@ struct neigh_parms {
int ucast_probes;
int app_probes;
int mcast_probes;
+ int mcast_reprobes;
int anycast_delay;
int proxy_delay;
int proxy_qlen;
@@ -843,9 +843,9 @@ next_elt:
static __inline__ int neigh_max_probes(struct neighbour *n)
{
struct neigh_parms *p = n->parms;
- return (n->nud_state & NUD_PROBE) ?
- p->ucast_probes :
- p->ucast_probes + p->app_probes + p->mcast_probes;
+
+ return p->ucast_probes + p->app_probes +
+ (n->nud_state & NUD_PROBE) ? p->mcast_reprobes : p->mcast_probes;
}
static void neigh_invalidate(struct neighbour *neigh)
@@ -982,6 +982,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
goto out_unlock_bh;
if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {
+ /* We are in (NUD_NONE | NUD_FAILED) */
if (neigh->parms->mcast_probes + neigh->parms->app_probes) {
unsigned long next, now = jiffies;
@@ -1783,6 +1784,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes);
NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes);
NLA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes);
+ NLA_PUT_U32(skb, NDTPA_MCAST_REPROBES, parms->mcast_reprobes);
NLA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time);
NLA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME,
parms->base_reachable_time);
@@ -1932,6 +1934,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
[NDTPA_APP_PROBES] = { .type = NLA_U32 },
[NDTPA_UCAST_PROBES] = { .type = NLA_U32 },
[NDTPA_MCAST_PROBES] = { .type = NLA_U32 },
+ [NDTPA_MCAST_REPROBES] = { .type = NLA_U32 },
[NDTPA_BASE_REACHABLE_TIME] = { .type = NLA_U64 },
[NDTPA_GC_STALETIME] = { .type = NLA_U64 },
[NDTPA_DELAY_PROBE_TIME] = { .type = NLA_U64 },
@@ -2023,6 +2026,9 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
case NDTPA_MCAST_PROBES:
p->mcast_probes = nla_get_u32(tbp[i]);
break;
+ case NDTPA_MCAST_REPROBES:
+ p->mcast_reprobes = nla_get_u32(tbp[i]);
+ break;
case NDTPA_BASE_REACHABLE_TIME:
p->base_reachable_time = nla_get_msecs(tbp[i]);
break;
@@ -2773,6 +2779,7 @@ enum {
NEIGH_VAR_MCAST_PROBE,
NEIGH_VAR_UCAST_PROBE,
NEIGH_VAR_APP_PROBE,
+ NEIGH_VAR_MCAST_REPROBE,
NEIGH_VAR_RETRANS_TIME,
NEIGH_VAR_BASE_REACHABLE_TIME,
NEIGH_VAR_DELAY_PROBE_TIME,
@@ -2804,6 +2811,12 @@ static struct neigh_sysctl_table {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ [NEIGH_VAR_MCAST_REPROBE] = {
+ .procname = "mcast_resolicit",
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
[NEIGH_VAR_UCAST_PROBE] = {
.procname = "ucast_solicit",
.maxlen = sizeof(int),
@@ -2940,6 +2953,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
goto err;
t->neigh_vars[NEIGH_VAR_MCAST_PROBE].data = &p->mcast_probes;
+ t->neigh_vars[NEIGH_VAR_MCAST_REPROBE].data = &p->mcast_reprobes;
t->neigh_vars[NEIGH_VAR_UCAST_PROBE].data = &p->ucast_probes;
t->neigh_vars[NEIGH_VAR_APP_PROBE].data = &p->app_probes;
t->neigh_vars[NEIGH_VAR_RETRANS_TIME].data = &p->retrans_time;