mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-19 10:16:55 +07:00
Merge branch 'vlan_act_modify'
Shmulik Ladkani says: ==================== act_vlan: Introduce TCA_VLAN_ACT_MODIFY vlan action TCA_VLAN_ACT_MODIFY allows one to change an existing tag. It accepts same attributes as TCA_VLAN_ACT_PUSH (protocol, id, priority). If packet is vlan tagged, then the tag gets overwritten according to user specified attributes. For example, this allows user to replace a tag's vid while preserving its priority bits (as opposed to "action vlan pop pipe action vlan push"). ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
1fbafcb847
@ -3085,6 +3085,7 @@ bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu);
|
|||||||
struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
|
struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
|
||||||
struct sk_buff *skb_vlan_untag(struct sk_buff *skb);
|
struct sk_buff *skb_vlan_untag(struct sk_buff *skb);
|
||||||
int skb_ensure_writable(struct sk_buff *skb, int write_len);
|
int skb_ensure_writable(struct sk_buff *skb, int write_len);
|
||||||
|
int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci);
|
||||||
int skb_vlan_pop(struct sk_buff *skb);
|
int skb_vlan_pop(struct sk_buff *skb);
|
||||||
int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
|
int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
|
||||||
struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy,
|
struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#define TCA_VLAN_ACT_POP 1
|
#define TCA_VLAN_ACT_POP 1
|
||||||
#define TCA_VLAN_ACT_PUSH 2
|
#define TCA_VLAN_ACT_PUSH 2
|
||||||
|
#define TCA_VLAN_ACT_MODIFY 3
|
||||||
|
|
||||||
struct tc_vlan {
|
struct tc_vlan {
|
||||||
tc_gen;
|
tc_gen;
|
||||||
|
@ -4522,8 +4522,10 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(skb_ensure_writable);
|
EXPORT_SYMBOL(skb_ensure_writable);
|
||||||
|
|
||||||
/* remove VLAN header from packet and update csum accordingly. */
|
/* remove VLAN header from packet and update csum accordingly.
|
||||||
static int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci)
|
* expects a non skb_vlan_tag_present skb with a vlan tag payload
|
||||||
|
*/
|
||||||
|
int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci)
|
||||||
{
|
{
|
||||||
struct vlan_hdr *vhdr;
|
struct vlan_hdr *vhdr;
|
||||||
unsigned int offset = skb->data - skb_mac_header(skb);
|
unsigned int offset = skb->data - skb_mac_header(skb);
|
||||||
@ -4554,6 +4556,7 @@ static int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci)
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(__skb_vlan_pop);
|
||||||
|
|
||||||
int skb_vlan_pop(struct sk_buff *skb)
|
int skb_vlan_pop(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
|
|||||||
struct tcf_vlan *v = to_vlan(a);
|
struct tcf_vlan *v = to_vlan(a);
|
||||||
int action;
|
int action;
|
||||||
int err;
|
int err;
|
||||||
|
u16 tci;
|
||||||
|
|
||||||
spin_lock(&v->tcf_lock);
|
spin_lock(&v->tcf_lock);
|
||||||
tcf_lastuse_update(&v->tcf_tm);
|
tcf_lastuse_update(&v->tcf_tm);
|
||||||
@ -48,6 +49,30 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
|
|||||||
if (err)
|
if (err)
|
||||||
goto drop;
|
goto drop;
|
||||||
break;
|
break;
|
||||||
|
case TCA_VLAN_ACT_MODIFY:
|
||||||
|
/* No-op if no vlan tag (either hw-accel or in-payload) */
|
||||||
|
if (!skb_vlan_tagged(skb))
|
||||||
|
goto unlock;
|
||||||
|
/* extract existing tag (and guarantee no hw-accel tag) */
|
||||||
|
if (skb_vlan_tag_present(skb)) {
|
||||||
|
tci = skb_vlan_tag_get(skb);
|
||||||
|
skb->vlan_tci = 0;
|
||||||
|
} else {
|
||||||
|
/* in-payload vlan tag, pop it */
|
||||||
|
err = __skb_vlan_pop(skb, &tci);
|
||||||
|
if (err)
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
/* replace the vid */
|
||||||
|
tci = (tci & ~VLAN_VID_MASK) | v->tcfv_push_vid;
|
||||||
|
/* replace prio bits, if tcfv_push_prio specified */
|
||||||
|
if (v->tcfv_push_prio) {
|
||||||
|
tci &= ~VLAN_PRIO_MASK;
|
||||||
|
tci |= v->tcfv_push_prio << VLAN_PRIO_SHIFT;
|
||||||
|
}
|
||||||
|
/* put updated tci as hwaccel tag */
|
||||||
|
__vlan_hwaccel_put_tag(skb, v->tcfv_push_proto, tci);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
@ -102,6 +127,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
|||||||
case TCA_VLAN_ACT_POP:
|
case TCA_VLAN_ACT_POP:
|
||||||
break;
|
break;
|
||||||
case TCA_VLAN_ACT_PUSH:
|
case TCA_VLAN_ACT_PUSH:
|
||||||
|
case TCA_VLAN_ACT_MODIFY:
|
||||||
if (!tb[TCA_VLAN_PUSH_VLAN_ID]) {
|
if (!tb[TCA_VLAN_PUSH_VLAN_ID]) {
|
||||||
if (exists)
|
if (exists)
|
||||||
tcf_hash_release(*a, bind);
|
tcf_hash_release(*a, bind);
|
||||||
@ -185,7 +211,8 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
|
|||||||
if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt))
|
if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
if (v->tcfv_action == TCA_VLAN_ACT_PUSH &&
|
if ((v->tcfv_action == TCA_VLAN_ACT_PUSH ||
|
||||||
|
v->tcfv_action == TCA_VLAN_ACT_MODIFY) &&
|
||||||
(nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) ||
|
(nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) ||
|
||||||
nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL,
|
nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL,
|
||||||
v->tcfv_push_proto) ||
|
v->tcfv_push_proto) ||
|
||||||
|
Loading…
Reference in New Issue
Block a user