aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJiri Bohac <jbohac@suse.cz>2012-05-08 21:01:40 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-10 23:30:01 -0400
commit13a8e0c8cdb43982372bd6c65fb26839c8fd8ce9 (patch)
tree824f5daec5b68663a7feaebb76ebbb2cfce5d4c0 /drivers/net/bonding
parent38bf1953987c1735f3c9140fca762949a8cae507 (diff)
bonding: don't increase rx_dropped after processing LACPDUs
Since commit 3aba891d, bonding processes LACP frames (802.3ad mode) with bond_handle_frame(). Currently a copy of the skb is made and the original is left to be processed by other rx_handlers and the rest of the network stack by returning RX_HANDLER_ANOTHER. As there is no protocol handler for PKT_TYPE_LACPDU, the frame is dropped and dev->rx_dropped increased. Fix this by making bond_handle_frame() return RX_HANDLER_CONSUMED if bonding has processed the LACP frame. Signed-off-by: Jiri Bohac <jbohac@suse.cz> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_3ad.c18
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_main.c16
3 files changed, 24 insertions, 12 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 793b0013827..3463b469e65 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2173,9 +2173,10 @@ re_arm:
2173 * received frames (loopback). Since only the payload is given to this 2173 * received frames (loopback). Since only the payload is given to this
2174 * function, it check for loopback. 2174 * function, it check for loopback.
2175 */ 2175 */
2176static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length) 2176static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
2177{ 2177{
2178 struct port *port; 2178 struct port *port;
2179 int ret = RX_HANDLER_ANOTHER;
2179 2180
2180 if (length >= sizeof(struct lacpdu)) { 2181 if (length >= sizeof(struct lacpdu)) {
2181 2182
@@ -2184,11 +2185,12 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
2184 if (!port->slave) { 2185 if (!port->slave) {
2185 pr_warning("%s: Warning: port of slave %s is uninitialized\n", 2186 pr_warning("%s: Warning: port of slave %s is uninitialized\n",
2186 slave->dev->name, slave->dev->master->name); 2187 slave->dev->name, slave->dev->master->name);
2187 return; 2188 return ret;
2188 } 2189 }
2189 2190
2190 switch (lacpdu->subtype) { 2191 switch (lacpdu->subtype) {
2191 case AD_TYPE_LACPDU: 2192 case AD_TYPE_LACPDU:
2193 ret = RX_HANDLER_CONSUMED;
2192 pr_debug("Received LACPDU on port %d\n", 2194 pr_debug("Received LACPDU on port %d\n",
2193 port->actor_port_number); 2195 port->actor_port_number);
2194 /* Protect against concurrent state machines */ 2196 /* Protect against concurrent state machines */
@@ -2198,6 +2200,7 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
2198 break; 2200 break;
2199 2201
2200 case AD_TYPE_MARKER: 2202 case AD_TYPE_MARKER:
2203 ret = RX_HANDLER_CONSUMED;
2201 // No need to convert fields to Little Endian since we don't use the marker's fields. 2204 // No need to convert fields to Little Endian since we don't use the marker's fields.
2202 2205
2203 switch (((struct bond_marker *)lacpdu)->tlv_type) { 2206 switch (((struct bond_marker *)lacpdu)->tlv_type) {
@@ -2219,6 +2222,7 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
2219 } 2222 }
2220 } 2223 }
2221 } 2224 }
2225 return ret;
2222} 2226}
2223 2227
2224/** 2228/**
@@ -2456,18 +2460,20 @@ out:
2456 return NETDEV_TX_OK; 2460 return NETDEV_TX_OK;
2457} 2461}
2458 2462
2459void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, 2463int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
2460 struct slave *slave) 2464 struct slave *slave)
2461{ 2465{
2466 int ret = RX_HANDLER_ANOTHER;
2462 if (skb->protocol != PKT_TYPE_LACPDU) 2467 if (skb->protocol != PKT_TYPE_LACPDU)
2463 return; 2468 return ret;
2464 2469
2465 if (!pskb_may_pull(skb, sizeof(struct lacpdu))) 2470 if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
2466 return; 2471 return ret;
2467 2472
2468 read_lock(&bond->lock); 2473 read_lock(&bond->lock);
2469 bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); 2474 ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
2470 read_unlock(&bond->lock); 2475 read_unlock(&bond->lock);
2476 return ret;
2471} 2477}
2472 2478
2473/* 2479/*
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 235b2cc58b2..5ee7e3c45db 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -274,7 +274,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
274void bond_3ad_handle_link_change(struct slave *slave, char link); 274void bond_3ad_handle_link_change(struct slave *slave, char link);
275int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); 275int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
276int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); 276int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
277void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, 277int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
278 struct slave *slave); 278 struct slave *slave);
279int bond_3ad_set_carrier(struct bonding *bond); 279int bond_3ad_set_carrier(struct bonding *bond);
280void bond_3ad_update_lacp_rate(struct bonding *bond); 280void bond_3ad_update_lacp_rate(struct bonding *bond);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 62d2409bb29..bc13b3d7743 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1444,8 +1444,9 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
1444 struct sk_buff *skb = *pskb; 1444 struct sk_buff *skb = *pskb;
1445 struct slave *slave; 1445 struct slave *slave;
1446 struct bonding *bond; 1446 struct bonding *bond;
1447 void (*recv_probe)(struct sk_buff *, struct bonding *, 1447 int (*recv_probe)(struct sk_buff *, struct bonding *,
1448 struct slave *); 1448 struct slave *);
1449 int ret = RX_HANDLER_ANOTHER;
1449 1450
1450 skb = skb_share_check(skb, GFP_ATOMIC); 1451 skb = skb_share_check(skb, GFP_ATOMIC);
1451 if (unlikely(!skb)) 1452 if (unlikely(!skb))
@@ -1464,8 +1465,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
1464 struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); 1465 struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
1465 1466
1466 if (likely(nskb)) { 1467 if (likely(nskb)) {
1467 recv_probe(nskb, bond, slave); 1468 ret = recv_probe(nskb, bond, slave);
1468 dev_kfree_skb(nskb); 1469 dev_kfree_skb(nskb);
1470 if (ret == RX_HANDLER_CONSUMED) {
1471 consume_skb(skb);
1472 return ret;
1473 }
1469 } 1474 }
1470 } 1475 }
1471 1476
@@ -1487,7 +1492,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
1487 memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN); 1492 memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN);
1488 } 1493 }
1489 1494
1490 return RX_HANDLER_ANOTHER; 1495 return ret;
1491} 1496}
1492 1497
1493/* enslave device <slave> to bond device <master> */ 1498/* enslave device <slave> to bond device <master> */
@@ -2723,7 +2728,7 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
2723 } 2728 }
2724} 2729}
2725 2730
2726static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, 2731static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
2727 struct slave *slave) 2732 struct slave *slave)
2728{ 2733{
2729 struct arphdr *arp; 2734 struct arphdr *arp;
@@ -2731,7 +2736,7 @@ static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
2731 __be32 sip, tip; 2736 __be32 sip, tip;
2732 2737
2733 if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) 2738 if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
2734 return; 2739 return RX_HANDLER_ANOTHER;
2735 2740
2736 read_lock(&bond->lock); 2741 read_lock(&bond->lock);
2737 2742
@@ -2776,6 +2781,7 @@ static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
2776 2781
2777out_unlock: 2782out_unlock:
2778 read_unlock(&bond->lock); 2783 read_unlock(&bond->lock);
2784 return RX_HANDLER_ANOTHER;
2779} 2785}
2780 2786
2781/* 2787/*