add xdp_features support for bonding driver
Subsystems (7)
cover add xdp_features support for bonding driver
Introduce missing xdp_features support for bonding driver. xdp_features is required whenever we want to xdp_redirect traffic into a bond device and then into selected slaves attached to it.
Lorenzo Bianconi (2):
bonding: add xdp_features support selftests/bpf: add xdp_feature selftest for bond device
drivers/net/bonding/bond_main.c | 48 +++++++ drivers/net/bonding/bond_options.c | 2 + include/net/bonding.h | 1 + .../selftests/bpf/prog_tests/xdp_bonding.c | 121 ++++++++++++++++++ 4 files changed, 172 insertions(+)
Signature · 1 line
2.40.0
PATCH 1/2 bonding: add xdp_features support
Introduce xdp_features support for bonding driver according to the slave devices attached to the master one.
--- drivers/net/bonding/bond_main.c | 48 ++++++++++++++++++++++++++++++ drivers/net/bonding/bond_options.c | 2 ++ include/net/bonding.h | 1 + 3 files changed, 51 insertions(+)
drivers/net/bonding/bond_main.c +48 -0
@@ -1789,6 +1789,45 @@ static void bond_ether_setup(struct net_device *bond_dev) bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING ; } +void bond_xdp_xdp_set_features (struct net_device *bond_dev) +{ +struct bonding *bond =netdev_priv (bond_dev); +xdp_features_t val =NETDEV_XDP_ACT_MASK ; +struct list_head *iter; +struct slave *slave; + +ASSERT_RTNL (); + +if (!bond_xdp_check (bond)) { +xdp_clear_features_flag (bond_dev); +return ; + } + +bond_for_each_slave (bond, slave, iter) { +struct net_device *dev = slave->dev; + +if (!(dev->xdp_features &NETDEV_XDP_ACT_BASIC )) { +xdp_clear_features_flag (bond_dev); +return ; + } + +if (!(dev->xdp_features &NETDEV_XDP_ACT_REDIRECT )) + val &= ~NETDEV_XDP_ACT_REDIRECT ; +if (!(dev->xdp_features &NETDEV_XDP_ACT_NDO_XMIT )) + val &= ~NETDEV_XDP_ACT_NDO_XMIT ; +if (!(dev->xdp_features &NETDEV_XDP_ACT_XSK_ZEROCOPY )) + val &= ~NETDEV_XDP_ACT_XSK_ZEROCOPY ; +if (!(dev->xdp_features &NETDEV_XDP_ACT_HW_OFFLOAD )) + val &= ~NETDEV_XDP_ACT_HW_OFFLOAD ; +if (!(dev->xdp_features &NETDEV_XDP_ACT_RX_SG )) + val &= ~NETDEV_XDP_ACT_RX_SG ; +if (!(dev->xdp_features &NETDEV_XDP_ACT_NDO_XMIT_SG )) + val &= ~NETDEV_XDP_ACT_NDO_XMIT_SG ; + } + +xdp_set_features_flag (bond_dev, val); +} +/* enslave device <slave> to bond device <master> */ int bond_enslave (struct net_device *bond_dev,struct net_device *slave_dev,struct netlink_ext_ack *extack)
@@ -2236,6 +2275,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,bpf_prog_inc (bond->xdp_prog); } +bond_xdp_xdp_set_features (bond_dev); +slave_info (bond_dev, slave_dev,"Enslaving as %s interface with %s link\n" ,bond_is_active_slave (new_slave) ?"an active" :"a backup" , new_slave->link !=BOND_LINK_DOWN ?"an up" :"a down" );
@@ -2483,6 +2524,7 @@ static int __bond_release_one(struct net_device *bond_dev,if (!netif_is_bond_master (slave_dev)) slave_dev->priv_flags &= ~IFF_BONDING ; +bond_xdp_xdp_set_features (bond_dev);kobject_put (&slave->kobj);return 0 ;
@@ -3930,6 +3972,9 @@ static int bond_slave_netdev_event(unsigned long event,/* Propagate to master device */ call_netdevice_notifiers (event, slave->bond->dev);break ; +case NETDEV_XDP_FEAT_CHANGE : +bond_xdp_xdp_set_features (bond_dev); +break ;default :break ; }
@@ -5874,6 +5919,9 @@ void bond_setup(struct net_device *bond_dev)if (BOND_MODE (bond) ==BOND_MODE_ACTIVEBACKUP ) bond_dev->features |=BOND_XFRM_FEATURES ;#endif /* CONFIG_XFRM_OFFLOAD */ + +if (bond_xdp_check (bond)) + bond_dev->xdp_features =NETDEV_XDP_ACT_MASK ; }/* Destroy a bonding device.
drivers/net/bonding/bond_options.c +2 -0
@@ -877,6 +877,8 @@ static int bond_option_mode_set(struct bonding *bond,netdev_update_features (bond->dev); } +bond_xdp_xdp_set_features (bond->dev); +return 0 ; }
include/net/bonding.h +1 -0
@@ -659,6 +659,7 @@ void bond_destroy_sysfs(struct bond_net *net);void bond_prepare_sysfs_group (struct bonding *bond);int bond_sysfs_slave_add (struct slave *slave);void bond_sysfs_slave_del (struct slave *slave); +void bond_xdp_xdp_set_features (struct net_device *bond_dev);int bond_enslave (struct net_device *bond_dev,struct net_device *slave_dev,struct netlink_ext_ack *extack);int bond_release (struct net_device *bond_dev,struct net_device *slave_dev);
Signature · 1 line
2.40.0
PATCH 2/2 selftests/bpf: add xdp_feature selftest for bond device
In reply to Lorenzo BianconiIntroduce selftests to check xdp_feature support for bond driver.
--- .../selftests/bpf/prog_tests/xdp_bonding.c | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+)
tools/testing/selftests/bpf/prog_tests/xdp_bonding.c +121 -0
@@ -18,6 +18,7 @@#include <linux/if_bonding.h> #include <linux/limits.h> #include <linux/udp.h> +#include <uapi/linux/netdev.h> #include "xdp_dummy.skel.h" #include "xdp_redirect_multi_kern.skel.h"
@@ -492,6 +493,123 @@ static void test_xdp_bonding_nested(struct skeletons *skeletons)system ("ip link del bond_nest2" ); } +static void test_xdp_bonding_features (struct skeletons *skeletons) +{ +LIBBPF_OPTS (bpf_xdp_query_opts, query_opts); +int bond_idx, veth1_idx, err; +struct bpf_link *link =NULL ; + +if (!ASSERT_OK (system ("ip link add bond type bond" ),"add bond" )) + goto out; + + bond_idx =if_nametoindex ("bond" ); +if (!ASSERT_GE (bond_idx,0 ,"if_nametoindex bond" )) + goto out; + +/* query default xdp-feature for bond device */ + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.feature_flags,NETDEV_XDP_ACT_MASK , +"bond query_opts.feature_flags" )) + goto out; + +if (!ASSERT_OK (system ("ip link add veth0 type veth peer name veth1" ), +"add veth{0,1} pair" )) + goto out; + +if (!ASSERT_OK (system ("ip link add veth2 type veth peer name veth3" ), +"add veth{2,3} pair" )) + goto out; + +if (!ASSERT_OK (system ("ip link set veth0 master bond" ), +"add veth0 to master bond" )) + goto out; + +/* xdp-feature for bond device should be obtained from the single slave +* device (veth0) +*/ + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.feature_flags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG , +"bond query_opts.feature_flags" )) + goto out; + + veth1_idx =if_nametoindex ("veth1" ); +if (!ASSERT_GE (veth1_idx,0 ,"if_nametoindex veth1" )) + goto out; + + link =bpf_program__attach_xdp (skeletons->xdp_dummy->progs.xdp_dummy_prog, + veth1_idx); +if (!ASSERT_OK_PTR (link,"attach program to veth1" )) + goto out; + +/* xdp-feature for veth0 are changed */ + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.feature_flags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG |NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"bond query_opts.feature_flags" )) + goto out; + +if (!ASSERT_OK (system ("ip link set veth2 master bond" ), +"add veth2 to master bond" )) + goto out; + + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +/* xdp-feature for bond device should be set to the most restrict +* value obtained from attached slave devices (veth0 and veth2) +*/ +if (!ASSERT_EQ (query_opts.feature_flags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG , +"bond query_opts.feature_flags" )) + goto out; + +if (!ASSERT_OK (system ("ip link set veth2 nomaster" ), +"del veth2 to master bond" )) + goto out; + + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +if (!ASSERT_EQ (query_opts.feature_flags, +NETDEV_XDP_ACT_BASIC |NETDEV_XDP_ACT_REDIRECT | +NETDEV_XDP_ACT_RX_SG |NETDEV_XDP_ACT_NDO_XMIT | +NETDEV_XDP_ACT_NDO_XMIT_SG , +"bond query_opts.feature_flags" )) + goto out; + +if (!ASSERT_OK (system ("ip link set veth0 nomaster" ), +"del veth0 to master bond" )) + goto out; + + err =bpf_xdp_query (bond_idx,XDP_FLAGS_DRV_MODE , &query_opts); +if (!ASSERT_OK (err,"bond bpf_xdp_query" )) + goto out; + +ASSERT_EQ (query_opts.feature_flags,NETDEV_XDP_ACT_MASK , +"bond query_opts.feature_flags" ); +out: +bpf_link__destroy (link); +system ("ip link del veth0" ); +system ("ip link del veth2" ); +system ("ip link del bond" ); +} +static int libbpf_debug_print (enum libbpf_print_level level,const char *format,va_list args) {
@@ -546,6 +664,9 @@ void serial_test_xdp_bonding(void)if (test__start_subtest ("xdp_bonding_nested" ))test_xdp_bonding_nested (&skeletons); +if (test__start_subtest ("xdp_bonding_features" )) +test_xdp_bonding_features (&skeletons); +for (i =0 ; i <ARRAY_SIZE (bond_test_cases); i++) {struct bond_test_case *test_case = &bond_test_cases[i];
Signature · 1 line
2.40.0
Re: [PATCH net 2/2] selftests/bpf: add xdp_feature selftest for bond device
Quoted 7 lines · Lorenzo Bianconi
Introduce selftests to check
xdp_featuresupport for bond driver.Signed-off-by Lorenzo Bianconi <[email protected]>--- .../selftests/bpf/prog_tests/xdp_bonding.c | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+)
Please always submit patches that touch bpf selftest via bpf tree. Otherwise BPF CI doesn't run on them.
We've seen failures in the past when such patches went through net tree.
Re: [PATCH net 2/2] selftests/bpf: add xdp_feature selftest for bond device
Quoted 12 lines · Lorenzo Bianconi
Quoted 7 lines
Introduce selftests to check
xdp_featuresupport for bond driver.Signed-off-by Lorenzo Bianconi <[email protected]>--- .../selftests/bpf/prog_tests/xdp_bonding.c | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+)Please always submit patches that touch bpf selftest via bpf tree. Otherwise BPF CI doesn't run on them.
We've seen failures in the past when such patches went through net tree.
ack, I will repost after the "guard" period splitting the series.
Regards,
Lorenzo