Re: [PATCH v2 net-next 4/4] net/sched: act_mirred: Implement ingress actions
From: Shmulik Ladkani <hidden>
Date: 2016-09-27 21:42:55
Hi, On Tue, 27 Sep 2016 14:27:13 -0700 Eric Dumazet [off-list ref] wrote:
On Tue, 2016-09-27 at 23:59 +0300, Shmulik Ladkani wrote:quoted
Up until now, 'action mirred' supported only egress actions (either TCA_EGRESS_REDIR or TCA_EGRESS_MIRROR). This patch implements the corresponding ingress actions TCA_INGRESS_REDIR and TCA_INGRESS_MIRROR.quoted
- if (m->tcfm_mac_header_xmit) + /* If action's target direction differs than filter's direction, + * and devices expect a mac header on xmit, then mac push/pull is + * needed. + */ + if (at != tcf_mirred_act_direction(m->tcfm_eaction) &&Note that m->tcfm_eaction is read here.quoted
+ m->tcfm_mac_header_xmit) { + if (at & AT_EGRESS) { + /* caught at egress, act ingress: pull mac */ + mac_len = skb_network_header(skb) - skb_mac_header(skb); + skb_pull_rcsum(skb2, mac_len); + } else { + /* caught at ingress, act egress: push mac */ skb_push_rcsum(skb2, skb->mac_len); + } } /* mirror is always swallowed */ - if (m->tcfm_eaction != TCA_EGRESS_MIRROR) + if (tcf_mirred_is_act_redirect(m->tcfm_eaction)) skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at); skb2->skb_iif = skb->dev->ifindex; skb2->dev = dev; - err = dev_queue_xmit(skb2);Note that m->tcfm_eaction is read another time here.quoted
+ if (tcf_mirred_act_direction(m->tcfm_eaction) & AT_EGRESS) + err = dev_queue_xmit(skb2); + else + netif_receive_skb(skb2);Since this runs lockless, another cpu might change m->tcfm_eaction in the middle, and you could call dev_queue_xmit(skb2) while the skb2 was prepared for the opposite action.
Thanks Eric. I assume adding a READ_ONCE(m->tcfm_eaction) at beggining of section, and using the read value, will solve this specific inconsistency?