|
@@ -43,7 +43,8 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
|
|
|
goto drop;
|
|
|
break;
|
|
|
case TCA_VLAN_ACT_PUSH:
|
|
|
- err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid);
|
|
|
+ err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid |
|
|
|
+ (v->tcfv_push_prio << VLAN_PRIO_SHIFT));
|
|
|
if (err)
|
|
|
goto drop;
|
|
|
break;
|
|
@@ -65,6 +66,7 @@ static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
|
|
|
[TCA_VLAN_PARMS] = { .len = sizeof(struct tc_vlan) },
|
|
|
[TCA_VLAN_PUSH_VLAN_ID] = { .type = NLA_U16 },
|
|
|
[TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type = NLA_U16 },
|
|
|
+ [TCA_VLAN_PUSH_VLAN_PRIORITY] = { .type = NLA_U8 },
|
|
|
};
|
|
|
|
|
|
static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|
@@ -78,6 +80,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|
|
int action;
|
|
|
__be16 push_vid = 0;
|
|
|
__be16 push_proto = 0;
|
|
|
+ u8 push_prio = 0;
|
|
|
bool exists = false;
|
|
|
int ret = 0, err;
|
|
|
|
|
@@ -123,6 +126,9 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|
|
} else {
|
|
|
push_proto = htons(ETH_P_8021Q);
|
|
|
}
|
|
|
+
|
|
|
+ if (tb[TCA_VLAN_PUSH_VLAN_PRIORITY])
|
|
|
+ push_prio = nla_get_u8(tb[TCA_VLAN_PUSH_VLAN_PRIORITY]);
|
|
|
break;
|
|
|
default:
|
|
|
if (exists)
|
|
@@ -150,6 +156,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|
|
|
|
|
v->tcfv_action = action;
|
|
|
v->tcfv_push_vid = push_vid;
|
|
|
+ v->tcfv_push_prio = push_prio;
|
|
|
v->tcfv_push_proto = push_proto;
|
|
|
|
|
|
v->tcf_action = parm->action;
|
|
@@ -181,7 +188,9 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
|
|
|
if (v->tcfv_action == TCA_VLAN_ACT_PUSH &&
|
|
|
(nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) ||
|
|
|
nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL,
|
|
|
- v->tcfv_push_proto)))
|
|
|
+ v->tcfv_push_proto) ||
|
|
|
+ (nla_put_u8(skb, TCA_VLAN_PUSH_VLAN_PRIORITY,
|
|
|
+ v->tcfv_push_prio))))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
tcf_tm_dump(&t, &v->tcf_tm);
|