Skip to content

Commit bc31c90

Browse files
wdebruijdavem330
authored andcommitted
net-tc: convert tc_from to tc_from_ingress and tc_redirected
The tc_from field fulfills two roles. It encodes whether a packet was redirected by an act_mirred device and, if so, whether act_mirred was called on ingress or egress. Split it into separate fields. The information is needed by the special IFB loop, where packets are taken out of the normal path by act_mirred, forwarded to IFB, then reinjected at their original location (ingress or egress) by IFB. The IFB device cannot use skb->tc_at_ingress, because that may have been overwritten as the packet travels from act_mirred to ifb_xmit, when it passes through tc_classify on the IFB egress path. Cache this value in skb->tc_from_ingress. That field is valid only if a packet arriving at ifb_xmit came from act_mirred. Other packets can be crafted to reach ifb_xmit. These must be dropped. Set tc_redirected on redirection and drop all packets that do not have this bit set. Both fields are set only on cloned skbs in tc actions, so original packet sources do not have to clear the bit when reusing packets (notably, pktgen and octeon). Signed-off-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8dc07fd commit bc31c90

File tree

6 files changed

+15
-19
lines changed

6 files changed

+15
-19
lines changed

drivers/net/ifb.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,7 @@ static void ifb_ri_tasklet(unsigned long _txp)
7878
}
7979

8080
while ((skb = __skb_dequeue(&txp->tq)) != NULL) {
81-
u32 from = skb->tc_from;
82-
83-
skb_reset_tc(skb);
81+
skb->tc_redirected = 0;
8482
skb->tc_skip_classify = 1;
8583

8684
u64_stats_update_begin(&txp->tsync);
@@ -101,13 +99,12 @@ static void ifb_ri_tasklet(unsigned long _txp)
10199
rcu_read_unlock();
102100
skb->skb_iif = txp->dev->ifindex;
103101

104-
if (from & AT_EGRESS) {
102+
if (!skb->tc_from_ingress) {
105103
dev_queue_xmit(skb);
106-
} else if (from & AT_INGRESS) {
104+
} else {
107105
skb_pull(skb, skb->mac_len);
108106
netif_receive_skb(skb);
109-
} else
110-
BUG();
107+
}
111108
}
112109

113110
if (__netif_tx_trylock(txq)) {
@@ -246,7 +243,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
246243
txp->rx_bytes += skb->len;
247244
u64_stats_update_end(&txp->rsync);
248245

249-
if (skb->tc_from == AT_STACK || !skb->skb_iif) {
246+
if (!skb->tc_redirected || !skb->skb_iif) {
250247
dev_kfree_skb(skb);
251248
dev->stats.rx_dropped++;
252249
return NETDEV_TX_OK;

include/linux/skbuff.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,8 @@ static inline bool skb_mstamp_after(const struct skb_mstamp *t1,
591591
* @ipvs_property: skbuff is owned by ipvs
592592
* @tc_skip_classify: do not classify packet. set by IFB device
593593
* @tc_at_ingress: used within tc_classify to distinguish in/egress
594+
* @tc_redirected: packet was redirected by a tc action
595+
* @tc_from_ingress: if tc_redirected, tc_at_ingress at time of redirect
594596
* @peeked: this packet has been seen already, so stats have been
595597
* done for it, don't do them again
596598
* @nf_trace: netfilter packet trace flag
@@ -753,7 +755,8 @@ struct sk_buff {
753755
#ifdef CONFIG_NET_CLS_ACT
754756
__u8 tc_skip_classify:1;
755757
__u8 tc_at_ingress:1;
756-
__u8 tc_from:2;
758+
__u8 tc_redirected:1;
759+
__u8 tc_from_ingress:1;
757760
#endif
758761

759762
#ifdef CONFIG_NET_SCHED

include/net/sch_generic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ int skb_do_redirect(struct sk_buff *);
412412
static inline void skb_reset_tc(struct sk_buff *skb)
413413
{
414414
#ifdef CONFIG_NET_CLS_ACT
415-
skb->tc_from = 0;
415+
skb->tc_redirected = 0;
416416
#endif
417417
}
418418

include/uapi/linux/pkt_cls.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44
#include <linux/types.h>
55
#include <linux/pkt_sched.h>
66

7-
#ifdef __KERNEL__
8-
#define AT_STACK 0x0
9-
#define AT_INGRESS 0x1
10-
#define AT_EGRESS 0x2
11-
#endif
12-
137
/* Action attributes */
148
enum {
159
TCA_ACT_UNSPEC,

net/sched/act_mirred.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,10 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
211211
}
212212

213213
/* mirror is always swallowed */
214-
if (tcf_mirred_is_act_redirect(m_eaction))
215-
skb2->tc_from = skb_at_tc_ingress(skb) ? AT_INGRESS : AT_EGRESS;
214+
if (tcf_mirred_is_act_redirect(m_eaction)) {
215+
skb2->tc_redirected = 1;
216+
skb2->tc_from_ingress = skb2->tc_at_ingress;
217+
}
216218

217219
skb2->skb_iif = skb->dev->ifindex;
218220
skb2->dev = dev;

net/sched/sch_netem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
626626
* If it's at ingress let's pretend the delay is
627627
* from the network (tstamp will be updated).
628628
*/
629-
if (skb->tc_from & AT_INGRESS)
629+
if (skb->tc_redirected && skb->tc_from_ingress)
630630
skb->tstamp = 0;
631631
#endif
632632

0 commit comments

Comments
 (0)