Jay Vosburgh wrote:
> Kenzo Iwami <[EMAIL PROTECTED]> wrote:
>
>
>>I think this patch is ready to be applied to the upstream kernel.
>>Do you see any problems in this patch? I'd like to hear your comments.
>
>
> In general, I think the methodology is ok. I haven't tried this
> current version of the patch, so I may have some more questions later if
> it doesn't seem to act quite right. From just reading the patch, I'd
> make some changes, as follows:
Thank you for your comment. I corrected the place that you pointed out,
and I re-created this patch.
This patch fixes the problem that broadcast/multicast packets or
duplicate packets flooded by the switch are received from all slaves.
[...]
>>@@ -1938,6 +1946,8 @@ static int bond_enslave(struct net_devic
>> * is OK, so make this interface the active one
>> */
>> bond_change_active_slave(bond, new_slave);
>>+ } else {
>>+ bond_set_slave_inactive_flags(new_slave);
>
>
> If I'm reading this right, this will set the IFF_SLAVE_INACTIVE
> flag for all of the ALB and TLB slaves (except for the active one),
> which would in turn cause all incoming traffic to be dropped on the
> affected slaves. Does that actually make sense for ALB mode, which
> receives traffic on multiple slaves? Or am I not seeing something here?
In ALB mode, bonding driver only drops Broadcast/Multicast packets
received from inactive slave in skb_bond(), so I think there is no problem.
[...]
> Also, in regards to the ordering of the clauses: Shouldn't the
> "IFF_SLAVE_INACTIVE" test be first, as an inactive active-backup mode
> slave really shouldn't pass Slow frames (or should it?).
Yes, you're right. bonding driver shouldn't receive Slow frames from
inactive slave in active-backup mode. However, bonding driver must not
discard Slow frames in 802.3ad mode. So, I added IFF_MASTER_8023AD flag
to distinguish from the other mode. Therefore, Slow frames is received
from inactive slave only in 802.3ad mode.
--
Kenzo Iwami ([EMAIL PROTECTED])
Signed-off-by: Kenzo Iwami <[EMAIL PROTECTED]>
diff -urpN linux-2.6.15/drivers/net/bonding/bond_main.c
linux-2.6.15_fix/drivers/net/bonding/bond_main.c
--- linux-2.6.15/drivers/net/bonding/bond_main.c 2006-01-06
09:24:25.000000000 +0900
+++ linux-2.6.15_fix/drivers/net/bonding/bond_main.c 2006-01-10
18:20:00.000000000 +0900
@@ -1496,6 +1496,11 @@ static void bond_change_active_slave(str
if ((bond->params.mode == BOND_MODE_TLB) ||
(bond->params.mode == BOND_MODE_ALB)) {
bond_alb_handle_active_change(bond, new_active);
+ if (old_active)
+ bond_set_slave_inactive_flags(old_active);
+
+ if (new_active)
+ bond_set_slave_active_flags(new_active);
} else {
bond->curr_active_slave = new_active;
}
@@ -1890,14 +1895,13 @@ static int bond_enslave(struct net_devic
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
SLAVE_INACTIVE
+ * flag set because we need them to be drop all packets. 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_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
@@ -1938,6 +1942,8 @@ static int bond_enslave(struct net_devic
* is OK, so make this interface the active one
*/
bond_change_active_slave(bond, new_slave);
+ } else {
+ bond_set_slave_inactive_flags(new_slave);
}
break;
default:
@@ -2160,13 +2166,7 @@ static int bond_release(struct net_devic
addr.sa_family = slave_dev->type;
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_SLAVE_INACTIVE;
kfree(slave);
@@ -2251,12 +2251,7 @@ static int bond_release_all(struct net_d
addr.sa_family = slave_dev->type;
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_SLAVE_INACTIVE;
kfree(slave);
@@ -4453,14 +4448,17 @@ static inline void bond_set_mode_ops(str
bond_dev->hard_start_xmit = bond_xmit_broadcast;
break;
case BOND_MODE_8023AD:
+ bond_set_master_3ad_flags(bond);
bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
else
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
break;
- case BOND_MODE_TLB:
case BOND_MODE_ALB:
+ bond_set_master_rlb_flags(bond);
+ /* FALLTHRU */
+ case BOND_MODE_TLB:
bond_dev->hard_start_xmit = bond_alb_xmit;
bond_dev->set_mac_address = bond_alb_set_mac_address;
break;
diff -urpN linux-2.6.15/drivers/net/bonding/bonding.h
linux-2.6.15_fix/drivers/net/bonding/bonding.h
--- linux-2.6.15/drivers/net/bonding/bonding.h 2006-01-06 09:24:25.000000000
+0900
+++ linux-2.6.15_fix/drivers/net/bonding/bonding.h 2006-01-10
18:23:40.000000000 +0900
@@ -243,14 +243,27 @@ extern inline struct bonding *bond_get_b
extern inline void bond_set_slave_inactive_flags(struct slave *slave)
{
- slave->state = BOND_STATE_BACKUP;
- slave->dev->flags |= IFF_NOARP;
+ struct bonding *bond = slave->dev->master->priv;
+ if (bond->params.mode != BOND_MODE_TLB &&
+ bond->params.mode != BOND_MODE_ALB)
+ slave->state = BOND_STATE_BACKUP;
+ slave->dev->priv_flags |= IFF_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_SLAVE_INACTIVE;
+}
+
+extern inline void bond_set_master_3ad_flags(struct bonding *bond)
+{
+ bond->dev->priv_flags |= IFF_MASTER_8023AD;
+}
+
+extern inline void bond_set_master_rlb_flags(struct bonding *bond)
+{
+ bond->dev->priv_flags |= IFF_MASTER_RLB;
}
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry
*curr);
diff -urpN linux-2.6.15/include/linux/if.h linux-2.6.15_fix/include/linux/if.h
--- linux-2.6.15/include/linux/if.h 2006-01-06 09:23:47.000000000 +0900
+++ linux-2.6.15_fix/include/linux/if.h 2006-01-10 18:09:11.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_SLAVE_INACTIVE 0x4 /* Inactive slave of Bonding */
+#define IFF_MASTER_8023AD 0x8 /* Master of Bonding in 802.3ad mode */
+#define IFF_MASTER_RLB 0x10 /* Master of Bonding in balance-alb
mode */
#define IF_GET_IFACE 0x0001 /* for querying only */
#define IF_GET_PROTO 0x0002
diff -urpN linux-2.6.15/include/linux/if_ether.h
linux-2.6.15_fix/include/linux/if_ether.h
--- linux-2.6.15/include/linux/if_ether.h 2006-01-06 09:23:47.000000000
+0900
+++ linux-2.6.15_fix/include/linux/if_ether.h 2006-01-06 11:22:50.000000000
+0900
@@ -61,6 +61,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 -urpN linux-2.6.15/net/core/dev.c linux-2.6.15_fix/net/core/dev.c
--- linux-2.6.15/net/core/dev.c 2006-01-06 09:24:14.000000000 +0900
+++ linux-2.6.15_fix/net/core/dev.c 2006-01-10 18:19:27.000000000 +0900
@@ -1450,8 +1450,25 @@ static inline struct net_device *skb_bon
{
struct net_device *dev = skb->dev;
- if (dev->master)
- skb->dev = dev->master;
+ if (dev->master) {
+ if (dev->master->priv_flags & IFF_MASTER_RLB)
+ if (skb->pkt_type != PACKET_BROADCAST &&
+ skb->pkt_type != PACKET_MULTICAST)
+ goto keep;
+
+ if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
+ /* Slow Protocol frame must no be dropped. */
+ if (dev->master->priv_flags & IFF_MASTER_8023AD &&
+ skb->protocol == __constant_htons(ETH_P_SLOW))
+ goto keep;
+ dev = NULL;
+ kfree_skb(skb);
+ }
+
+keep:
+ if (dev && dev->master)
+ skb->dev = dev->master;
+ }
return dev;
}
@@ -1595,6 +1612,9 @@ int netif_receive_skb(struct sk_buff *sk
orig_dev = skb_bond(skb);
+ if (!orig_dev)
+ return NET_RX_DROP;
+
__get_cpu_var(netdev_rx_stat).total++;
skb->h.raw = skb->nh.raw = skb->data;
-
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