On Fri, May 31, 2019 at 3:01 PM Davide Caratti <dcara...@redhat.com> wrote: > > Please note: this loop was here also before this patch (the 'goto again;' > line is only patch context). It has been introduced with commit > 2ecba2d1e45b ("net: sched: act_csum: Fix csum calc for tagged packets"). >
This is exactly why I ask... > > Why do you still need to loop here? tc_skb_pull_vlans() already > > contains a loop to pop all vlan tags? > > The reason why the loop is here is: > 1) in case there is a stripped vlan tag, it replaces tc_skb_protocol(skb) > with the inner ethertype (i.e. skb->protocol) > > 2) in case there is one or more unstripped VLAN tags, it pulls them. At > the last iteration, when it does: Let me ask it in another way: The original code, without your patch, has a loop (the "goto again") to pop all vlan tags. The code with your patch adds yet another loop (the while loop inside your tc_skb_pull_vlans()) to pop all vlan tags. So, after your patch, we have both loops. So, I am confused why we need these two nested loops to just pop all vlan tags? I think one is sufficient. > > > > > > } > > > > > > 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. > > Ok, I don't know if other parts of the kernel really need it. Its use > should be combined with tc_skb_protocol(), which is in pkt_sched.h. > > But i can move it to skbuff, or elsewhwere, unless somebody disagrees. > > > > > > +{ > > > + 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); > > Again, this code was in act_csum.c also before. The only intention of this > patch is to ensure that pskb_may_pull() is called before skb_pull(), as > per Eric suggestion, and move this code out of act_csum to use it with > other TC actions. Sure, no one says the code before yours is more correct, right? :) > > > Any reason not to call __skb_vlan_pop() directly? > > I think we can't use __skb_vlan_pop(), because 'act_csum' needs to read > the innermost ethertype in the packet to understand if it's IPv4, IPv6 or > else (ARP, EAPOL, ...). > > If I well read __skb_vlan_pop(), it returns the VLAN ID, which is useless > here. > I am confused, this could be checked by eth_type_vlan(skb->protocol), right? So why it stops you from considering __skb_vlan_pop() or skb_vlan_pop()? They both should return error or zero, not vlan ID. Thanks.