net: core: Send ARP probe and trigger RTM_NEWNEIGH
Send ARP probe and generate RTM_NEWNEIGH if the neighbor
state is not NUD_REACHABLE. Also featurize changes for
sending neighbor probe.
Change-Id: I633285b8e0cbcd49291d5e52136f11e20f2388bc
Signed-off-by: Mohammed Javid <mjavid@codeaurora.org>
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 8b68384..ddfb742 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -62,6 +62,7 @@
NEIGH_VAR_GC_THRESH1,
NEIGH_VAR_GC_THRESH2,
NEIGH_VAR_GC_THRESH3,
+ NEIGH_VAR_PROBE,
NEIGH_VAR_MAX
};
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 227c249..62893eb 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -56,6 +56,7 @@
static void neigh_update_notify(struct neighbour *neigh);
static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
+static unsigned int neigh_probe_enable;
#ifdef CONFIG_PROC_FS
static const struct file_operations neigh_stat_seq_fops;
#endif
@@ -1258,9 +1259,20 @@
{
struct neighbour *neigh = __neigh_lookup(tbl, saddr, dev,
lladdr || !dev->addr_len);
- if (neigh)
- neigh_update(neigh, lladdr, NUD_STALE,
- NEIGH_UPDATE_F_OVERRIDE);
+ if (neigh) {
+ if (neigh_probe_enable) {
+ if (!(neigh->nud_state == NUD_REACHABLE)) {
+ neigh_update(neigh, lladdr, NUD_STALE,
+ NEIGH_UPDATE_F_OVERRIDE);
+ write_lock(&neigh->lock);
+ neigh_probe(neigh);
+ neigh_update_notify(neigh);
+ }
+ } else {
+ neigh_update(neigh, lladdr, NUD_STALE,
+ NEIGH_UPDATE_F_OVERRIDE);
+ }
+ }
return neigh;
}
EXPORT_SYMBOL(neigh_event_ns);
@@ -3107,6 +3119,12 @@
.extra2 = &int_max,
.proc_handler = proc_dointvec_minmax,
},
+ [NEIGH_VAR_PROBE] = {
+ .procname = "neigh_probe",
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
{},
},
};
@@ -3142,6 +3160,7 @@
t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = &tbl->gc_thresh1;
t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = &tbl->gc_thresh2;
t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = &tbl->gc_thresh3;
+ t->neigh_vars[NEIGH_VAR_PROBE].data = &neigh_probe_enable;
}
if (handler) {