diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/cls_flow.c | 17 | ||||
-rw-r--r-- | net/sched/em_meta.c | 18 | ||||
-rw-r--r-- | net/sched/ematch.c | 8 | ||||
-rw-r--r-- | net/sched/sch_htb.c | 13 |
4 files changed, 39 insertions, 17 deletions
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 8d7698621f0a..971b867e0484 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -19,6 +19,7 @@ #include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> +#include <linux/if_vlan.h> #include <net/pkt_cls.h> #include <net/ip.h> @@ -270,6 +271,15 @@ static u32 flow_get_skgid(const struct sk_buff *skb) return 0; } +static u32 flow_get_vlan_tag(const struct sk_buff *skb) +{ + u16 uninitialized_var(tag); + + if (vlan_get_tag(skb, &tag) < 0) + return 0; + return tag & VLAN_VID_MASK; +} + static u32 flow_key_get(const struct sk_buff *skb, int key) { switch (key) { @@ -305,6 +315,8 @@ static u32 flow_key_get(const struct sk_buff *skb, int key) return flow_get_skuid(skb); case FLOW_KEY_SKGID: return flow_get_skgid(skb); + case FLOW_KEY_VLAN_TAG: + return flow_get_vlan_tag(skb); default: WARN_ON(1); return 0; @@ -402,12 +414,13 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, if (tb[TCA_FLOW_KEYS]) { keymask = nla_get_u32(tb[TCA_FLOW_KEYS]); - if (fls(keymask) - 1 > FLOW_KEY_MAX) - return -EOPNOTSUPP; nkeys = hweight32(keymask); if (nkeys == 0) return -EINVAL; + + if (fls(keymask) - 1 > FLOW_KEY_MAX) + return -EOPNOTSUPP; } err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 9c2ec1992a2a..3da4129b89d1 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -176,7 +176,7 @@ META_COLLECTOR(var_dev) META_COLLECTOR(int_vlan_tag) { - unsigned short tag; + unsigned short uninitialized_var(tag); if (vlan_get_tag(skb, &tag) < 0) *err = -1; else @@ -687,8 +687,8 @@ static inline struct meta_type_ops * meta_type_ops(struct meta_value *v) * Core **************************************************************************/ -static inline int meta_get(struct sk_buff *skb, struct tcf_pkt_info *info, - struct meta_value *v, struct meta_obj *dst) +static int meta_get(struct sk_buff *skb, struct tcf_pkt_info *info, + struct meta_value *v, struct meta_obj *dst) { int err = 0; @@ -733,13 +733,15 @@ static int em_meta_match(struct sk_buff *skb, struct tcf_ematch *m, return 0; } -static inline void meta_delete(struct meta_match *meta) +static void meta_delete(struct meta_match *meta) { - struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); + if (meta) { + struct meta_type_ops *ops = meta_type_ops(&meta->lvalue); - if (ops && ops->destroy) { - ops->destroy(&meta->lvalue); - ops->destroy(&meta->rvalue); + if (ops && ops->destroy) { + ops->destroy(&meta->lvalue); + ops->destroy(&meta->rvalue); + } } kfree(meta); diff --git a/net/sched/ematch.c b/net/sched/ematch.c index 74ff918455a2..5e6f82e0e6f3 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c @@ -312,10 +312,9 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla, struct tcf_ematch_tree_hdr *tree_hdr; struct tcf_ematch *em; - if (!nla) { - memset(tree, 0, sizeof(*tree)); + memset(tree, 0, sizeof(*tree)); + if (!nla) return 0; - } err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, em_policy); if (err < 0) @@ -410,7 +409,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree) if (em->ops) { if (em->ops->destroy) em->ops->destroy(tp, em); - else if (!tcf_em_is_simple(em) && em->data) + else if (!tcf_em_is_simple(em)) kfree((void *) em->data); module_put(em->ops->owner); } @@ -418,6 +417,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree) tree->hdr.nmatches = 0; kfree(tree->matches); + tree->matches = NULL; } EXPORT_SYMBOL(tcf_em_tree_destroy); diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index e1a579efc215..795c761ad99f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -609,14 +609,14 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) /* TODO: requeuing packet charges it to policers again !! */ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) { + int ret; struct htb_sched *q = qdisc_priv(sch); - int ret = NET_XMIT_SUCCESS; struct htb_class *cl = htb_classify(skb, sch, &ret); struct sk_buff *tskb; - if (cl == HTB_DIRECT || !cl) { + if (cl == HTB_DIRECT) { /* enqueue to helper queue */ - if (q->direct_queue.qlen < q->direct_qlen && cl) { + if (q->direct_queue.qlen < q->direct_qlen) { __skb_queue_head(&q->direct_queue, skb); } else { __skb_queue_head(&q->direct_queue, skb); @@ -625,6 +625,13 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) sch->qstats.drops++; return NET_XMIT_CN; } +#ifdef CONFIG_NET_CLS_ACT + } else if (!cl) { + if (ret == NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return ret; +#endif } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { sch->qstats.drops++; |