From f7aa74e483e81c7a064ebc29e5deeb6b31cde412 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Sat, 22 Sep 2018 21:26:19 -0700 Subject: [PATCH 1/2] neighbour: allow admin to set NTF_ROUTER This patch allows admin setting of NTF_ROUTER flag on a neighbour entry. This enables external control plane (like bgp evpn) to manage neigh entries with NTF_ROUTER flag. Signed-off-by: Roopa Prabhu Signed-off-by: David S. Miller --- net/core/neighbour.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 91592fceeaad..0e1cad89184f 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1712,7 +1712,8 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { - int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE; + int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE | + NEIGH_UPDATE_F_OVERRIDE_ISROUTER; struct net *net = sock_net(skb->sk); struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; @@ -1787,12 +1788,16 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, } if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) - flags &= ~NEIGH_UPDATE_F_OVERRIDE; + flags &= ~(NEIGH_UPDATE_F_OVERRIDE | + NEIGH_UPDATE_F_OVERRIDE_ISROUTER); } if (ndm->ndm_flags & NTF_EXT_LEARNED) flags |= NEIGH_UPDATE_F_EXT_LEARNED; + if (ndm->ndm_flags & NTF_ROUTER) + flags |= NEIGH_UPDATE_F_ISROUTER; + if (ndm->ndm_flags & NTF_USE) { neigh_event_send(neigh, NULL); err = 0; From fc6e8073f304010605f834cb2eb8c07c46461c9d Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Sat, 22 Sep 2018 21:26:20 -0700 Subject: [PATCH 2/2] neighbour: send netlink notification if NTF_ROUTER changes send netlink notification if neigh_update results in NTF_ROUTER change and if NEIGH_UPDATE_F_ISROUTER is on. Also move the NTF_ROUTER change function into a helper. Signed-off-by: Roopa Prabhu Signed-off-by: David S. Miller --- include/net/neighbour.h | 15 +++++++++++++++ net/core/neighbour.c | 7 ++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 6c1eecd56a4d..0874f7fcd859 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -544,4 +544,19 @@ static inline void neigh_update_ext_learned(struct neighbour *neigh, u32 flags, *notify = 1; } } + +static inline void neigh_update_is_router(struct neighbour *neigh, u32 flags, + int *notify) +{ + u8 ndm_flags = 0; + + ndm_flags |= (flags & NEIGH_UPDATE_F_ISROUTER) ? NTF_ROUTER : 0; + if ((neigh->flags ^ ndm_flags) & NTF_ROUTER) { + if (ndm_flags & NTF_ROUTER) + neigh->flags |= NTF_ROUTER; + else + neigh->flags &= ~NTF_ROUTER; + *notify = 1; + } +} #endif diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 0e1cad89184f..20e0d3308148 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1280,11 +1280,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, neigh->arp_queue_len_bytes = 0; } out: - if (update_isrouter) { - neigh->flags = (flags & NEIGH_UPDATE_F_ISROUTER) ? - (neigh->flags | NTF_ROUTER) : - (neigh->flags & ~NTF_ROUTER); - } + if (update_isrouter) + neigh_update_is_router(neigh, flags, ¬ify); write_unlock_bh(&neigh->lock); if (notify)