Skip to content

Commit

Permalink
neighbour: support for NTF_EXT_LEARNED flag
Browse files Browse the repository at this point in the history
This patch extends NTF_EXT_LEARNED support to the neighbour system.
Example use-case: An Ethernet VPN implementation (eg in FRR routing suite)
can use this flag to add dynamic reachable external neigh entires
learned via control plane. The use of neigh NTF_EXT_LEARNED in this
patch is consistent with its use with bridge and vxlan fdb entries.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Roopa Prabhu authored and David S. Miller committed Apr 25, 2018
1 parent 0aef78a commit 9ce33e4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
19 changes: 18 additions & 1 deletion include/net/neighbour.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ static inline void *neighbour_priv(const struct neighbour *n)
#define NEIGH_UPDATE_F_OVERRIDE 0x00000001
#define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002
#define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004
#define NEIGH_UPDATE_F_EXT_LEARNED 0x20000000
#define NEIGH_UPDATE_F_ISROUTER 0x40000000
#define NEIGH_UPDATE_F_ADMIN 0x80000000

Expand Down Expand Up @@ -526,5 +527,21 @@ static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n,
} while (read_seqretry(&n->ha_lock, seq));
}


static inline void neigh_update_ext_learned(struct neighbour *neigh, u32 flags,
int *notify)
{
u8 ndm_flags = 0;

if (!(flags & NEIGH_UPDATE_F_ADMIN))
return;

ndm_flags |= (flags & NEIGH_UPDATE_F_EXT_LEARNED) ? NTF_EXT_LEARNED : 0;
if ((neigh->flags ^ ndm_flags) & NTF_EXT_LEARNED) {
if (ndm_flags & NTF_EXT_LEARNED)
neigh->flags |= NTF_EXT_LEARNED;
else
neigh->flags &= ~NTF_EXT_LEARNED;
*notify = 1;
}
}
#endif
8 changes: 7 additions & 1 deletion net/core/neighbour.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,8 @@ static void neigh_periodic_work(struct work_struct *work)
write_lock(&n->lock);

state = n->nud_state;
if (state & (NUD_PERMANENT | NUD_IN_TIMER)) {
if ((state & (NUD_PERMANENT | NUD_IN_TIMER)) ||
(n->flags & NTF_EXT_LEARNED)) {
write_unlock(&n->lock);
goto next_elt;
}
Expand Down Expand Up @@ -1136,6 +1137,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
if (neigh->dead)
goto out;

neigh_update_ext_learned(neigh, flags, &notify);

if (!(new & NUD_VALID)) {
neigh_del_timer(neigh);
if (old & NUD_CONNECTED)
Expand Down Expand Up @@ -1781,6 +1784,9 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
flags &= ~NEIGH_UPDATE_F_OVERRIDE;
}

if (ndm->ndm_flags & NTF_EXT_LEARNED)
flags |= NEIGH_UPDATE_F_EXT_LEARNED;

if (ndm->ndm_flags & NTF_USE) {
neigh_event_send(neigh, NULL);
err = 0;
Expand Down

0 comments on commit 9ce33e4

Please sign in to comment.