aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/iseries_veth.c
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-08-31 21:29:02 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-31 22:37:57 -0400
commit2a5391a12297d1759b1c736634acb95793d43fb3 (patch)
tree1ada6ec6cd236f98371c32fc02c30c97546f84d9 /drivers/net/iseries_veth.c
parent58c5900bdaffbf76afd7ad5e053410cb95eb3169 (diff)
[PATCH] iseries_veth: Fix broken promiscuous handling
Due to a logic bug, once promiscuous mode is enabled in the iseries_veth driver it is never disabled. The driver keeps two flags, promiscuous and all_mcast which have exactly the same effect. This is because we only ever receive packets destined for us, or multicast packets. So consolidate them into one promiscuous flag for simplicity. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r--drivers/net/iseries_veth.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index db83b0d31327..74ee937c4606 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -159,7 +159,6 @@ struct veth_port {
159 159
160 rwlock_t mcast_gate; 160 rwlock_t mcast_gate;
161 int promiscuous; 161 int promiscuous;
162 int all_mcast;
163 int num_mcast; 162 int num_mcast;
164 u64 mcast_addr[VETH_MAX_MCAST]; 163 u64 mcast_addr[VETH_MAX_MCAST];
165}; 164};
@@ -756,17 +755,15 @@ static void veth_set_multicast_list(struct net_device *dev)
756 755
757 write_lock_irqsave(&port->mcast_gate, flags); 756 write_lock_irqsave(&port->mcast_gate, flags);
758 757
759 if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ 758 if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
760 printk(KERN_INFO "%s: Promiscuous mode enabled.\n", 759 (dev->mc_count > VETH_MAX_MCAST)) {
761 dev->name);
762 port->promiscuous = 1; 760 port->promiscuous = 1;
763 } else if ( (dev->flags & IFF_ALLMULTI)
764 || (dev->mc_count > VETH_MAX_MCAST) ) {
765 port->all_mcast = 1;
766 } else { 761 } else {
767 struct dev_mc_list *dmi = dev->mc_list; 762 struct dev_mc_list *dmi = dev->mc_list;
768 int i; 763 int i;
769 764
765 port->promiscuous = 0;
766
770 /* Update table */ 767 /* Update table */
771 port->num_mcast = 0; 768 port->num_mcast = 0;
772 769
@@ -1145,12 +1142,9 @@ static inline int veth_frame_wanted(struct veth_port *port, u64 mac_addr)
1145 if ( (mac_addr == port->mac_addr) || (mac_addr == 0xffffffffffff0000) ) 1142 if ( (mac_addr == port->mac_addr) || (mac_addr == 0xffffffffffff0000) )
1146 return 1; 1143 return 1;
1147 1144
1148 if (! (((char *) &mac_addr)[0] & 0x01))
1149 return 0;
1150
1151 read_lock_irqsave(&port->mcast_gate, flags); 1145 read_lock_irqsave(&port->mcast_gate, flags);
1152 1146
1153 if (port->promiscuous || port->all_mcast) { 1147 if (port->promiscuous) {
1154 wanted = 1; 1148 wanted = 1;
1155 goto out; 1149 goto out;
1156 } 1150 }