dect
/
linux-2.6
Archived
13
0
Fork 0

sch_teql: Convert over to dev_neigh_lookup_skb().

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2012-07-02 21:57:45 -07:00
parent f894cbf847
commit dbedbe6d56
1 changed files with 22 additions and 25 deletions

View File

@ -67,7 +67,6 @@ struct teql_master {
struct teql_sched_data { struct teql_sched_data {
struct Qdisc *next; struct Qdisc *next;
struct teql_master *m; struct teql_master *m;
struct neighbour *ncache;
struct sk_buff_head q; struct sk_buff_head q;
}; };
@ -134,7 +133,6 @@ teql_reset(struct Qdisc *sch)
skb_queue_purge(&dat->q); skb_queue_purge(&dat->q);
sch->q.qlen = 0; sch->q.qlen = 0;
teql_neigh_release(xchg(&dat->ncache, NULL));
} }
static void static void
@ -166,7 +164,6 @@ teql_destroy(struct Qdisc *sch)
} }
} }
skb_queue_purge(&dat->q); skb_queue_purge(&dat->q);
teql_neigh_release(xchg(&dat->ncache, NULL));
break; break;
} }
@ -225,21 +222,25 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
static int static int
__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
struct net_device *dev, struct netdev_queue *txq, struct net_device *dev, struct netdev_queue *txq,
struct neighbour *mn) struct dst_entry *dst)
{ {
struct teql_sched_data *q = qdisc_priv(txq->qdisc); struct neighbour *n;
struct neighbour *n = q->ncache; int err = 0;
if (mn->tbl == NULL) n = dst_neigh_lookup_skb(dst, skb);
return -EINVAL; if (!n)
if (n && n->tbl == mn->tbl && return -ENOENT;
memcmp(n->primary_key, mn->primary_key, mn->tbl->key_len) == 0) {
atomic_inc(&n->refcnt); if (dst->dev != dev) {
} else { struct neighbour *mn;
n = __neigh_lookup_errno(mn->tbl, mn->primary_key, dev);
if (IS_ERR(n)) mn = __neigh_lookup_errno(n->tbl, n->primary_key, dev);
return PTR_ERR(n); neigh_release(n);
if (IS_ERR(mn))
return PTR_ERR(mn);
n = mn;
} }
if (neigh_event_send(n, skb_res) == 0) { if (neigh_event_send(n, skb_res) == 0) {
int err; int err;
char haddr[MAX_ADDR_LEN]; char haddr[MAX_ADDR_LEN];
@ -248,15 +249,13 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr,
NULL, skb->len); NULL, skb->len);
if (err < 0) { if (err < 0)
neigh_release(n); err = -EINVAL;
return -EINVAL; } else {
} err = (skb_res == NULL) ? -EAGAIN : 1;
teql_neigh_release(xchg(&q->ncache, n));
return 0;
} }
neigh_release(n); neigh_release(n);
return (skb_res == NULL) ? -EAGAIN : 1; return err;
} }
static inline int teql_resolve(struct sk_buff *skb, static inline int teql_resolve(struct sk_buff *skb,
@ -265,7 +264,6 @@ static inline int teql_resolve(struct sk_buff *skb,
struct netdev_queue *txq) struct netdev_queue *txq)
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct neighbour *mn;
int res; int res;
if (txq->qdisc == &noop_qdisc) if (txq->qdisc == &noop_qdisc)
@ -275,8 +273,7 @@ static inline int teql_resolve(struct sk_buff *skb,
return 0; return 0;
rcu_read_lock(); rcu_read_lock();
mn = dst_get_neighbour_noref(dst); res = __teql_resolve(skb, skb_res, dev, txq, dst);
res = mn ? __teql_resolve(skb, skb_res, dev, txq, mn) : 0;
rcu_read_unlock(); rcu_read_unlock();
return res; return res;