summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/iface.c6
-rw-r--r--nest/iface.h1
-rw-r--r--nest/neighbor.c22
3 files changed, 28 insertions, 1 deletions
diff --git a/nest/iface.c b/nest/iface.c
index 8e459363..c5236782 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -117,7 +117,7 @@ if_what_changed(struct iface *i, struct iface *j)
{
unsigned c;
- if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_TMP_DOWN | IF_JUST_CREATED))
+ if (((i->flags ^ j->flags) & ~(IF_UP | IF_SHUTDOWN | IF_UPDATED | IF_ADMIN_UP | IF_LINK_UP | IF_TMP_DOWN | IF_JUST_CREATED))
|| i->index != j->index)
return IF_CHANGE_TOO_MUCH;
c = 0;
@@ -213,6 +213,10 @@ if_notify_change(unsigned c, struct iface *i)
a->flags = (i->flags & ~IA_FLAGS) | (a->flags & IA_FLAGS);
ifa_notify_change(IF_CHANGE_UP, a);
}
+
+ if ((c & (IF_CHANGE_UP | IF_CHANGE_DOWN | IF_CHANGE_LINK)) == IF_CHANGE_LINK)
+ neigh_if_link(i);
+
if (c & IF_CHANGE_DOWN)
neigh_if_down(i);
}
diff --git a/nest/iface.h b/nest/iface.h
index 471625f2..1936885c 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -125,6 +125,7 @@ void neigh_dump_all(void);
void neigh_prune(void);
void neigh_if_up(struct iface *);
void neigh_if_down(struct iface *);
+void neigh_if_link(struct iface *);
void neigh_init(struct pool *);
/*
diff --git a/nest/neighbor.c b/nest/neighbor.c
index 7e7cc491..785b1d46 100644
--- a/nest/neighbor.c
+++ b/nest/neighbor.c
@@ -278,6 +278,28 @@ neigh_if_down(struct iface *i)
}
}
+/**
+ * neigh_if_link - notify neighbor cache about interface link change
+ * @i: the interface in question
+ *
+ * Notify the neighbor cache that an interface changed link state.
+ * All owners of neighbor entries connected to this interface are
+ * notified.
+ */
+
+void
+neigh_if_link(struct iface *i)
+{
+ node *x, *y;
+
+ WALK_LIST_DELSAFE(x, y, i->neighbors)
+ {
+ neighbor *n = SKIP_BACK(neighbor, if_n, x);
+ if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
+ n->proto->neigh_notify(n);
+ }
+}
+
static inline void
neigh_prune_one(neighbor *n)
{