struct xfrm_state *xfrm;
int (*input)(struct sk_buff*);
- int (*output)(struct sk_buff*);
+ int (*output)(struct sk_buff**);
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
int (*gc)(void);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
void (*destroy)(struct dst_entry *);
+ void (*ifdown)(struct dst_entry *, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
return dst;
}
+extern const char dst_underflow_bug_msg[];
+
static inline
void dst_release(struct dst_entry * dst)
{
if (dst) {
- if (atomic_read(&dst->__refcnt) < 1) {
- printk("BUG: dst underflow %d: %p\n",
- atomic_read(&dst->__refcnt),
- current_text_addr());
- }
+ if (atomic_read(&dst->__refcnt) < 1)
+ printk(dst_underflow_bug_msg,
+ atomic_read(&dst->__refcnt),
+ dst, current_text_addr());
atomic_dec(&dst->__refcnt);
}
}
__dst_free(dst);
}
+static inline void dst_rcu_free(struct rcu_head *head)
+{
+ struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
+ dst_free(dst);
+}
+
static inline void dst_confirm(struct dst_entry *dst)
{
if (dst)
int err;
for (;;) {
- err = skb->dst->output(skb);
+ err = skb->dst->output(&skb);
if (likely(err == 0))
return err;