未验证 提交 c3f923af 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!346 anolis: bond: broadcast ARP or ND messages to all slaves

Merge Pull Request from: @wang-yufen316 
 
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. 
 
Link:https://gitee.com/openeuler/kernel/pulls/346 

Reviewed-by: Yue Haibing <yuehaibing@huawei.com> 
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com> 
Acked-by: Xie XiuQi <xiexiuqi@huawei.com> 
......@@ -2663,3 +2663,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
......@@ -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)
......
......@@ -4549,6 +4549,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)
......@@ -4577,6 +4610,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))
......@@ -5493,6 +5530,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);
......@@ -5509,6 +5547,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);
......@@ -5521,6 +5560,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);
......
// 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);
}
......@@ -114,6 +114,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;
......@@ -659,6 +661,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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册