Skip to content

Commit 3998d18

Browse files
borkmannAlexei Starovoitov
authored and
Alexei Starovoitov
committed
netkit: Fix pkt_type override upon netkit pass verdict
When running Cilium connectivity test suite with netkit in L2 mode, we found that compared to tcx a few tests were failing which pushed traffic into an L7 proxy sitting in host namespace. The problem in particular is around the invocation of eth_type_trans() in netkit. In case of tcx, this is run before the tcx ingress is triggered inside host namespace and thus if the BPF program uses the bpf_skb_change_type() helper the newly set type is retained. However, in case of netkit, the late eth_type_trans() invocation overrides the earlier decision from the BPF program which eventually leads to the test failure. Instead of eth_type_trans(), split out the relevant parts, meaning, reset of mac header and call to eth_skb_pkt_type() before the BPF program is run in order to have the same behavior as with tcx, and refactor a small helper called eth_skb_pull_mac() which is run in case it's passed up the stack where the mac header must be pulled. With this all connectivity tests pass. Fixes: 35dfaad ("netkit, bpf: Add bpf programmable net device") Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d6fe532 commit 3998d18

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

drivers/net/netkit.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static void netkit_prep_forward(struct sk_buff *skb, bool xnet)
5555
skb_scrub_packet(skb, xnet);
5656
skb->priority = 0;
5757
nf_skip_egress(skb, true);
58+
skb_reset_mac_header(skb);
5859
}
5960

6061
static struct netkit *netkit_priv(const struct net_device *dev)
@@ -78,14 +79,15 @@ static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
7879
skb_orphan_frags(skb, GFP_ATOMIC)))
7980
goto drop;
8081
netkit_prep_forward(skb, !net_eq(dev_net(dev), dev_net(peer)));
82+
eth_skb_pkt_type(skb, peer);
8183
skb->dev = peer;
8284
entry = rcu_dereference(nk->active);
8385
if (entry)
8486
ret = netkit_run(entry, skb, ret);
8587
switch (ret) {
8688
case NETKIT_NEXT:
8789
case NETKIT_PASS:
88-
skb->protocol = eth_type_trans(skb, skb->dev);
90+
eth_skb_pull_mac(skb);
8991
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
9092
if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
9193
dev_sw_netstats_tx_add(dev, 1, len);

include/linux/etherdevice.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,14 @@ static inline void eth_skb_pkt_type(struct sk_buff *skb,
636636
}
637637
}
638638

639+
static inline struct ethhdr *eth_skb_pull_mac(struct sk_buff *skb)
640+
{
641+
struct ethhdr *eth = (struct ethhdr *)skb->data;
642+
643+
skb_pull_inline(skb, ETH_HLEN);
644+
return eth;
645+
}
646+
639647
/**
640648
* eth_skb_pad - Pad buffer to mininum number of octets for Ethernet frame
641649
* @skb: Buffer to pad

net/ethernet/eth.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
161161
skb->dev = dev;
162162
skb_reset_mac_header(skb);
163163

164-
eth = (struct ethhdr *)skb->data;
165-
skb_pull_inline(skb, ETH_HLEN);
166-
164+
eth = eth_skb_pull_mac(skb);
167165
eth_skb_pkt_type(skb, dev);
168166

169167
/*

0 commit comments

Comments
 (0)