Hi.

>>      I wonder if it would be better to add a dev->priv_flags for,
>> e.g., IFF_SLAVE_INACTIVE or the like, set that when a slave is marked
>> inactive, and clear it when the slave becomes active (similarly to how
>> NOARP is done today).  The rationale for this is that NOARP can be
>> changed by a user via ifconfig, whereas priv_flags cannot, so it's a
>> little more bulletproof.  In this case, setting NOARP on inactive slaves
>> would no longer be necessary (because skb_bond would reject the traffic
>> before it gets to ARP).
>
> I think your idea using dev->priv_flags is better than using NOARP. Bonding
> driver should have a mechanism to discard the packets picked up on standby 
> interfaces, and this mechanism should not be able to operated by users. 
>
> I created a new patch using dev->priv_flags, but somehow, I wasn't able to
> send packet in 802.3ad mode when I applied my patch. I'll further look into
> the problem.

In 802.3ad mode, the slave interface will become active after bonding
driver receives LACPDU packets.  If all packets including LACPDU packets
were dropped, the inactive slave can never become active.

The attached patch drops packets except for Slow Protocol frames
(including LACPDU) based on dev->priv_flags.  This way, the slave
interface in 802.3ad mode can become active.  I have tested it for both
active-backup and 802.3ad modes.

--
Shuya MAEDA<[EMAIL PROTECTED]>



diff -Nur /usr/src/archive/linux-2.6.13_rc1/drivers/net/bonding/bond_main.c 
./linux-2.6.13_rc1_priv1/drivers/net/bonding/bond_main.c
--- /usr/src/archive/linux-2.6.13_rc1/drivers/net/bonding/bond_main.c   
2005-07-04 09:05:29.000000000 +0900
+++ ./linux-2.6.13_rc1_priv1/drivers/net/bonding/bond_main.c    2005-07-06 
19:37:40.000000000 +0900
@@ -1888,14 +1888,13 @@
        switch (bond->params.mode) {
        case BOND_MODE_ACTIVEBACKUP:
                /* if we're in active-backup mode, we need one and only one 
active
-                * interface. The backup interfaces will have their NOARP flag 
set
-                * because we need them to be completely deaf and not to 
respond to
-                * any ARP request on the network to avoid fooling a switch. 
Thus,
-                * since we guarantee that curr_active_slave always point to 
the last
-                * usable interface, we just have to verify this interface's 
flag.
+                * interface. The backup interfaces will have their 
BOND_SLAVE_INACTIVE
+                * flag set because we need them to drop packets except for 
Slow Protocol
+                * frames. Thus, since we guarantee that curr_active_slave 
always point to 
+                * the last usable interface, we just have to verify this 
interface's flag.
                 */
                if (((!bond->curr_active_slave) ||
-                    (bond->curr_active_slave->dev->flags & IFF_NOARP)) &&
+                     (bond->curr_active_slave->dev->priv_flags & 
IFF_BOND_SLAVE_INACTIVE)) &&
                    (new_slave->link != BOND_LINK_DOWN)) {
                        dprintk("This is the first active slave\n");
                        /* first slave or no active slave yet, and this link
@@ -2191,13 +2190,7 @@
                dev_set_mac_address(slave_dev, &addr);
        }
 
-       /* restore the original state of the
-        * IFF_NOARP flag that might have been
-        * set by bond_set_slave_inactive_flags()
-        */
-       if ((slave->original_flags & IFF_NOARP) == 0) {
-               slave_dev->flags &= ~IFF_NOARP;
-       }
+        slave_dev->priv_flags &= ~IFF_BOND_SLAVE_INACTIVE;
 
        kfree(slave);
 
@@ -2282,12 +2275,7 @@
                        dev_set_mac_address(slave_dev, &addr);
                }
 
-               /* restore the original state of the IFF_NOARP flag that might 
have
-                * been set by bond_set_slave_inactive_flags()
-                */
-               if ((slave->original_flags & IFF_NOARP) == 0) {
-                       slave_dev->flags &= ~IFF_NOARP;
-               }
+                slave_dev->priv_flags &= ~IFF_BOND_SLAVE_INACTIVE;
 
                kfree(slave);
 
@@ -4566,6 +4554,7 @@
        /* Initialize the device options */
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
+        bond_dev->priv_flags |= IFF_BOND_MASTER;
 
        /* At first, we block adding VLANs. That's the only way to
         * prevent problems that occur when adding VLANs over an
diff -Nur /usr/src/archive/linux-2.6.13_rc1/drivers/net/bonding/bonding.h 
./linux-2.6.13_rc1_priv1/drivers/net/bonding/bonding.h
--- /usr/src/archive/linux-2.6.13_rc1/drivers/net/bonding/bonding.h     
2005-07-04 09:05:29.000000000 +0900
+++ ./linux-2.6.13_rc1_priv1/drivers/net/bonding/bonding.h      2005-07-05 
09:41:56.000000000 +0900
@@ -244,13 +244,13 @@
 extern inline void bond_set_slave_inactive_flags(struct slave *slave)
 {
        slave->state = BOND_STATE_BACKUP;
-       slave->dev->flags |= IFF_NOARP;
+        slave->dev->priv_flags |= IFF_BOND_SLAVE_INACTIVE;
 }
 
 extern inline void bond_set_slave_active_flags(struct slave *slave)
 {
        slave->state = BOND_STATE_ACTIVE;
-       slave->dev->flags &= ~IFF_NOARP;
+        slave->dev->priv_flags &= ~IFF_BOND_SLAVE_INACTIVE;
 }
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry 
*curr);
diff -Nur /usr/src/archive/linux-2.6.13_rc1/include/linux/if.h 
./linux-2.6.13_rc1_priv1/include/linux/if.h
--- /usr/src/archive/linux-2.6.13_rc1/include/linux/if.h        2005-07-04 
09:06:10.000000000 +0900
+++ ./linux-2.6.13_rc1_priv1/include/linux/if.h 2005-07-04 16:41:36.000000000 
+0900
@@ -52,6 +52,9 @@
 /* Private (from user) interface flags (netdevice->priv_flags). */
 #define IFF_802_1Q_VLAN 0x1             /* 802.1Q VLAN device.          */
 #define IFF_EBRIDGE    0x2             /* Ethernet bridging device.    */
+#define IFF_BOND_SLAVE_INACTIVE 0x4     /* Inactive slave of Bonding.   */
+#define IFF_BOND_MASTER         0x8     /* Master of Bonding.           */ 
+
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
diff -Nur /usr/src/archive/linux-2.6.13_rc1/include/linux/if_ether.h 
./linux-2.6.13_rc1_priv1/include/linux/if_ether.h
--- /usr/src/archive/linux-2.6.13_rc1/include/linux/if_ether.h  2005-06-18 
04:48:29.000000000 +0900
+++ ./linux-2.6.13_rc1_priv1/include/linux/if_ether.h   2005-07-04 
16:28:38.000000000 +0900
@@ -59,6 +59,7 @@
 #define ETH_P_8021Q    0x8100          /* 802.1Q VLAN Extended Header  */
 #define ETH_P_IPX      0x8137          /* IPX over DIX                 */
 #define ETH_P_IPV6     0x86DD          /* IPv6 over bluebook           */
+#define ETH_P_SLOW      0x8809          /* Slow Protocol. See 802.3ad 43B */
 #define ETH_P_WCCP     0x883E          /* Web-cache coordination protocol
                                         * defined in 
draft-wilson-wrec-wccp-v2-00.txt */
 #define ETH_P_PPP_DISC 0x8863          /* PPPoE discovery messages     */
diff -Nur /usr/src/archive/linux-2.6.13_rc1/net/core/dev.c 
./linux-2.6.13_rc1_priv1/net/core/dev.c
--- /usr/src/archive/linux-2.6.13_rc1/net/core/dev.c    2005-07-04 
09:06:16.000000000 +0900
+++ ./linux-2.6.13_rc1_priv1/net/core/dev.c     2005-07-05 15:50:07.000000000 
+0900
@@ -1426,11 +1426,23 @@
 
 EXPORT_SYMBOL(netif_rx_ni);
 
-static __inline__ void skb_bond(struct sk_buff *skb)
+static __inline__ int skb_bond(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
 
        if (dev->master) {
+
+                /* Slow Protocol frame must not be dropped.*/
+                if( skb->protocol == __constant_htons(ETH_P_SLOW) ){
+                        goto skip;
+                }
+
+                if( (dev->master->priv_flags & IFF_BOND_MASTER) &&
+                    (dev->priv_flags & IFF_BOND_SLAVE_INACTIVE) ){
+                        kfree_skb(skb);
+                        return NET_RX_DROP;
+                }
+        skip:
                skb->real_dev = skb->dev;
                skb->dev = dev->master;
        }
@@ -1570,7 +1582,9 @@
        if (!skb->stamp.tv_sec)
                net_timestamp(&skb->stamp);
 
-       skb_bond(skb);
+       if( skb_bond(skb) == NET_RX_DROP ){
+                goto out;
+        }
 
        __get_cpu_var(netdev_rx_stat).total++;
 
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to