Message ID | 1524602974-11476-1-git-send-email-roopa@cumulusnetworks.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net-next] neighbour: support for NTF_EXT_LEARNED flag | expand |
From: Roopa Prabhu <roopa@cumulusnetworks.com> Date: Tue, 24 Apr 2018 13:49:34 -0700 > From: Roopa Prabhu <roopa@cumulusnetworks.com> > > 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> No objection to the patch or the facility, so applied, thanks. What exactly is the name of this VPN technology in the FRR routing suite?
On Wed, Apr 25, 2018 at 10:20 AM, David Miller <davem@davemloft.net> wrote: > From: Roopa Prabhu <roopa@cumulusnetworks.com> > Date: Tue, 24 Apr 2018 13:49:34 -0700 > >> From: Roopa Prabhu <roopa@cumulusnetworks.com> >> >> 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> > > No objection to the patch or the facility, so applied, thanks. Thanks! > > What exactly is the name of this VPN technology in the FRR routing > suite? Its "Ethernet VPN" with BGP based control plane. https://github.com/FRRouting/frr/wiki/Frr-3.0-%E2%86%92-4.0 reference RFC's: https://tools.ietf.org/html/rfc7432 : BGP MPLS-Based Ethernet VPN https://tools.ietf.org/html/draft-ietf-bess-evpn-overlay-07 (describes how rfc7432 can be used as an Network Virtualization Overlay (NVO) solution: eg with vxlan). I also talked about it in my netdev2.2 tutorial: https://www.netdevconf.org/2.2/slides/prabhu-linuxbridge-tutorial.pdf (slide 60) Found this blog by Vincent which describes it well: https://vincent.bernat.im/en/blog/2017-vxlan-bgp-evpn For the context of this patch: Neighbor reachability information is exchanged via BGP. Remote neighbors learnt via BGP are installed in the kernel with NTF_EXT_LEARNED to indicate that they are external neighbor entries. FRR BGP also installs vxlan and bridge remote fdb entries with the same flag. Basically replaces flood and learn with control plane learning via BGP. Remote neighbor entries are also used for arp/nd proxy.
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index e421f86..6c1eecd 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -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 @@ -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 diff --git a/net/core/neighbour.c b/net/core/neighbour.c index ce51986..5afae29 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -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; } @@ -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, ¬ify); + if (!(new & NUD_VALID)) { neigh_del_timer(neigh); if (old & NUD_CONNECTED) @@ -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;