[PATCH OLK-6.6] anolis: bond: broadcast ARP or ND messages to all slaves

From: Tony Lu <tonylu(a)linux.alibaba.com> anolis inclusion from devel-5.10-v5.10.134-12 commit b90e28f7170e1ae40c572f9f80a50bbdc8f8b99f category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8JTCU Reference: https://gitee.com/anolis/cloud-kernel/commit/b90e28f7170e1ae40c572f9f80a50bb... --------------------------- OpenAnolis Bug Tracker:0000282 This is achieved by broadcasting ARP or ND packets to all of its slave devices on transmit side. The switch will take further actions based on proper configuration. A new sysctl knob "net.bonding.broadcast_arp_or_nd" is introduced which controls the behaviour of broadcasting. Signed-off-by: Tony Lu <tonylu(a)linux.alibaba.com> Acked-by: Dust Li <dust.li(a)linux.alibaba.com> Signed-off-by: Qiao Ma <mqaio(a)linux.alibaba.com> Reviewed-by: Shile Zhang <shile.zhang(a)linux.alibaba.com> Acked-by: Dust Li <dust.li(a)linux.alibaba.com> Signed-off-by: Wang Yufen <wangyufen(a)huawei.com> (cherry picked from commit 7c902772d8ee8840b6092b1de94ed0c17c9a8a50) Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com> --- Documentation/networking/ip-sysctl.rst | 11 +++++++ drivers/net/bonding/Makefile | 2 +- drivers/net/bonding/bond_main.c | 40 ++++++++++++++++++++++++++ drivers/net/bonding/bond_sysctl.c | 32 +++++++++++++++++++++ include/net/bonding.h | 4 +++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bonding/bond_sysctl.c diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index a66054d0763a..12fa38639102 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -3206,3 +3206,14 @@ max_dgram_qlen - INTEGER Default: 10 + +``/proc/sys/net/bonding/*`` +======================== + +broadcast_arp_or_nd - INTEGER + Control broadcasting ARP or ND messages to all slaves + + 0: Not broadcasting + 1: Broadcasting + + Default: 0 diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 30e8ae3da2da..9dd55d91185a 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_BONDING) += bonding.o -bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_sysfs_slave.o bond_debugfs.o bond_netlink.o bond_options.o +bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_sysfs_slave.o bond_debugfs.o bond_netlink.o bond_options.o bond_sysctl.o proc-$(CONFIG_PROC_FS) += bond_procfs.o bonding-objs += $(proc-y) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 51d47eda1c87..842a138a574d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5127,6 +5127,39 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) return ret; } +/* Check whether the skb is arp or nd msg */ +static inline bool skb_is_arp_or_nd(struct sk_buff *skb) +{ + switch (ntohs(skb->protocol)) { + case ETH_P_ARP: + return true; + case ETH_P_IPV6: + if (pskb_may_pull(skb, sizeof(struct ipv6hdr) + + sizeof(struct nd_msg))) { + struct ipv6hdr *hdr = ipv6_hdr(skb); + u8 nexthdr = hdr->nexthdr; + struct icmp6hdr *icmp6; + + if (nexthdr == IPPROTO_ICMPV6) { + icmp6 = icmp6_hdr(skb); + + if ((icmp6->icmp6_type == + NDISC_NEIGHBOUR_SOLICITATION || + icmp6->icmp6_type == + NDISC_NEIGHBOUR_ADVERTISEMENT) && + icmp6->icmp6_code == 0) { + return true; + } + } + } + } + + return false; +} + +static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, + struct net_device *bond_dev); + static struct slave *bond_xmit_3ad_xor_slave_get(struct bonding *bond, struct sk_buff *skb, struct bond_up_slave *slaves) @@ -5171,6 +5204,10 @@ static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb, struct bond_up_slave *slaves; struct slave *slave; + /* Broadcast to all slaves. */ + if (sysctl_bond_broadcast_arp_or_nd && skb_is_arp_or_nd(skb)) + return bond_xmit_broadcast(skb, dev); + slaves = rcu_dereference(bond->usable_slaves); slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); if (likely(slave)) @@ -6488,6 +6525,7 @@ static int __init bonding_init(void) goto err_link; bond_create_debugfs(); + bond_create_sysctl(); for (i = 0; i < max_bonds; i++) { res = bond_create(&init_net, NULL); @@ -6504,6 +6542,7 @@ static int __init bonding_init(void) return res; err: bond_destroy_debugfs(); + bond_destroy_sysctl(); bond_netlink_fini(); err_link: unregister_pernet_subsys(&bond_net_ops); @@ -6516,6 +6555,7 @@ static void __exit bonding_exit(void) unregister_netdevice_notifier(&bond_netdev_notifier); bond_destroy_debugfs(); + bond_destroy_sysctl(); bond_netlink_fini(); unregister_pernet_subsys(&bond_net_ops); diff --git a/drivers/net/bonding/bond_sysctl.c b/drivers/net/bonding/bond_sysctl.c new file mode 100644 index 000000000000..17404d37a2fd --- /dev/null +++ b/drivers/net/bonding/bond_sysctl.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <net/net_namespace.h> +#include <linux/sysctl.h> +#include <net/bonding.h> + +int sysctl_bond_broadcast_arp_or_nd __read_mostly; +EXPORT_SYMBOL(sysctl_bond_broadcast_arp_or_nd); + +struct ctl_table_header *bond_broadcast_arp_or_nd_table_header; + +static struct ctl_table bond_broadcast_arp_or_nd_table[] = { + { + .procname = "broadcast_arp_or_nd", + .data = &sysctl_bond_broadcast_arp_or_nd, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + {} +}; + +void bond_create_sysctl(void) +{ + bond_broadcast_arp_or_nd_table_header = + register_net_sysctl(&init_net, "net/bonding", + bond_broadcast_arp_or_nd_table); +} + +void bond_destroy_sysctl(void) +{ + unregister_net_sysctl_table(bond_broadcast_arp_or_nd_table_header); +} diff --git a/include/net/bonding.h b/include/net/bonding.h index 5b8b1b644a2d..0f065f150b81 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -115,6 +115,8 @@ static inline int is_netpoll_tx_blocked(struct net_device *dev) #define is_netpoll_tx_blocked(dev) (0) #endif +extern int sysctl_bond_broadcast_arp_or_nd; + struct bond_params { int mode; int xmit_policy; @@ -684,6 +686,8 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave); void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay); void bond_work_init_all(struct bonding *bond); +void bond_create_sysctl(void); +void bond_destroy_sysctl(void); #ifdef CONFIG_PROC_FS void bond_create_proc_entry(struct bonding *bond); -- 2.34.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/3013 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/2... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/3013 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/2...
participants (2)
-
patchwork bot
-
Zhengchao Shao