]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - include/net/dst.h
net: Do delayed neigh confirmation.
[mirror_ubuntu-zesty-kernel.git] / include / net / dst.h
index f0bf3b8d5911bfa37a8988dee849481c807728db..84e7a3ff968d7cb7c6a6613432a99d9f4f15cb68 100644 (file)
@@ -51,7 +51,7 @@ struct dst_entry {
        int                     (*input)(struct sk_buff *);
        int                     (*output)(struct sk_buff *);
 
-       int                     flags;
+       unsigned short          flags;
 #define DST_HOST               0x0001
 #define DST_NOXFRM             0x0002
 #define DST_NOPOLICY           0x0004
@@ -62,6 +62,8 @@ struct dst_entry {
 #define DST_FAKE_RTABLE                0x0080
 #define DST_XFRM_TUNNEL                0x0100
 
+       unsigned short          pending_confirm;
+
        short                   error;
        short                   obsolete;
        unsigned short          header_len;     /* more space at head required */
@@ -371,7 +373,8 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
 
 extern int dst_discard(struct sk_buff *skb);
 extern void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
-                      int initial_ref, int initial_obsolete, int flags);
+                      int initial_ref, int initial_obsolete,
+                      unsigned short flags);
 extern void __dst_free(struct dst_entry *dst);
 extern struct dst_entry *dst_destroy(struct dst_entry *dst);
 
@@ -395,14 +398,24 @@ static inline void dst_rcu_free(struct rcu_head *head)
 
 static inline void dst_confirm(struct dst_entry *dst)
 {
-       if (dst) {
-               struct neighbour *n;
+       dst->pending_confirm = 1;
+}
 
-               rcu_read_lock();
-               n = dst_get_neighbour_noref(dst);
-               neigh_confirm(n);
-               rcu_read_unlock();
+static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n,
+                                  struct sk_buff *skb)
+{
+       struct hh_cache *hh;
+
+       if (unlikely(dst->pending_confirm)) {
+               n->confirmed = jiffies;
+               dst->pending_confirm = 0;
        }
+
+       hh = &n->hh;
+       if ((n->nud_state & NUD_CONNECTED) && hh->hh_len)
+               return neigh_hh_output(hh, skb);
+       else
+               return n->output(n, skb);
 }
 
 static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)