|
@@ -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)
|