Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bonding: make it possible to have unlimited nested upper vlans

Currently we're limited by a constant level of vlan nestings, and fail to
find anything beyound that level (currently 2).

To fix this - remove the limit of nestings when going through device tree,
and when the end device is found - allocate the needed amount of vlan tags
and return them, instead of found/not found.

CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Veaceslav Falico and committed by
David S. Miller
3e403a77 224e923c

+61 -42
+5 -3
drivers/net/bonding/bond_alb.c
··· 1042 1042 struct bonding *bond = bond_get_bond_by_slave(slave); 1043 1043 struct net_device *upper; 1044 1044 struct list_head *iter; 1045 - struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP]; 1045 + struct bond_vlan_tag *tags; 1046 1046 1047 1047 /* send untagged */ 1048 1048 alb_send_lp_vid(slave, mac_addr, 0, 0); ··· 1070 1070 * when strict_match is turned off. 1071 1071 */ 1072 1072 if (netif_is_macvlan(upper) && !strict_match) { 1073 - memset(tags, 0, sizeof(tags)); 1074 - bond_verify_device_path(bond->dev, upper, tags); 1073 + tags = bond_verify_device_path(bond->dev, upper, 0); 1074 + if (IS_ERR_OR_NULL(tags)) 1075 + BUG(); 1075 1076 alb_send_lp_vid(slave, upper->dev_addr, 1076 1077 tags[0].vlan_proto, tags[0].vlan_id); 1078 + kfree(tags); 1077 1079 } 1078 1080 } 1079 1081 rcu_read_unlock();
+53 -35
drivers/net/bonding/bond_main.c
··· 2145 2145 struct bond_vlan_tag *tags) 2146 2146 { 2147 2147 struct sk_buff *skb; 2148 - int i; 2148 + struct bond_vlan_tag *outer_tag = tags; 2149 2149 2150 2150 netdev_dbg(slave_dev, "arp %d on slave %s: dst %pI4 src %pI4\n", 2151 2151 arp_op, slave_dev->name, &dest_ip, &src_ip); ··· 2158 2158 return; 2159 2159 } 2160 2160 2161 + if (!tags || tags->vlan_proto == VLAN_N_VID) 2162 + goto xmit; 2163 + 2164 + tags++; 2165 + 2161 2166 /* Go through all the tags backwards and add them to the packet */ 2162 - for (i = BOND_MAX_VLAN_ENCAP - 1; i > 0; i--) { 2163 - if (!tags[i].vlan_id) 2167 + while (tags->vlan_proto != VLAN_N_VID) { 2168 + if (!tags->vlan_id) { 2169 + tags++; 2164 2170 continue; 2171 + } 2165 2172 2166 2173 netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n", 2167 - ntohs(tags[i].vlan_proto), tags[i].vlan_id); 2168 - skb = __vlan_put_tag(skb, tags[i].vlan_proto, 2169 - tags[i].vlan_id); 2174 + ntohs(outer_tag->vlan_proto), tags->vlan_id); 2175 + skb = __vlan_put_tag(skb, tags->vlan_proto, 2176 + tags->vlan_id); 2170 2177 if (!skb) { 2171 2178 net_err_ratelimited("failed to insert inner VLAN tag\n"); 2172 2179 return; 2173 2180 } 2181 + 2182 + tags++; 2174 2183 } 2175 2184 /* Set the outer tag */ 2176 - if (tags[0].vlan_id) { 2185 + if (outer_tag->vlan_id) { 2177 2186 netdev_dbg(slave_dev, "outer tag: proto %X vid %X\n", 2178 - ntohs(tags[0].vlan_proto), tags[0].vlan_id); 2179 - skb = vlan_put_tag(skb, tags[0].vlan_proto, tags[0].vlan_id); 2187 + ntohs(outer_tag->vlan_proto), outer_tag->vlan_id); 2188 + skb = vlan_put_tag(skb, outer_tag->vlan_proto, 2189 + outer_tag->vlan_id); 2180 2190 if (!skb) { 2181 2191 net_err_ratelimited("failed to insert outer VLAN tag\n"); 2182 2192 return; 2183 2193 } 2184 2194 } 2195 + 2196 + xmit: 2185 2197 arp_xmit(skb); 2186 2198 } 2187 2199 ··· 2203 2191 * When the path is validated, collect any vlan information in the 2204 2192 * path. 2205 2193 */ 2206 - bool bond_verify_device_path(struct net_device *start_dev, 2207 - struct net_device *end_dev, 2208 - struct bond_vlan_tag *tags) 2194 + struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, 2195 + struct net_device *end_dev, 2196 + int level) 2209 2197 { 2198 + struct bond_vlan_tag *tags; 2210 2199 struct net_device *upper; 2211 2200 struct list_head *iter; 2212 - int idx; 2213 2201 2214 - if (start_dev == end_dev) 2215 - return true; 2216 - 2217 - netdev_for_each_upper_dev_rcu(start_dev, upper, iter) { 2218 - if (bond_verify_device_path(upper, end_dev, tags)) { 2219 - if (is_vlan_dev(upper)) { 2220 - idx = vlan_get_encap_level(upper); 2221 - if (idx >= BOND_MAX_VLAN_ENCAP) 2222 - return false; 2223 - 2224 - tags[idx].vlan_proto = 2225 - vlan_dev_vlan_proto(upper); 2226 - tags[idx].vlan_id = vlan_dev_vlan_id(upper); 2227 - } 2228 - return true; 2229 - } 2202 + if (start_dev == end_dev) { 2203 + tags = kzalloc(sizeof(*tags) * (level + 1), GFP_ATOMIC); 2204 + if (!tags) 2205 + return ERR_PTR(-ENOMEM); 2206 + tags[level].vlan_proto = VLAN_N_VID; 2207 + return tags; 2230 2208 } 2231 2209 2232 - return false; 2210 + netdev_for_each_upper_dev_rcu(start_dev, upper, iter) { 2211 + tags = bond_verify_device_path(upper, end_dev, level + 1); 2212 + if (IS_ERR_OR_NULL(tags)) { 2213 + if (IS_ERR(tags)) 2214 + return tags; 2215 + continue; 2216 + } 2217 + if (is_vlan_dev(upper)) { 2218 + tags[level].vlan_proto = vlan_dev_vlan_proto(upper); 2219 + tags[level].vlan_id = vlan_dev_vlan_id(upper); 2220 + } 2221 + 2222 + return tags; 2223 + } 2224 + 2225 + return NULL; 2233 2226 } 2234 2227 2235 2228 static void bond_arp_send_all(struct bonding *bond, struct slave *slave) 2236 2229 { 2237 2230 struct rtable *rt; 2238 - struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP]; 2231 + struct bond_vlan_tag *tags; 2239 2232 __be32 *targets = bond->params.arp_targets, addr; 2240 2233 int i; 2241 - bool ret; 2242 2234 2243 2235 for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) { 2244 2236 netdev_dbg(bond->dev, "basa: target %pI4\n", &targets[i]); 2245 - memset(tags, 0, sizeof(tags)); 2237 + tags = NULL; 2246 2238 2247 2239 /* Find out through which dev should the packet go */ 2248 2240 rt = ip_route_output(dev_net(bond->dev), targets[i], 0, ··· 2269 2253 goto found; 2270 2254 2271 2255 rcu_read_lock(); 2272 - ret = bond_verify_device_path(bond->dev, rt->dst.dev, tags); 2256 + tags = bond_verify_device_path(bond->dev, rt->dst.dev, 0); 2273 2257 rcu_read_unlock(); 2274 2258 2275 - if (ret) 2259 + if (!IS_ERR_OR_NULL(tags)) 2276 2260 goto found; 2277 2261 2278 2262 /* Not our device - skip */ ··· 2287 2271 ip_rt_put(rt); 2288 2272 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 2289 2273 addr, tags); 2274 + if (!tags) 2275 + kfree(tags); 2290 2276 } 2291 2277 } 2292 2278
+3 -4
drivers/net/bonding/bonding.h
··· 36 36 37 37 #define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n" 38 38 39 - #define BOND_MAX_VLAN_ENCAP 2 40 39 #define BOND_MAX_ARP_TARGETS 16 41 40 42 41 #define BOND_DEFAULT_MIIMON 100 ··· 524 525 void bond_netlink_fini(void); 525 526 struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); 526 527 const char *bond_slave_link_status(s8 link); 527 - bool bond_verify_device_path(struct net_device *start_dev, 528 - struct net_device *end_dev, 529 - struct bond_vlan_tag *tags); 528 + struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, 529 + struct net_device *end_dev, 530 + int level); 530 531 531 532 #ifdef CONFIG_PROC_FS 532 533 void bond_create_proc_entry(struct bonding *bond);