aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 14f789551616..023ec365209c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2145,7 +2145,7 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2145 struct bond_vlan_tag *tags) 2145 struct bond_vlan_tag *tags)
2146{ 2146{
2147 struct sk_buff *skb; 2147 struct sk_buff *skb;
2148 int i; 2148 struct bond_vlan_tag *outer_tag = tags;
2149 2149
2150 netdev_dbg(slave_dev, "arp %d on slave %s: dst %pI4 src %pI4\n", 2150 netdev_dbg(slave_dev, "arp %d on slave %s: dst %pI4 src %pI4\n",
2151 arp_op, slave_dev->name, &dest_ip, &src_ip); 2151 arp_op, slave_dev->name, &dest_ip, &src_ip);
@@ -2158,30 +2158,42 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2158 return; 2158 return;
2159 } 2159 }
2160 2160
2161 if (!tags || tags->vlan_proto == VLAN_N_VID)
2162 goto xmit;
2163
2164 tags++;
2165
2161 /* Go through all the tags backwards and add them to the packet */ 2166 /* Go through all the tags backwards and add them to the packet */
2162 for (i = BOND_MAX_VLAN_ENCAP - 1; i > 0; i--) { 2167 while (tags->vlan_proto != VLAN_N_VID) {
2163 if (!tags[i].vlan_id) 2168 if (!tags->vlan_id) {
2169 tags++;
2164 continue; 2170 continue;
2171 }
2165 2172
2166 netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n", 2173 netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n",
2167 ntohs(tags[i].vlan_proto), tags[i].vlan_id); 2174 ntohs(outer_tag->vlan_proto), tags->vlan_id);
2168 skb = __vlan_put_tag(skb, tags[i].vlan_proto, 2175 skb = __vlan_put_tag(skb, tags->vlan_proto,
2169 tags[i].vlan_id); 2176 tags->vlan_id);
2170 if (!skb) { 2177 if (!skb) {
2171 net_err_ratelimited("failed to insert inner VLAN tag\n"); 2178 net_err_ratelimited("failed to insert inner VLAN tag\n");
2172 return; 2179 return;
2173 } 2180 }
2181
2182 tags++;
2174 } 2183 }
2175 /* Set the outer tag */ 2184 /* Set the outer tag */
2176 if (tags[0].vlan_id) { 2185 if (outer_tag->vlan_id) {
2177 netdev_dbg(slave_dev, "outer tag: proto %X vid %X\n", 2186 netdev_dbg(slave_dev, "outer tag: proto %X vid %X\n",
2178 ntohs(tags[0].vlan_proto), tags[0].vlan_id); 2187 ntohs(outer_tag->vlan_proto), outer_tag->vlan_id);
2179 skb = vlan_put_tag(skb, tags[0].vlan_proto, tags[0].vlan_id); 2188 skb = vlan_put_tag(skb, outer_tag->vlan_proto,
2189 outer_tag->vlan_id);
2180 if (!skb) { 2190 if (!skb) {
2181 net_err_ratelimited("failed to insert outer VLAN tag\n"); 2191 net_err_ratelimited("failed to insert outer VLAN tag\n");
2182 return; 2192 return;
2183 } 2193 }
2184 } 2194 }
2195
2196xmit:
2185 arp_xmit(skb); 2197 arp_xmit(skb);
2186} 2198}
2187 2199
@@ -2191,46 +2203,50 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2191 * When the path is validated, collect any vlan information in the 2203 * When the path is validated, collect any vlan information in the
2192 * path. 2204 * path.
2193 */ 2205 */
2194bool bond_verify_device_path(struct net_device *start_dev, 2206struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
2195 struct net_device *end_dev, 2207 struct net_device *end_dev,
2196 struct bond_vlan_tag *tags) 2208 int level)
2197{ 2209{
2210 struct bond_vlan_tag *tags;
2198 struct net_device *upper; 2211 struct net_device *upper;
2199 struct list_head *iter; 2212 struct list_head *iter;
2200 int idx;
2201 2213
2202 if (start_dev == end_dev) 2214 if (start_dev == end_dev) {
2203 return true; 2215 tags = kzalloc(sizeof(*tags) * (level + 1), GFP_ATOMIC);
2216 if (!tags)
2217 return ERR_PTR(-ENOMEM);
2218 tags[level].vlan_proto = VLAN_N_VID;
2219 return tags;
2220 }
2204 2221
2205 netdev_for_each_upper_dev_rcu(start_dev, upper, iter) { 2222 netdev_for_each_upper_dev_rcu(start_dev, upper, iter) {
2206 if (bond_verify_device_path(upper, end_dev, tags)) { 2223 tags = bond_verify_device_path(upper, end_dev, level + 1);
2207 if (is_vlan_dev(upper)) { 2224 if (IS_ERR_OR_NULL(tags)) {
2208 idx = vlan_get_encap_level(upper); 2225 if (IS_ERR(tags))
2209 if (idx >= BOND_MAX_VLAN_ENCAP) 2226 return tags;
2210 return false; 2227 continue;
2211
2212 tags[idx].vlan_proto =
2213 vlan_dev_vlan_proto(upper);
2214 tags[idx].vlan_id = vlan_dev_vlan_id(upper);
2215 }
2216 return true;
2217 } 2228 }
2229 if (is_vlan_dev(upper)) {
2230 tags[level].vlan_proto = vlan_dev_vlan_proto(upper);
2231 tags[level].vlan_id = vlan_dev_vlan_id(upper);
2232 }
2233
2234 return tags;
2218 } 2235 }
2219 2236
2220 return false; 2237 return NULL;
2221} 2238}
2222 2239
2223static void bond_arp_send_all(struct bonding *bond, struct slave *slave) 2240static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2224{ 2241{
2225 struct rtable *rt; 2242 struct rtable *rt;
2226 struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP]; 2243 struct bond_vlan_tag *tags;
2227 __be32 *targets = bond->params.arp_targets, addr; 2244 __be32 *targets = bond->params.arp_targets, addr;
2228 int i; 2245 int i;
2229 bool ret;
2230 2246
2231 for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) { 2247 for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
2232 netdev_dbg(bond->dev, "basa: target %pI4\n", &targets[i]); 2248 netdev_dbg(bond->dev, "basa: target %pI4\n", &targets[i]);
2233 memset(tags, 0, sizeof(tags)); 2249 tags = NULL;
2234 2250
2235 /* Find out through which dev should the packet go */ 2251 /* Find out through which dev should the packet go */
2236 rt = ip_route_output(dev_net(bond->dev), targets[i], 0, 2252 rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
@@ -2253,10 +2269,10 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2253 goto found; 2269 goto found;
2254 2270
2255 rcu_read_lock(); 2271 rcu_read_lock();
2256 ret = bond_verify_device_path(bond->dev, rt->dst.dev, tags); 2272 tags = bond_verify_device_path(bond->dev, rt->dst.dev, 0);
2257 rcu_read_unlock(); 2273 rcu_read_unlock();
2258 2274
2259 if (ret) 2275 if (!IS_ERR_OR_NULL(tags))
2260 goto found; 2276 goto found;
2261 2277
2262 /* Not our device - skip */ 2278 /* Not our device - skip */
@@ -2271,6 +2287,8 @@ found:
2271 ip_rt_put(rt); 2287 ip_rt_put(rt);
2272 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 2288 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
2273 addr, tags); 2289 addr, tags);
2290 if (!tags)
2291 kfree(tags);
2274 } 2292 }
2275} 2293}
2276 2294