Re: [patch net-next-2.6 V3] net: convert bonding to use rx_handler
From: Nicolas de Pesloüan <hidden>
Date: 2011-02-27 14:17:06
Le 23/02/2011 20:05, Jiri Pirko a écrit :
This patch converts bonding to use rx_handler. Results in cleaner
__netif_receive_skb() with much less exceptions needed. Also
bond-specific work is moved into bond code.
Did performance test using pktgen and counting incoming packets by
iptables. No regression noted.
Signed-off-by: Jiri Pirko<redacted>
v1->v2:
using skb_iif instead of new input_dev to remember original
device
v2->v3:
do another loop in case skb->dev is changed. That way orig_dev
core can be left untouched.
Signed-off-by: Jiri Pirko<redacted>
---[snip]
+static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
+{
+ struct net_device *slave_dev;
+ struct net_device *bond_dev;
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ return NULL;
+ slave_dev = skb->dev;
+ bond_dev = ACCESS_ONCE(slave_dev->master);
+ if (unlikely(!bond_dev))
+ return skb;
+
+ if (bond_dev->priv_flags& IFF_MASTER_ARPMON)
+ slave_dev->last_rx = jiffies;
+
+ if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) {
+ skb->deliver_no_wcard = 1;
+ return skb;Shouldn't we return NULL here ?
+ }
+
+ skb->dev = bond_dev;
+
+ if (bond_dev->priv_flags& IFF_MASTER_ALB&&
+ bond_dev->priv_flags& IFF_BRIDGE_PORT&&
+ skb->pkt_type == PACKET_HOST) {
+ u16 *dest = (u16 *) eth_hdr(skb)->h_dest;
+
+ memcpy(dest, bond_dev->dev_addr, ETH_ALEN);
+ }
+
+ return skb;
+}
+[snip]
+static void vlan_on_bond_hook(struct sk_buff *skb)
{
- if (skb->pkt_type == PACKET_HOST) {
- u16 *dest = (u16 *) eth_hdr(skb)->h_dest;
+ /*
+ * Make sure ARP frames received on VLAN interfaces stacked on
+ * bonding interfaces still make their way to any base bonding
+ * device that may have registered for a specific ptype.
+ */
+ if (skb->dev->priv_flags& IFF_802_1Q_VLAN&&
+ vlan_dev_real_dev(skb->dev)->priv_flags& IFF_BONDING&&
+ skb->protocol == htons(ETH_P_ARP)) {The vlan_on_bond case used to be cost effective. Now, we clone the skb and call netif_rx...
+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); - memcpy(dest, master->dev_addr, ETH_ALEN); + if (!skb2) + return; + skb2->dev = vlan_dev_real_dev(skb->dev); + netif_rx(skb2); } }
[snip]
if (rx_handler) {
+ struct net_device *prev_dev;
+
if (pt_prev) {
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = NULL;
}
+ prev_dev = skb->dev;
skb = rx_handler(skb);
if (!skb)
goto out;I would instead consider NULL as meaning exact-match-delivery-only. (The same effect as dev_bond_should_drop() returning true).
+ if (skb->dev != prev_dev) + goto another_round; }
Anyway, all my comments can't be postponed to follow-up patchs. Thanks Jiri. Reviewed-by: Nicolas de Pesloüan <redacted>