| @@ -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 | #endif | 90 | #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 | |
| 2978 | int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, | 2979 | static 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) |
| | 3061 | static 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 | |
| | 3083 | static 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 | |
| | 3134 | found: |
| | 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 | |
| | 3142 | static 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 | |
| | 3150 | static 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 | |
| | 3168 | static 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 | |
| | 3189 | static 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 | |
| | 3226 | out: |
| | 3227 | return RX_HANDLER_ANOTHER; |
| | 3228 | } |
| | 3229 | #endif |
| | 3230 | |
| | 3231 | int 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 | |
| | 3262 | static 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 if | 3270 | /* 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 periods | 3362 | * 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 | } |