On Fri, May 31, 2019 at 10:26 AM Davide Caratti <dcara...@redhat.com> wrote: > diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c > index 14bb525e355e..e8308ddcae9d 100644 > --- a/net/sched/act_csum.c > +++ b/net/sched/act_csum.c > @@ -574,7 +574,6 @@ static int tcf_csum_act(struct sk_buff *skb, const struct > tc_action *a, > struct tcf_result *res) > { > struct tcf_csum *p = to_tcf_csum(a); > - bool orig_vlan_tag_present = false; > unsigned int vlan_hdr_count = 0; > struct tcf_csum_params *params; > u32 update_flags; > @@ -604,17 +603,8 @@ static int tcf_csum_act(struct sk_buff *skb, const > struct tc_action *a, > break; > case cpu_to_be16(ETH_P_8021AD): /* fall through */ > case cpu_to_be16(ETH_P_8021Q): > - if (skb_vlan_tag_present(skb) && !orig_vlan_tag_present) { > - protocol = skb->protocol; > - orig_vlan_tag_present = true; > - } else { > - struct vlan_hdr *vlan = (struct vlan_hdr *)skb->data; > - > - protocol = vlan->h_vlan_encapsulated_proto; > - skb_pull(skb, VLAN_HLEN); > - skb_reset_network_header(skb); > - vlan_hdr_count++; > - } > + if (tc_skb_pull_vlans(skb, &vlan_hdr_count, &protocol)) > + goto drop; > goto again;
Why do you still need to loop here? tc_skb_pull_vlans() already contains a loop to pop all vlan tags? > } > > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c > index d4699156974a..382ee69fb1a5 100644 > --- a/net/sched/cls_api.c > +++ b/net/sched/cls_api.c > @@ -3300,6 +3300,28 @@ unsigned int tcf_exts_num_actions(struct tcf_exts > *exts) > } > EXPORT_SYMBOL(tcf_exts_num_actions); > > +int tc_skb_pull_vlans(struct sk_buff *skb, unsigned int *hdr_count, > + __be16 *proto) It looks like this function fits better in net/core/skbuff.c, because I don't see anything TC specific. > +{ > + if (skb_vlan_tag_present(skb)) > + *proto = skb->protocol; > + > + while (eth_type_vlan(*proto)) { > + struct vlan_hdr *vlan; > + > + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) > + return -ENOMEM; > + > + vlan = (struct vlan_hdr *)skb->data; > + *proto = vlan->h_vlan_encapsulated_proto; > + skb_pull(skb, VLAN_HLEN); > + skb_reset_network_header(skb); Any reason not to call __skb_vlan_pop() directly? > + (*hdr_count)++; > + } > + return 0; > +} Thanks.