aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-16 22:29:17 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-16 22:29:17 -0400
commita8d0d8417c0bdc870d28afb83bc12e61a818efa3 (patch)
treec9c13fc99aaa8f2c62d21b5ffbb1ece6d1a2c00b
parent6bd64ac0f9c264082241da0db0dcc72a13e672a8 (diff)
parentf60c3704e87d39356d00c71bf51e55c2c55ad4f5 (diff)
Merge branch 'bond_stacked_vlans'
Vlad Yasevich says: ==================== Fixed stacked vlan usage on top of bonds Bonding device driver now support q-in-q on top for bonds. There are a few issues here though. First, when arp monitoring is used, bonding driver will not correctly tag traffic if the source of the arp device was configured on top of q-in-q. It may also incorrectly pick the wrong vlan id if the ordering of that upper devices isn't as expected (there is no guarntee on ordering). Second, the alb/tlb may use what would be considered 'inner' vlans in its learning announcements, as it simply announces all vlans configured on top of the bond without regard for encapsulation/stacking. This series fixes the above 2 issues. This series also depends on the functionality introduced in http://patchwork.ozlabs.org/patch/349766/ Since v1: - Changed how patch1 verifies the device path. We no longer use the _all_upper version of the function. We find the path and if it was found, then collect the vlan information. - Use the constant to devine maximum vlan nest level support on top of bonding. This can be changed if 2 is too low. - Inlude patch2 into the series. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_alb.c2
-rw-r--r--drivers/net/bonding/bond_main.c134
-rw-r--r--drivers/net/bonding/bonding.h1
-rw-r--r--include/linux/if_vlan.h6
-rw-r--r--include/linux/netdevice.h9
-rw-r--r--net/core/dev.c26
6 files changed, 108 insertions, 70 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 9f69e818b000..e53847884319 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1045,7 +1045,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
1045 /* loop through vlans and send one packet for each */ 1045 /* loop through vlans and send one packet for each */
1046 rcu_read_lock(); 1046 rcu_read_lock();
1047 netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) { 1047 netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
1048 if (upper->priv_flags & IFF_802_1Q_VLAN) 1048 if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0)
1049 alb_send_lp_vid(slave, mac_addr, 1049 alb_send_lp_vid(slave, mac_addr,
1050 vlan_dev_vlan_id(upper)); 1050 vlan_dev_vlan_id(upper));
1051 } 1051 }
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69aff72c8957..d3a67896d435 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2126,10 +2126,10 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
2126 */ 2126 */
2127static void bond_arp_send(struct net_device *slave_dev, int arp_op, 2127static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2128 __be32 dest_ip, __be32 src_ip, 2128 __be32 dest_ip, __be32 src_ip,
2129 struct bond_vlan_tag *inner, 2129 struct bond_vlan_tag *tags)
2130 struct bond_vlan_tag *outer)
2131{ 2130{
2132 struct sk_buff *skb; 2131 struct sk_buff *skb;
2132 int i;
2133 2133
2134 pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n", 2134 pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n",
2135 arp_op, slave_dev->name, &dest_ip, &src_ip); 2135 arp_op, slave_dev->name, &dest_ip, &src_ip);
@@ -2141,21 +2141,26 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2141 net_err_ratelimited("ARP packet allocation failed\n"); 2141 net_err_ratelimited("ARP packet allocation failed\n");
2142 return; 2142 return;
2143 } 2143 }
2144 if (outer->vlan_id) {
2145 if (inner->vlan_id) {
2146 pr_debug("inner tag: proto %X vid %X\n",
2147 ntohs(inner->vlan_proto), inner->vlan_id);
2148 skb = __vlan_put_tag(skb, inner->vlan_proto,
2149 inner->vlan_id);
2150 if (!skb) {
2151 net_err_ratelimited("failed to insert inner VLAN tag\n");
2152 return;
2153 }
2154 }
2155 2144
2156 pr_debug("outer reg: proto %X vid %X\n", 2145 /* Go through all the tags backwards and add them to the packet */
2157 ntohs(outer->vlan_proto), outer->vlan_id); 2146 for (i = BOND_MAX_VLAN_ENCAP - 1; i > 0; i--) {
2158 skb = vlan_put_tag(skb, outer->vlan_proto, outer->vlan_id); 2147 if (!tags[i].vlan_id)
2148 continue;
2149
2150 pr_debug("inner tag: proto %X vid %X\n",
2151 ntohs(tags[i].vlan_proto), tags[i].vlan_id);
2152 skb = __vlan_put_tag(skb, tags[i].vlan_proto,
2153 tags[i].vlan_id);
2154 if (!skb) {
2155 net_err_ratelimited("failed to insert inner VLAN tag\n");
2156 return;
2157 }
2158 }
2159 /* Set the outer tag */
2160 if (tags[0].vlan_id) {
2161 pr_debug("outer tag: proto %X vid %X\n",
2162 ntohs(tags[0].vlan_proto), tags[0].vlan_id);
2163 skb = vlan_put_tag(skb, tags[0].vlan_proto, tags[0].vlan_id);
2159 if (!skb) { 2164 if (!skb) {
2160 net_err_ratelimited("failed to insert outer VLAN tag\n"); 2165 net_err_ratelimited("failed to insert outer VLAN tag\n");
2161 return; 2166 return;
@@ -2164,22 +2169,52 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2164 arp_xmit(skb); 2169 arp_xmit(skb);
2165} 2170}
2166 2171
2172/* Validate the device path between the @start_dev and the @end_dev.
2173 * The path is valid if the @end_dev is reachable through device
2174 * stacking.
2175 * When the path is validated, collect any vlan information in the
2176 * path.
2177 */
2178static bool bond_verify_device_path(struct net_device *start_dev,
2179 struct net_device *end_dev,
2180 struct bond_vlan_tag *tags)
2181{
2182 struct net_device *upper;
2183 struct list_head *iter;
2184 int idx;
2185
2186 if (start_dev == end_dev)
2187 return true;
2188
2189 netdev_for_each_upper_dev_rcu(start_dev, upper, iter) {
2190 if (bond_verify_device_path(upper, end_dev, tags)) {
2191 if (is_vlan_dev(upper)) {
2192 idx = vlan_get_encap_level(upper);
2193 if (idx >= BOND_MAX_VLAN_ENCAP)
2194 return false;
2195
2196 tags[idx].vlan_proto =
2197 vlan_dev_vlan_proto(upper);
2198 tags[idx].vlan_id = vlan_dev_vlan_id(upper);
2199 }
2200 return true;
2201 }
2202 }
2203
2204 return false;
2205}
2167 2206
2168static void bond_arp_send_all(struct bonding *bond, struct slave *slave) 2207static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2169{ 2208{
2170 struct net_device *upper, *vlan_upper;
2171 struct list_head *iter, *vlan_iter;
2172 struct rtable *rt; 2209 struct rtable *rt;
2173 struct bond_vlan_tag inner, outer; 2210 struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP];
2174 __be32 *targets = bond->params.arp_targets, addr; 2211 __be32 *targets = bond->params.arp_targets, addr;
2175 int i; 2212 int i;
2213 bool ret;
2176 2214
2177 for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) { 2215 for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
2178 pr_debug("basa: target %pI4\n", &targets[i]); 2216 pr_debug("basa: target %pI4\n", &targets[i]);
2179 inner.vlan_proto = 0; 2217 memset(tags, 0, sizeof(tags));
2180 inner.vlan_id = 0;
2181 outer.vlan_proto = 0;
2182 outer.vlan_id = 0;
2183 2218
2184 /* Find out through which dev should the packet go */ 2219 /* Find out through which dev should the packet go */
2185 rt = ip_route_output(dev_net(bond->dev), targets[i], 0, 2220 rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
@@ -2192,7 +2227,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2192 net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n", 2227 net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
2193 bond->dev->name, 2228 bond->dev->name,
2194 &targets[i]); 2229 &targets[i]);
2195 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 0, &inner, &outer); 2230 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
2231 0, tags);
2196 continue; 2232 continue;
2197 } 2233 }
2198 2234
@@ -2201,52 +2237,12 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
2201 goto found; 2237 goto found;
2202 2238
2203 rcu_read_lock(); 2239 rcu_read_lock();
2204 /* first we search only for vlan devices. for every vlan 2240 ret = bond_verify_device_path(bond->dev, rt->dst.dev, tags);
2205 * found we verify its upper dev list, searching for the
2206 * rt->dst.dev. If found we save the tag of the vlan and
2207 * proceed to send the packet.
2208 */
2209 netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper,
2210 vlan_iter) {
2211 if (!is_vlan_dev(vlan_upper))
2212 continue;
2213
2214 if (vlan_upper == rt->dst.dev) {
2215 outer.vlan_proto = vlan_dev_vlan_proto(vlan_upper);
2216 outer.vlan_id = vlan_dev_vlan_id(vlan_upper);
2217 rcu_read_unlock();
2218 goto found;
2219 }
2220 netdev_for_each_all_upper_dev_rcu(vlan_upper, upper,
2221 iter) {
2222 if (upper == rt->dst.dev) {
2223 /* If the upper dev is a vlan dev too,
2224 * set the vlan tag to inner tag.
2225 */
2226 if (is_vlan_dev(upper)) {
2227 inner.vlan_proto = vlan_dev_vlan_proto(upper);
2228 inner.vlan_id = vlan_dev_vlan_id(upper);
2229 }
2230 outer.vlan_proto = vlan_dev_vlan_proto(vlan_upper);
2231 outer.vlan_id = vlan_dev_vlan_id(vlan_upper);
2232 rcu_read_unlock();
2233 goto found;
2234 }
2235 }
2236 }
2237
2238 /* if the device we're looking for is not on top of any of
2239 * our upper vlans, then just search for any dev that
2240 * matches, and in case it's a vlan - save the id
2241 */
2242 netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
2243 if (upper == rt->dst.dev) {
2244 rcu_read_unlock();
2245 goto found;
2246 }
2247 }
2248 rcu_read_unlock(); 2241 rcu_read_unlock();
2249 2242
2243 if (ret)
2244 goto found;
2245
2250 /* Not our device - skip */ 2246 /* Not our device - skip */
2251 pr_debug("%s: no path to arp_ip_target %pI4 via rt.dev %s\n", 2247 pr_debug("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
2252 bond->dev->name, &targets[i], 2248 bond->dev->name, &targets[i],
@@ -2259,7 +2255,7 @@ found:
2259 addr = bond_confirm_addr(rt->dst.dev, targets[i], 0); 2255 addr = bond_confirm_addr(rt->dst.dev, targets[i], 0);
2260 ip_rt_put(rt); 2256 ip_rt_put(rt);
2261 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 2257 bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
2262 addr, &inner, &outer); 2258 addr, tags);
2263 } 2259 }
2264} 2260}
2265 2261
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index b8bdd0acc8f3..00bea320e3b5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -36,6 +36,7 @@
36 36
37#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n" 37#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
38 38
39#define BOND_MAX_VLAN_ENCAP 2
39#define BOND_MAX_ARP_TARGETS 16 40#define BOND_MAX_ARP_TARGETS 16
40 41
41#define BOND_DEFAULT_MIIMON 100 42#define BOND_DEFAULT_MIIMON 100
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 724bde8477b2..c901b13b6f03 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -484,4 +484,10 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
484 */ 484 */
485 skb->protocol = htons(ETH_P_802_2); 485 skb->protocol = htons(ETH_P_802_2);
486} 486}
487
488static inline int vlan_get_encap_level(struct net_device *dev)
489{
490 BUG_ON(!is_vlan_dev(dev));
491 return vlan_dev_priv(dev)->nest_level;
492}
487#endif /* !(_LINUX_IF_VLAN_H_) */ 493#endif /* !(_LINUX_IF_VLAN_H_) */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9d4b1f1b6b75..b42d07b0390b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3056,10 +3056,19 @@ extern int weight_p;
3056extern int bpf_jit_enable; 3056extern int bpf_jit_enable;
3057 3057
3058bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev); 3058bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev);
3059struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
3060 struct list_head **iter);
3059struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, 3061struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
3060 struct list_head **iter); 3062 struct list_head **iter);
3061 3063
3062/* iterate through upper list, must be called under RCU read lock */ 3064/* iterate through upper list, must be called under RCU read lock */
3065#define netdev_for_each_upper_dev_rcu(dev, updev, iter) \
3066 for (iter = &(dev)->adj_list.upper, \
3067 updev = netdev_upper_get_next_dev_rcu(dev, &(iter)); \
3068 updev; \
3069 updev = netdev_upper_get_next_dev_rcu(dev, &(iter)))
3070
3071/* iterate through upper list, must be called under RCU read lock */
3063#define netdev_for_each_all_upper_dev_rcu(dev, updev, iter) \ 3072#define netdev_for_each_all_upper_dev_rcu(dev, updev, iter) \
3064 for (iter = &(dev)->all_adj_list.upper, \ 3073 for (iter = &(dev)->all_adj_list.upper, \
3065 updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)); \ 3074 updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)); \
diff --git a/net/core/dev.c b/net/core/dev.c
index 2b872bfbd172..9abc503b19b7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4542,6 +4542,32 @@ void *netdev_adjacent_get_private(struct list_head *adj_list)
4542EXPORT_SYMBOL(netdev_adjacent_get_private); 4542EXPORT_SYMBOL(netdev_adjacent_get_private);
4543 4543
4544/** 4544/**
4545 * netdev_upper_get_next_dev_rcu - Get the next dev from upper list
4546 * @dev: device
4547 * @iter: list_head ** of the current position
4548 *
4549 * Gets the next device from the dev's upper list, starting from iter
4550 * position. The caller must hold RCU read lock.
4551 */
4552struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
4553 struct list_head **iter)
4554{
4555 struct netdev_adjacent *upper;
4556
4557 WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held());
4558
4559 upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
4560
4561 if (&upper->list == &dev->adj_list.upper)
4562 return NULL;
4563
4564 *iter = &upper->list;
4565
4566 return upper->dev;
4567}
4568EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu);
4569
4570/**
4545 * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list 4571 * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list
4546 * @dev: device 4572 * @dev: device
4547 * @iter: list_head ** of the current position 4573 * @iter: list_head ** of the current position