static int pop_vlan(struct sk_buff *skb, struct sw_flow_key *key) { int err; err = skb_vlan_pop(skb); if (skb_vlan_tag_present(skb)) invalidate_flow_key(key); else key->eth.tci = 0; return err; }
static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { struct tcf_vlan *v = a->priv; int action; int err; spin_lock(&v->tcf_lock); v->tcf_tm.lastuse = jiffies; bstats_update(&v->tcf_bstats, skb); action = v->tcf_action; switch (v->tcfv_action) { case TCA_VLAN_ACT_POP: err = skb_vlan_pop(skb); if (err) goto drop; break; case TCA_VLAN_ACT_PUSH: err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid); if (err) goto drop; break; default: BUG(); } goto unlock; drop: action = TC_ACT_SHOT; v->tcf_qstats.drops++; unlock: spin_unlock(&v->tcf_lock); return action; }