Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bpf_redirect_peer fixes'

Daniel Borkmann says:

====================
This fixes bpf_redirect_peer stats accounting for veth and netkit,
and adds tstats in the first place for the latter. Utilise indirect
call wrapper for bpf_redirect_peer, and improve test coverage of the
latter also for netkit devices. Details in the patches, thanks!

The series was targeted at bpf originally, and is done here as well,
so it can trigger BPF CI. Jakub, if you think directly going via net
is better since the majority of the diff touches net anyway, that is
fine, too.

Thanks!

v2 -> v3:
- Add kdoc for pcpu_stat_type (Simon)
- Reject invalid type value in netdev_do_alloc_pcpu_stats (Simon)
- Add Reviewed-by tags from list
v1 -> v2:
- Move stats allocation/freeing into net core (Jakub)
- As prepwork for the above, move vrf's dstats over into the core
- Add a check into stats alloc to enforce tstats upon
implementing ndo_get_peer_dev
- Add Acked-by tags from list

Daniel Borkmann (6):
net, vrf: Move dstats structure to core
net: Move {l,t,d}stats allocation to core and convert veth & vrf
netkit: Add tstats per-CPU traffic counters
bpf, netkit: Add indirect call wrapper for fetching peer dev
selftests/bpf: De-veth-ize the tc_redirect test case
selftests/bpf: Add netkit to tc_redirect selftest
====================

Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

+333 -198
+20 -2
drivers/net/netkit.c
··· 7 7 #include <linux/filter.h> 8 8 #include <linux/netfilter_netdev.h> 9 9 #include <linux/bpf_mprog.h> 10 + #include <linux/indirect_call_wrapper.h> 10 11 11 12 #include <net/netkit.h> 12 13 #include <net/dst.h> ··· 69 68 netdev_tx_t ret_dev = NET_XMIT_SUCCESS; 70 69 const struct bpf_mprog_entry *entry; 71 70 struct net_device *peer; 71 + int len = skb->len; 72 72 73 73 rcu_read_lock(); 74 74 peer = rcu_dereference(nk->peer); ··· 87 85 case NETKIT_PASS: 88 86 skb->protocol = eth_type_trans(skb, skb->dev); 89 87 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); 90 - __netif_rx(skb); 88 + if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) { 89 + dev_sw_netstats_tx_add(dev, 1, len); 90 + dev_sw_netstats_rx_add(peer, len); 91 + } else { 92 + goto drop_stats; 93 + } 91 94 break; 92 95 case NETKIT_REDIRECT: 96 + dev_sw_netstats_tx_add(dev, 1, len); 93 97 skb_do_redirect(skb); 94 98 break; 95 99 case NETKIT_DROP: 96 100 default: 97 101 drop: 98 102 kfree_skb(skb); 103 + drop_stats: 99 104 dev_core_stats_tx_dropped_inc(dev); 100 105 ret_dev = NET_XMIT_DROP; 101 106 break; ··· 178 169 rcu_read_unlock(); 179 170 } 180 171 181 - static struct net_device *netkit_peer_dev(struct net_device *dev) 172 + INDIRECT_CALLABLE_SCOPE struct net_device *netkit_peer_dev(struct net_device *dev) 182 173 { 183 174 return rcu_dereference(netkit_priv(dev)->peer); 175 + } 176 + 177 + static void netkit_get_stats(struct net_device *dev, 178 + struct rtnl_link_stats64 *stats) 179 + { 180 + dev_fetch_sw_netstats(stats, dev->tstats); 181 + stats->tx_dropped = DEV_STATS_READ(dev, tx_dropped); 184 182 } 185 183 186 184 static void netkit_uninit(struct net_device *dev); ··· 200 184 .ndo_set_rx_headroom = netkit_set_headroom, 201 185 .ndo_get_iflink = netkit_get_iflink, 202 186 .ndo_get_peer_dev = netkit_peer_dev, 187 + .ndo_get_stats64 = netkit_get_stats, 203 188 .ndo_uninit = netkit_uninit, 204 189 .ndo_features_check = passthru_features_check, 205 190 }; ··· 235 218 236 219 ether_setup(dev); 237 220 dev->max_mtu = ETH_MAX_MTU; 221 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 238 222 239 223 dev->flags |= IFF_NOARP; 240 224 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+12 -32
drivers/net/veth.c
··· 373 373 skb_tx_timestamp(skb); 374 374 if (likely(veth_forward_skb(rcv, skb, rq, use_napi) == NET_RX_SUCCESS)) { 375 375 if (!use_napi) 376 - dev_lstats_add(dev, length); 376 + dev_sw_netstats_tx_add(dev, 1, length); 377 377 else 378 378 __veth_xdp_flush(rq); 379 379 } else { ··· 385 385 rcu_read_unlock(); 386 386 387 387 return ret; 388 - } 389 - 390 - static u64 veth_stats_tx(struct net_device *dev, u64 *packets, u64 *bytes) 391 - { 392 - struct veth_priv *priv = netdev_priv(dev); 393 - 394 - dev_lstats_read(dev, packets, bytes); 395 - return atomic64_read(&priv->dropped); 396 388 } 397 389 398 390 static void veth_stats_rx(struct veth_stats *result, struct net_device *dev) ··· 424 432 struct veth_priv *priv = netdev_priv(dev); 425 433 struct net_device *peer; 426 434 struct veth_stats rx; 427 - u64 packets, bytes; 428 435 429 - tot->tx_dropped = veth_stats_tx(dev, &packets, &bytes); 430 - tot->tx_bytes = bytes; 431 - tot->tx_packets = packets; 436 + tot->tx_dropped = atomic64_read(&priv->dropped); 437 + dev_fetch_sw_netstats(tot, dev->tstats); 432 438 433 439 veth_stats_rx(&rx, dev); 434 440 tot->tx_dropped += rx.xdp_tx_err; 435 441 tot->rx_dropped = rx.rx_drops + rx.peer_tq_xdp_xmit_err; 436 - tot->rx_bytes = rx.xdp_bytes; 437 - tot->rx_packets = rx.xdp_packets; 442 + tot->rx_bytes += rx.xdp_bytes; 443 + tot->rx_packets += rx.xdp_packets; 438 444 439 445 rcu_read_lock(); 440 446 peer = rcu_dereference(priv->peer); 441 447 if (peer) { 442 - veth_stats_tx(peer, &packets, &bytes); 443 - tot->rx_bytes += bytes; 444 - tot->rx_packets += packets; 448 + struct rtnl_link_stats64 tot_peer = {}; 449 + 450 + dev_fetch_sw_netstats(&tot_peer, peer->tstats); 451 + tot->rx_bytes += tot_peer.tx_bytes; 452 + tot->rx_packets += tot_peer.tx_packets; 445 453 446 454 veth_stats_rx(&rx, peer); 447 455 tot->tx_dropped += rx.peer_tq_xdp_xmit_err; ··· 1498 1506 1499 1507 static int veth_dev_init(struct net_device *dev) 1500 1508 { 1501 - int err; 1502 - 1503 - dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats); 1504 - if (!dev->lstats) 1505 - return -ENOMEM; 1506 - 1507 - err = veth_alloc_queues(dev); 1508 - if (err) { 1509 - free_percpu(dev->lstats); 1510 - return err; 1511 - } 1512 - 1513 - return 0; 1509 + return veth_alloc_queues(dev); 1514 1510 } 1515 1511 1516 1512 static void veth_dev_free(struct net_device *dev) 1517 1513 { 1518 1514 veth_free_queues(dev); 1519 - free_percpu(dev->lstats); 1520 1515 } 1521 1516 1522 1517 #ifdef CONFIG_NET_POLL_CONTROLLER ··· 1775 1796 NETIF_F_HW_VLAN_STAG_RX); 1776 1797 dev->needs_free_netdev = true; 1777 1798 dev->priv_destructor = veth_dev_free; 1799 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; 1778 1800 dev->max_mtu = ETH_MAX_MTU; 1779 1801 1780 1802 dev->hw_features = VETH_FEATURES;
+10 -28
drivers/net/vrf.c
··· 121 121 int ifindex; 122 122 }; 123 123 124 - struct pcpu_dstats { 125 - u64 tx_pkts; 126 - u64 tx_bytes; 127 - u64 tx_drps; 128 - u64 rx_pkts; 129 - u64 rx_bytes; 130 - u64 rx_drps; 131 - struct u64_stats_sync syncp; 132 - }; 133 - 134 124 static void vrf_rx_stats(struct net_device *dev, int len) 135 125 { 136 126 struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 137 127 138 128 u64_stats_update_begin(&dstats->syncp); 139 - dstats->rx_pkts++; 129 + dstats->rx_packets++; 140 130 dstats->rx_bytes += len; 141 131 u64_stats_update_end(&dstats->syncp); 142 132 } ··· 151 161 do { 152 162 start = u64_stats_fetch_begin(&dstats->syncp); 153 163 tbytes = dstats->tx_bytes; 154 - tpkts = dstats->tx_pkts; 155 - tdrops = dstats->tx_drps; 164 + tpkts = dstats->tx_packets; 165 + tdrops = dstats->tx_drops; 156 166 rbytes = dstats->rx_bytes; 157 - rpkts = dstats->rx_pkts; 167 + rpkts = dstats->rx_packets; 158 168 } while (u64_stats_fetch_retry(&dstats->syncp, start)); 159 169 stats->tx_bytes += tbytes; 160 170 stats->tx_packets += tpkts; ··· 411 421 if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) 412 422 vrf_rx_stats(dev, len); 413 423 else 414 - this_cpu_inc(dev->dstats->rx_drps); 424 + this_cpu_inc(dev->dstats->rx_drops); 415 425 416 426 return NETDEV_TX_OK; 417 427 } ··· 606 616 struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); 607 617 608 618 u64_stats_update_begin(&dstats->syncp); 609 - dstats->tx_pkts++; 619 + dstats->tx_packets++; 610 620 dstats->tx_bytes += len; 611 621 u64_stats_update_end(&dstats->syncp); 612 622 } else { 613 - this_cpu_inc(dev->dstats->tx_drps); 623 + this_cpu_inc(dev->dstats->tx_drops); 614 624 } 615 625 616 626 return ret; ··· 1164 1174 1165 1175 vrf_rtable_release(dev, vrf); 1166 1176 vrf_rt6_release(dev, vrf); 1167 - 1168 - free_percpu(dev->dstats); 1169 - dev->dstats = NULL; 1170 1177 } 1171 1178 1172 1179 static int vrf_dev_init(struct net_device *dev) 1173 1180 { 1174 1181 struct net_vrf *vrf = netdev_priv(dev); 1175 1182 1176 - dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); 1177 - if (!dev->dstats) 1178 - goto out_nomem; 1179 - 1180 1183 /* create the default dst which points back to us */ 1181 1184 if (vrf_rtable_create(dev) != 0) 1182 - goto out_stats; 1185 + goto out_nomem; 1183 1186 1184 1187 if (vrf_rt6_create(dev) != 0) 1185 1188 goto out_rth; ··· 1186 1203 1187 1204 out_rth: 1188 1205 vrf_rtable_release(dev, vrf); 1189 - out_stats: 1190 - free_percpu(dev->dstats); 1191 - dev->dstats = NULL; 1192 1206 out_nomem: 1193 1207 return -ENOMEM; 1194 1208 } ··· 1684 1704 dev->min_mtu = IPV6_MIN_MTU; 1685 1705 dev->max_mtu = IP6_MAX_MTU; 1686 1706 dev->mtu = dev->max_mtu; 1707 + 1708 + dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 1687 1709 } 1688 1710 1689 1711 static int vrf_validate(struct nlattr *tb[], struct nlattr *data[],
+26 -4
include/linux/netdevice.h
··· 1797 1797 ML_PRIV_CAN, 1798 1798 }; 1799 1799 1800 + enum netdev_stat_type { 1801 + NETDEV_PCPU_STAT_NONE, 1802 + NETDEV_PCPU_STAT_LSTATS, /* struct pcpu_lstats */ 1803 + NETDEV_PCPU_STAT_TSTATS, /* struct pcpu_sw_netstats */ 1804 + NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */ 1805 + }; 1806 + 1800 1807 /** 1801 1808 * struct net_device - The DEVICE structure. 1802 1809 * ··· 1998 1991 * 1999 1992 * @ml_priv: Mid-layer private 2000 1993 * @ml_priv_type: Mid-layer private type 2001 - * @lstats: Loopback statistics 2002 - * @tstats: Tunnel statistics 2003 - * @dstats: Dummy statistics 2004 - * @vstats: Virtual ethernet statistics 1994 + * 1995 + * @pcpu_stat_type: Type of device statistics which the core should 1996 + * allocate/free: none, lstats, tstats, dstats. none 1997 + * means the driver is handling statistics allocation/ 1998 + * freeing internally. 1999 + * @lstats: Loopback statistics: packets, bytes 2000 + * @tstats: Tunnel statistics: RX/TX packets, RX/TX bytes 2001 + * @dstats: Dummy statistics: RX/TX/drop packets, RX/TX bytes 2005 2002 * 2006 2003 * @garp_port: GARP 2007 2004 * @mrp_port: MRP ··· 2365 2354 void *ml_priv; 2366 2355 enum netdev_ml_priv_type ml_priv_type; 2367 2356 2357 + enum netdev_stat_type pcpu_stat_type:8; 2368 2358 union { 2369 2359 struct pcpu_lstats __percpu *lstats; 2370 2360 struct pcpu_sw_netstats __percpu *tstats; ··· 2766 2754 u64_stats_t tx_bytes; 2767 2755 struct u64_stats_sync syncp; 2768 2756 } __aligned(4 * sizeof(u64)); 2757 + 2758 + struct pcpu_dstats { 2759 + u64 rx_packets; 2760 + u64 rx_bytes; 2761 + u64 rx_drops; 2762 + u64 tx_packets; 2763 + u64 tx_bytes; 2764 + u64 tx_drops; 2765 + struct u64_stats_sync syncp; 2766 + } __aligned(8 * sizeof(u64)); 2769 2767 2770 2768 struct pcpu_lstats { 2771 2769 u64_stats_t packets;
+6
include/net/netkit.h
··· 10 10 int netkit_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); 11 11 int netkit_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog); 12 12 int netkit_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr); 13 + INDIRECT_CALLABLE_DECLARE(struct net_device *netkit_peer_dev(struct net_device *dev)); 13 14 #else 14 15 static inline int netkit_prog_attach(const union bpf_attr *attr, 15 16 struct bpf_prog *prog) ··· 34 33 union bpf_attr __user *uattr) 35 34 { 36 35 return -EINVAL; 36 + } 37 + 38 + static inline struct net_device *netkit_peer_dev(struct net_device *dev) 39 + { 40 + return NULL; 37 41 } 38 42 #endif /* CONFIG_NETKIT */ 39 43 #endif /* __NET_NETKIT_H */
+56 -1
net/core/dev.c
··· 10051 10051 } 10052 10052 EXPORT_SYMBOL(netif_tx_stop_all_queues); 10053 10053 10054 + static int netdev_do_alloc_pcpu_stats(struct net_device *dev) 10055 + { 10056 + void __percpu *v; 10057 + 10058 + /* Drivers implementing ndo_get_peer_dev must support tstat 10059 + * accounting, so that skb_do_redirect() can bump the dev's 10060 + * RX stats upon network namespace switch. 10061 + */ 10062 + if (dev->netdev_ops->ndo_get_peer_dev && 10063 + dev->pcpu_stat_type != NETDEV_PCPU_STAT_TSTATS) 10064 + return -EOPNOTSUPP; 10065 + 10066 + switch (dev->pcpu_stat_type) { 10067 + case NETDEV_PCPU_STAT_NONE: 10068 + return 0; 10069 + case NETDEV_PCPU_STAT_LSTATS: 10070 + v = dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats); 10071 + break; 10072 + case NETDEV_PCPU_STAT_TSTATS: 10073 + v = dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 10074 + break; 10075 + case NETDEV_PCPU_STAT_DSTATS: 10076 + v = dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); 10077 + break; 10078 + default: 10079 + return -EINVAL; 10080 + } 10081 + 10082 + return v ? 0 : -ENOMEM; 10083 + } 10084 + 10085 + static void netdev_do_free_pcpu_stats(struct net_device *dev) 10086 + { 10087 + switch (dev->pcpu_stat_type) { 10088 + case NETDEV_PCPU_STAT_NONE: 10089 + return; 10090 + case NETDEV_PCPU_STAT_LSTATS: 10091 + free_percpu(dev->lstats); 10092 + break; 10093 + case NETDEV_PCPU_STAT_TSTATS: 10094 + free_percpu(dev->tstats); 10095 + break; 10096 + case NETDEV_PCPU_STAT_DSTATS: 10097 + free_percpu(dev->dstats); 10098 + break; 10099 + } 10100 + } 10101 + 10054 10102 /** 10055 10103 * register_netdevice() - register a network device 10056 10104 * @dev: device to register ··· 10159 10111 goto err_uninit; 10160 10112 } 10161 10113 10114 + ret = netdev_do_alloc_pcpu_stats(dev); 10115 + if (ret) 10116 + goto err_uninit; 10117 + 10162 10118 ret = dev_index_reserve(net, dev->ifindex); 10163 10119 if (ret < 0) 10164 - goto err_uninit; 10120 + goto err_free_pcpu; 10165 10121 dev->ifindex = ret; 10166 10122 10167 10123 /* Transfer changeable features to wanted_features and enable ··· 10271 10219 call_netdevice_notifiers(NETDEV_PRE_UNINIT, dev); 10272 10220 err_ifindex_release: 10273 10221 dev_index_release(net, dev->ifindex); 10222 + err_free_pcpu: 10223 + netdev_do_free_pcpu_stats(dev); 10274 10224 err_uninit: 10275 10225 if (dev->netdev_ops->ndo_uninit) 10276 10226 dev->netdev_ops->ndo_uninit(dev); ··· 10525 10471 WARN_ON(rcu_access_pointer(dev->ip_ptr)); 10526 10472 WARN_ON(rcu_access_pointer(dev->ip6_ptr)); 10527 10473 10474 + netdev_do_free_pcpu_stats(dev); 10528 10475 if (dev->priv_destructor) 10529 10476 dev->priv_destructor(dev); 10530 10477 if (dev->needs_free_netdev)
+14 -5
net/core/filter.c
··· 81 81 #include <net/xdp.h> 82 82 #include <net/mptcp.h> 83 83 #include <net/netfilter/nf_conntrack_bpf.h> 84 + #include <net/netkit.h> 84 85 #include <linux/un.h> 85 86 86 87 #include "dev.h" ··· 2469 2468 DEFINE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info); 2470 2469 EXPORT_PER_CPU_SYMBOL_GPL(bpf_redirect_info); 2471 2470 2471 + static struct net_device *skb_get_peer_dev(struct net_device *dev) 2472 + { 2473 + const struct net_device_ops *ops = dev->netdev_ops; 2474 + 2475 + if (likely(ops->ndo_get_peer_dev)) 2476 + return INDIRECT_CALL_1(ops->ndo_get_peer_dev, 2477 + netkit_peer_dev, dev); 2478 + return NULL; 2479 + } 2480 + 2472 2481 int skb_do_redirect(struct sk_buff *skb) 2473 2482 { 2474 2483 struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info); ··· 2492 2481 if (unlikely(!dev)) 2493 2482 goto out_drop; 2494 2483 if (flags & BPF_F_PEER) { 2495 - const struct net_device_ops *ops = dev->netdev_ops; 2496 - 2497 - if (unlikely(!ops->ndo_get_peer_dev || 2498 - !skb_at_tc_ingress(skb))) 2484 + if (unlikely(!skb_at_tc_ingress(skb))) 2499 2485 goto out_drop; 2500 - dev = ops->ndo_get_peer_dev(dev); 2486 + dev = skb_get_peer_dev(dev); 2501 2487 if (unlikely(!dev || 2502 2488 !(dev->flags & IFF_UP) || 2503 2489 net_eq(net, dev_net(dev)))) 2504 2490 goto out_drop; 2505 2491 skb->dev = dev; 2492 + dev_sw_netstats_rx_add(dev, skb->len); 2506 2493 return -EAGAIN; 2507 2494 } 2508 2495 return flags & BPF_F_NEIGH ?
+189 -126
tools/testing/selftests/bpf/prog_tests/tc_redirect.c
··· 24 24 25 25 #include "test_progs.h" 26 26 #include "network_helpers.h" 27 + #include "netlink_helpers.h" 27 28 #include "test_tc_neigh_fib.skel.h" 28 29 #include "test_tc_neigh.skel.h" 29 30 #include "test_tc_peer.skel.h" ··· 111 110 } 112 111 } 113 112 113 + enum dev_mode { 114 + MODE_VETH, 115 + MODE_NETKIT, 116 + }; 117 + 114 118 struct netns_setup_result { 115 - int ifindex_veth_src; 116 - int ifindex_veth_src_fwd; 117 - int ifindex_veth_dst; 118 - int ifindex_veth_dst_fwd; 119 + enum dev_mode dev_mode; 120 + int ifindex_src; 121 + int ifindex_src_fwd; 122 + int ifindex_dst; 123 + int ifindex_dst_fwd; 119 124 }; 120 125 121 126 static int get_ifaddr(const char *name, char *ifaddr) ··· 144 137 return 0; 145 138 } 146 139 140 + static int create_netkit(int mode, char *prim, char *peer) 141 + { 142 + struct rtattr *linkinfo, *data, *peer_info; 143 + struct rtnl_handle rth = { .fd = -1 }; 144 + const char *type = "netkit"; 145 + struct { 146 + struct nlmsghdr n; 147 + struct ifinfomsg i; 148 + char buf[1024]; 149 + } req = {}; 150 + int err; 151 + 152 + err = rtnl_open(&rth, 0); 153 + if (!ASSERT_OK(err, "open_rtnetlink")) 154 + return err; 155 + 156 + memset(&req, 0, sizeof(req)); 157 + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 158 + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; 159 + req.n.nlmsg_type = RTM_NEWLINK; 160 + req.i.ifi_family = AF_UNSPEC; 161 + 162 + addattr_l(&req.n, sizeof(req), IFLA_IFNAME, prim, strlen(prim)); 163 + linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO); 164 + addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, strlen(type)); 165 + data = addattr_nest(&req.n, sizeof(req), IFLA_INFO_DATA); 166 + addattr32(&req.n, sizeof(req), IFLA_NETKIT_MODE, mode); 167 + peer_info = addattr_nest(&req.n, sizeof(req), IFLA_NETKIT_PEER_INFO); 168 + req.n.nlmsg_len += sizeof(struct ifinfomsg); 169 + addattr_l(&req.n, sizeof(req), IFLA_IFNAME, peer, strlen(peer)); 170 + addattr_nest_end(&req.n, peer_info); 171 + addattr_nest_end(&req.n, data); 172 + addattr_nest_end(&req.n, linkinfo); 173 + 174 + err = rtnl_talk(&rth, &req.n, NULL); 175 + ASSERT_OK(err, "talk_rtnetlink"); 176 + rtnl_close(&rth); 177 + return err; 178 + } 179 + 147 180 static int netns_setup_links_and_routes(struct netns_setup_result *result) 148 181 { 149 182 struct nstoken *nstoken = NULL; 150 - char veth_src_fwd_addr[IFADDR_STR_LEN+1] = {}; 183 + char src_fwd_addr[IFADDR_STR_LEN+1] = {}; 184 + int err; 151 185 152 - SYS(fail, "ip link add veth_src type veth peer name veth_src_fwd"); 153 - SYS(fail, "ip link add veth_dst type veth peer name veth_dst_fwd"); 186 + if (result->dev_mode == MODE_VETH) { 187 + SYS(fail, "ip link add src type veth peer name src_fwd"); 188 + SYS(fail, "ip link add dst type veth peer name dst_fwd"); 154 189 155 - SYS(fail, "ip link set veth_dst_fwd address " MAC_DST_FWD); 156 - SYS(fail, "ip link set veth_dst address " MAC_DST); 190 + SYS(fail, "ip link set dst_fwd address " MAC_DST_FWD); 191 + SYS(fail, "ip link set dst address " MAC_DST); 192 + } else if (result->dev_mode == MODE_NETKIT) { 193 + err = create_netkit(NETKIT_L3, "src", "src_fwd"); 194 + if (!ASSERT_OK(err, "create_ifindex_src")) 195 + goto fail; 196 + err = create_netkit(NETKIT_L3, "dst", "dst_fwd"); 197 + if (!ASSERT_OK(err, "create_ifindex_dst")) 198 + goto fail; 199 + } 157 200 158 - if (get_ifaddr("veth_src_fwd", veth_src_fwd_addr)) 201 + if (get_ifaddr("src_fwd", src_fwd_addr)) 159 202 goto fail; 160 203 161 - result->ifindex_veth_src = if_nametoindex("veth_src"); 162 - if (!ASSERT_GT(result->ifindex_veth_src, 0, "ifindex_veth_src")) 204 + result->ifindex_src = if_nametoindex("src"); 205 + if (!ASSERT_GT(result->ifindex_src, 0, "ifindex_src")) 163 206 goto fail; 164 207 165 - result->ifindex_veth_src_fwd = if_nametoindex("veth_src_fwd"); 166 - if (!ASSERT_GT(result->ifindex_veth_src_fwd, 0, "ifindex_veth_src_fwd")) 208 + result->ifindex_src_fwd = if_nametoindex("src_fwd"); 209 + if (!ASSERT_GT(result->ifindex_src_fwd, 0, "ifindex_src_fwd")) 167 210 goto fail; 168 211 169 - result->ifindex_veth_dst = if_nametoindex("veth_dst"); 170 - if (!ASSERT_GT(result->ifindex_veth_dst, 0, "ifindex_veth_dst")) 212 + result->ifindex_dst = if_nametoindex("dst"); 213 + if (!ASSERT_GT(result->ifindex_dst, 0, "ifindex_dst")) 171 214 goto fail; 172 215 173 - result->ifindex_veth_dst_fwd = if_nametoindex("veth_dst_fwd"); 174 - if (!ASSERT_GT(result->ifindex_veth_dst_fwd, 0, "ifindex_veth_dst_fwd")) 216 + result->ifindex_dst_fwd = if_nametoindex("dst_fwd"); 217 + if (!ASSERT_GT(result->ifindex_dst_fwd, 0, "ifindex_dst_fwd")) 175 218 goto fail; 176 219 177 - SYS(fail, "ip link set veth_src netns " NS_SRC); 178 - SYS(fail, "ip link set veth_src_fwd netns " NS_FWD); 179 - SYS(fail, "ip link set veth_dst_fwd netns " NS_FWD); 180 - SYS(fail, "ip link set veth_dst netns " NS_DST); 220 + SYS(fail, "ip link set src netns " NS_SRC); 221 + SYS(fail, "ip link set src_fwd netns " NS_FWD); 222 + SYS(fail, "ip link set dst_fwd netns " NS_FWD); 223 + SYS(fail, "ip link set dst netns " NS_DST); 181 224 182 225 /** setup in 'src' namespace */ 183 226 nstoken = open_netns(NS_SRC); 184 227 if (!ASSERT_OK_PTR(nstoken, "setns src")) 185 228 goto fail; 186 229 187 - SYS(fail, "ip addr add " IP4_SRC "/32 dev veth_src"); 188 - SYS(fail, "ip addr add " IP6_SRC "/128 dev veth_src nodad"); 189 - SYS(fail, "ip link set dev veth_src up"); 230 + SYS(fail, "ip addr add " IP4_SRC "/32 dev src"); 231 + SYS(fail, "ip addr add " IP6_SRC "/128 dev src nodad"); 232 + SYS(fail, "ip link set dev src up"); 190 233 191 - SYS(fail, "ip route add " IP4_DST "/32 dev veth_src scope global"); 192 - SYS(fail, "ip route add " IP4_NET "/16 dev veth_src scope global"); 193 - SYS(fail, "ip route add " IP6_DST "/128 dev veth_src scope global"); 234 + SYS(fail, "ip route add " IP4_DST "/32 dev src scope global"); 235 + SYS(fail, "ip route add " IP4_NET "/16 dev src scope global"); 236 + SYS(fail, "ip route add " IP6_DST "/128 dev src scope global"); 194 237 195 - SYS(fail, "ip neigh add " IP4_DST " dev veth_src lladdr %s", 196 - veth_src_fwd_addr); 197 - SYS(fail, "ip neigh add " IP6_DST " dev veth_src lladdr %s", 198 - veth_src_fwd_addr); 238 + if (result->dev_mode == MODE_VETH) { 239 + SYS(fail, "ip neigh add " IP4_DST " dev src lladdr %s", 240 + src_fwd_addr); 241 + SYS(fail, "ip neigh add " IP6_DST " dev src lladdr %s", 242 + src_fwd_addr); 243 + } 199 244 200 245 close_netns(nstoken); 201 246 ··· 260 201 * needs v4 one in order to start ARP probing. IP4_NET route is added 261 202 * to the endpoints so that the ARP processing will reply. 262 203 */ 263 - SYS(fail, "ip addr add " IP4_SLL "/32 dev veth_src_fwd"); 264 - SYS(fail, "ip addr add " IP4_DLL "/32 dev veth_dst_fwd"); 265 - SYS(fail, "ip link set dev veth_src_fwd up"); 266 - SYS(fail, "ip link set dev veth_dst_fwd up"); 204 + SYS(fail, "ip addr add " IP4_SLL "/32 dev src_fwd"); 205 + SYS(fail, "ip addr add " IP4_DLL "/32 dev dst_fwd"); 206 + SYS(fail, "ip link set dev src_fwd up"); 207 + SYS(fail, "ip link set dev dst_fwd up"); 267 208 268 - SYS(fail, "ip route add " IP4_SRC "/32 dev veth_src_fwd scope global"); 269 - SYS(fail, "ip route add " IP6_SRC "/128 dev veth_src_fwd scope global"); 270 - SYS(fail, "ip route add " IP4_DST "/32 dev veth_dst_fwd scope global"); 271 - SYS(fail, "ip route add " IP6_DST "/128 dev veth_dst_fwd scope global"); 209 + SYS(fail, "ip route add " IP4_SRC "/32 dev src_fwd scope global"); 210 + SYS(fail, "ip route add " IP6_SRC "/128 dev src_fwd scope global"); 211 + SYS(fail, "ip route add " IP4_DST "/32 dev dst_fwd scope global"); 212 + SYS(fail, "ip route add " IP6_DST "/128 dev dst_fwd scope global"); 272 213 273 214 close_netns(nstoken); 274 215 ··· 277 218 if (!ASSERT_OK_PTR(nstoken, "setns dst")) 278 219 goto fail; 279 220 280 - SYS(fail, "ip addr add " IP4_DST "/32 dev veth_dst"); 281 - SYS(fail, "ip addr add " IP6_DST "/128 dev veth_dst nodad"); 282 - SYS(fail, "ip link set dev veth_dst up"); 221 + SYS(fail, "ip addr add " IP4_DST "/32 dev dst"); 222 + SYS(fail, "ip addr add " IP6_DST "/128 dev dst nodad"); 223 + SYS(fail, "ip link set dev dst up"); 283 224 284 - SYS(fail, "ip route add " IP4_SRC "/32 dev veth_dst scope global"); 285 - SYS(fail, "ip route add " IP4_NET "/16 dev veth_dst scope global"); 286 - SYS(fail, "ip route add " IP6_SRC "/128 dev veth_dst scope global"); 225 + SYS(fail, "ip route add " IP4_SRC "/32 dev dst scope global"); 226 + SYS(fail, "ip route add " IP4_NET "/16 dev dst scope global"); 227 + SYS(fail, "ip route add " IP6_SRC "/128 dev dst scope global"); 287 228 288 - SYS(fail, "ip neigh add " IP4_SRC " dev veth_dst lladdr " MAC_DST_FWD); 289 - SYS(fail, "ip neigh add " IP6_SRC " dev veth_dst lladdr " MAC_DST_FWD); 229 + if (result->dev_mode == MODE_VETH) { 230 + SYS(fail, "ip neigh add " IP4_SRC " dev dst lladdr " MAC_DST_FWD); 231 + SYS(fail, "ip neigh add " IP6_SRC " dev dst lladdr " MAC_DST_FWD); 232 + } 290 233 291 234 close_netns(nstoken); 292 235 ··· 354 293 const struct bpf_program *chk_prog, 355 294 const struct netns_setup_result *setup_result) 356 295 { 357 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_src_fwd); 358 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_dst_fwd); 296 + LIBBPF_OPTS(bpf_tc_hook, qdisc_src_fwd); 297 + LIBBPF_OPTS(bpf_tc_hook, qdisc_dst_fwd); 359 298 int err; 360 299 361 - /* tc qdisc add dev veth_src_fwd clsact */ 362 - QDISC_CLSACT_CREATE(&qdisc_veth_src_fwd, setup_result->ifindex_veth_src_fwd); 363 - /* tc filter add dev veth_src_fwd ingress bpf da src_prog */ 364 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_INGRESS, src_prog, 0); 365 - /* tc filter add dev veth_src_fwd egress bpf da chk_prog */ 366 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_EGRESS, chk_prog, 0); 300 + /* tc qdisc add dev src_fwd clsact */ 301 + QDISC_CLSACT_CREATE(&qdisc_src_fwd, setup_result->ifindex_src_fwd); 302 + /* tc filter add dev src_fwd ingress bpf da src_prog */ 303 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_INGRESS, src_prog, 0); 304 + /* tc filter add dev src_fwd egress bpf da chk_prog */ 305 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_EGRESS, chk_prog, 0); 367 306 368 - /* tc qdisc add dev veth_dst_fwd clsact */ 369 - QDISC_CLSACT_CREATE(&qdisc_veth_dst_fwd, setup_result->ifindex_veth_dst_fwd); 370 - /* tc filter add dev veth_dst_fwd ingress bpf da dst_prog */ 371 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_INGRESS, dst_prog, 0); 372 - /* tc filter add dev veth_dst_fwd egress bpf da chk_prog */ 373 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_EGRESS, chk_prog, 0); 307 + /* tc qdisc add dev dst_fwd clsact */ 308 + QDISC_CLSACT_CREATE(&qdisc_dst_fwd, setup_result->ifindex_dst_fwd); 309 + /* tc filter add dev dst_fwd ingress bpf da dst_prog */ 310 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_INGRESS, dst_prog, 0); 311 + /* tc filter add dev dst_fwd egress bpf da chk_prog */ 312 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_EGRESS, chk_prog, 0); 374 313 375 314 return 0; 376 315 fail: ··· 600 539 static int netns_load_dtime_bpf(struct test_tc_dtime *skel, 601 540 const struct netns_setup_result *setup_result) 602 541 { 603 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_src_fwd); 604 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_dst_fwd); 605 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_src); 606 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_dst); 542 + LIBBPF_OPTS(bpf_tc_hook, qdisc_src_fwd); 543 + LIBBPF_OPTS(bpf_tc_hook, qdisc_dst_fwd); 544 + LIBBPF_OPTS(bpf_tc_hook, qdisc_src); 545 + LIBBPF_OPTS(bpf_tc_hook, qdisc_dst); 607 546 struct nstoken *nstoken; 608 547 int err; 609 548 ··· 611 550 nstoken = open_netns(NS_SRC); 612 551 if (!ASSERT_OK_PTR(nstoken, "setns " NS_SRC)) 613 552 return -1; 614 - /* tc qdisc add dev veth_src clsact */ 615 - QDISC_CLSACT_CREATE(&qdisc_veth_src, setup_result->ifindex_veth_src); 616 - /* tc filter add dev veth_src ingress bpf da ingress_host */ 617 - XGRESS_FILTER_ADD(&qdisc_veth_src, BPF_TC_INGRESS, skel->progs.ingress_host, 0); 618 - /* tc filter add dev veth_src egress bpf da egress_host */ 619 - XGRESS_FILTER_ADD(&qdisc_veth_src, BPF_TC_EGRESS, skel->progs.egress_host, 0); 553 + /* tc qdisc add dev src clsact */ 554 + QDISC_CLSACT_CREATE(&qdisc_src, setup_result->ifindex_src); 555 + /* tc filter add dev src ingress bpf da ingress_host */ 556 + XGRESS_FILTER_ADD(&qdisc_src, BPF_TC_INGRESS, skel->progs.ingress_host, 0); 557 + /* tc filter add dev src egress bpf da egress_host */ 558 + XGRESS_FILTER_ADD(&qdisc_src, BPF_TC_EGRESS, skel->progs.egress_host, 0); 620 559 close_netns(nstoken); 621 560 622 561 /* setup ns_dst tc progs */ 623 562 nstoken = open_netns(NS_DST); 624 563 if (!ASSERT_OK_PTR(nstoken, "setns " NS_DST)) 625 564 return -1; 626 - /* tc qdisc add dev veth_dst clsact */ 627 - QDISC_CLSACT_CREATE(&qdisc_veth_dst, setup_result->ifindex_veth_dst); 628 - /* tc filter add dev veth_dst ingress bpf da ingress_host */ 629 - XGRESS_FILTER_ADD(&qdisc_veth_dst, BPF_TC_INGRESS, skel->progs.ingress_host, 0); 630 - /* tc filter add dev veth_dst egress bpf da egress_host */ 631 - XGRESS_FILTER_ADD(&qdisc_veth_dst, BPF_TC_EGRESS, skel->progs.egress_host, 0); 565 + /* tc qdisc add dev dst clsact */ 566 + QDISC_CLSACT_CREATE(&qdisc_dst, setup_result->ifindex_dst); 567 + /* tc filter add dev dst ingress bpf da ingress_host */ 568 + XGRESS_FILTER_ADD(&qdisc_dst, BPF_TC_INGRESS, skel->progs.ingress_host, 0); 569 + /* tc filter add dev dst egress bpf da egress_host */ 570 + XGRESS_FILTER_ADD(&qdisc_dst, BPF_TC_EGRESS, skel->progs.egress_host, 0); 632 571 close_netns(nstoken); 633 572 634 573 /* setup ns_fwd tc progs */ 635 574 nstoken = open_netns(NS_FWD); 636 575 if (!ASSERT_OK_PTR(nstoken, "setns " NS_FWD)) 637 576 return -1; 638 - /* tc qdisc add dev veth_dst_fwd clsact */ 639 - QDISC_CLSACT_CREATE(&qdisc_veth_dst_fwd, setup_result->ifindex_veth_dst_fwd); 640 - /* tc filter add dev veth_dst_fwd ingress prio 100 bpf da ingress_fwdns_prio100 */ 641 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_INGRESS, 577 + /* tc qdisc add dev dst_fwd clsact */ 578 + QDISC_CLSACT_CREATE(&qdisc_dst_fwd, setup_result->ifindex_dst_fwd); 579 + /* tc filter add dev dst_fwd ingress prio 100 bpf da ingress_fwdns_prio100 */ 580 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_INGRESS, 642 581 skel->progs.ingress_fwdns_prio100, 100); 643 - /* tc filter add dev veth_dst_fwd ingress prio 101 bpf da ingress_fwdns_prio101 */ 644 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_INGRESS, 582 + /* tc filter add dev dst_fwd ingress prio 101 bpf da ingress_fwdns_prio101 */ 583 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_INGRESS, 645 584 skel->progs.ingress_fwdns_prio101, 101); 646 - /* tc filter add dev veth_dst_fwd egress prio 100 bpf da egress_fwdns_prio100 */ 647 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_EGRESS, 585 + /* tc filter add dev dst_fwd egress prio 100 bpf da egress_fwdns_prio100 */ 586 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_EGRESS, 648 587 skel->progs.egress_fwdns_prio100, 100); 649 - /* tc filter add dev veth_dst_fwd egress prio 101 bpf da egress_fwdns_prio101 */ 650 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_EGRESS, 588 + /* tc filter add dev dst_fwd egress prio 101 bpf da egress_fwdns_prio101 */ 589 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_EGRESS, 651 590 skel->progs.egress_fwdns_prio101, 101); 652 591 653 - /* tc qdisc add dev veth_src_fwd clsact */ 654 - QDISC_CLSACT_CREATE(&qdisc_veth_src_fwd, setup_result->ifindex_veth_src_fwd); 655 - /* tc filter add dev veth_src_fwd ingress prio 100 bpf da ingress_fwdns_prio100 */ 656 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_INGRESS, 592 + /* tc qdisc add dev src_fwd clsact */ 593 + QDISC_CLSACT_CREATE(&qdisc_src_fwd, setup_result->ifindex_src_fwd); 594 + /* tc filter add dev src_fwd ingress prio 100 bpf da ingress_fwdns_prio100 */ 595 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_INGRESS, 657 596 skel->progs.ingress_fwdns_prio100, 100); 658 - /* tc filter add dev veth_src_fwd ingress prio 101 bpf da ingress_fwdns_prio101 */ 659 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_INGRESS, 597 + /* tc filter add dev src_fwd ingress prio 101 bpf da ingress_fwdns_prio101 */ 598 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_INGRESS, 660 599 skel->progs.ingress_fwdns_prio101, 101); 661 - /* tc filter add dev veth_src_fwd egress prio 100 bpf da egress_fwdns_prio100 */ 662 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_EGRESS, 600 + /* tc filter add dev src_fwd egress prio 100 bpf da egress_fwdns_prio100 */ 601 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_EGRESS, 663 602 skel->progs.egress_fwdns_prio100, 100); 664 - /* tc filter add dev veth_src_fwd egress prio 101 bpf da egress_fwdns_prio101 */ 665 - XGRESS_FILTER_ADD(&qdisc_veth_src_fwd, BPF_TC_EGRESS, 603 + /* tc filter add dev src_fwd egress prio 101 bpf da egress_fwdns_prio101 */ 604 + XGRESS_FILTER_ADD(&qdisc_src_fwd, BPF_TC_EGRESS, 666 605 skel->progs.egress_fwdns_prio101, 101); 667 606 close_netns(nstoken); 668 607 return 0; ··· 838 777 if (!ASSERT_OK_PTR(skel, "test_tc_dtime__open")) 839 778 return; 840 779 841 - skel->rodata->IFINDEX_SRC = setup_result->ifindex_veth_src_fwd; 842 - skel->rodata->IFINDEX_DST = setup_result->ifindex_veth_dst_fwd; 780 + skel->rodata->IFINDEX_SRC = setup_result->ifindex_src_fwd; 781 + skel->rodata->IFINDEX_DST = setup_result->ifindex_dst_fwd; 843 782 844 783 err = test_tc_dtime__load(skel); 845 784 if (!ASSERT_OK(err, "test_tc_dtime__load")) ··· 929 868 if (!ASSERT_OK_PTR(skel, "test_tc_neigh__open")) 930 869 goto done; 931 870 932 - skel->rodata->IFINDEX_SRC = setup_result->ifindex_veth_src_fwd; 933 - skel->rodata->IFINDEX_DST = setup_result->ifindex_veth_dst_fwd; 871 + skel->rodata->IFINDEX_SRC = setup_result->ifindex_src_fwd; 872 + skel->rodata->IFINDEX_DST = setup_result->ifindex_dst_fwd; 934 873 935 874 err = test_tc_neigh__load(skel); 936 875 if (!ASSERT_OK(err, "test_tc_neigh__load")) ··· 965 904 if (!ASSERT_OK_PTR(skel, "test_tc_peer__open")) 966 905 goto done; 967 906 968 - skel->rodata->IFINDEX_SRC = setup_result->ifindex_veth_src_fwd; 969 - skel->rodata->IFINDEX_DST = setup_result->ifindex_veth_dst_fwd; 907 + skel->rodata->IFINDEX_SRC = setup_result->ifindex_src_fwd; 908 + skel->rodata->IFINDEX_DST = setup_result->ifindex_dst_fwd; 970 909 971 910 err = test_tc_peer__load(skel); 972 911 if (!ASSERT_OK(err, "test_tc_peer__load")) ··· 1057 996 static void test_tc_redirect_peer_l3(struct netns_setup_result *setup_result) 1058 997 { 1059 998 LIBBPF_OPTS(bpf_tc_hook, qdisc_tun_fwd); 1060 - LIBBPF_OPTS(bpf_tc_hook, qdisc_veth_dst_fwd); 999 + LIBBPF_OPTS(bpf_tc_hook, qdisc_dst_fwd); 1061 1000 struct test_tc_peer *skel = NULL; 1062 1001 struct nstoken *nstoken = NULL; 1063 1002 int err; ··· 1106 1045 goto fail; 1107 1046 1108 1047 skel->rodata->IFINDEX_SRC = ifindex; 1109 - skel->rodata->IFINDEX_DST = setup_result->ifindex_veth_dst_fwd; 1048 + skel->rodata->IFINDEX_DST = setup_result->ifindex_dst_fwd; 1110 1049 1111 1050 err = test_tc_peer__load(skel); 1112 1051 if (!ASSERT_OK(err, "test_tc_peer__load")) ··· 1114 1053 1115 1054 /* Load "tc_src_l3" to the tun_fwd interface to redirect packets 1116 1055 * towards dst, and "tc_dst" to redirect packets 1117 - * and "tc_chk" on veth_dst_fwd to drop non-redirected packets. 1056 + * and "tc_chk" on dst_fwd to drop non-redirected packets. 1118 1057 */ 1119 1058 /* tc qdisc add dev tun_fwd clsact */ 1120 1059 QDISC_CLSACT_CREATE(&qdisc_tun_fwd, ifindex); 1121 1060 /* tc filter add dev tun_fwd ingress bpf da tc_src_l3 */ 1122 1061 XGRESS_FILTER_ADD(&qdisc_tun_fwd, BPF_TC_INGRESS, skel->progs.tc_src_l3, 0); 1123 1062 1124 - /* tc qdisc add dev veth_dst_fwd clsact */ 1125 - QDISC_CLSACT_CREATE(&qdisc_veth_dst_fwd, setup_result->ifindex_veth_dst_fwd); 1126 - /* tc filter add dev veth_dst_fwd ingress bpf da tc_dst_l3 */ 1127 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_INGRESS, skel->progs.tc_dst_l3, 0); 1128 - /* tc filter add dev veth_dst_fwd egress bpf da tc_chk */ 1129 - XGRESS_FILTER_ADD(&qdisc_veth_dst_fwd, BPF_TC_EGRESS, skel->progs.tc_chk, 0); 1063 + /* tc qdisc add dev dst_fwd clsact */ 1064 + QDISC_CLSACT_CREATE(&qdisc_dst_fwd, setup_result->ifindex_dst_fwd); 1065 + /* tc filter add dev dst_fwd ingress bpf da tc_dst_l3 */ 1066 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_INGRESS, skel->progs.tc_dst_l3, 0); 1067 + /* tc filter add dev dst_fwd egress bpf da tc_chk */ 1068 + XGRESS_FILTER_ADD(&qdisc_dst_fwd, BPF_TC_EGRESS, skel->progs.tc_chk, 0); 1130 1069 1131 1070 /* Setup route and neigh tables */ 1132 1071 SYS(fail, "ip -netns " NS_SRC " addr add dev tun_src " IP4_TUN_SRC "/24"); ··· 1135 1074 SYS(fail, "ip -netns " NS_SRC " addr add dev tun_src " IP6_TUN_SRC "/64 nodad"); 1136 1075 SYS(fail, "ip -netns " NS_FWD " addr add dev tun_fwd " IP6_TUN_FWD "/64 nodad"); 1137 1076 1138 - SYS(fail, "ip -netns " NS_SRC " route del " IP4_DST "/32 dev veth_src scope global"); 1077 + SYS(fail, "ip -netns " NS_SRC " route del " IP4_DST "/32 dev src scope global"); 1139 1078 SYS(fail, "ip -netns " NS_SRC " route add " IP4_DST "/32 via " IP4_TUN_FWD 1140 1079 " dev tun_src scope global"); 1141 - SYS(fail, "ip -netns " NS_DST " route add " IP4_TUN_SRC "/32 dev veth_dst scope global"); 1142 - SYS(fail, "ip -netns " NS_SRC " route del " IP6_DST "/128 dev veth_src scope global"); 1080 + SYS(fail, "ip -netns " NS_DST " route add " IP4_TUN_SRC "/32 dev dst scope global"); 1081 + SYS(fail, "ip -netns " NS_SRC " route del " IP6_DST "/128 dev src scope global"); 1143 1082 SYS(fail, "ip -netns " NS_SRC " route add " IP6_DST "/128 via " IP6_TUN_FWD 1144 1083 " dev tun_src scope global"); 1145 - SYS(fail, "ip -netns " NS_DST " route add " IP6_TUN_SRC "/128 dev veth_dst scope global"); 1084 + SYS(fail, "ip -netns " NS_DST " route add " IP6_TUN_SRC "/128 dev dst scope global"); 1146 1085 1147 - SYS(fail, "ip -netns " NS_DST " neigh add " IP4_TUN_SRC " dev veth_dst lladdr " MAC_DST_FWD); 1148 - SYS(fail, "ip -netns " NS_DST " neigh add " IP6_TUN_SRC " dev veth_dst lladdr " MAC_DST_FWD); 1086 + SYS(fail, "ip -netns " NS_DST " neigh add " IP4_TUN_SRC " dev dst lladdr " MAC_DST_FWD); 1087 + SYS(fail, "ip -netns " NS_DST " neigh add " IP6_TUN_SRC " dev dst lladdr " MAC_DST_FWD); 1149 1088 1150 1089 if (!ASSERT_OK(set_forwarding(false), "disable forwarding")) 1151 1090 goto fail; ··· 1167 1106 close_netns(nstoken); 1168 1107 } 1169 1108 1170 - #define RUN_TEST(name) \ 1109 + #define RUN_TEST(name, mode) \ 1171 1110 ({ \ 1172 - struct netns_setup_result setup_result; \ 1111 + struct netns_setup_result setup_result = { .dev_mode = mode, }; \ 1173 1112 if (test__start_subtest(#name)) \ 1174 1113 if (ASSERT_OK(netns_setup_namespaces("add"), "setup namespaces")) { \ 1175 1114 if (ASSERT_OK(netns_setup_links_and_routes(&setup_result), \ ··· 1183 1122 { 1184 1123 netns_setup_namespaces_nofail("delete"); 1185 1124 1186 - RUN_TEST(tc_redirect_peer); 1187 - RUN_TEST(tc_redirect_peer_l3); 1188 - RUN_TEST(tc_redirect_neigh); 1189 - RUN_TEST(tc_redirect_neigh_fib); 1190 - RUN_TEST(tc_redirect_dtime); 1125 + RUN_TEST(tc_redirect_peer, MODE_VETH); 1126 + RUN_TEST(tc_redirect_peer, MODE_NETKIT); 1127 + RUN_TEST(tc_redirect_peer_l3, MODE_VETH); 1128 + RUN_TEST(tc_redirect_peer_l3, MODE_NETKIT); 1129 + RUN_TEST(tc_redirect_neigh, MODE_VETH); 1130 + RUN_TEST(tc_redirect_neigh_fib, MODE_VETH); 1131 + RUN_TEST(tc_redirect_dtime, MODE_VETH); 1191 1132 return NULL; 1192 1133 } 1193 1134