net: Shift responsibility for FDB notifications to drivers
Subsystems (9)
Petr Machata
maintainerv2 cover net: Shift responsibility for FDB notifications to drivers
Currently when FDB entries are added to or deleted from a VXLAN netdevice, the VXLAN driver emits one notification, including the VXLAN-specific attributes. The core however always sends a notification as well, a generic one. Thus two notifications are unnecessarily sent for these operations. A similar situation comes up with bridge driver, which also emits notifications on its own.
# ip link add name vx type vxlan id 1000 dstport 4789 # bridge monitor fdb & [1] 1981693 # bridge fdb add de:ad:be:ef:13:37 dev vx self dst 192.0.2.1 de:ad:be:ef:13:37 dev vx dst 192.0.2.1 self permanent de:ad:be:ef:13:37 dev vx self permanent
In order to prevent this duplicity, shift the responsibility to send the notification always to the drivers. Only where the default FDB add / del operations are used does the core emit notifications. If fdb_add and fdb_del are overridden, the driver should do that instead.
To facilitate upholding this new responsibility, export rtnl_fdb_notify() for drivers to use.
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Patches #1 to #3 are concerned with the above.
In the remaining patches, #4 to #8, add a selftest. This takes place across several patches. Many of the helpers we would like to use for the test are in forwarding/lib.sh, whereas net/ is a more suitable place for the test, so the libraries need to be massaged a bit first.
v2:
- Patches #2, #3:
- Fix qlcnic build
Petr Machata (8):
net: rtnetlink: Publish rtnl_fdb_notify()
ndo_fdb_add: Shift responsibility for notifying to drivers
ndo_fdb_del: Shift responsibility for notifying to drivers
selftests: net: lib: Move logging from forwarding/lib.sh here
selftests: net: lib: Move tests_run from forwarding/lib.sh here
selftests: net: lib: Move checks from forwarding/lib.sh here
selftests: net: lib: Add kill_process
selftests: net: fdb_notify: Add a test for FDB notifications
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 + drivers/net/ethernet/intel/ice/ice_main.c | 6 + drivers/net/ethernet/mscc/ocelot_net.c | 16 +- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 12 +- drivers/net/macvlan.c | 6 + include/linux/netdevice.h | 5 + include/linux/rtnetlink.h | 2 + net/core/rtnetlink.c | 24 +- .../drivers/net/mlxsw/devlink_trap.sh | 2 +- .../net/mlxsw/devlink_trap_l3_drops.sh | 4 +- .../net/mlxsw/devlink_trap_l3_exceptions.sh | 12 +- .../net/mlxsw/devlink_trap_tunnel_ipip.sh | 4 +- .../net/mlxsw/devlink_trap_tunnel_ipip6.sh | 4 +- .../net/mlxsw/devlink_trap_tunnel_vxlan.sh | 4 +- .../mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh | 4 +- .../selftests/drivers/net/mlxsw/tc_sample.sh | 4 +- .../net/netdevsim/fib_notifications.sh | 6 +- tools/testing/selftests/net/Makefile | 2 +- .../selftests/net/drop_monitor_tests.sh | 2 +- tools/testing/selftests/net/fdb_notify.sh | 95 ++++++++ tools/testing/selftests/net/fib_tests.sh | 8 +- .../selftests/net/forwarding/devlink_lib.sh | 2 +- tools/testing/selftests/net/forwarding/lib.sh | 199 +--------------- .../selftests/net/forwarding/tc_police.sh | 8 +- tools/testing/selftests/net/lib.sh | 223 ++++++++++++++++++ 25 files changed, 411 insertions(+), 246 deletions(-) create mode 100755 tools/testing/selftests/net/fdb_notify.sh
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 1/8 net: rtnetlink: Publish rtnl_fdb_notify()
In the next patch, responsibility for sending notification is moved from the core to the driver that implement fdb_add (and fdb_del in the patch after that). In this patch, export a helper that the core currently uses for sending FDB notifications for the drivers to use as a fallback if there is nothing specific to report.
---
Notes:
CC: Przemek Kitszel <[email protected]>
CC: [email protected]
CC: [email protected]
CC: Manish Chopra <[email protected]>
CC: [email protected]
CC: Kuniyuki Iwashima <[email protected]>
CC: Andrew Lunn <[email protected]>
include/linux/rtnetlink.h | 2 ++ net/core/rtnetlink.c | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-)
include/linux/rtnetlink.h +2 -0
@@ -192,6 +192,8 @@ extern int ndo_dflt_fdb_add(struct ndmsg *ndm,const unsigned char *addr, u16 vid, u16 flags); +extern void rtnl_fdb_notify (struct net_device *dev,const u8 *addr,u16 vid, +int type,u16 ndm_state); extern int ndo_dflt_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], struct net_device *dev,
net/core/rtnetlink.c +4 -3
@@ -4271,7 +4271,7 @@ void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change,static int nlmsg_populate_fdb_fill (struct sk_buff *skb,struct net_device *dev, -u8 *addr,u16 vid,u32 pid,u32 seq, +const u8 *addr,u16 vid,u32 pid,u32 seq,int type,unsigned int flags,int nlflags,u16 ndm_state) {
@@ -4313,8 +4313,8 @@ static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev)0 ; } -static void rtnl_fdb_notify (struct net_device *dev,u8 *addr,u16 vid,int type, -u16 ndm_state) +void rtnl_fdb_notify (struct net_device *dev,const u8 *addr,u16 vid,int type, +u16 ndm_state) {struct net *net =dev_net (dev);struct sk_buff *skb;
@@ -4336,6 +4336,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, errout:rtnl_set_sk_err (net,RTNLGRP_NEIGH , err); } +EXPORT_SYMBOL_GPL (rtnl_fdb_notify);/* * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 2/8 ndo_fdb_add: Shift responsibility for notifying to drivers
In reply to Petr MachataCurrently when FDB entries are added to or deleted from a VXLAN netdevice, the VXLAN driver emits one notification, including the VXLAN-specific attributes. The core however always sends a notification as well, a generic one. Thus two notifications are unnecessarily sent for these operations. A similar situation comes up with bridge driver, which also emits notifications on its own:
# ip link add name vx type vxlan id 1000 dstport 4789 # bridge monitor fdb & [1] 1981693 # bridge fdb add de:ad:be:ef:13:37 dev vx self dst 192.0.2.1 de:ad:be:ef:13:37 dev vx dst 192.0.2.1 self permanent de:ad:be:ef:13:37 dev vx self permanent
In order to prevent this duplicity, shift the responsibility to send the notification always to the drivers. Only where the default FDB add / del operations are used does the core emit notifications. If fdb_add and fdb_del are overridden, the driver should do that instead.
Drivers can use rtnl_fdb_notify(), exported in the previous patch, to get the default notification behavior back. This function is made to notify on success, which means several drivers do not need to change at all.
---
Notes:
v2:
- Fix qlcnic build
---
CC: Przemek Kitszel <[email protected]>
CC: [email protected]
CC: [email protected]
CC: Manish Chopra <[email protected]>
CC: [email protected]
CC: Kuniyuki Iwashima <[email protected]>
CC: Andrew Lunn <[email protected]>
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/ethernet/intel/ice/ice_main.c | 3 +++ drivers/net/ethernet/mscc/ocelot_net.c | 8 +++++++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 7 ++++++- drivers/net/macvlan.c | 3 +++ include/linux/netdevice.h | 3 +++ net/core/rtnetlink.c | 8 ++++---- 7 files changed, 29 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +3 -0
@@ -13126,6 +13126,9 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],if (err == -EEXIST && !(flags &NLM_F_EXCL )) err =0 ; +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , ndm->ndm_state); +return err; }
drivers/net/ethernet/intel/ice/ice_main.c +3 -0
@@ -6154,6 +6154,9 @@ ice_fdb_add(struct ndmsg *ndm, struct nlattr __always_unused *tb[],if (err == -EEXIST && !(flags &NLM_F_EXCL )) err =0 ; +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , ndm->ndm_state); +return err; }
drivers/net/ethernet/mscc/ocelot_net.c +7 -1
@@ -737,8 +737,14 @@ static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],struct ocelot_port *ocelot_port = &priv->port;struct ocelot *ocelot = ocelot_port->ocelot;int port = priv->port.index; +int err; -return ocelot_fdb_add (ocelot, port, addr, vid, ocelot_port->bridge); + err =ocelot_fdb_add (ocelot, port, addr, vid, ocelot_port->bridge); + +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , ndm->ndm_state); + +return err; } static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +6 -1
@@ -409,7 +409,7 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], }if (ether_addr_equal (addr, adapter->mac_addr)) -return err; + goto out;if (is_unicast_ether_addr (addr)) {if (netdev_uc_count (netdev) < adapter->ahw->max_uc_count)
@@ -422,6 +422,11 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], err = -EINVAL ; } +out: +if (!err) +rtnl_fdb_notify (netdev, addr, vid,RTM_NEWNEIGH , + ndm->ndm_state); +return err; }
drivers/net/macvlan.c +3 -0
@@ -1044,6 +1044,9 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],else if (is_multicast_ether_addr (addr)) err =dev_mc_add_excl (dev, addr); +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , ndm->ndm_state); +return err; }
include/linux/netdevice.h +3 -0
@@ -1247,6 +1247,9 @@ struct netdev_net_notifier {* const unsigned char *addr, u16 vid, u16 flags, * struct netlink_ext_ack *extack); * Adds an FDB entry to dev for addr. +* Callee is responsible for sending appropriate notification. The helper +* rtnl_fdb_notify() can be invoked to send a generic notification in case +* the driver does not need to customize the notification. * int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[], * struct net_device *dev, * const unsigned char *addr, u16 vid)
net/core/rtnetlink.c +4 -4
@@ -4376,6 +4376,9 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm,if (err == -EEXIST && !(flags &NLM_F_EXCL )) err =0 ; +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , ndm->ndm_state); +return err; }EXPORT_SYMBOL (ndo_dflt_fdb_add);
@@ -4473,11 +4476,8 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, err =ndo_dflt_fdb_add (ndm, tb, dev, addr, vid, nlh->nlmsg_flags); -if (!err) { -rtnl_fdb_notify (dev, addr, vid,RTM_NEWNEIGH , - ndm->ndm_state); +if (!err) ndm->ndm_flags &= ~NTF_SELF ; - } } out:return err;
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 3/8 ndo_fdb_del: Shift responsibility for notifying to drivers
In reply to Petr MachataAs described in the previous patch, the drivers that provide their own fdb_add and fdb_del callbacks should from now on be responsible for sending the notification themselves. In this patch, implement the fdb_del leg of the change.
---
Notes:
v2:
- Fix qlcnic build
---
CC: Przemek Kitszel <[email protected]>
CC: [email protected]
CC: [email protected]
CC: Manish Chopra <[email protected]>
CC: [email protected]
CC: Kuniyuki Iwashima <[email protected]>
CC: Andrew Lunn <[email protected]>
drivers/net/ethernet/intel/ice/ice_main.c | 3 +++ drivers/net/ethernet/mscc/ocelot_net.c | 8 +++++++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +++++ drivers/net/macvlan.c | 3 +++ include/linux/netdevice.h | 2 ++ net/core/rtnetlink.c | 9 ++++----- 6 files changed, 24 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/ice/ice_main.c +3 -0
@@ -6188,6 +6188,9 @@ ice_fdb_del(struct ndmsg *ndm, __always_unused struct nlattr *tb[],else err = -EINVAL ; +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_DELNEIGH , ndm->ndm_state); +return err; }
drivers/net/ethernet/mscc/ocelot_net.c +7 -1
@@ -756,8 +756,14 @@ static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],struct ocelot_port *ocelot_port = &priv->port;struct ocelot *ocelot = ocelot_port->ocelot;int port = priv->port.index; +int err; -return ocelot_fdb_del (ocelot, port, addr, vid, ocelot_port->bridge); + err =ocelot_fdb_del (ocelot, port, addr, vid, ocelot_port->bridge); + +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_DELNEIGH , ndm->ndm_state); + +return err; } static int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +5 -0
@@ -388,6 +388,11 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], err = -EINVAL ; } } + +if (!err) +rtnl_fdb_notify (netdev, addr, vid,RTM_DELNEIGH , + ndm->ndm_state); +return err; }
drivers/net/macvlan.c +3 -0
@@ -1069,6 +1069,9 @@ static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],else if (is_multicast_ether_addr (addr)) err =dev_mc_del (dev, addr); +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_DELNEIGH , ndm->ndm_state); +return err; }
include/linux/netdevice.h +2 -0
@@ -1254,6 +1254,8 @@ struct netdev_net_notifier {* struct net_device *dev, * const unsigned char *addr, u16 vid) * Deletes the FDB entry from dev corresponding to addr. +* Callee is responsible for sending appropriate notification, as with +* ndo_fdb_add(). * int (*ndo_fdb_del_bulk)(struct nlmsghdr *nlh, struct net_device *dev, * struct netlink_ext_ack *extack); * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
net/core/rtnetlink.c +4 -5
@@ -4506,6 +4506,9 @@ int ndo_dflt_fdb_del(struct ndmsg *ndm,else if (is_multicast_ether_addr (addr)) err =dev_mc_del (dev, addr); +if (!err) +rtnl_fdb_notify (dev, addr, vid,RTM_DELNEIGH , ndm->ndm_state); +return err; }EXPORT_SYMBOL (ndo_dflt_fdb_del);
@@ -4604,12 +4607,8 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, err = ops->ndo_fdb_del_bulk (nlh, dev, extack); } -if (!err) { -if (!del_bulk) -rtnl_fdb_notify (dev, addr, vid,RTM_DELNEIGH , - ndm->ndm_state); +if (!err) ndm->ndm_flags &= ~NTF_SELF ; - } } out:return err;
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 4/8 selftests: net: lib: Move logging from forwarding/lib.sh here
In reply to Petr MachataMany net selftests invent their own logging helpers. These really should be in a library sourced by these tests. Currently forwarding/lib.sh has a suite of perfectly fine logging helpers, but sourcing a forwarding/ library from a higher-level directory smells of layering violation. In this patch, move the logging helpers to net/lib.sh so that every net test can use them.
Together with the logging helpers, it's also necessary to move pause_on_fail(), and EXIT_STATUS and RET.
Existing lib.sh users might be using these same names for their functions or variables. However lib.sh is always sourced near the top of the file (checked), and whatever new definitions will simply override the ones provided by lib.sh.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: Benjamin Poirier <[email protected]>
CC: Hangbin Liu <[email protected]>
CC: [email protected]
CC: Jiri Pirko <[email protected]>
---
tools/testing/selftests/net/forwarding/lib.sh | 113 ----------------- tools/testing/selftests/net/lib.sh | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+), 113 deletions(-)
tools/testing/selftests/net/forwarding/lib.sh +0 -113
@@ -48,7 +48,6 @@ declare -A NETIFS=( : "${WAIT_TIME:=5}" # Whether to pause on, respectively, after a failure and before cleanup. -: "${PAUSE_ON_FAIL:=no}" : "${PAUSE_ON_CLEANUP:=no}" # Whether to create virtual interfaces, and what netdevice type they should be.
@@ -446,22 +445,6 @@ done ############################################################################## # Helpers -# Exit status to return at the end. Set in case one of the tests fails. -EXIT_STATUS=0 -# Per-test return value. Clear at the beginning of each test. -RET=0 - -ret_set_ksft_status() -{ - local ksft_status=$1; shift - local msg=$1; shift - - RET=$(ksft_status_merge $RET $ksft_status) - if (( $? )); then - retmsg=$msg - fi -} - # Whether FAILs should be interpreted as XFAILs. Internal. FAIL_TO_XFAIL=
@@ -535,102 +518,6 @@ xfail_on_veth() fi } -log_test_result() -{ - local test_name=$1; shift - local opt_str=$1; shift - local result=$1; shift - local retmsg=$1; shift - - printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result" - if [[ $retmsg ]]; then - printf "\t%s\n" "$retmsg" - fi -} - -pause_on_fail() -{ - if [[ $PAUSE_ON_FAIL == yes ]]; then - echo "Hit enter to continue, 'q' to quit" - read a - [[ $a == q ]] && exit 1 - fi -} - -handle_test_result_pass() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" " OK " -} - -handle_test_result_fail() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" FAIL "$retmsg" - pause_on_fail -} - -handle_test_result_xfail() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" XFAIL "$retmsg" - pause_on_fail -} - -handle_test_result_skip() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" SKIP "$retmsg" -} - -log_test() -{ - local test_name=$1 - local opt_str=$2 - - if [[ $# -eq 2 ]]; then - opt_str="($opt_str)" - fi - - if ((RET == ksft_pass)); then - handle_test_result_pass "$test_name" "$opt_str" - elif ((RET == ksft_xfail)); then - handle_test_result_xfail "$test_name" "$opt_str" - elif ((RET == ksft_skip)); then - handle_test_result_skip "$test_name" "$opt_str" - else - handle_test_result_fail "$test_name" "$opt_str" - fi - - EXIT_STATUS=$(ksft_exit_status_merge $EXIT_STATUS $RET) - return $RET -} - -log_test_skip() -{ - RET=$ksft_skip retmsg= log_test "$@" -} - -log_test_xfail() -{ - RET=$ksft_xfail retmsg= log_test "$@" -} - -log_info() -{ - local msg=$1 - - echo "INFO: $msg" -} - not() { "$@"
tools/testing/selftests/net/lib.sh +115 -0
130 lines not on this page · raw message
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 5/8 selftests: net: lib: Move tests_run from forwarding/lib.sh here
In reply to Petr MachataIt would be good to use the same mechanism for scheduling and dispatching general net tests as the many forwarding tests already use. To that end, move the logging helpers to net/lib.sh so that every net test can use them.
Existing lib.sh users might be using the name themselves. However lib.sh is always sourced near the top of the file (checked), and whatever new definition will simply override the one provided by lib.sh.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: Benjamin Poirier <[email protected]>
CC: Hangbin Liu <[email protected]>
CC: [email protected]
CC: Jiri Pirko <[email protected]>
---
tools/testing/selftests/net/forwarding/lib.sh | 10 ---------- tools/testing/selftests/net/lib.sh | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-)
tools/testing/selftests/net/forwarding/lib.sh +0 -10
@@ -1285,16 +1285,6 @@ matchall_sink_create() action drop } -tests_run() -{ - local current_test - - for current_test in ${TESTS:-$ALL_TESTS}; do - in_defer_scope \ - $current_test - done -} - cleanup() { pre_cleanup
tools/testing/selftests/net/lib.sh +10 -0
@@ -351,3 +351,13 @@ log_info() echo "INFO: $msg" } + +tests_run() +{ + local current_test + + for current_test in ${TESTS:-$ALL_TESTS}; do + in_defer_scope \ + $current_test + done +}
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 6/8 selftests: net: lib: Move checks from forwarding/lib.sh here
In reply to Petr MachataFor logging to be useful, something has to set RET and retmsg by calling ret_set_ksft_status(). There is a suite of functions to that end in forwarding/lib: check_err, check_fail et.al. Move them to net/lib.sh so that every net test can use them.
Existing lib.sh users might be using these same names for their functions. However lib.sh is always sourced near the top of the file (checked), and whatever new definitions will simply override the ones provided by lib.sh.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: Benjamin Poirier <[email protected]>
CC: Hangbin Liu <[email protected]>
CC: [email protected]
CC: Jiri Pirko <[email protected]>
---
tools/testing/selftests/net/forwarding/lib.sh | 73 ------------------- tools/testing/selftests/net/lib.sh | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+), 73 deletions(-)
tools/testing/selftests/net/forwarding/lib.sh +0 -73
@@ -445,79 +445,6 @@ done ############################################################################## # Helpers -# Whether FAILs should be interpreted as XFAILs. Internal. -FAIL_TO_XFAIL= - -check_err() -{ - local err=$1 - local msg=$2 - - if ((err)); then - if [[ $FAIL_TO_XFAIL = yes ]]; then - ret_set_ksft_status $ksft_xfail "$msg" - else - ret_set_ksft_status $ksft_fail "$msg" - fi - fi -} - -check_fail() -{ - local err=$1 - local msg=$2 - - check_err $((!err)) "$msg" -} - -check_err_fail() -{ - local should_fail=$1; shift - local err=$1; shift - local what=$1; shift - - if ((should_fail)); then - check_fail $err "$what succeeded, but should have failed" - else - check_err $err "$what failed" - fi -} - -xfail() -{ - FAIL_TO_XFAIL=yes "$@" -} - -xfail_on_slow() -{ - if [[ $KSFT_MACHINE_SLOW = yes ]]; then - FAIL_TO_XFAIL=yes "$@" - else - "$@" - fi -} - -omit_on_slow() -{ - if [[ $KSFT_MACHINE_SLOW != yes ]]; then - "$@" - fi -} - -xfail_on_veth() -{ - local dev=$1; shift - local kind - - kind=$(ip -j -d link show dev $dev | - jq -r '.[].linkinfo.info_kind') - if [[ $kind = veth ]]; then - FAIL_TO_XFAIL=yes "$@" - else - "$@" - fi -} - not() { "$@"
tools/testing/selftests/net/lib.sh +73 -0
76 lines not on this page · raw message
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 7/8 selftests: net: lib: Add kill_process
In reply to Petr MachataA number of selftests run processes in the background and need to kill them afterwards. Instead for everyone to open-code the kill / wait / redirect mantra, add a helper in net/lib.sh. Convert existing open-code sites.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: Benjamin Poirier <[email protected]>
CC: Hangbin Liu <[email protected]>
CC: [email protected]
CC: Jiri Pirko <[email protected]>
CC: Andrew Lunn <[email protected]>
---
.../selftests/drivers/net/mlxsw/devlink_trap.sh | 2 +- .../drivers/net/mlxsw/devlink_trap_l3_drops.sh | 4 ++-- .../drivers/net/mlxsw/devlink_trap_l3_exceptions.sh | 12 ++++++------ .../drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh | 4 ++-- .../drivers/net/mlxsw/devlink_trap_tunnel_ipip6.sh | 4 ++-- .../drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh | 4 ++-- .../net/mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh | 4 ++-- .../testing/selftests/drivers/net/mlxsw/tc_sample.sh | 4 ++-- .../drivers/net/netdevsim/fib_notifications.sh | 6 +++--- tools/testing/selftests/net/drop_monitor_tests.sh | 2 +- tools/testing/selftests/net/fib_tests.sh | 8 ++++---- .../testing/selftests/net/forwarding/devlink_lib.sh | 2 +- tools/testing/selftests/net/forwarding/lib.sh | 3 +-- tools/testing/selftests/net/forwarding/tc_police.sh | 8 ++++---- tools/testing/selftests/net/lib.sh | 8 ++++++++ 15 files changed, 41 insertions(+), 34 deletions(-)
tools/testing/selftests/drivers/net/mlxsw/devlink_trap.sh +1 -1
@@ -116,7 +116,7 @@ dev_del_test() log_test "Device delete" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid } trap cleanup EXIT
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_drops.sh +2 -2
@@ -595,7 +595,7 @@ irif_disabled_test() log_test "Ingress RIF disabled" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid ip link set dev $rp1 nomaster __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64 ip link del dev br0 type bridge
@@ -645,7 +645,7 @@ erif_disabled_test() log_test "Egress RIF disabled" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64 ip link del dev br0 type bridge devlink_trap_action_set $trap_name "drop"
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_l3_exceptions.sh +6 -6
@@ -202,7 +202,7 @@ mtu_value_is_too_small_test() mtu_restore $rp2 - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower }
@@ -235,7 +235,7 @@ __ttl_value_is_too_small_test() log_test "TTL value is too small: TTL=$ttl_val" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower }
@@ -299,7 +299,7 @@ __mc_reverse_path_forwarding_test() log_test "Multicast reverse path forwarding: $desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $rp2 egress protocol $proto pref 1 handle 101 flower }
@@ -347,7 +347,7 @@ __reject_route_test() log_test "Reject route: $desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid ip route del unreachable $unreachable tc filter del dev $h1 ingress protocol $proto pref 1 handle 101 flower }
@@ -542,7 +542,7 @@ ipv4_lpm_miss_test() log_test "LPM miss: IPv4" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid vrf_without_routes_destroy }
@@ -569,7 +569,7 @@ ipv6_lpm_miss_test() log_test "LPM miss: IPv6" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid vrf_without_routes_destroy }
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip.sh +2 -2
@@ -176,7 +176,7 @@ ecn_decap_test() log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower }
@@ -207,7 +207,7 @@ no_matching_tunnel_test() log_test "$desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower }
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_ipip6.sh +2 -2
@@ -176,7 +176,7 @@ ecn_decap_test() log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower }
@@ -207,7 +207,7 @@ no_matching_tunnel_test() log_test "$desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower }
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan.sh +2 -2
@@ -183,7 +183,7 @@ ecn_decap_test() log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower }
@@ -253,7 +253,7 @@ corrupted_packet_test() log_test "$desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower }
tools/testing/selftests/drivers/net/mlxsw/devlink_trap_tunnel_vxlan_ipv6.sh +2 -2
@@ -188,7 +188,7 @@ ecn_decap_test() log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower }
@@ -262,7 +262,7 @@ corrupted_packet_test() log_test "$desc" - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $swp1 egress protocol ipv6 pref 1 handle 101 flower }
tools/testing/selftests/drivers/net/mlxsw/tc_sample.sh +2 -2
@@ -218,7 +218,7 @@ psample_capture_start() psample_capture_stop() { - { kill %% && wait %%; } 2>/dev/null + kill_process %% } __tc_sample_rate_test()
@@ -499,7 +499,7 @@ tc_sample_md_out_tc_occ_test() backlog=$(tc -j -p -s qdisc show dev $rp2 | jq '.[0]["backlog"]') # Kill mausezahn. - { kill %% && wait %%; } 2>/dev/null + kill_process %% psample_capture_stop
tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh +3 -3
@@ -94,7 +94,7 @@ route_addition_check() sleep 1 $IP route add $route dev dummy1 sleep 1 - kill %% && wait %% &> /dev/null + kill_process %% route_notify_check $outfile $expected_num_notifications $offload_failed rm -f $outfile
@@ -148,7 +148,7 @@ route_deletion_check() sleep 1 $IP route del $route dev dummy1 sleep 1 - kill %% && wait %% &> /dev/null + kill_process %% route_notify_check $outfile $expected_num_notifications rm -f $outfile
@@ -191,7 +191,7 @@ route_replacement_check() sleep 1 $IP route replace $route dev dummy2 sleep 1 - kill %% && wait %% &> /dev/null + kill_process %% route_notify_check $outfile $expected_num_notifications rm -f $outfile
tools/testing/selftests/net/drop_monitor_tests.sh +1 -1
@@ -77,7 +77,7 @@ sw_drops_test() rm ${dir}/packets.pcap - { kill %% && wait %%; } 2>/dev/null + kill_process %% timeout 5 dwdump -o sw -w ${dir}/packets.pcap (( $(tshark -r ${dir}/packets.pcap \ -Y 'ip.dst == 192.0.2.10' 2> /dev/null | wc -l) == 0))
tools/testing/selftests/net/fib_tests.sh +4 -4
@@ -689,7 +689,7 @@ fib6_notify_test() log_test $ret 0 "ipv6 route add notify" - { kill %% && wait %%; } 2>/dev/null + kill_process %% #rm errors.txt
@@ -736,7 +736,7 @@ fib_notify_test() log_test $ret 0 "ipv4 route add notify" - { kill %% && wait %%; } 2>/dev/null + kill_process %% rm errors.txt
@@ -2328,7 +2328,7 @@ ipv4_mangle_test() $IP route del table 123 172.16.101.0/24 dev veth1 $IP rule del pref 100 - { kill %% && wait %%; } 2>/dev/null + kill_process %% rm $tmp_file route_cleanup
@@ -2386,7 +2386,7 @@ ipv6_mangle_test() $IP -6 route del table 123 2001:db8:101::/64 dev veth1 $IP -6 rule del pref 100 - { kill %% && wait %%; } 2>/dev/null + kill_process %% rm $tmp_file route_cleanup
tools/testing/selftests/net/forwarding/devlink_lib.sh +1 -1
@@ -501,7 +501,7 @@ devlink_trap_drop_cleanup() local pref=$1; shift local handle=$1; shift - kill $mz_pid && wait $mz_pid &> /dev/null + kill_process $mz_pid tc filter del dev $dev egress protocol $proto pref $pref handle $handle flower }
tools/testing/selftests/net/forwarding/lib.sh +1 -2
@@ -1574,8 +1574,7 @@ stop_traffic() { local pid=${1-%%}; shift - # Suppress noise from killing mausezahn. - { kill $pid && wait $pid; } 2>/dev/null + kill_process "$pid" } declare -A cappid
tools/testing/selftests/net/forwarding/tc_police.sh +4 -4
@@ -148,7 +148,7 @@ police_common_test() log_test "$test_name" - { kill %% && wait %%; } 2>/dev/null + kill_process %% tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower }
@@ -198,7 +198,7 @@ police_shared_common_test() log_test "$test_name" - { kill %% && wait %%; } 2>/dev/null + kill_process %% } police_shared_test()
@@ -278,7 +278,7 @@ police_mirror_common_test() log_test "$test_name" - { kill %% && wait %%; } 2>/dev/null + kill_process %% tc filter del dev $pol_if $dir protocol ip pref 1 handle 101 flower tc filter del dev $h3 ingress protocol ip pref 1 handle 101 flower tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
@@ -320,7 +320,7 @@ police_pps_common_test() log_test "$test_name" - { kill %% && wait %%; } 2>/dev/null + kill_process %% tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower }
tools/testing/selftests/net/lib.sh +8 -0
@@ -434,3 +434,11 @@ xfail_on_veth() "$@" fi } + +kill_process() +{ + local pid=$1; shift + + # Suppress noise from killing the process. + { kill $pid && wait $pid; } 2>/dev/null +}
Signature · 1 line
2.45.0
Petr Machata
maintainerPATCH v2 8/8 selftests: net: fdb_notify: Add a test for FDB notifications
In reply to Petr MachataCheck that only one notification is produced for various FDB edit operations.
Regarding the ip_link_add() and ip_link_master() helpers. This pattern of action plus corresponding defer is bound to come up often, and a dedicated vocabulary to capture it will be handy. tunnel_create() and vlan_create() from forwarding/lib.sh are somewhat opaque and perhaps too kitchen-sinky, so I tried to go in the opposite direction with these ones, and wrapped only the bare minimum to schedule a corresponding cleanup.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: Benjamin Poirier <[email protected]>
CC: Hangbin Liu <[email protected]>
CC: [email protected]
CC: Jiri Pirko <[email protected]>
---
tools/testing/selftests/net/Makefile | 2 +- tools/testing/selftests/net/fdb_notify.sh | 95 +++++++++++++++++++++++ tools/testing/selftests/net/lib.sh | 17 ++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/net/fdb_notify.sh
tools/testing/selftests/net/Makefile +1 -1
@@ -92,7 +92,7 @@ TEST_PROGS += test_vxlan_mdb.sh TEST_PROGS += test_bridge_neigh_suppress.sh TEST_PROGS += test_vxlan_nolocalbypass.sh TEST_PROGS += test_bridge_backup_port.sh -TEST_PROGS += fdb_flush.sh +TEST_PROGS += fdb_flush.sh fdb_notify.sh TEST_PROGS += fq_band_pktlimit.sh TEST_PROGS += vlan_hw_filter.sh TEST_PROGS += bpf_offload.py
tools/testing/selftests/net/fdb_notify.sh new file +95 -0
95 lines not on this page · raw message
tools/testing/selftests/net/lib.sh +17 -0
@@ -442,3 +442,20 @@ kill_process() # Suppress noise from killing the process. { kill $pid && wait $pid; } 2>/dev/null } + +ip_link_add() +{ + local name=$1; shift + + ip link add name "$name" "$@" + defer ip link del dev "$name" +} + +ip_link_master() +{ + local member=$1; shift + local master=$1; shift + + ip link set dev "$member" master "$master" + defer ip link set dev "$member" nomaster +}
Signature · 1 line
2.45.0
Jakub Kicinski
maintainerQuoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Petr Machata
maintainerQuoted 5 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Quoted 8 lines
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Sorry for only responding now, I was out of office last week.
The reason I went with outright responsibility shift is that the alternatives are more complex.
For the flag in particular, first there's no place to set the flag currently, we'd need a field in struct net_device_ops. But mainly, then you have a code that needs to corrently handle both states of the flag, and new-style drivers need to remember to set the flag, which is done in a different place from the fdb_add/del themselves. It might be fewer LOCs, but it's a harder to understand system.
Responsibility shift is easy. "Thou shalt notify." Done, easy to understand, easy to document. When cut'n'pasting, you won't miss it.
Let me know what you think.
Jakub Kicinski
maintainerQuoted 26 lines · On Mon, 4 Nov 2024 12:43:11 +0100 Petr Machata wrote:
Quoted 5 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Quoted 3 lines
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Quoted 8 lines
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Sorry for only responding now, I was out of office last week.
The reason I went with outright responsibility shift is that the alternatives are more complex.
For the flag in particular, first there's no place to set the flag currently, we'd need a field in struct
net_device_ops. But mainly, then you have a code that needs to corrently handle both states of the flag, and new-style drivers need to remember to set the flag, which is done in a different place from the fdb_add/del themselves. It might be fewer LOCs, but it's a harder to understand system.
Quoted 2 lines
Responsibility shift is easy. "Thou shalt notify." Done, easy to understand, easy to document. When cut'n'pasting, you won't miss it.
Makes sense for real proto drivers, but we also need to touch 4 Ethernet drivers. While we can trust proto drivers to do the right thing, HW driver devs on average are average. And I can't think of another case where driver would send netlink notifications directly.
Quoted 1 line
Let me know what you think.
Mild preference towards keeping the expectations from HW drivers as low as possible. But I don't feel strongly. Let me revive the series in PW so it is top of the list for Paolo tomorrow.. :)
Paolo Abeni
maintainerQuoted 27 lines · Petr Machata
Quoted 5 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Quoted 8 lines
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Sorry for only responding now, I was out of office last week.
The reason I went with outright responsibility shift is that the alternatives are more complex.
For the flag in particular, first there's no place to set the flag currently, we'd need a field in struct
net_device_ops. But mainly, then you have a code that needs to corrently handle both states of the flag, and new-style drivers need to remember to set the flag, which is done in a different place from the fdb_add/del themselves. It might be fewer LOCs, but it's a harder to understand system.
Quoted 4 lines
Responsibility shift is easy. "Thou shalt notify." Done, easy to understand, easy to document. When cut'n'pasting, you won't miss it.
Let me know what you think.
I think that keeping as much action/responsibilities as possible in the core code is in general a better option - at very least to avoid duplicate code.
I don't think that the C&P is a very good argument, as I would argue against C&P without understanding of the underlying code. Still I agree that keeping all the relevant info together is better, and a separate flag would be not so straight-forward.
What about using the return value of fbd_add/fdb_del to tell the core that the driver did the notification? a positive value means 'already notified', a negative one error, zero 'please notify.
Cheers,
Paolo
Petr Machata
maintainerQuoted 37 lines · Paolo Abeni
Quoted 27 lines · Petr Machata
Quoted 5 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Quoted 8 lines
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Sorry for only responding now, I was out of office last week.
The reason I went with outright responsibility shift is that the alternatives are more complex.
For the flag in particular, first there's no place to set the flag currently, we'd need a field in struct
net_device_ops. But mainly, then you have a code that needs to corrently handle both states of the flag, and new-style drivers need to remember to set the flag, which is done in a different place from the fdb_add/del themselves. It might be fewer LOCs, but it's a harder to understand system.Quoted 4 lines
Responsibility shift is easy. "Thou shalt notify." Done, easy to understand, easy to document. When cut'n'pasting, you won't miss it.
Let me know what you think.
I think that keeping as much action/responsibilities as possible in the core code is in general a better option - at very least to avoid duplicate code.
Quoted 8 lines
I don't think that the C&P is a very good argument, as I would argue against C&P without understanding of the underlying code. Still I agree that keeping all the relevant info together is better, and a separate flag would be not so straight-forward.
What about using the return value of fbd_add/fdb_del to tell the core that the driver did the notification? a positive value means 'already notified', a negative one error, zero 'please notify.
That would work.
How about passing an explicit bool* argument for the callee to set? I'm suspicious of these one-off errno protocols. Most of the time the return value is an errno, these aberrations feel easy to miss.
We decided against a dedicated argument originally, because it's not very pretty, but if the callback itself should somehow carry the please-notify interface (and I think it should), an argument is a more explicit and obvious way to do it.
Paolo Abeni
maintainerQuoted 47 lines · Petr Machata
Quoted 37 lines · Paolo Abeni
Quoted 27 lines · Petr Machata
Quoted 5 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Quoted 8 lines
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Sorry for only responding now, I was out of office last week.
The reason I went with outright responsibility shift is that the alternatives are more complex.
For the flag in particular, first there's no place to set the flag currently, we'd need a field in struct
net_device_ops. But mainly, then you have a code that needs to corrently handle both states of the flag, and new-style drivers need to remember to set the flag, which is done in a different place from the fdb_add/del themselves. It might be fewer LOCs, but it's a harder to understand system.Quoted 4 lines
Responsibility shift is easy. "Thou shalt notify." Done, easy to understand, easy to document. When cut'n'pasting, you won't miss it.
Let me know what you think.
I think that keeping as much action/responsibilities as possible in the core code is in general a better option - at very least to avoid duplicate code.
Quoted 8 lines
I don't think that the C&P is a very good argument, as I would argue against C&P without understanding of the underlying code. Still I agree that keeping all the relevant info together is better, and a separate flag would be not so straight-forward.
What about using the return value of fbd_add/fdb_del to tell the core that the driver did the notification? a positive value means 'already notified', a negative one error, zero 'please notify.
Quoted 5 lines
That would work.
How about passing an explicit bool* argument for the callee to set? I'm suspicious of these one-off errno protocols. Most of the time the return value is an errno, these aberrations feel easy to miss.
I would be ok with that - a large arguments list should not be something concerning for the control path. Just to be clear: the caller init the bool to false, only the callees doing the notification set it, right?
Thanks!
Paolo
Petr Machata
maintainerQuoted 16 lines · Paolo Abeni
Quoted 15 lines · Petr Machata
Quoted 13 lines · Paolo Abeni
Quoted 12 lines · Petr Machata
Quoted 11 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 24 Oct 2024 18:57:35 +0200 Petr Machata wrote:
Besides this approach, we considered just passing a boolean back from the driver, which would indicate whether the notification was done. But the approach presented here seems cleaner.
Oops, I missed the v2, same question:
What about adding a bit to the ops struct to indicate that the driver will generate the notification? Seems smaller in terms of LoC and shifts the responsibility of doing extra work towards more complex users.
Quoted 7 lines
Quoted 3 lines
How about passing an explicit bool* argument for the callee to set? I'm suspicious of these one-off errno protocols. Most of the time the return value is an errno, these aberrations feel easy to miss.
I would be ok with that - a large arguments list should not be something concerning for the control path. Just to be clear: the caller init the bool to false, only the callees doing the notification set it, right?
Yes.
OK, I'll do it like that.