lkml.org 
[lkml]   [2020]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 243/639] net: sched: act_csum: Fix csum calc for tagged packets
    Date
    From: Eli Britstein <elibr@mellanox.com>

    [ Upstream commit 2ecba2d1e45b24620a7c3df9531895cf68d5dec6 ]

    The csum calculation is different for IPv4/6. For VLAN packets,
    tc_skb_protocol returns the VLAN protocol rather than the packet's one
    (e.g. IPv4/6), so csum is not calculated. Furthermore, VLAN may not be
    stripped so csum is not calculated in this case too. Calculate the
    csum for those cases.

    Fixes: d8b9605d2697 ("net: sched: fix skb->protocol use in case of accelerated vlan path")
    Signed-off-by: Eli Britstein <elibr@mellanox.com>
    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/sched/act_csum.c | 31 +++++++++++++++++++++++++++++--
    1 file changed, 29 insertions(+), 2 deletions(-)

    diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
    index 1e269441065a6..9ecbf8edcf390 100644
    --- a/net/sched/act_csum.c
    +++ b/net/sched/act_csum.c
    @@ -560,8 +560,11 @@ 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;
    + __be16 protocol;
    int action;

    params = rcu_dereference_bh(p->params);
    @@ -574,7 +577,9 @@ static int tcf_csum_act(struct sk_buff *skb, const struct tc_action *a,
    goto drop;

    update_flags = params->update_flags;
    - switch (tc_skb_protocol(skb)) {
    + protocol = tc_skb_protocol(skb);
    +again:
    + switch (protocol) {
    case cpu_to_be16(ETH_P_IP):
    if (!tcf_csum_ipv4(skb, update_flags))
    goto drop;
    @@ -583,13 +588,35 @@ static int tcf_csum_act(struct sk_buff *skb, const struct tc_action *a,
    if (!tcf_csum_ipv6(skb, update_flags))
    goto drop;
    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++;
    + }
    + goto again;
    + }
    +
    +out:
    + /* Restore the skb for the pulled VLAN tags */
    + while (vlan_hdr_count--) {
    + skb_push(skb, VLAN_HLEN);
    + skb_reset_network_header(skb);
    }

    return action;

    drop:
    qstats_drop_inc(this_cpu_ptr(p->common.cpu_qstats));
    - return TC_ACT_SHOT;
    + action = TC_ACT_SHOT;
    + goto out;
    }

    static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-24 12:12    [W:5.524 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site