* [PATCH] Fix IXP4xx Ethernet RX with both IFF_ALLMULTI and IFF_PROMISC.
@ 2015-03-09 22:07 Krzysztof Halasa
2015-03-10 17:32 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Krzysztof Halasa @ 2015-03-09 22:07 UTC (permalink / raw)
To: netdev
This long standing bug caused IFF_PROMISC to be ignored when
IFF_ALLMULTI was requested.
Also, without any multicast address configured, the driver will use
device MAC address for the multicast filter, instead of accepting all
inbound traffic.
Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -933,40 +933,42 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
static void eth_set_mcast_list(struct net_device *dev)
{
struct port *port = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- u8 diffs[ETH_ALEN], *addr;
int i;
static const u8 allmulti[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
- if (dev->flags & IFF_ALLMULTI) {
- for (i = 0; i < ETH_ALEN; i++) {
- __raw_writel(allmulti[i], &port->regs->mcast_addr[i]);
- __raw_writel(allmulti[i], &port->regs->mcast_mask[i]);
- }
- __raw_writel(DEFAULT_RX_CNTRL0 | RX_CNTRL0_ADDR_FLTR_EN,
- &port->regs->rx_control[0]);
- return;
- }
-
- if ((dev->flags & IFF_PROMISC) || netdev_mc_empty(dev)) {
+ if (dev->flags & IFF_PROMISC) {
__raw_writel(DEFAULT_RX_CNTRL0 & ~RX_CNTRL0_ADDR_FLTR_EN,
&port->regs->rx_control[0]);
return;
}
- memset(diffs, 0, ETH_ALEN);
+ if (dev->flags & IFF_ALLMULTI) {
+ for (i = 0; i < ETH_ALEN; i++) {
+ __raw_writel(allmulti[i], &port->regs->mcast_addr[i]);
+ __raw_writel(allmulti[i], &port->regs->mcast_mask[i]);
+ }
+ } else {
+ struct netdev_hw_addr *ha;
+ u8 diffs[ETH_ALEN], *addr = NULL;
+
+ memset(diffs, 0, ETH_ALEN);
+
+ /* calculate bits which differ between multicast addresses */
+ netdev_for_each_mc_addr(ha, dev) {
+ if (!addr)
+ addr = ha->addr; /* first multicast address */
+ else
+ for (i = 0; i < ETH_ALEN; i++)
+ diffs[i] |= addr[i] ^ ha->addr[i];
+ }
- addr = NULL;
- netdev_for_each_mc_addr(ha, dev) {
- if (!addr)
- addr = ha->addr; /* first MAC address */
- for (i = 0; i < ETH_ALEN; i++)
- diffs[i] |= addr[i] ^ ha->addr[i];
- }
+ if (!addr) /* use device MAC address instead */
+ addr = dev->dev_addr;
- for (i = 0; i < ETH_ALEN; i++) {
- __raw_writel(addr[i], &port->regs->mcast_addr[i]);
- __raw_writel(~diffs[i], &port->regs->mcast_mask[i]);
+ for (i = 0; i < ETH_ALEN; i++) {
+ __raw_writel(addr[i], &port->regs->mcast_addr[i]);
+ __raw_writel(~diffs[i], &port->regs->mcast_mask[i]);
+ }
}
__raw_writel(DEFAULT_RX_CNTRL0 | RX_CNTRL0_ADDR_FLTR_EN,
--
Krzysztof Halasa
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix IXP4xx Ethernet RX with both IFF_ALLMULTI and IFF_PROMISC.
2015-03-09 22:07 [PATCH] Fix IXP4xx Ethernet RX with both IFF_ALLMULTI and IFF_PROMISC Krzysztof Halasa
@ 2015-03-10 17:32 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2015-03-10 17:32 UTC (permalink / raw)
To: khc; +Cc: netdev
From: Krzysztof Halasa <khc@pm.waw.pl>
Date: Mon, 09 Mar 2015 23:07:28 +0100
> This long standing bug caused IFF_PROMISC to be ignored when
> IFF_ALLMULTI was requested.
>
> Also, without any multicast address configured, the driver will use
> device MAC address for the multicast filter, instead of accepting all
> inbound traffic.
>
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
One big consequence of not basing your patches on the correct tree, is
that you don't even notice when the bug you are fixing is already
fixed (whether partially or fully).
Please see:
commit f81edc6ac1e1e2e2cbe98bcd6ef5ebb7afb00807
Author: Derrick Pallas <pallas@meraki.com>
Date: Wed Feb 18 00:50:25 2015 -0800
ethernet/ixp4xx: prevent allmulti from clobbering promisc
If both promisc and allmulti are set, promisc should trump allmulti and
disable the MAC filter; otherwise, the interface is not really promisc.
Previously, this code checked IFF_ALLMULTI prior to and without regard for
IFF_PROMISC; if both were set, only multicast and direct unicast traffic
would make it through the filter.
Signed-off-by: Derrick Pallas <pallas@meraki.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index f7e0f0f..9e16a28 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -938,7 +938,7 @@ static void eth_set_mcast_list(struct net_device *dev)
int i;
static const u8 allmulti[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
- if (dev->flags & IFF_ALLMULTI) {
+ if ((dev->flags & IFF_ALLMULTI) && !(dev->flags & IFF_PROMISC)) {
for (i = 0; i < ETH_ALEN; i++) {
__raw_writel(allmulti[i], &port->regs->mcast_addr[i]);
__raw_writel(allmulti[i], &port->regs->mcast_mask[i]);
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-03-10 17:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-09 22:07 [PATCH] Fix IXP4xx Ethernet RX with both IFF_ALLMULTI and IFF_PROMISC Krzysztof Halasa
2015-03-10 17:32 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).