bonding: Extend arp_ip_target format to allow for a list of vlan tags.
Subsystems (5)
v4 cover bonding: Extend arp_ip_target format to allow for a list of vlan tags.
The current implementation of the arp monitor builds a list of vlan-tags by following the chain of net_devices above the bond. See bond_verify_device_path(). Unfortunately, with some configurations, this is not possible. One example is when an ovs switch is configured above the bond.
This change extends the "arp_ip_target" parameter format to allow for a list of vlan tags to be included for each arp target. This new list of tags is optional and may be omitted to preserve the current format and process of discovering vlans.
The new format for arp_ip_target is:arp_ip_target ipv4-address[vlan-tag\...],...
For example:arp_ip_target 10.0.0.1[10/20]arp_ip_target 10.0.0.1[] (used to disable vlan discovery)
The extended format of arp_ip_target is only supported by using the ip command when creating the bond. Module parameters and the sysfs file do not allow the use of the extended format.
Changes since V3:
1) Moved the parsing of the extended arp_ip_target out of the kernel and into userspace (ip command). A separate patch to iproute2 to follow shortly.
2) Split up the patch set to make review easier.
--
I have run into issues with the ns_ip6_target feature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change for ns_ip6_target.
Thank you for your time and reviews.
David Wilder (7):
bonding: Adding struct bond_arp_target
bonding: Adding extra_len field to struct bond_opt_value.
bonding: arp_ip_target helpers.
bonding: Processing extended arp_ip_target from user space.
bonding: Update to bond_arp_send_all() to use supplied vlan tags
bonding: Update to bond's sysfs and procfs for extended arp_ip_target
format.
bonding: Selftest and documentation for the arp_ip_target parameter.
Documentation/networking/bonding.rst | 11 + drivers/net/bonding/bond_main.c | 47 +++-- drivers/net/bonding/bond_netlink.c | 9 +- drivers/net/bonding/bond_options.c | 95 ++++++--- drivers/net/bonding/bond_procfs.c | 7 +- drivers/net/bonding/bond_sysfs.c | 9 +- include/net/bond_options.h | 29 ++- include/net/bonding.h | 60 +++++- .../selftests/drivers/net/bonding/Makefile | 3 +- .../drivers/net/bonding/bond-arp-ip-target.sh | 194 ++++++++++++++++++ 10 files changed, 390 insertions(+), 74 deletions(-) create mode 100755 tools/testing/selftests/drivers/net/bonding/bond-arp-ip-target.sh
Signature · 1 line
2.43.5
PATCH v4 1/7 bonding: Adding struct bond_arp_target
Replacing the definition of bond_params.arp_targets (__be32 arp_targets[]) with:
struct bond_arp_target {
__be32 target_ip;
struct bond_vlan_tag *tags;
u32 flags;
};To provide storage for a list of vlan tags for each target.
All references to arp_target are change to use the new structure.
--- drivers/net/bonding/bond_main.c | 29 ++++++++++++++++------------- drivers/net/bonding/bond_netlink.c | 4 ++-- drivers/net/bonding/bond_options.c | 18 +++++++++--------- drivers/net/bonding/bond_procfs.c | 4 ++-- drivers/net/bonding/bond_sysfs.c | 4 ++-- include/net/bond_options.h | 20 ++++++++++++++++++++ include/net/bonding.h | 15 +++++---------- 7 files changed, 56 insertions(+), 38 deletions(-)
drivers/net/bonding/bond_main.c +16 -13
@@ -3146,26 +3146,29 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) {struct rtable *rt;struct bond_vlan_tag *tags; -__be32 *targets = bond->params.arp_targets, addr; +struct bond_arp_target *targets = bond->params.arp_targets; +__be32 target_ip, addr;int i; -for (i =0 ; i <BOND_MAX_ARP_TARGETS && targets[i]; i++) { +for (i =0 ; i <BOND_MAX_ARP_TARGETS && targets[i].target_ip; i++) { + target_ip = targets[i].target_ip; + tags = targets[i].tags; +slave_dbg (bond->dev, slave->dev,"%s: target %pI4\n" , - __func__, &targets[i]); - tags =NULL ; + __func__, &target_ip);/* Find out through which dev should the packet go */ - rt =ip_route_output (dev_net (bond->dev), targets[i],0 ,0 ,0 , + rt =ip_route_output (dev_net (bond->dev), target_ip,0 ,0 ,0 ,RT_SCOPE_LINK );if (IS_ERR (rt)) { -/* there's no route to target - try to send arp +/* there's no route to target_ip - try to send arp * probe to generate any traffic (arp_validate=0) */ if (bond->params.arp_validate)pr_warn_once ("%s: no route to arp_ip_target %pI4 and arp_validate is set\n" , bond->dev->name, - &targets[i]); -bond_arp_send (slave,ARPOP_REQUEST , targets[i], + &target_ip); +bond_arp_send (slave,ARPOP_REQUEST , target_ip,0 , tags);continue ; }
@@ -3183,15 +3186,15 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)/* Not our device - skip */ slave_dbg (bond->dev, slave->dev,"no path to arp_ip_target %pI4 via rt.dev %s\n" , - &targets[i], rt->dst.dev ? rt->dst.dev->name :"NULL" ); + &target_ip, rt->dst.dev ? rt->dst.dev->name :"NULL" );ip_rt_put (rt);continue ; found: - addr =bond_confirm_addr (rt->dst.dev, targets[i],0 ); + addr =bond_confirm_addr (rt->dst.dev, target_ip,0 );ip_rt_put (rt); -bond_arp_send (slave,ARPOP_REQUEST , targets[i], addr, tags); +bond_arp_send (slave,ARPOP_REQUEST , target_ip, addr, tags);kfree (tags); } }
@@ -6096,7 +6099,7 @@ static int __init bond_check_params(struct bond_params *params)int arp_all_targets_value =0 ;u16 ad_actor_sys_prio =0 ;u16 ad_user_port_key =0 ; -__be32 arp_target[BOND_MAX_ARP_TARGETS ] = {0 }; +struct bond_arp_target arp_target[BOND_MAX_ARP_TARGETS ] = {0 };int arp_ip_count;int bond_mode =BOND_MODE_ROUNDROBIN ;int xmit_hashtype =BOND_XMIT_POLICY_LAYER2 ;
@@ -6290,7 +6293,7 @@ static int __init bond_check_params(struct bond_params *params) arp_interval =0 ; }else {if (bond_get_targets_ip (arp_target, ip) ==-1 ) - arp_target[arp_ip_count++] = ip; + arp_target[arp_ip_count++].target_ip = ip;else pr_warn ("Warning: duplicate address %pI4 in arp_ip_target, skipping\n" , &ip);
drivers/net/bonding/bond_netlink.c +2 -2
@@ -688,8 +688,8 @@ static int bond_fill_info(struct sk_buff *skb, targets_added =0 ;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) { -if (bond->params.arp_targets[i]) { -if (nla_put_be32 (skb, i, bond->params.arp_targets[i])) +if (bond->params.arp_targets[i].target_ip) { +if (nla_put_be32 (skb, i, bond->params.arp_targets[i].target_ip)) goto nla_put_failure; targets_added =1 ; }
drivers/net/bonding/bond_options.c +9 -9
@@ -1090,7 +1090,7 @@ static int bond_option_arp_interval_set(struct bonding *bond,netdev_dbg (bond->dev,"ARP monitoring cannot be used with MII monitoring. Disabling MII monitoring\n" ); bond->params.miimon =0 ; } -if (!bond->params.arp_targets[0 ]) +if (!bond->params.arp_targets[0 ].target_ip)netdev_dbg (bond->dev,"ARP monitoring has been set up, but no ARP targets have been specified\n" ); }if (bond->dev->flags &IFF_UP ) {
@@ -1118,20 +1118,20 @@ static void _bond_options_arp_ip_target_set(struct bonding *bond, int slot, __be32 target, unsigned long last_rx) { -__be32 *targets = bond->params.arp_targets; +struct bond_arp_target *targets = bond->params.arp_targets;struct list_head *iter;struct slave *slave;if (slot >=0 && slot <BOND_MAX_ARP_TARGETS ) {bond_for_each_slave (bond, slave, iter) slave->target_last_arp_rx[slot] = last_rx; - targets[slot] = target; + targets[slot].target_ip = target; } }static int _bond_option_arp_ip_target_add (struct bonding *bond,__be32 target) { -__be32 *targets = bond->params.arp_targets; +struct bond_arp_target *targets = bond->params.arp_targets;int ind;if (!bond_is_ip_target_ok (target)) {
@@ -1166,7 +1166,7 @@ static int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)static int bond_option_arp_ip_target_rem (struct bonding *bond,__be32 target) { -__be32 *targets = bond->params.arp_targets; +struct bond_arp_target *targets = bond->params.arp_targets;struct list_head *iter;struct slave *slave;unsigned long *targets_rx;
@@ -1185,20 +1185,20 @@ static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target)return -EINVAL ; } -if (ind ==0 && !targets[1 ] && bond->params.arp_interval) +if (ind ==0 && !targets[1 ].target_ip && bond->params.arp_interval)netdev_warn (bond->dev,"Removing last arp target with arp_interval on\n" );netdev_dbg (bond->dev,"Removing ARP target %pI4\n" , &target);bond_for_each_slave (bond, slave, iter) { targets_rx = slave->target_last_arp_rx; -for (i = ind; (i <BOND_MAX_ARP_TARGETS -1 ) && targets[i+1 ]; i++) +for (i = ind; (i <BOND_MAX_ARP_TARGETS -1 ) && targets[i +1 ].target_ip; i++) targets_rx[i] = targets_rx[i+1 ]; targets_rx[i] =0 ; } -for (i = ind; (i <BOND_MAX_ARP_TARGETS -1 ) && targets[i+1 ]; i++) +for (i = ind; (i <BOND_MAX_ARP_TARGETS -1 ) && targets[i +1 ].target_ip; i++) targets[i] = targets[i+1 ]; - targets[i] =0 ; + targets[i].target_ip =0 ;return 0 ; }
drivers/net/bonding/bond_procfs.c +2 -2
@@ -121,11 +121,11 @@ static void bond_info_show_master(struct seq_file *seq)seq_printf (seq,"ARP IP target/s (n.n.n.n form):" );for (i =0 ; (i <BOND_MAX_ARP_TARGETS ); i++) { -if (!bond->params.arp_targets[i]) +if (!bond->params.arp_targets[i].target_ip)break ;if (printed)seq_printf (seq,"," ); -seq_printf (seq," %pI4" , &bond->params.arp_targets[i]); +seq_printf (seq," %pI4" , &bond->params.arp_targets[i].target_ip); printed =1 ; }seq_printf (seq,"\n" );
drivers/net/bonding/bond_sysfs.c +2 -2
@@ -290,9 +290,9 @@ static ssize_t bonding_show_arp_targets(struct device *d,int i, res =0 ;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) { -if (bond->params.arp_targets[i]) +if (bond->params.arp_targets[i].target_ip) res +=sysfs_emit_at (buf, res,"%pI4 " , - &bond->params.arp_targets[i]); + &bond->params.arp_targets[i].target_ip); }if (res) buf[res-1 ] ='\n' ;/* eat the leftover space */
include/net/bond_options.h +20 -0
@@ -119,6 +119,26 @@ struct bond_option {int (*set)(struct bonding *bond,const struct bond_opt_value *val); }; +struct bond_vlan_tag { +__be16 vlan_proto; +unsigned short vlan_id; +}; + +/* Value type flags: +* BOND_TARGET_DONTFREE - never free the tags +* BOND_TARGET_USERTAGS - tags have been supplied by the user +*/ +enum { +BOND_TARGET_DONTFREE =BIT (0 ), +BOND_TARGET_USERTAGS =BIT (1 ), +}; + +struct bond_arp_target { +__be32 target_ip; +struct bond_vlan_tag *tags; +u32 flags; +}; +int __bond_opt_set (struct bonding *bond,unsigned int option,struct bond_opt_value *val,struct nlattr *bad_attr,struct netlink_ext_ack *extack);
include/net/bonding.h +5 -10
@@ -135,7 +135,7 @@ struct bond_params {int ad_select;char primary[IFNAMSIZ ];int primary_reselect; -__be32 arp_targets[BOND_MAX_ARP_TARGETS ]; +struct bond_arp_target arp_targets[BOND_MAX_ARP_TARGETS ];int tx_queues;int all_slaves_active;int resend_igmp;
@@ -274,11 +274,6 @@ struct bonding {void bond_queue_slave_event (struct slave *slave);void bond_lower_state_changed (struct slave *slave); -struct bond_vlan_tag { -__be16 vlan_proto; -unsigned short vlan_id; -}; -/* * Returns NULL if the net_device does not belong to any of the bond's slaves *
@@ -522,7 +517,7 @@ static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,int i =1 ;unsigned long ret = slave->target_last_arp_rx[0 ]; -for (; (i <BOND_MAX_ARP_TARGETS ) && bond->params.arp_targets[i]; i++) +for (; (i <BOND_MAX_ARP_TARGETS ) && bond->params.arp_targets[i].target_ip; i++)if (time_before (slave->target_last_arp_rx[i], ret)) ret = slave->target_last_arp_rx[i];
@@ -760,14 +755,14 @@ static inline bool bond_slave_has_mac_rcu(struct bonding *bond, const u8 *mac)/* Check if the ip is present in arp ip list, or first free slot if ip == 0 * Returns -1 if not found, index if found */ -static inline int bond_get_targets_ip (__be32 *targets,__be32 ip) +static inline int bond_get_targets_ip (struct bond_arp_target *targets,__be32 ip) {int i;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) -if (targets[i] == ip) +if (targets[i].target_ip == ip)return i; -else if (targets[i] ==0 ) +else if (targets[i].target_ip ==0 )break ;return -1 ;
Signature · 1 line
2.43.5
PATCH v4 2/7 bonding: Adding extra_len field to struct bond_opt_value.
In reply to David WilderUsed to record the size of the extra array.
__bond_opt_init() is updated to set extra_len.BOND_OPT_EXTRA_MAXLEN is increased from 16 to 64.
This is needed for the extended arp_ip_target option. The ip command will now pass a variable length value when setting arp_ip_target.
--- include/net/bond_options.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
include/net/bond_options.h +6 -3
@@ -85,14 +85,15 @@ enum {* - if value != ULLONG_MAX -> parse value * - if string != NULL -> parse string * - if the opt is RAW data and length less than maxlen, -* copy the data to extra storage +* copy the data to extra storage, extra_len is set to the size of data copied. */ -#define BOND_OPT_EXTRA_MAXLEN 16 +#define BOND_OPT_EXTRA_MAXLEN 64struct bond_opt_value {char *string;u64 value;u32 flags; +u16 extra_len;union {char extra[BOND_OPT_EXTRA_MAXLEN ];struct net_device *slave_dev;
@@ -167,8 +168,10 @@ static inline void __bond_opt_init(struct bond_opt_value *optval,else if (string) optval->string = string; -if (extra && extra_len <=BOND_OPT_EXTRA_MAXLEN ) +if (extra && extra_len <=BOND_OPT_EXTRA_MAXLEN ) {memcpy (optval->extra, extra, extra_len); + optval->extra_len = extra_len; + } }#define bond_opt_initval (optval, value) __bond_opt_init(optval, NULL, value, NULL, 0)#define bond_opt_initstr (optval, str) __bond_opt_init(optval, str, ULLONG_MAX, NULL, 0)
Signature · 1 line
2.43.5
PATCH v4 3/7 bonding: arp_ip_target helpers.
In reply to David WilderAdding helpers and defines needed for extending the arp_ip_target parameters.
--- include/net/bonding.h | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
include/net/bonding.h +45 -0
@@ -806,4 +806,49 @@ static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *s return NET_XMIT_DROP; } +/* Helpers for handling arp_ip_target */ +#define BOND_OPTION_STRING_MAX_SIZE 64 +#define BOND_VLAN_PROTO_NONE cpu_to_be16(0xffff) + +static inline char *bond_arp_target_to_string (struct bond_arp_target *target, +char *buf,int size) +{ +struct bond_vlan_tag *tags = target->tags; +int i, num =0 ; + +if (!(target->flags &BOND_TARGET_USERTAGS )) { + num =snprintf (&buf[0 ], size,"%pI4" , &target->target_ip); +return buf; + } + + num =snprintf (&buf[0 ], size,"%pI4[" , &target->target_ip); +if (tags) { +for (i =0 ; (tags[i].vlan_proto !=BOND_VLAN_PROTO_NONE ); i++) { +if (!tags[i].vlan_id) +continue ; +if (i !=0 ) + num = num +snprintf (&buf[num], size-num,"/" ); + num = num +snprintf (&buf[num], size-num,"%u" , + tags[i].vlan_id); + } + } +snprintf (&buf[num], size-num,"]" ); +return buf; +} + +static inline void bond_free_vlan_tag (struct bond_arp_target *target) +{ +kfree (target->tags); +} + +static inline void __bond_free_vlan_tags (struct bond_arp_target *targets) +{ +int i; + +for (i =0 ; i <BOND_MAX_ARP_TARGETS && targets[i].tags; i++) +bond_free_vlan_tag (&targets[i]); +} + +#define bond_free_vlan_tags (targets) __bond_free_vlan_tags(targets) +#endif /* _NET_BONDING_H */
Signature · 1 line
2.43.5
PATCH v4 4/7 bonding: Processing extended arp_ip_target from user space.
In reply to David WilderChanges to bond_netlink and bond_options to process extended format arp_ip_target option sent from user space via the ip command.
The extended format adds a list of vlan tags to the ip target address.
--- drivers/net/bonding/bond_netlink.c | 5 +- drivers/net/bonding/bond_options.c | 81 +++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 26 deletions(-)
drivers/net/bonding/bond_netlink.c +3 -2
@@ -292,9 +292,10 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],if (nla_len (attr) <sizeof (target))return -EINVAL ; - target =nla_get_be32 (attr); +bond_opt_initextra (&newval, + (__force void *)nla_data (attr), +nla_len (attr)); -bond_opt_initval (&newval, (__force u64 )target); err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, &newval, data[IFLA_BOND_ARP_IP_TARGET],
drivers/net/bonding/bond_options.c +57 -24
176 lines not on this page · raw message
Signature · 1 line
2.43.5
PATCH v4 5/7 bonding: Update to bond_arp_send_all() to use supplied vlan tags
In reply to David Wilderbond_arp_send_all() will pass the vlan tags supplied by the user to bond_arp_send(). If vlan tags have not been supplied the vlans in the path to the target will be discovered by bond_verify_device_path(). The discovered vlan tags are then saved to be used on future calls to bond_arp_send().
bonding_exit() is also updated to free vlan tags when a bond is destroyed.
--- drivers/net/bonding/bond_main.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/net/bonding/bond_main.c +13 -9
@@ -3144,18 +3144,19 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,static void bond_arp_send_all (struct bonding *bond,struct slave *slave) { -struct rtable *rt; -struct bond_vlan_tag *tags;struct bond_arp_target *targets = bond->params.arp_targets; +char pbuf[BOND_OPTION_STRING_MAX_SIZE ]; +struct bond_vlan_tag *tags;__be32 target_ip, addr; +struct rtable *rt;int i;for (i =0 ; i <BOND_MAX_ARP_TARGETS && targets[i].target_ip; i++) { target_ip = targets[i].target_ip; tags = targets[i].tags; -slave_dbg (bond->dev, slave->dev,"%s: target %pI4\n" , - __func__, &target_ip); +slave_dbg (bond->dev, slave->dev,"%s: target %s\n" , __func__, +bond_arp_target_to_string (&targets[i], pbuf,sizeof (pbuf)));/* Find out through which dev should the packet go */ rt = ip_route_output(dev_net(bond->dev), target_ip, 0, 0, 0,
@@ -3177,9 +3178,13 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)if (rt->dst.dev == bond->dev) goto found; -rcu_read_lock (); - tags =bond_verify_device_path (bond->dev, rt->dst.dev,0 ); -rcu_read_unlock (); +if (!tags) { +rcu_read_lock (); + tags =bond_verify_device_path (bond->dev, rt->dst.dev,0 ); +/* cache the tags */ + targets[i].tags = tags; +rcu_read_unlock (); + }if (!IS_ERR_OR_NULL (tags)) goto found;
@@ -3195,7 +3200,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) addr =bond_confirm_addr (rt->dst.dev, target_ip,0 );ip_rt_put (rt);bond_arp_send (slave,ARPOP_REQUEST , target_ip, addr, tags); -kfree (tags); } }
@@ -6663,7 +6667,7 @@ static void __exit bonding_exit(void)bond_netlink_fini ();unregister_pernet_subsys (&bond_net_ops); - +bond_free_vlan_tags (bonding_defaults.arp_targets);bond_destroy_debugfs ();#ifdef CONFIG_NET_POLL_CONTROLLER
Signature · 1 line
2.43.5
PATCH v4 6/7 bonding: Update to bond's sysfs and procfs for extended arp_ip_target format.
In reply to David Wilder/sys/class/net/<bond>/bonding/arp_ip_target and /proc/net/bonding/<bond> will display vlan tags if they have been configured by the user
--- drivers/net/bonding/bond_procfs.c | 5 ++++- drivers/net/bonding/bond_sysfs.c | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-)
drivers/net/bonding/bond_procfs.c +4 -1
@@ -111,6 +111,7 @@ static void bond_info_show_master(struct seq_file *seq)/* ARP information */ if (bond->params.arp_interval >0 ) { +char pbuf[BOND_OPTION_STRING_MAX_SIZE ];int printed =0 ; seq_printf(seq, "ARP Polling Interval (ms): %d\n",
@@ -125,7 +126,9 @@ static void bond_info_show_master(struct seq_file *seq)break ;if (printed)seq_printf (seq,"," ); -seq_printf (seq," %pI4" , &bond->params.arp_targets[i].target_ip); +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); +seq_printf (seq," %s" , pbuf); printed =1 ; }seq_printf (seq,"\n" );
drivers/net/bonding/bond_sysfs.c +6 -3
@@ -286,13 +286,16 @@ static ssize_t bonding_show_arp_targets(struct device *d,struct device_attribute *attr, char *buf) { + char pbuf[BOND_OPTION_STRING_MAX_SIZE];struct bonding *bond =to_bond (d);int i, res =0 ;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) { -if (bond->params.arp_targets[i].target_ip) - res +=sysfs_emit_at (buf, res,"%pI4 " , - &bond->params.arp_targets[i].target_ip); +if (bond->params.arp_targets[i].target_ip) { +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); + res +=sysfs_emit_at (buf, res,"%s " , pbuf); + } }if (res) buf[res-1 ] ='\n' ;/* eat the leftover space */
Signature · 1 line
2.43.5
Jay Vosburgh
maintainerRe: [PATCH net-next v4 6/7] bonding: Update to bond's sysfs and procfs for extended arp_ip_target format.
Quoted 3 lines · David Wilder
/sys/class/net/<bond>/bonding/arp_ip_target and /proc/net/bonding/<bond> will display vlan tags if they have been configured by the user
I don't think we need to do any of this, the sysfs and proc APIs
to bonding should not be updated to support new functionality. Netlink and /sbin/ip must do the right thing, but the other APIs are more or less frozen in the past.
-J
Quoted 56 lines
Signed-off-by David Wilder <[email protected]>---
drivers/net/bonding/bond_procfs.c| 5 ++++-drivers/net/bonding/bond_sysfs.c| 9 ++++++---2 files changed, 10 insertions(+), 4 deletions(-)drivers/net/bonding/bond_procfs.c +4
-1@@ -111,6 +111,7 @@ static void bond_info_show_master(struct seq_file *seq)/* ARP information */ if (bond->params.arp_interval >0 ) { +char pbuf[BOND_OPTION_STRING_MAX_SIZE ];int printed =0 ; seq_printf(seq, "ARP Polling Interval (ms): %d\n",@@ -125,7 +126,9 @@ static void bond_info_show_master(struct seq_file *seq)break ;if (printed)seq_printf (seq,"," ); -seq_printf (seq," %pI4" , &bond->params.arp_targets[i].target_ip); +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); +seq_printf (seq," %s" , pbuf); printed =1 ; }seq_printf (seq,"\n" );drivers/net/bonding/bond_sysfs.c +6
-3@@ -286,13 +286,16 @@ static ssize_t bonding_show_arp_targets(struct device *d,struct device_attribute *attr, char *buf) { + char pbuf[BOND_OPTION_STRING_MAX_SIZE];struct bonding *bond =to_bond (d);int i, res =0 ;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) { -if (bond->params.arp_targets[i].target_ip) - res +=sysfs_emit_at (buf, res,"%pI4 " , - &bond->params.arp_targets[i].target_ip); +if (bond->params.arp_targets[i].target_ip) { +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); + res +=sysfs_emit_at (buf, res,"%s " , pbuf); + } }if (res) buf[res-1 ] ='\n' ;/* eat the leftover space */ Signature · 1 line
2.43.5
---
-Jay Vosburgh, [email protected]
RE: [PATCH net-next v4 6/7] bonding: Update to bond's sysfs and procfs for extended arp_ip_target format.
________________________________________
From: Jay Vosburgh <[email protected]>
Sent: Wednesday, July 2, 2025 11:32 AM
To: David Wilder
Cc: [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 6/7] bonding: Update to bond's sysfs and procfs for extended arp_ip_target format.
Quoted 10 lines
Quoted 3 lines · David Wilder
/sys/class/net/<bond>/bonding/arp_ip_target and /proc/net/bonding/<bond> will display vlan tags if they have been configured by the user
I don't think we need to do any of this, the sysfs and proc APIs
to bonding should not be updated to support new functionality. Netlink and/sbin/ipmust do the right thing, but the other APIs are more or less frozen in the past.
ok, I can remove this patch from the set.
Quoted 63 lines
-JQuoted 55 lines
Signed-off-by David Wilder <[email protected]>---
drivers/net/bonding/bond_procfs.c| 5 ++++-drivers/net/bonding/bond_sysfs.c| 9 ++++++---2 files changed, 10 insertions(+), 4 deletions(-)drivers/net/bonding/bond_procfs.c +4
-1@@ -111,6 +111,7 @@ static void bond_info_show_master(struct seq_file *seq)/* ARP information */ if (bond->params.arp_interval >0 ) { +char pbuf[BOND_OPTION_STRING_MAX_SIZE ];int printed =0 ; seq_printf(seq, "ARP Polling Interval (ms): %d\n",@@ -125,7 +126,9 @@ static void bond_info_show_master(struct seq_file *seq)break ;if (printed)seq_printf (seq,"," ); -seq_printf (seq," %pI4" , &bond->params.arp_targets[i].target_ip); +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); +seq_printf (seq," %s" , pbuf); printed =1 ; }seq_printf (seq,"\n" );drivers/net/bonding/bond_sysfs.c +6
-4@@ -286,13 +286,16 @@ static ssize_t bonding_show_arp_targets(struct device *d,struct device_attribute *attr, char *buf) { + char pbuf[BOND_OPTION_STRING_MAX_SIZE];struct bonding *bond =to_bond (d);int i, res =0 ;for (i =0 ; i <BOND_MAX_ARP_TARGETS ; i++) { -if (bond->params.arp_targets[i].target_ip) - res +=sysfs_emit_at (buf, res,"%pI4 " , - &bond->params.arp_targets[i].target_ip); +if (bond->params.arp_targets[i].target_ip) { +bond_arp_target_to_string (&bond->params.arp_targets[i], + pbuf,sizeof (pbuf)); + res +=sysfs_emit_at (buf, res,"%s " , pbuf); + } }if (res) buf[res-1 ] ='\n' ;/* eat the leftover space */ --Quoted 2 lines
2.43.5
---
-Jay Vosburgh, [email protected]
PATCH v4 7/7 bonding: Selftest and documentation for the arp_ip_target parameter.
In reply to David WilderThis selftest provided a functional test for the arp_ip_target parameter both with and without user supplied vlan tags.
and
Updates to the bonding documentation.
--- Documentation/networking/bonding.rst | 11 + .../selftests/drivers/net/bonding/Makefile | 3 +- .../drivers/net/bonding/bond-arp-ip-target.sh | 194 ++++++++++++++++++ 3 files changed, 207 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/drivers/net/bonding/bond-arp-ip-target.sh
Documentation/networking/bonding.rst +11 -0
@@ -313,6 +313,17 @@ arp_ip_target maximum number of targets that can be specified is 16. The default value is no IP addresses. + When an arp_ip_target is configured the bonding driver will + attempt to automatically determine what vlans the arp probe will + pass through. This process of gathering vlan tags is required + for the arp probe to be sent. However, in some configurations + this process may fail. In these cases you may manually + supply a list of vlan tags. To specify a list of vlan tags + append the ipv4 address with [tag1/tag2...]. For example: + arp_ip_target=10.0.0.1[10]. If you simply need to disable the + vlan discovery process you may provide an empty list, for example: + arp_ip_target=10.0.0.1[]. + ns_ip6_target Specifies the IPv6 addresses to use as IPv6 monitoring peers when
tools/testing/selftests/drivers/net/bonding/Makefile +2 -1
@@ -10,7 +10,8 @@ TEST_PROGS := \ mode-2-recovery-updelay.sh \ bond_options.sh \ bond-eth-type-change.sh \ - bond_macvlan_ipvlan.sh + bond_macvlan_ipvlan.sh \ + bond-arp-ip-target.sh TEST_FILES := \ lag_lib.sh \
tools/testing/selftests/drivers/net/bonding/bond-arp-ip-target.sh new file +194 -0
194 lines not on this page · raw message
Signature · 1 line
2.43.5
Jakub Kicinski
maintainerQuoted 21 lines · On Fri, 27 Jun 2025 13:17:13 -0700 David Wilder wrote:
The current implementation of the arp monitor builds a list of vlan-tags by following the chain of
net_devicesabove the bond. Seebond_verify_device_path(). Unfortunately, with some configurations, this is not possible. One example is when an ovs switch is configured above the bond.This change extends the "
arp_ip_target" parameter format to allow for a list of vlan tags to be included for each arp target. This new list of tags is optional and may be omitted to preserve the current format and process of discovering vlans.The new format for
arp_ip_targetis:arp_ip_targetipv4-address[vlan-tag\...],...For example:
arp_ip_target10.0.0.1[10/20]arp_ip_target10.0.0.1[] (used to disable vlan discovery)The extended format of
arp_ip_targetis only supported by using the ip command when creating the bond. Module parameters and the sysfs file do not allow the use of the extended format.
Quoted 5 lines
Changes since V3:
1) Moved the parsing of the extended
arp_ip_targetout of the kernel and into userspace (ip command). A separate patch to iproute2 to follow shortly.
2) Split up the patch set to make review easier.
This appears to trigger the following warning when running the newly added tests (BTW please run shellcheck on the test, too):
[ 1315.127007][ T9889] WARNING: CPU: 2 PID: 9889 at lib/vsprintf.c:2802 vsnprintf+0xa76/0x1050 [ 1315.127471][ T9889] Modules linked in: [last unloaded: netdevsim] [ 1315.127908][ T9889] CPU: 2 UID: 0 PID: 9889 Comm: grep Not tainted 6.16.0-rc3-virtme #1 PREEMPT(full) [ 1315.128709][ T9889] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 1315.129070][ T9889] RIP: 0010:vsnprintf+0xa76/0x1050 [ 1315.129378][ T9889] Code: 01 89 44 24 50 83 e8 01 89 44 24 7c 85 c0 7f c2 4c 89 f8 48 c1 e8 03 42 0f b6 04 08 84 c0 0f 85 72 fa ff ff e9 75 fa ff ff 90 <0f> 0b 90 e9 f1 f7 ff ff 48 8b 44 24 28 80 38 00 0f 85 a7 04 00 00 [ 1315.130388][ T9889] RSP: 0018:ffffc90001227970 EFLAGS: 00010286 [ 1315.130749][ T9889] RAX: 0000000000000000 RBX: fffff52000244f4c RCX: ffffc90001227a80 [ 1315.131233][ T9889] RDX: ffffffffb80db4e0 RSI: ffffffffffffffff RDI: 1ffff92000244f39 [ 1315.131654][ T9889] RBP: ffffc90001227a50 R08: ffffffffb80db4a1 R09: ffffffffb6e54d12 [ 1315.132073][ T9889] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 1315.132509][ T9889] R13: 000000000000000c R14: ffffffffb6e54ce0 R15: ffffc90001227ba0 [ 1315.132937][ T9889] FS: 00007f554d21e740(0000) GS:ffff88807bb4d000(0000) knlGS:0000000000000000 [ 1315.133437][ T9889] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1315.133794][ T9889] CR2: 000055c1198c67f8 CR3: 000000000ca1b001 CR4: 0000000000772ef0 [ 1315.134244][ T9889] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1315.134968][ T9889] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 1315.135406][ T9889] PKRU: 55555554 [ 1315.135626][ T9889] Call Trace: [ 1315.135843][ T9889] <TASK> [ 1315.136005][ T9889] ? __pfx_vsnprintf+0x10/0x10 [ 1315.136310][ T9889] ? __pfx_bond_opt_parse+0x10/0x10 [ 1315.136602][ T9889] snprintf+0xa1/0xd0 [ 1315.136823][ T9889] ? __pfx_snprintf+0x10/0x10 [ 1315.137133][ T9889] ? bond_opt_parse+0x32/0x6e0 [ 1315.137414][ T9889] ? bond_opt_parse+0x30/0x6e0 [ 1315.137696][ T9889] bond_info_show_master+0x84c/0x1140 [ 1315.137977][ T9889] ? bond_opt_parse+0x32/0x6e0 [ 1315.138276][ T9889] ? __pfx_bond_info_show_master+0x10/0x10 [ 1315.138625][ T9889] ? __pfx_seq_printf+0x10/0x10 [ 1315.138917][ T9889] ? __pfx_bond_info_seq_start+0x10/0x10 [ 1315.139218][ T9889] bond_info_seq_show+0x43/0x50 [ 1315.139507][ T9889] seq_read_iter+0x40e/0x1090 [ 1315.139805][ T9889] proc_reg_read_iter+0x1a3/0x270 [ 1315.140100][ T9889] vfs_read+0x75a/0xce0 [ 1315.140324][ T9889] ? vfs_getattr_nosec+0x2c0/0x3e0 [ 1315.140608][ T9889] ? __pfx_vfs_read+0x10/0x10 [ 1315.140896][ T9889] ? __do_sys_newfstat+0x7b/0xc0 [ 1315.141201][ T9889] ksys_read+0xf7/0x1d0
Signature · 1 line
pw-bot: cr
Quoted 3 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.
Any reason why this is incompatible with ns_ip6_target?
Thanks
Hangbin
________________________________________
From: Hangbin Liu <[email protected]>
Sent: Monday, June 30, 2025 3:18 AM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extend arp_ip_target format to allow for a list of vlan tags.
Quoted 6 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.Any reason why this is incompatible with
ns_ip6_target?
Hi Hangbin
I am unable to get the existing ns_ip6_target code to function when the target is in a vlan. If the existing code is not working with vlans it makes no sense to specify the vlan tags.
This is what I think is happening:
In ns_send_all() we have this bit of code:
dst = ip6_route_output(dev_net(bond->dev), NULL, &fl6);
if (dst->error) {
dst_release(dst);
/* there's no route to target - try to send arp
* probe to generate any traffic (arp_validate=0)
*/
if (bond->params.arp_validate)
bond_ns_send(slave, &targets[i], &in6addr_any, tags);
<.......>
continue;
}ip6_route_output() is returning an error as there is no neighbor entry for the target. A ns is then sent with no vlan header. I found that the multicast ns (with no vlan header) is not passed to the vlan siblings with the target address so no reply is sent.
The ipv4 code is simmiler but the arp is sent as a brodcast. The broadcast arp will be propagated to the vlan sibling (in the linux vlan code).
This could be a testing issue, I am unsure. Can you help with a test case with the target in a vlan?
Thanks
David Wilder
Quoted 44 lines · David Wilder
________________________________________
From: Hangbin Liu <[email protected]>
Sent: Monday, June 30, 2025 3:18 AM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extendarp_ip_targetformat to allow for a list of vlan tags.Quoted 6 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.Any reason why this is incompatible with
ns_ip6_target?Hi Hangbin
I am unable to get the existing
ns_ip6_targetcode to function when the target is in a vlan. If the existing code is not working with vlans it makes no sense to specify the vlan tags.This is what I think is happening:
In
ns_send_all()we have this bit of code:dst =
ip6_route_output(dev_net(bond->dev), NULL, &fl6);if (dst->error) { dst_release(dst); /* there's no route to target - try to send arp * probe to generate any traffic (arp_validate=0) */ if (bond->params.arp_validate) bond_ns_send(slave, &targets[i], &in6addr_any, tags); <.......> continue; }
ip6_route_output()is returning an error as there is no neighbor entry for the target. A ns is then sent with no vlan header. I found that the multicast ns (with no vlan header) is not passed to the vlan siblings with the target address so no reply is sent.
Quoted 5 lines
The ipv4 code is simmiler but the arp is sent as a brodcast. The broadcast arp will be propagated to the vlan sibling (in the linux vlan code).
This could be a testing issue, I am unsure. Can you help with a test case with the target in a vlan?
I can reproduce this issue. I guess it's because the IPv6 route code is different with IPv4. I will check this issue.
Thanks
Hangbin
Hi David,
Quoted 40 lines · Hangbin Liu
Quoted 40 lines
From: Hangbin Liu <[email protected]>
Sent: Monday, June 30, 2025 3:18 AM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extendarp_ip_targetformat to allow for a list of vlan tags.Quoted 6 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.Any reason why this is incompatible with
ns_ip6_target?Hi Hangbin
I am unable to get the existing
ns_ip6_targetcode to function when the target is in a vlan. If the existing code is not working with vlans it makes no sense to specify the vlan tags.This is what I think is happening:
In
ns_send_all()we have this bit of code:dst =
ip6_route_output(dev_net(bond->dev), NULL, &fl6);if (dst->error) { dst_release(dst); /* there's no route to target - try to send arp * probe to generate any traffic (arp_validate=0) */ if (bond->params.arp_validate) bond_ns_send(slave, &targets[i], &in6addr_any, tags); <.......> continue; }
ip6_route_output()is returning an error as there is no neighbor entry for the target. A ns is then sent with no vlan header. I found that the multicast ns (with no vlan header) is not passed to the vlan siblings with the target address so no reply is sent.
Quoted 5 lines
Quoted 5 lines
The ipv4 code is simmiler but the arp is sent as a brodcast. The broadcast arp will be propagated to the vlan sibling (in the linux vlan code).
This could be a testing issue, I am unsure. Can you help with a test case with the target in a vlan?
I looked into this recently, and you are right — ip6_route_output() returns an error dst. The root cause is that we cannot get the destination IPv6 address through the bond interface, because the source IPv6 address is configured on other interfaces, the VLAN sub-interface.
This is a key difference between IPv6 and IPv4:
In IPv4, it's possible to get a destination route via the bond even when the source IP is configured on a different interface. But in IPv6, the routing mechanism is stricter in requiring the source address to be valid on the outgoing interface.
I'm not sure how to fix this yet, as it's fundamentally tied to how IPv6 routing behaves.
Thanks
Hangbin
Quoted 7 lines
I can reproduce this issue. I guess it's because the IPv6 route code is different with IPv4. I will check this issue.
Thanks
Hangbin
________________________________________
From: Hangbin Liu <[email protected]>
Sent: Wednesday, August 6, 2025 9:38 PM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extend arp_ip_target format to allow for a list of vlan tags.
Hi Hangbin
Quoted 53 lines
Hi David,
Quoted 40 lines · Hangbin Liu
From: Hangbin Liu <[email protected]>
Sent: Monday, June 30, 2025 3:18 AM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extendarp_ip_targetformat to allow for a list of vlan tags.Quoted 6 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.Any reason why this is incompatible with
ns_ip6_target?Hi Hangbin
I am unable to get the existing
ns_ip6_targetcode to function when the target is in a vlan. If the existing code is not working with vlans it makes no sense to specify the vlan tags.This is what I think is happening:
In
ns_send_all()we have this bit of code:dst =
ip6_route_output(dev_net(bond->dev), NULL, &fl6);if (dst->error) { dst_release(dst); /* there's no route to target - try to send arp * probe to generate any traffic (arp_validate=0) */ if (bond->params.arp_validate) bond_ns_send(slave, &targets[i], &in6addr_any, tags); <.......> continue; }
ip6_route_output()is returning an error as there is no neighbor entry for the target. A ns is then sent with no vlan header. I found that the multicast ns (with no vlan header) is not passed to the vlan siblings with the target address so no reply is sent.Quoted 5 lines
The ipv4 code is simmiler but the arp is sent as a brodcast. The broadcast arp will be propagated to the vlan sibling (in the linux vlan code).
This could be a testing issue, I am unsure. Can you help with a test case with the target in a vlan?
I looked into this recently, and you are right —
ip6_route_output()returns an error dst. The root cause is that we cannot get the destination IPv6 address through the bond interface, because the source IPv6 address is configured on other interfaces, the VLAN sub-interface.
Quoted 8 lines
This is a key difference between IPv6 and IPv4:
In IPv4, it's possible to get a destination route via the bond even when the source IP is configured on a different interface. But in IPv6, the routing mechanism is stricter in requiring the source address to be valid on the outgoing interface.I'm not sure how to fix this yet, as it's fundamentally tied to how IPv6 routing behaves.
I am thinking that we don't need to do a route lookup as if we are sending from the bonding interface. We only need to find the interface we should send the packet through. As if we ran "ip route get <dest addr>".
David Wilder
Jay Vosburgh
maintainerQuoted 67 lines · David Wilder
From: Hangbin Liu <[email protected]>
Sent: Wednesday, August 6, 2025 9:38 PM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extendarp_ip_targetformat to allow for a list of vlan tags.Hi Hangbin
Quoted 59 lines
Hi David,
Quoted 40 lines · Hangbin Liu
From: Hangbin Liu <[email protected]>
Sent: Monday, June 30, 2025 3:18 AM
To: David Wilder
Cc: [email protected]; [email protected]; [email protected]; Pradeep Satyanarayana; [email protected]; Adrian Moreno Zapata; Hangbin Liu
Subject: [EXTERNAL] Re: [PATCH net-next v4 0/7] bonding: Extendarp_ip_targetformat to allow for a list of vlan tags.Quoted 6 lines · David Wilder
I have run into issues with the
ns_ip6_targetfeature. I am unable to get the existing code to function with vlans. Therefor I am unable to support A this change forns_ip6_target.Any reason why this is incompatible with
ns_ip6_target?Hi Hangbin
I am unable to get the existing
ns_ip6_targetcode to function when the target is in a vlan. If the existing code is not working with vlans it makes no sense to specify the vlan tags.This is what I think is happening:
In
ns_send_all()we have this bit of code:dst =
ip6_route_output(dev_net(bond->dev), NULL, &fl6);if (dst->error) { dst_release(dst); /* there's no route to target - try to send arp * probe to generate any traffic (arp_validate=0) */ if (bond->params.arp_validate) bond_ns_send(slave, &targets[i], &in6addr_any, tags); <.......> continue; }
ip6_route_output()is returning an error as there is no neighbor entry for the target. A ns is then sent with no vlan header. I found that the multicast ns (with no vlan header) is not passed to the vlan siblings with the target address so no reply is sent.Quoted 5 lines
The ipv4 code is simmiler but the arp is sent as a brodcast. The broadcast arp will be propagated to the vlan sibling (in the linux vlan code).
This could be a testing issue, I am unsure. Can you help with a test case with the target in a vlan?
I looked into this recently, and you are right —
ip6_route_output()returns an error dst. The root cause is that we cannot get the destination IPv6 address through the bond interface, because the source IPv6 address is configured on other interfaces, the VLAN sub-interface.This is a key difference between IPv6 and IPv4:
In IPv4, it's possible to get a destination route via the bond even when the source IP is configured on a different interface. But in IPv6, the routing mechanism is stricter in requiring the source address to be valid on the outgoing interface.
Quoted 6 lines
Quoted 2 lines
I'm not sure how to fix this yet, as it's fundamentally tied to how IPv6 routing behaves.
I am thinking that we don't need to do a route lookup as if we are sending from the bonding interface. We only need to find the interface we should send the packet through. As if we ran "ip route get <dest addr>".
Assuming I'm following correctly, the whole point of the route
lookup is to determine which interface the ARP (or NS for IPv6) should nominally sent through (based on the destination address). This serves two purposes:
- collecting the VLAN tags,
- insuring that the ARP / NS won't be sent on a logically
incorrect interface (e.g., its address corresponds to some totally unrelated interface).
So, really, I'm agreed that what we're really looking for is
"what is the proper output interface to use to send to destination X," which we can then check to see if that interface is logically connected to the bond (e.g., a VLAN atop the bond).
Is the solution to call ip6_route_output() with the flowi6_oif
set to zero? That seems to be what happens for the "ip route get" case in inet6_rtm_getroute() (he says, looking at the code but not running actual tests).
-J
---
-Jay Vosburgh, [email protected]
Quoted 29 lines · Jay Vosburgh
Quoted 6 lines
Quoted 6 lines
This is a key difference between IPv6 and IPv4:
In IPv4, it's possible to get a destination route via the bond even when the source IP is configured on a different interface. But in IPv6, the routing mechanism is stricter in requiring the source address to be valid on the outgoing interface.Quoted 6 lines
Quoted 2 lines
I'm not sure how to fix this yet, as it's fundamentally tied to how IPv6 routing behaves.
I am thinking that we don't need to do a route lookup as if we are sending from the bonding interface. We only need to find the interface we should send the packet through. As if we ran "ip route get <dest addr>".
Assuming I'm following correctly, the whole point of the route
lookup is to determine which interface the ARP (or NS for IPv6) should nominally sent through (based on the destination address). This serves two purposes:- collecting the VLAN tags,
- insuring that the ARP / NS won't be sent on a logically
incorrect interface (e.g., its address corresponds to some totally unrelated interface).So, really, I'm agreed that what we're really looking for is
"what is the proper output interface to use to send to destination X," which we can then check to see if that interface is logically connected to the bond (e.g., a VLAN atop the bond).
Quoted 4 lines
Is the solution to call
ip6_route_output()with theflowi6_oif
set to zero? That seems to be what happens for the "ip route get" case ininet6_rtm_getroute()(he says, looking at the code but not running actual tests).
Looks reasonable to me. We can find the dst interface first and check if it's an upper link of the bond interface.
Thanks
Hangbin