History

bonding: add new parameter ns_targets

Add a new bonding parameter ns_targets to store IPv6 address. Add required bond_ns_send/rcv functions first before adding IPv6 address option setting. Add two functions bond_send/rcv_validate so we can send/recv ARP and NS at the same time.

Hangbin Liu committed 4 years ago

Commit 4e24be01 parent 841e9563 files · +237 −21Browse files

Unified · Split

3 files
  1. drivers/net/bonding/bond_main.c +218 −19
  2. drivers/net/bonding/bond_options.c +1 −1
  3. include/net/bonding.h +18 −1
drivers/net/bonding/bond_main.c+218−19
@@ -88,6 +88,7 @@ · 87 unmodified lines
88#if IS_ENABLED(CONFIG_TLS_DEVICE)88#if IS_ENABLED(CONFIG_TLS_DEVICE)
89#include <net/tls.h>89#include <net/tls.h>
90#endif90#endif
91#include <net/ip6_route.h>
91 92
92#include "bonding_priv.h"93#include "bonding_priv.h"
93 94
@@ -2975,30 +2976,17 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 · 2881 unmodified lines
2975 slave->target_last_arp_rx[i] = jiffies;2976 slave->target_last_arp_rx[i] = jiffies;
2976}2977}
2977 2978
2978int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,2979static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
2979 struct slave *slave)2980 struct slave *slave)
2980{2981{
2981 struct arphdr *arp = (struct arphdr *)skb->data;2982 struct arphdr *arp = (struct arphdr *)skb->data;
2982 struct slave *curr_active_slave, *curr_arp_slave;2983 struct slave *curr_active_slave, *curr_arp_slave;
2983 unsigned char *arp_ptr;2984 unsigned char *arp_ptr;
2984 __be32 sip, tip;2985 __be32 sip, tip;
2985 int is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
2986 unsigned int alen;2986 unsigned int alen;
2987 2987
2988 if (!slave_do_arp_validate(bond, slave)) {
2989 if ((slave_do_arp_validate_only(bond) && is_arp) ||
2990 !slave_do_arp_validate_only(bond))
2991 slave->last_rx = jiffies;
2992 return RX_HANDLER_ANOTHER;
2993 } else if (!is_arp) {
2994 return RX_HANDLER_ANOTHER;
2995 }
2996
2997 alen = arp_hdr_len(bond->dev);2988 alen = arp_hdr_len(bond->dev);
2998 2989
2999 slave_dbg(bond->dev, slave->dev, "%s: skb->dev %s\n",
3000 __func__, skb->dev->name);
3001
3002 if (alen > skb_headlen(skb)) {2990 if (alen > skb_headlen(skb)) {
3003 arp = kmalloc(alen, GFP_ATOMIC);2991 arp = kmalloc(alen, GFP_ATOMIC);
3004 if (!arp)2992 if (!arp)
@@ -3069,6 +3057,216 @@ out_unlock: · 64 unmodified lines
3069 return RX_HANDLER_ANOTHER;3057 return RX_HANDLER_ANOTHER;
3070}3058}
3071 3059
3060#if IS_ENABLED(CONFIG_IPV6)
3061static void bond_ns_send(struct slave *slave, const struct in6_addr *daddr,
3062 const struct in6_addr *saddr, struct bond_vlan_tag *tags)
3063{
3064 struct net_device *bond_dev = slave->bond->dev;
3065 struct net_device *slave_dev = slave->dev;
3066 struct in6_addr mcaddr;
3067 struct sk_buff *skb;
3068
3069 slave_dbg(bond_dev, slave_dev, "NS on slave: dst %pI6c src %pI6c\n",
3070 daddr, saddr);
3071
3072 skb = ndisc_ns_create(slave_dev, daddr, saddr, 0);
3073 if (!skb) {
3074 net_err_ratelimited("NS packet allocation failed\n");
3075 return;
3076 }
3077
3078 addrconf_addr_solict_mult(daddr, &mcaddr);
3079 if (bond_handle_vlan(slave, tags, skb))
3080 ndisc_send_skb(skb, &mcaddr, saddr);
3081}
3082
3083static void bond_ns_send_all(struct bonding *bond, struct slave *slave)
3084{
3085 struct in6_addr *targets = bond->params.ns_targets;
3086 struct bond_vlan_tag *tags;
3087 struct dst_entry *dst;
3088 struct in6_addr saddr;
3089 struct flowi6 fl6;
3090 int i;
3091
3092 for (i = 0; i < BOND_MAX_NS_TARGETS && !ipv6_addr_any(&targets[i]); i++) {
3093 slave_dbg(bond->dev, slave->dev, "%s: target %pI6c\n",
3094 __func__, &targets[i]);
3095 tags = NULL;
3096
3097 /* Find out through which dev should the packet go */
3098 memset(&fl6, 0, sizeof(struct flowi6));
3099 fl6.daddr = targets[i];
3100 fl6.flowi6_oif = bond->dev->ifindex;
3101
3102 dst = ip6_route_output(dev_net(bond->dev), NULL, &fl6);
3103 if (dst->error) {
3104 dst_release(dst);
3105 /* there's no route to target - try to send arp
3106 * probe to generate any traffic (arp_validate=0)
3107 */
3108 if (bond->params.arp_validate)
3109 pr_warn_once("%s: no route to ns_ip6_target %pI6c and arp_validate is set\n",
3110 bond->dev->name,
3111 &targets[i]);
3112 bond_ns_send(slave, &targets[i], &in6addr_any, tags);
3113 continue;
3114 }
3115
3116 /* bond device itself */
3117 if (dst->dev == bond->dev)
3118 goto found;
3119
3120 rcu_read_lock();
3121 tags = bond_verify_device_path(bond->dev, dst->dev, 0);
3122 rcu_read_unlock();
3123
3124 if (!IS_ERR_OR_NULL(tags))
3125 goto found;
3126
3127 /* Not our device - skip */
3128 slave_dbg(bond->dev, slave->dev, "no path to ns_ip6_target %pI6c via dst->dev %s\n",
3129 &targets[i], dst->dev ? dst->dev->name : "NULL");
3130
3131 dst_release(dst);
3132 continue;
3133
3134found:
3135 if (!ipv6_dev_get_saddr(dev_net(dst->dev), dst->dev, &targets[i], 0, &saddr))
3136 bond_ns_send(slave, &targets[i], &saddr, tags);
3137 dst_release(dst);
3138 kfree(tags);
3139 }
3140}
3141
3142static int bond_confirm_addr6(struct net_device *dev,
3143 struct netdev_nested_priv *priv)
3144{
3145 struct in6_addr *addr = (struct in6_addr *)priv->data;
3146
3147 return ipv6_chk_addr(dev_net(dev), addr, dev, 0);
3148}
3149
3150static bool bond_has_this_ip6(struct bonding *bond, struct in6_addr *addr)
3151{
3152 struct netdev_nested_priv priv = {
3153 .data = addr,
3154 };
3155 int ret = false;
3156
3157 if (bond_confirm_addr6(bond->dev, &priv))
3158 return true;
3159
3160 rcu_read_lock();
3161 if (netdev_walk_all_upper_dev_rcu(bond->dev, bond_confirm_addr6, &priv))
3162 ret = true;
3163 rcu_read_unlock();
3164
3165 return ret;
3166}
3167
3168static void bond_validate_ns(struct bonding *bond, struct slave *slave,
3169 struct in6_addr *saddr, struct in6_addr *daddr)
3170{
3171 int i;
3172
3173 if (ipv6_addr_any(saddr) || !bond_has_this_ip6(bond, daddr)) {
3174 slave_dbg(bond->dev, slave->dev, "%s: sip %pI6c tip %pI6c not found\n",
3175 __func__, saddr, daddr);
3176 return;
3177 }
3178
3179 i = bond_get_targets_ip6(bond->params.ns_targets, saddr);
3180 if (i == -1) {
3181 slave_dbg(bond->dev, slave->dev, "%s: sip %pI6c not found in targets\n",
3182 __func__, saddr);
3183 return;
3184 }
3185 slave->last_rx = jiffies;
3186 slave->target_last_arp_rx[i] = jiffies;
3187}
3188
3189static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
3190 struct slave *slave)
3191{
3192 struct slave *curr_active_slave, *curr_arp_slave;
3193 struct icmp6hdr *hdr = icmp6_hdr(skb);
3194 struct in6_addr *saddr, *daddr;
3195
3196 if (skb->pkt_type == PACKET_OTHERHOST ||
3197 skb->pkt_type == PACKET_LOOPBACK ||
3198 hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
3199 goto out;
3200
3201 saddr = &ipv6_hdr(skb)->saddr;
3202 daddr = &ipv6_hdr(skb)->daddr;
3203
3204 slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
3205 __func__, slave->dev->name, bond_slave_state(slave),
3206 bond->params.arp_validate, slave_do_arp_validate(bond, slave),
3207 saddr, daddr);
3208
3209 curr_active_slave = rcu_dereference(bond->curr_active_slave);
3210 curr_arp_slave = rcu_dereference(bond->current_arp_slave);
3211
3212 /* We 'trust' the received ARP enough to validate it if:
3213 * see bond_arp_rcv().
3214 */
3215 if (bond_is_active_slave(slave))
3216 bond_validate_ns(bond, slave, saddr, daddr);
3217 else if (curr_active_slave &&
3218 time_after(slave_last_rx(bond, curr_active_slave),
3219 curr_active_slave->last_link_up))
3220 bond_validate_ns(bond, slave, saddr, daddr);
3221 else if (curr_arp_slave &&
3222 bond_time_in_interval(bond,
3223 dev_trans_start(curr_arp_slave->dev), 1))
3224 bond_validate_ns(bond, slave, saddr, daddr);
3225
3226out:
3227 return RX_HANDLER_ANOTHER;
3228}
3229#endif
3230
3231int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond,
3232 struct slave *slave)
3233{
3234#if IS_ENABLED(CONFIG_IPV6)
3235 bool is_ipv6 = skb->protocol == __cpu_to_be16(ETH_P_IPV6);
3236#endif
3237 bool is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
3238
3239 slave_dbg(bond->dev, slave->dev, "%s: skb->dev %s\n",
3240 __func__, skb->dev->name);
3241
3242 /* Use arp validate logic for both ARP and NS */
3243 if (!slave_do_arp_validate(bond, slave)) {
3244 if ((slave_do_arp_validate_only(bond) && is_arp) ||
3245#if IS_ENABLED(CONFIG_IPV6)
3246 (slave_do_arp_validate_only(bond) && is_ipv6) ||
3247#endif
3248 !slave_do_arp_validate_only(bond))
3249 slave->last_rx = jiffies;
3250 return RX_HANDLER_ANOTHER;
3251 } else if (is_arp) {
3252 return bond_arp_rcv(skb, bond, slave);
3253#if IS_ENABLED(CONFIG_IPV6)
3254 } else if (is_ipv6) {
3255 return bond_na_rcv(skb, bond, slave);
3256#endif
3257 } else {
3258 return RX_HANDLER_ANOTHER;
3259 }
3260}
3261
3262static void bond_send_validate(struct bonding *bond, struct slave *slave)
3263{
3264 bond_arp_send_all(bond, slave);
3265#if IS_ENABLED(CONFIG_IPV6)
3266 bond_ns_send_all(bond, slave);
3267#endif
3268}
3269
3072/* function to verify if we're in the arp_interval timeslice, returns true if3270/* function to verify if we're in the arp_interval timeslice, returns true if
3073 * (last_act - arp_interval) <= jiffies <= (last_act + mod * arp_interval +3271 * (last_act - arp_interval) <= jiffies <= (last_act + mod * arp_interval +
3074 * arp_interval/2) . the arp_interval/2 is needed for really fast networks.3272 * arp_interval/2) . the arp_interval/2 is needed for really fast networks.
@@ -3164,7 +3362,7 @@ static void bond_loadbalance_arp_mon(struct bonding *bond) · 89 unmodified lines
3164 * to be unstable during low/no traffic periods3362 * to be unstable during low/no traffic periods
3165 */3363 */
3166 if (bond_slave_is_up(slave))3364 if (bond_slave_is_up(slave))
3167 bond_arp_send_all(bond, slave);3365 bond_send_validate(bond, slave);
3168 }3366 }
3169 3367
3170 rcu_read_unlock();3368 rcu_read_unlock();
@@ -3378,7 +3576,7 @@ static bool bond_ab_arp_probe(struct bonding *bond) · 207 unmodified lines
3378 curr_active_slave->dev->name);3576 curr_active_slave->dev->name);
3379 3577
3380 if (curr_active_slave) {3578 if (curr_active_slave) {
3381 bond_arp_send_all(bond, curr_active_slave);3579 bond_send_validate(bond, curr_active_slave);
3382 return should_notify_rtnl;3580 return should_notify_rtnl;
3383 }3581 }
3384 3582
@@ -3430,7 +3628,7 @@ static bool bond_ab_arp_probe(struct bonding *bond) · 45 unmodified lines
3430 bond_set_slave_link_state(new_slave, BOND_LINK_BACK,3628 bond_set_slave_link_state(new_slave, BOND_LINK_BACK,
3431 BOND_SLAVE_NOTIFY_LATER);3629 BOND_SLAVE_NOTIFY_LATER);
3432 bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);3630 bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
3433 bond_arp_send_all(bond, new_slave);3631 bond_send_validate(bond, new_slave);
3434 new_slave->last_link_up = jiffies;3632 new_slave->last_link_up = jiffies;
3435 rcu_assign_pointer(bond->current_arp_slave, new_slave);3633 rcu_assign_pointer(bond->current_arp_slave, new_slave);
3436 3634
@@ -3966,7 +4164,7 @@ static int bond_open(struct net_device *bond_dev) · 529 unmodified lines
3966 4164
3967 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */4165 if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
3968 queue_delayed_work(bond->wq, &bond->arp_work, 0);4166 queue_delayed_work(bond->wq, &bond->arp_work, 0);
3969 bond->recv_probe = bond_arp_rcv;4167 bond->recv_probe = bond_rcv_validate;
3970 }4168 }
3971 4169
3972 if (BOND_MODE(bond) == BOND_MODE_8023AD) {4170 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
@@ -5947,6 +6145,7 @@ static int bond_check_params(struct bond_params *params) · 1974 unmodified lines
5947 strscpy_pad(params->primary, primary, sizeof(params->primary));6145 strscpy_pad(params->primary, primary, sizeof(params->primary));
5948 6146
5949 memcpy(params->arp_targets, arp_target, sizeof(arp_target));6147 memcpy(params->arp_targets, arp_target, sizeof(arp_target));
6148 memset(params->ns_targets, 0, sizeof(struct in6_addr) * BOND_MAX_NS_TARGETS);
5950 6149
5951 return 0;6150 return 0;
5952}6151}
drivers/net/bonding/bond_options.c+1−1
@@ -1052,7 +1052,7 @@ static int bond_option_arp_interval_set(struct bonding *bond, · 1051 unmodified lines
1052 cancel_delayed_work_sync(&bond->arp_work);1052 cancel_delayed_work_sync(&bond->arp_work);
1053 } else {1053 } else {
1054 /* arp_validate can be set only in active-backup mode */1054 /* arp_validate can be set only in active-backup mode */
1055 bond->recv_probe = bond_arp_rcv;1055 bond->recv_probe = bond_rcv_validate;
1056 cancel_delayed_work_sync(&bond->mii_work);1056 cancel_delayed_work_sync(&bond->mii_work);
1057 queue_delayed_work(bond->wq, &bond->arp_work, 0);1057 queue_delayed_work(bond->wq, &bond->arp_work, 0);
1058 }1058 }
include/net/bonding.h+18−1
@@ -29,8 +29,11 @@ · 28 unmodified lines
29#include <net/bond_3ad.h>29#include <net/bond_3ad.h>
30#include <net/bond_alb.h>30#include <net/bond_alb.h>
31#include <net/bond_options.h>31#include <net/bond_options.h>
32#include <net/ipv6.h>
33#include <net/addrconf.h>
32 34
33#define BOND_MAX_ARP_TARGETS 1635#define BOND_MAX_ARP_TARGETS 16
36#define BOND_MAX_NS_TARGETS BOND_MAX_ARP_TARGETS
34 37
35#define BOND_DEFAULT_MIIMON 10038#define BOND_DEFAULT_MIIMON 100
36 39
@@ -146,6 +149,7 @@ struct bond_params { · 109 unmodified lines
146 struct reciprocal_value reciprocal_packets_per_slave;149 struct reciprocal_value reciprocal_packets_per_slave;
147 u16 ad_actor_sys_prio;150 u16 ad_actor_sys_prio;
148 u16 ad_user_port_key;151 u16 ad_user_port_key;
152 struct in6_addr ns_targets[BOND_MAX_NS_TARGETS];
149 153
150 /* 2 bytes of padding : see ether_addr_equal_64bits() */154 /* 2 bytes of padding : see ether_addr_equal_64bits() */
151 u8 ad_actor_system[ETH_ALEN + 2];155 u8 ad_actor_system[ETH_ALEN + 2];
@@ -628,7 +632,7 @@ struct bond_net { · 476 unmodified lines
628 struct class_attribute class_attr_bonding_masters;632 struct class_attribute class_attr_bonding_masters;
629};633};
630 634
631int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);635int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);
632netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);636netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
633int bond_create(struct net *net, const char *name);637int bond_create(struct net *net, const char *name);
634int bond_create_sysfs(struct bond_net *net);638int bond_create_sysfs(struct bond_net *net);
@@ -735,6 +739,19 @@ static inline int bond_get_targets_ip(__be32 *targets, __be32 ip) · 100 unmodified lines
735 return -1;739 return -1;
736}740}
737 741
742static inline int bond_get_targets_ip6(struct in6_addr *targets, struct in6_addr *ip)
743{
744 int i;
745
746 for (i = 0; i < BOND_MAX_NS_TARGETS; i++)
747 if (ipv6_addr_equal(&targets[i], ip))
748 return i;
749 else if (ipv6_addr_any(&targets[i]))
750 break;
751
752 return -1;
753}
754
738/* exported from bond_main.c */755/* exported from bond_main.c */
739extern unsigned int bond_net_id;756extern unsigned int bond_net_id;
740 757

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t