Commit 2ed08b5e authored by David S. Miller's avatar David S. Miller

Merge branch 'Managed-Neighbor-Entries'

Daniel Borkmann says:

====================
Managed Neighbor Entries

This series adds a couple of fixes related to NTF_EXT_LEARNED and NTF_USE
neighbor flags, extends the UAPI with a new NDA_FLAGS_EXT netlink attribute
in order to be able to add new neighbor flags from user space given all
current struct ndmsg / ndm_flags bits are used up. Finally, the core of this
series adds a new NTF_EXT_MANAGED flag to neighbors, which allows user space
control planes to add 'managed' neighbor entries. Meaning, user space may
either transition existing entries or can push down new L3 entries without
lladdr into the kernel where the latter will periodically try to keep such
NTF_EXT_MANAGED managed entries in reachable state. Main use case for this
series are XDP / tc BPF load-balancers which make use of the bpf_fib_lookup()
helper for backends. For more details, please see individual patches. Thanks!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7bb39a39 7482e384
...@@ -144,17 +144,18 @@ struct neighbour { ...@@ -144,17 +144,18 @@ struct neighbour {
struct timer_list timer; struct timer_list timer;
unsigned long used; unsigned long used;
atomic_t probes; atomic_t probes;
__u8 flags; u8 nud_state;
__u8 nud_state; u8 type;
__u8 type; u8 dead;
__u8 dead;
u8 protocol; u8 protocol;
u32 flags;
seqlock_t ha_lock; seqlock_t ha_lock;
unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8); unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))] __aligned(8);
struct hh_cache hh; struct hh_cache hh;
int (*output)(struct neighbour *, struct sk_buff *); int (*output)(struct neighbour *, struct sk_buff *);
const struct neigh_ops *ops; const struct neigh_ops *ops;
struct list_head gc_list; struct list_head gc_list;
struct list_head managed_list;
struct rcu_head rcu; struct rcu_head rcu;
struct net_device *dev; struct net_device *dev;
u8 primary_key[0]; u8 primary_key[0];
...@@ -172,7 +173,7 @@ struct pneigh_entry { ...@@ -172,7 +173,7 @@ struct pneigh_entry {
struct pneigh_entry *next; struct pneigh_entry *next;
possible_net_t net; possible_net_t net;
struct net_device *dev; struct net_device *dev;
u8 flags; u32 flags;
u8 protocol; u8 protocol;
u8 key[]; u8 key[];
}; };
...@@ -216,11 +217,13 @@ struct neigh_table { ...@@ -216,11 +217,13 @@ struct neigh_table {
int gc_thresh3; int gc_thresh3;
unsigned long last_flush; unsigned long last_flush;
struct delayed_work gc_work; struct delayed_work gc_work;
struct delayed_work managed_work;
struct timer_list proxy_timer; struct timer_list proxy_timer;
struct sk_buff_head proxy_queue; struct sk_buff_head proxy_queue;
atomic_t entries; atomic_t entries;
atomic_t gc_entries; atomic_t gc_entries;
struct list_head gc_list; struct list_head gc_list;
struct list_head managed_list;
rwlock_t lock; rwlock_t lock;
unsigned long last_rand; unsigned long last_rand;
struct neigh_statistics __percpu *stats; struct neigh_statistics __percpu *stats;
...@@ -250,12 +253,21 @@ static inline void *neighbour_priv(const struct neighbour *n) ...@@ -250,12 +253,21 @@ static inline void *neighbour_priv(const struct neighbour *n)
} }
/* flags for neigh_update() */ /* flags for neigh_update() */
#define NEIGH_UPDATE_F_OVERRIDE 0x00000001 #define NEIGH_UPDATE_F_OVERRIDE BIT(0)
#define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002 #define NEIGH_UPDATE_F_WEAK_OVERRIDE BIT(1)
#define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004 #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER BIT(2)
#define NEIGH_UPDATE_F_EXT_LEARNED 0x20000000 #define NEIGH_UPDATE_F_USE BIT(3)
#define NEIGH_UPDATE_F_ISROUTER 0x40000000 #define NEIGH_UPDATE_F_MANAGED BIT(4)
#define NEIGH_UPDATE_F_ADMIN 0x80000000 #define NEIGH_UPDATE_F_EXT_LEARNED BIT(5)
#define NEIGH_UPDATE_F_ISROUTER BIT(6)
#define NEIGH_UPDATE_F_ADMIN BIT(7)
/* In-kernel representation for NDA_FLAGS_EXT flags: */
#define NTF_OLD_MASK 0xff
#define NTF_EXT_SHIFT 8
#define NTF_EXT_MASK (NTF_EXT_MANAGED)
#define NTF_MANAGED (NTF_EXT_MANAGED << NTF_EXT_SHIFT)
extern const struct nla_policy nda_policy[]; extern const struct nla_policy nda_policy[];
......
...@@ -31,6 +31,7 @@ enum { ...@@ -31,6 +31,7 @@ enum {
NDA_PROTOCOL, /* Originator of entry */ NDA_PROTOCOL, /* Originator of entry */
NDA_NH_ID, NDA_NH_ID,
NDA_FDB_EXT_ATTRS, NDA_FDB_EXT_ATTRS,
NDA_FLAGS_EXT,
__NDA_MAX __NDA_MAX
}; };
...@@ -40,14 +41,16 @@ enum { ...@@ -40,14 +41,16 @@ enum {
* Neighbor Cache Entry Flags * Neighbor Cache Entry Flags
*/ */
#define NTF_USE 0x01 #define NTF_USE (1 << 0)
#define NTF_SELF 0x02 #define NTF_SELF (1 << 1)
#define NTF_MASTER 0x04 #define NTF_MASTER (1 << 2)
#define NTF_PROXY 0x08 /* == ATF_PUBL */ #define NTF_PROXY (1 << 3) /* == ATF_PUBL */
#define NTF_EXT_LEARNED 0x10 #define NTF_EXT_LEARNED (1 << 4)
#define NTF_OFFLOADED 0x20 #define NTF_OFFLOADED (1 << 5)
#define NTF_STICKY 0x40 #define NTF_STICKY (1 << 6)
#define NTF_ROUTER 0x80 #define NTF_ROUTER (1 << 7)
/* Extended flags under NDA_FLAGS_EXT: */
#define NTF_EXT_MANAGED (1 << 0)
/* /*
* Neighbor Cache Entry States. * Neighbor Cache Entry States.
...@@ -65,12 +68,22 @@ enum { ...@@ -65,12 +68,22 @@ enum {
#define NUD_PERMANENT 0x80 #define NUD_PERMANENT 0x80
#define NUD_NONE 0x00 #define NUD_NONE 0x00
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change /* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change and make no
* and make no address resolution or NUD. * address resolution or NUD.
* NUD_PERMANENT also cannot be deleted by garbage collectors. *
* NUD_PERMANENT also cannot be deleted by garbage collectors. This holds true
* for dynamic entries with NTF_EXT_LEARNED flag as well. However, upon carrier
* down event, NUD_PERMANENT entries are not flushed whereas NTF_EXT_LEARNED
* flagged entries explicitly are (which is also consistent with the routing
* subsystem).
*
* When NTF_EXT_LEARNED is set for a bridge fdb entry the different cache entry * When NTF_EXT_LEARNED is set for a bridge fdb entry the different cache entry
* states don't make sense and thus are ignored. Such entries don't age and * states don't make sense and thus are ignored. Such entries don't age and
* can roam. * can roam.
*
* NTF_EXT_MANAGED flagged neigbor entries are managed by the kernel on behalf
* of a user space control plane, and automatically refreshed so that (if
* possible) they remain in NUD_REACHABLE state.
*/ */
struct nda_cacheinfo { struct nda_cacheinfo {
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment