Skip to content

Commit b620cb3

Browse files
committed
Merge branch 'bonding-next'
Ding Tianhong says: ==================== bonding: support QinQ for bond arp interval v1->v2: remvoe the comment "TODO: QinQ?". convert pr_xxx() to pr_xxx_ratelimited() for arp interval. v2->v3: remove the unnecessary log for arp interval and add net ratelimit to avoid spam log. v3->v4: Add ratelimit for debugging is not a good idea, it will miss some message if the user turns the debugging on, so don't add ratelimited on debugging. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 5a6b991 + 4873ac3 commit b620cb3

File tree

4 files changed

+69
-22
lines changed

4 files changed

+69
-22
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,24 +2124,40 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
21242124
* switches in VLAN mode (especially if ports are configured as
21252125
* "native" to a VLAN) might not pass non-tagged frames.
21262126
*/
2127-
static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ip, __be32 src_ip, unsigned short vlan_id)
2127+
static void bond_arp_send(struct net_device *slave_dev, int arp_op,
2128+
__be32 dest_ip, __be32 src_ip,
2129+
struct bond_vlan_tag *inner,
2130+
struct bond_vlan_tag *outer)
21282131
{
21292132
struct sk_buff *skb;
21302133

2131-
pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n",
2132-
arp_op, slave_dev->name, &dest_ip, &src_ip, vlan_id);
2134+
pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n",
2135+
arp_op, slave_dev->name, &dest_ip, &src_ip);
21332136

21342137
skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
21352138
NULL, slave_dev->dev_addr, NULL);
21362139

21372140
if (!skb) {
2138-
pr_err("ARP packet allocation failed\n");
2141+
net_err_ratelimited("ARP packet allocation failed\n");
21392142
return;
21402143
}
2141-
if (vlan_id) {
2142-
skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_id);
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+
2156+
pr_debug("outer reg: proto %X vid %X\n",
2157+
ntohs(outer->vlan_proto), outer->vlan_id);
2158+
skb = vlan_put_tag(skb, outer->vlan_proto, outer->vlan_id);
21432159
if (!skb) {
2144-
pr_err("failed to insert VLAN tag\n");
2160+
net_err_ratelimited("failed to insert outer VLAN tag\n");
21452161
return;
21462162
}
21472163
}
@@ -2154,11 +2170,16 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
21542170
struct net_device *upper, *vlan_upper;
21552171
struct list_head *iter, *vlan_iter;
21562172
struct rtable *rt;
2173+
struct bond_vlan_tag inner, outer;
21572174
__be32 *targets = bond->params.arp_targets, addr;
2158-
int i, vlan_id;
2175+
int i;
21592176

21602177
for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
21612178
pr_debug("basa: target %pI4\n", &targets[i]);
2179+
inner.vlan_proto = 0;
2180+
inner.vlan_id = 0;
2181+
outer.vlan_proto = 0;
2182+
outer.vlan_id = 0;
21622183

21632184
/* Find out through which dev should the packet go */
21642185
rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
@@ -2167,15 +2188,14 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
21672188
/* there's no route to target - try to send arp
21682189
* probe to generate any traffic (arp_validate=0)
21692190
*/
2170-
if (bond->params.arp_validate && net_ratelimit())
2171-
pr_warn("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
2172-
bond->dev->name, &targets[i]);
2173-
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 0, 0);
2191+
if (bond->params.arp_validate)
2192+
net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
2193+
bond->dev->name,
2194+
&targets[i]);
2195+
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], 0, &inner, &outer);
21742196
continue;
21752197
}
21762198

2177-
vlan_id = 0;
2178-
21792199
/* bond device itself */
21802200
if (rt->dst.dev == bond->dev)
21812201
goto found;
@@ -2185,17 +2205,30 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
21852205
* found we verify its upper dev list, searching for the
21862206
* rt->dst.dev. If found we save the tag of the vlan and
21872207
* proceed to send the packet.
2188-
*
2189-
* TODO: QinQ?
21902208
*/
21912209
netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper,
21922210
vlan_iter) {
21932211
if (!is_vlan_dev(vlan_upper))
21942212
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+
}
21952220
netdev_for_each_all_upper_dev_rcu(vlan_upper, upper,
21962221
iter) {
21972222
if (upper == rt->dst.dev) {
2198-
vlan_id = vlan_dev_vlan_id(vlan_upper);
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);
21992232
rcu_read_unlock();
22002233
goto found;
22012234
}
@@ -2208,10 +2241,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
22082241
*/
22092242
netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
22102243
if (upper == rt->dst.dev) {
2211-
/* if it's a vlan - get its VID */
2212-
if (is_vlan_dev(upper))
2213-
vlan_id = vlan_dev_vlan_id(upper);
2214-
22152244
rcu_read_unlock();
22162245
goto found;
22172246
}
@@ -2230,7 +2259,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
22302259
addr = bond_confirm_addr(rt->dst.dev, targets[i], 0);
22312260
ip_rt_put(rt);
22322261
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
2233-
addr, vlan_id);
2262+
addr, &inner, &outer);
22342263
}
22352264
}
22362265

drivers/net/bonding/bonding.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ struct bonding {
266266
#define bond_slave_get_rtnl(dev) \
267267
((struct slave *) rtnl_dereference(dev->rx_handler_data))
268268

269+
struct bond_vlan_tag {
270+
__be16 vlan_proto;
271+
unsigned short vlan_id;
272+
};
273+
269274
/**
270275
* Returns NULL if the net_device does not belong to any of the bond's slaves
271276
*

include/linux/if_vlan.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
110110
__be16 vlan_proto, u16 vlan_id);
111111
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
112112
extern u16 vlan_dev_vlan_id(const struct net_device *dev);
113+
extern __be16 vlan_dev_vlan_proto(const struct net_device *dev);
113114

114115
/**
115116
* struct vlan_priority_tci_mapping - vlan egress priority mappings
@@ -216,6 +217,12 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
216217
return 0;
217218
}
218219

220+
static inline __be16 vlan_dev_vlan_proto(const struct net_device *dev)
221+
{
222+
BUG();
223+
return 0;
224+
}
225+
219226
static inline u16 vlan_dev_get_egress_qos_mask(struct net_device *dev,
220227
u32 skprio)
221228
{

net/8021q/vlan_core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
106106
}
107107
EXPORT_SYMBOL(vlan_dev_vlan_id);
108108

109+
__be16 vlan_dev_vlan_proto(const struct net_device *dev)
110+
{
111+
return vlan_dev_priv(dev)->vlan_proto;
112+
}
113+
EXPORT_SYMBOL(vlan_dev_vlan_proto);
114+
109115
static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
110116
{
111117
if (skb_cow(skb, skb_headroom(skb)) < 0)

0 commit comments

Comments
 (0)