Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: David Miller @ 2007-11-12 22:33 UTC (permalink / raw)
  To: kaber
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81
In-Reply-To: <47388B9F.7050308@trash.net>

From: Patrick McHardy <kaber@trash.net>
Date: Mon, 12 Nov 2007 18:21:35 +0100

> Do you really consider that a realistic choice? Who is going to
> remove interfaces that are in use just to see traffic for other
> VLANs? Sniffing specific VLANs can always be done on the VLAN
> device itself.

Change the example to wanting to see traffic on another
physical switch.

How is this any different?

> IMO its more a question of what we want promiscous mode to mean,
> and I tend to agree with Joonwoo that it should receive all packets.

On what LAN?

When you select VLAN, you by definition are asking for non-VLAN
traffic to be elided.  It is like plugging the ethernet cable
into one switch or another.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Chris Friesen @ 2007-11-12 22:43 UTC (permalink / raw)
  To: David Miller
  Cc: kaber, auke-jan.h.kok, joonwpark81, netdev, djohnson+linux-kernel,
	linux-kernel, e1000-devel
In-Reply-To: <20071112.143342.10809862.davem@davemloft.net>

David Miller wrote:

> When you select VLAN, you by definition are asking for non-VLAN
> traffic to be elided.  It is like plugging the ethernet cable
> into one switch or another.

For max functionality it seems like the raw eth device should show 
everything on the wire in promiscuous mode.

If we want to sniff only the traffic for a specific vlan, we can sniff 
the vlan device.

Chris

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Kok, Auke @ 2007-11-12 22:54 UTC (permalink / raw)
  To: Chris Friesen
  Cc: e1000-devel, netdev, djohnson+linux-kernel, linux-kernel,
	joonwpark81, kaber, David Miller
In-Reply-To: <4738D70C.4060404@nortel.com>

Chris Friesen wrote:
> David Miller wrote:
> 
>> When you select VLAN, you by definition are asking for non-VLAN
>> traffic to be elided.  It is like plugging the ethernet cable
>> into one switch or another.
> 
> For max functionality it seems like the raw eth device should show
> everything on the wire in promiscuous mode.
> 
> If we want to sniff only the traffic for a specific vlan, we can sniff
> the vlan device.

actually the impact can be quite negative, imagine doing a tcpdump on a 10gig
interface with vlan's enabled - all of a sudden you might accidentally flood the
system with a 100-fold increase in traffic and force the stack to dump all those
packets for you.

I'm still very reluctant about this patch, I think the current situation is OK for
everyone and offers everyone the possibility to do what they need, without hidden
consequences.

Auke

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: David Miller @ 2007-11-12 22:57 UTC (permalink / raw)
  To: cfriesen
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81, kaber
In-Reply-To: <4738D70C.4060404@nortel.com>

From: "Chris Friesen" <cfriesen@nortel.com>
Date: Mon, 12 Nov 2007 16:43:24 -0600

> David Miller wrote:
> 
> > When you select VLAN, you by definition are asking for non-VLAN
> > traffic to be elided.  It is like plugging the ethernet cable
> > into one switch or another.
> 
> For max functionality it seems like the raw eth device should show 
> everything on the wire in promiscuous mode.
> 
> If we want to sniff only the traffic for a specific vlan, we can sniff 
> the vlan device.

VLAN settings are a filter of sorts, much like plugging into
one switch or another filters traffic physically.

If you don't want that filter, turn the VLAN settings off.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: [RFC][BNX2X] .h files rewrite
From: Ram Pai @ 2007-11-12 23:13 UTC (permalink / raw)
  To: Eliezer Tamir; +Cc: Max Asbock, davem, Michael Chan, jeff, netdev
In-Reply-To: <1194162468.4836.186.camel@eliezer>



On Sun, 2007-11-04 at 09:47 +0200, Eliezer Tamir wrote:
> On Fri, 2007-11-02 at 16:35 -0700, Max Asbock wrote:
> 
> > I built the newest bnx2x code against the net-2.6 kernel and ran a
> > number of stress tests with netperf and pktgen. I did not encounter
> > any
> > errors.
> > 
> > Max
> > 
> > 
> Thanks,

Dave/Jeff,
	
        What is the current outlook for this driver? 
	Is it ready for upstream?

thanks,
RP


> Eliezer
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* Re: [RFC][BNX2X] .h files rewrite
From: David Miller @ 2007-11-12 23:13 UTC (permalink / raw)
  To: linuxram; +Cc: eliezert, masbock, mchan, jeff, netdev
In-Reply-To: <1194909203.8981.28.camel@ram.us.ibm.com>

From: Ram Pai <linuxram@us.ibm.com>
Date: Mon, 12 Nov 2007 15:13:23 -0800

> 
> 
> On Sun, 2007-11-04 at 09:47 +0200, Eliezer Tamir wrote:
> > On Fri, 2007-11-02 at 16:35 -0700, Max Asbock wrote:
> > 
> > > I built the newest bnx2x code against the net-2.6 kernel and ran a
> > > number of stress tests with netperf and pktgen. I did not encounter
> > > any
> > > errors.
> > > 
> > > Max
> > > 
> > > 
> > Thanks,
> 
> Dave/Jeff,
> 	
>         What is the current outlook for this driver? 
> 	Is it ready for upstream?

Yes, I intend to add it for 2.6.25

^ permalink raw reply

* [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
From: Templin, Fred L @ 2007-11-12 23:14 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明,
	Vlad Yasevich
In-Reply-To: <39C363776A4E8C4A94691D2BD9D1C9A1029EDC22@XCH-NW-7V2.nw.nos.boeing.com>


From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility.

The following diffs are specific to the Linux 2.6.24-rc2 kernel
distribution. This message includes the full and patchable diff text;
please use this version to apply patches.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 14:29:51.000000000 -0800
@@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 14:32:43.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,20 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+
+	return 0;
+}
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1449,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,8 +1487,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2217,29 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+	/* ISATAP (RFC4214) - NBMA link */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		addrconf_add_lroute(dev);
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+			struct inet6_ifaddr *ifp;
+
+			ifp = ipv6_add_addr(idev, &addr, 64,
+					IFA_LINK, IFA_F_PERMANENT);
+			if (!IS_ERR(ifp)) {
+				addrconf_prefix_route(&ifp->addr,
+					ifp->prefix_len, idev->dev, 0, 0);
+				addrconf_dad_start(ifp, 0);
+				in6_ifa_put(ifp);
+			}
+		}
+		return;
+	}
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
 		goto out;
 	}
 
@@ -2545,10 +2596,28 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+			}
+		}
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2663,7 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+	    dev->priv_flags&IFF_ISATAP ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,7 +2760,16 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		/*
 		 *	If a host as already performed a random delay
--- linux-2.6.24-rc2/net/ipv6/sit.c.orig	2007-11-08 12:03:41.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/sit.c	2007-11-12 14:30:52.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -382,6 +385,47 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		/* ISATAP (RFC4214) - check source address */
+		if (tunnel->dev->priv_flags & IFF_ISATAP) {
+			struct neighbour *neigh;
+			struct dst_entry *dst;
+			struct flowi fl;
+			struct in6_addr *addr6;
+			struct ipv6hdr *iph6;
+
+			/* from ISATAP router */
+			if ((tunnel->parms.i_key != INADDR_NONE) &&
+			    (iph->saddr == tunnel->parms.i_key)) goto accept;
+
+			iph6 = ipv6_hdr(skb);
+			addr6 = &iph6->saddr;
+
+			/* from legitimate previous hop */
+			memset(&fl, 0, sizeof(fl));
+			fl.proto = iph6->nexthdr;
+			ipv6_addr_copy(&fl.fl6_dst, addr6);
+			fl.oif = tunnel->dev->ifindex;
+			security_skb_classify_flow(skb, &fl);
+
+			if (!(dst = ip6_route_output(NULL, &fl)) ||
+			     (dst->dev != tunnel->dev) ||
+			     ((neigh = dst->neighbour) == NULL)) goto drop;
+
+			addr6 = (struct in6_addr*)&neigh->primary_key;
+
+			if (!(ipv6_addr_is_isatap(addr6)) ||
+			     (addr6->s6_addr32[3] != iph->saddr)) {
+drop:
+				tunnel->stat.rx_errors++;
+				read_unlock(&ipip6_lock);
+				dst_release(dst);
+				kfree_skb(skb);
+				return 0;
+		    	}
+			dst_release(dst);
+		}
+accept:
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +488,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* ISATAP (RFC4214) - must come before 6to4 */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct neighbour *neigh = NULL;
+
+		if (skb->dst)
+			neigh = skb->dst->neighbour;
+
+		if (neigh == NULL) {
+			if (net_ratelimit())
+		    		printk(KERN_DEBUG "sit: nexthop == NULL\n");
+			goto tx_error;
+	    	}
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+		addr_type = ipv6_addr_type(addr6);
+
+		if ((addr_type & IPV6_ADDR_UNICAST) &&
+		     ipv6_addr_is_isatap(addr6))
+			dst = addr6->s6_addr32[3];
+		else
+			goto tx_error;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +718,8 @@ ipip6_tunnel_ioctl (struct net_device *d
 				ipip6_tunnel_unlink(t);
 				t->parms.iph.saddr = p.iph.saddr;
 				t->parms.iph.daddr = p.iph.daddr;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +732,8 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Willy Tarreau @ 2007-11-12 23:15 UTC (permalink / raw)
  To: David Miller
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81, cfriesen, kaber
In-Reply-To: <20071112.145716.06352378.davem@davemloft.net>

On Mon, Nov 12, 2007 at 02:57:16PM -0800, David Miller wrote:
> From: "Chris Friesen" <cfriesen@nortel.com>
> Date: Mon, 12 Nov 2007 16:43:24 -0600
> 
> > David Miller wrote:
> > 
> > > When you select VLAN, you by definition are asking for non-VLAN
> > > traffic to be elided.  It is like plugging the ethernet cable
> > > into one switch or another.
> > 
> > For max functionality it seems like the raw eth device should show 
> > everything on the wire in promiscuous mode.
> > 
> > If we want to sniff only the traffic for a specific vlan, we can sniff 
> > the vlan device.
> 
> VLAN settings are a filter of sorts, much like plugging into
> one switch or another filters traffic physically.
> 
> If you don't want that filter, turn the VLAN settings off.

I don't really agree with that view. Having spent a lot of time with
tcpdump on production systems, I can say that sometimes you'd like to
be aware that one of your VLANs is wrong and you'd simply like to
sniff the wire to guess the correct tag. And on production, you simply
cannot remove other VLANs, otherwise you disrupt the service.

Basically, what generally happens is that the guy responsible for the
switch tells you "it's OK now", but for you it isn't and you cannot
access the switch.

If the solution is to disable VLAN hardware acceleration, I agree that
it is very risky to do that without the user being aware of it. But at
least we should be able to do this by any means (eg: ethtool) without
disabling what's running.

And since you made the parallel with a switch, when you receive tagged
traffic on a switch port, you generally can mirror that port to another
one and catch all VLANs at once. A new feature that is starting to appear
is the ability to mirror tagged traffic to a VLAN on another port (which
means you get a double 802.1q tag). This is useful for inter-site links
between data-centers for instance.

Regards,
Willy


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (v2.0)
From: Templin, Fred L @ 2007-11-12 23:17 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明
In-Reply-To: <39C363776A4E8C4A94691D2BD9D1C9A1029EDC20@XCH-NW-7V2.nw.nos.boeing.com>

From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214.

The following diffs are specific to the iproute2-2.6.23
software distribution. This message includes the full and
patchable diff text; please use this version to apply patches.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- iproute2-2.6.23/ip/iptunnel.c.orig	2007-11-08 16:27:24.000000000 -0800
+++ iproute2-2.6.23/ip/iptunnel.c	2007-11-12 06:53:38.000000000 -0800
@@ -39,7 +39,8 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
 	fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
-	fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+	fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+	fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
 	fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
 	fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
 	fprintf(stderr, "\n");
@@ -55,6 +56,9 @@ static int parse_args(int argc, char **a
 {
 	int count = 0;
 	char medium[IFNAMSIZ];
+	int isatap = 0;
+	unsigned router = 0;
+	unsigned lifetime = 0;
 
 	memset(p, 0, sizeof(*p));
 	memset(&medium, 0, sizeof(medium));
@@ -90,6 +94,13 @@ static int parse_args(int argc, char **a
 					exit(-1);
 				}
 				p->iph.protocol = IPPROTO_IPV6;
+			} else if (strcmp(*argv, "isatap") == 0) {
+				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+					exit(-1);
+				}
+				p->iph.protocol = IPPROTO_IPV6;
+				isatap++;
 			} else {
 				fprintf(stderr,"Cannot guess tunnel mode.\n");
 				exit(-1);
@@ -160,6 +171,18 @@ static int parse_args(int argc, char **a
 			NEXT_ARG();
 			if (strcmp(*argv, "any"))
 				p->iph.saddr = get_addr32(*argv);
+		} else if (strcmp(*argv, "router") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "any"))
+				router = get_addr32(*argv);
+		} else if (strcmp(*argv, "lifetime") == 0) {
+			unsigned uval;
+			NEXT_ARG();
+			if (get_unsigned(&uval, *argv, 0)) {
+				invarg("invalid lifetime\n", *argv);
+				exit(-1);
+			}
+			lifetime = uval;
 		} else if (strcmp(*argv, "dev") == 0) {
 			NEXT_ARG();
 			strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +235,10 @@ static int parse_args(int argc, char **a
 			p->iph.protocol = IPPROTO_IPIP;
 		else if (memcmp(p->name, "sit", 3) == 0)
 			p->iph.protocol = IPPROTO_IPV6;
+		else if (memcmp(p->name, "isatap", 6) == 0) {
+			p->iph.protocol = IPPROTO_IPV6;
+			isatap++;
+		}
 	}
 
 	if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +266,20 @@ static int parse_args(int argc, char **a
 		fprintf(stderr, "Broadcast tunnel requires a source address.\n");
 		return -1;
 	}
+	if (isatap) {
+		if (p->iph.daddr) {
+			fprintf(stderr, "no remote with isatap.\n");
+			return -1;
+		}
+		p->i_key = router ? router : INADDR_NONE;
+		p->o_key = lifetime ? lifetime : 120;	/* RFC4214 default */
+	} else {
+		if (router || lifetime) {
+			fprintf(stderr, "router/lifetime only for isatap.\n");
+			return -1;
+		}
+	}
+
 	return 0;
 }

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: David Miller @ 2007-11-12 23:19 UTC (permalink / raw)
  To: w
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81, cfriesen, kaber
In-Reply-To: <20071112231516.GA15227@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Tue, 13 Nov 2007 00:15:16 +0100

> I can say that sometimes you'd like to be aware that one of your
> VLANs is wrong and you'd simply like to sniff the wire to guess the
> correct tag. And on production, you simply cannot remove other
> VLANs, otherwise you disrupt the service.

If you were plugged into the wrong physical switch, how might
you debug that problem in production? :-)

Really, it's the same issue, just virtualized, as in the name
for the feature, VLAN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* [PATCH] Add support for the RDC R6040 Fast Ethernet controller
From: Florian Fainelli @ 2007-11-12 22:58 UTC (permalink / raw)
  To: netdev, Stephen Hemminger, Jeff Garzik

This patch adds support for the RDC R6040 MAC we can find in the RDC R-321x System-on-chips.

Signed-off-by: Sten Wang <sten.wang@rdc.com.tw>
Signed-off-by: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
Signed-off-by: Florian Fainelli <florian.fainelli@telecomint.eu>
--
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index cb581eb..ab84303 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1645,6 +1645,18 @@ config 8139_OLD_RX_RESET
 	  experience problems, you can enable this option to restore the
 	  old RX-reset behavior.  If unsure, say N.
 
+config R6040
+	tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)"
+	depends on NET_PCI && PCI
+	select CRC32
+	select MII
+	help
+	  This is a driver for the R6040 Fast Ethernet MACs found in the
+	  the RDC R-321x System-on-chips.
+	  
+	  To compile this driver as a module, choose M here: the module
+	  will be called r6040. This is recommended.
+
 config SIS900
 	tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
 	depends on NET_PCI && PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0e5fde4..afc60df 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_TLAN) += tlan.o
 obj-$(CONFIG_EPIC100) += epic100.o
 obj-$(CONFIG_SIS190) += sis190.o
 obj-$(CONFIG_SIS900) += sis900.o
+obj-$(CONFIG_R6040) += r6040.o
 obj-$(CONFIG_YELLOWFIN) += yellowfin.o
 obj-$(CONFIG_ACENIC) += acenic.o
 obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
new file mode 100644
index 0000000..edce5a4
--- /dev/null
+++ b/drivers/net/r6040.c
@@ -0,0 +1,1109 @@
+/*
+ * RDC R6040 Fast Ethernet MAC support
+ *
+ * Copyright (C) 2004 Sten Wang <sten.wang@rdc.com.tw>
+ * Copyright (C) 2007
+ * 	Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
+ *	Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/spinlock.h>
+
+#include <asm/processor.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define DRV_NAME	"r6040"
+#define DRV_VERSION	"0.16"
+#define DRV_RELDATE	"10Nov2007"
+
+/* PHY CHIP Address */
+#define PHY1_ADDR	1	/* For MAC1 */
+#define PHY2_ADDR	2	/* For MAC2 */
+#define PHY_MODE	0x3100	/* PHY CHIP Register 0 */
+#define PHY_CAP		0x01E1	/* PHY CHIP Register 4 */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  	(6000 * HZ / 1000)
+#define TIMER_WUT	(jiffies + HZ * 1)/* timer wakeup time : 1 second */
+
+/* RDC MAC I/O Size */
+#define R6040_IO_SIZE	256
+
+/* MAX RDC MAC */
+#define MAX_MAC		2
+
+/* MAC registers */
+#define MCR0		0x00	/* Control register 0 */
+#define MCR1		0x04	/* Control register 1 */
+#define  MAC_RST	0x0001	/* Reset the MAC */
+#define MBCR		0x08	/* Bus control */
+#define MT_ICR		0x0C	/* TX interrupt control */
+#define MR_ICR		0x10	/* RX interrupt control */
+#define MTPR		0x14	/* TX poll command register */
+#define MR_BSR		0x18	/* RX buffer size */
+#define MR_DCR		0x1A	/* RX descriptor control */
+#define MLSR		0x1C	/* Last status */
+#define MMDIO		0x20	/* MDIO control register */
+#define  MDIO_WRITE	0x4000	/* MDIO write */
+#define  MDIO_READ	0x2000	/* MDIO read */
+#define MMRD		0x24	/* MDIO read data register */
+#define MMWD		0x28	/* MDIO write data register */
+#define MTD_SA0		0x2C	/* TX descriptor start address 0 */
+#define MTD_SA1		0x30	/* TX descriptor start address 1 */
+#define MRD_SA0		0x34	/* RX descriptor start address 0 */
+#define MRD_SA1		0x38	/* RX descriptor start address 1 */
+#define MISR		0x3C	/* Status register */
+#define MIER		0x40	/* INT enable register */
+#define  MSK_INT	0x0000	/* Mask off interrupts */
+#define ME_CISR		0x44	/* Event counter INT status */
+#define ME_CIER		0x48	/* Event counter INT enable  */
+#define MR_CNT		0x50	/* Successfully received packet counter */
+#define ME_CNT0		0x52	/* Event counter 0 */
+#define ME_CNT1		0x54	/* Event counter 1 */
+#define ME_CNT2		0x56	/* Event counter 2 */
+#define ME_CNT3		0x58	/* Event counter 3 */
+#define MT_CNT		0x5A	/* Successfully transmit packet counter */
+#define ME_CNT4		0x5C	/* Event counter 4 */
+#define MP_CNT		0x5E	/* Pause frame counter register */
+#define MAR0		0x60	/* Hash table 0 */
+#define MAR1		0x62	/* Hash table 1 */
+#define MAR2		0x64	/* Hash table 2 */
+#define MAR3		0x66	/* Hash table 3 */
+#define MID_0L		0x68	/* Multicast address MID0 Low */
+#define MID_0M		0x6A	/* Multicast address MID0 Medium */
+#define MID_0H		0x6C	/* Multicast address MID0 High */
+#define MID_1L		0x70	/* MID1 Low */
+#define MID_1M		0x72	/* MID1 Medium */
+#define MID_1H		0x74	/* MID1 High */
+#define MID_2L		0x78	/* MID2 Low */
+#define MID_2M		0x7A	/* MID2 Medium */
+#define MID_2H		0x7C	/* MID2 High */
+#define MID_3L		0x80	/* MID3 Low */
+#define MID_3M		0x82	/* MID3 Medium */
+#define MID_3H		0x84	/* MID3 High */
+#define PHY_CC		0x88	/* PHY status change configuration register */
+#define PHY_ST		0x8A	/* PHY status register */
+#define MAC_SM		0xAC	/* MAC status machine */
+#define MAC_ID		0xBE	/* Identifier register */
+
+#define TX_DCNT		0x80	/* TX descriptor count */
+#define RX_DCNT		0x80	/* RX descriptor count */
+#define MAX_BUF_SIZE	0x600
+#define ALLOC_DESC_SIZE	((TX_DCNT+RX_DCNT) * \
+	sizeof(struct r6040_descriptor) + 0x10)
+#define MBCR_DEFAULT	0x012A	/* MAC Bus Control Register */
+#define MCAST_MAX	4	/* Max number multicast addresses to filter */
+
+/* PHY settings */
+#define ICPLUS_PHY_ID	0x0243
+
+MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
+	"Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>,"
+	"Florian Fainelli <florian@openwrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
+
+#define RX_INT                         0x0001
+#define TX_INT                         0x0010
+#define RX_NO_DESC_INT                 0x0002
+#define INT_MASK                 (RX_INT | TX_INT)
+
+struct r6040_descriptor {
+	u16	status, len;		/* 0-3 */
+	__le32	buf;			/* 4-7 */
+	__le32	ndesc;			/* 8-B */
+	u32	rev1;			/* C-F */
+	char	*vbufp;			/* 10-13 */
+	struct r6040_descriptor *vndescp;	/* 14-17 */
+	struct sk_buff *skb_ptr;	/* 18-1B */
+	u32	rev2;			/* 1C-1F */
+} __attribute__((aligned(32)));
+
+struct r6040_private {
+	spinlock_t lock;		/* driver lock */
+	struct timer_list timer;
+	struct pci_dev *pdev;
+	struct r6040_descriptor *rx_insert_ptr;
+	struct r6040_descriptor *rx_remove_ptr;
+	struct r6040_descriptor *tx_insert_ptr;
+	struct r6040_descriptor *tx_remove_ptr;
+	u16	tx_free_desc, rx_free_desc, phy_addr, phy_mode;
+	u16	mcr0, mcr1;
+	dma_addr_t desc_dma;
+	char	*desc_pool;
+	u16	switch_sig;
+	struct net_device *dev;
+	struct mii_if_info mii_if;
+	struct napi_struct napi;
+	struct net_device_stats stats;
+	u16	napi_rx_running;
+	void __iomem *base;
+};
+
+static char version[] __devinitdata = KERN_INFO DRV_NAME
+	": RDC R6040 NAPI net driver,"
+	"version "DRV_VERSION " (" DRV_RELDATE ")\n";
+
+static int phy_table[] = { PHY1_ADDR, PHY2_ADDR};
+
+/* Read a word data from PHY Chip */
+static int phy_read(void __iomem *ioaddr, int phy_addr, int reg)
+{
+	int limit = 2048;
+	u16 cmd;
+
+	iowrite16(MDIO_READ + reg + (phy_addr << 8), ioaddr + MMDIO);
+	/* Wait for the read bit to be cleared */
+	while (limit--) {
+		cmd = ioread16(ioaddr + MMDIO);
+		if (cmd & MDIO_READ)
+			break;
+	}
+
+	return ioread16(ioaddr + MMRD);
+}
+
+/* Write a word data from PHY Chip */
+static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
+{
+	int limit = 2048;
+	u16 cmd;
+
+	iowrite16(val, ioaddr + MMWD);
+	/* Write the command to the MDIO bus */
+	iowrite16(MDIO_WRITE + reg + (phy_addr << 8), ioaddr + MMDIO);
+	/* Wait for the write bit to be cleared */
+	while (limit--) {
+		cmd = ioread16(ioaddr + MMDIO);
+		if (cmd & MDIO_WRITE)
+			break;
+	}
+}
+
+static int mdio_read(struct net_device *dev, int mii_id, int reg)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	return (phy_read(ioaddr, lp->phy_addr, reg));
+}
+
+static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	phy_write(ioaddr, lp->phy_addr, reg, val);
+}
+
+static void
+r6040_tx_timeout(struct net_device *dev)
+{
+	struct r6040_private *priv = netdev_priv(dev);
+
+	disable_irq(dev->irq);
+	napi_disable(&priv->napi);
+	spin_lock(&priv->lock);
+	dev->stats.tx_errors++;
+	spin_unlock(&priv->lock);
+
+	netif_stop_queue(dev);
+}
+
+/* Allocate skb buffer for rx descriptor */
+static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
+{
+	struct r6040_descriptor *descptr;
+	void __iomem *ioaddr = lp->base;
+
+	descptr = lp->rx_insert_ptr;
+	while (lp->rx_free_desc < RX_DCNT) {
+		descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
+
+		if (!descptr->skb_ptr)
+			break;
+		descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
+			descptr->skb_ptr->tail,
+			MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+		descptr->status = 0x8000;
+		descptr = descptr->vndescp;
+		lp->rx_free_desc++;
+		/* Trigger RX DMA */
+		iowrite16(lp->mcr0 | 0x0002, ioaddr);
+	}
+	lp->rx_insert_ptr = descptr;
+}
+
+
+static struct net_device_stats *r6040_get_stats(struct net_device *dev)
+{
+	struct r6040_private *priv = netdev_priv(dev);
+	void __iomem *ioaddr = priv->base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
+	priv->stats.multicast += ioread8(ioaddr + ME_CNT0);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return &priv->stats;
+}
+
+/* Stop RDC MAC and Free the allocated resource */
+static void r6040_down(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+	int i;
+	int limit = 2048;
+	u16 *adrp;
+	u16 cmd;
+
+	/* Stop MAC */
+	iowrite16(MSK_INT, ioaddr + MIER);	/* Mask Off Interrupt */
+	iowrite16(MAC_RST, ioaddr + MCR1);	/* Reset RDC MAC */
+	while (limit--) {
+		cmd = ioread16(ioaddr + MCR1);
+		if (cmd & 0x1)
+			break;
+	}
+
+	/* Restore MAC Address to MIDx */
+	adrp = (u16 *) dev->dev_addr;
+	iowrite16(adrp[0], ioaddr + MID_0L);
+	iowrite16(adrp[1], ioaddr + MID_0M);
+	iowrite16(adrp[2], ioaddr + MID_0H);
+	free_irq(dev->irq, dev);
+	/* Free RX buffer */
+	for (i = 0; i < RX_DCNT; i++) {
+		if (lp->rx_insert_ptr->skb_ptr) {
+			pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+				MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
+			lp->rx_insert_ptr->skb_ptr = NULL;
+		}
+		lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
+	}
+
+	/* Free TX buffer */
+	for (i = 0; i < TX_DCNT; i++) {
+		if (lp->tx_insert_ptr->skb_ptr) {
+			pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+				MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+			dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
+			lp->rx_insert_ptr->skb_ptr = NULL;
+		}
+		lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
+	}
+
+	/* Free Descriptor memory */
+	pci_free_consistent(lp->pdev, ALLOC_DESC_SIZE,
+		lp->desc_pool, lp->desc_dma);
+}
+
+static int
+r6040_close(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+
+	/* deleted timer */
+	del_timer_sync(&lp->timer);
+
+	spin_lock_irq(&lp->lock);
+	netif_stop_queue(dev);
+	r6040_down(dev);
+	spin_unlock_irq(&lp->lock);
+
+	return 0;
+}
+
+/* Status of PHY CHIP */
+static int phy_mode_chk(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+	int phy_dat;
+
+	/* PHY Link Status Check */
+	phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+	if (!(phy_dat & 0x4))
+		phy_dat = 0x8000;	/* Link Failed, full duplex */
+
+	/* PHY Chip Auto-Negotiation Status */
+	phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+	if (phy_dat & 0x0020) {
+		/* Auto Negotiation Mode */
+		phy_dat = phy_read(ioaddr, lp->phy_addr, 5);
+		phy_dat &= phy_read(ioaddr, lp->phy_addr, 4);
+		if (phy_dat & 0x140)
+			/* Force full duplex */
+			phy_dat = 0x8000;
+		else
+			phy_dat = 0;
+	} else {
+		/* Force Mode */
+		phy_dat = phy_read(ioaddr, lp->phy_addr, 0);
+		if (phy_dat & 0x100)
+			phy_dat = 0x8000;
+		else
+			phy_dat = 0x0000;
+	}
+
+	return phy_dat;
+};
+
+static void r6040_set_carrier(struct mii_if_info *mii)
+{
+	if (phy_mode_chk(mii->dev)) {
+		/* autoneg is off: Link is always assumed to be up */
+		if (!netif_carrier_ok(mii->dev))
+			netif_carrier_on(mii->dev);
+	} else
+		phy_mode_chk(mii->dev);
+}
+
+static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *) &rq->ifr_data;
+	int rc;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+	spin_lock_irq(&lp->lock);
+	rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL);
+	spin_unlock_irq(&lp->lock);
+	r6040_set_carrier(&lp->mii_if);
+	return rc;
+}
+
+static int r6040_rx(struct net_device *dev, int limit)
+{
+	struct r6040_private *priv = netdev_priv(dev);
+	int count;
+	void __iomem *ioaddr = priv->base;
+	u16 err;
+
+	for (count = 0; count < limit; ++count) {
+		struct r6040_descriptor *descptr = priv->rx_remove_ptr;
+		struct sk_buff *skb_ptr;
+
+		/* Disable RX interrupt */
+		iowrite16(ioread16(ioaddr + MIER) & (~RX_INT), ioaddr + MIER);
+		descptr = priv->rx_remove_ptr;
+
+		/* Check for errors */
+		err = ioread16(ioaddr + MLSR);
+		if (err & 0x0400) priv->stats.rx_errors++;
+		/* RX FIFO over-run */
+		if (err & 0x8000) priv->stats.rx_fifo_errors++;
+		/* RX descriptor unavailable */
+		if (err & 0x0080) priv->stats.rx_frame_errors++;
+		/* Received packet with length over buffer lenght */
+		if (err & 0x0020) priv->stats.rx_over_errors++;
+		/* Received packet with too long or short */
+		if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++;
+		/* Received packet with CRC errors */
+		if (err & 0x0004) {
+			spin_lock(&priv->lock);
+			priv->stats.rx_crc_errors++;
+			spin_unlock(&priv->lock);
+		}
+
+		while (priv->rx_free_desc) {
+			/* No RX packet */
+			if (descptr->status & 0x8000)
+				break;
+			skb_ptr = descptr->skb_ptr;
+			if (!skb_ptr) {
+				printk(KERN_ERR "%s: Inconsistent RX"
+					"descriptor chain\n",
+					dev->name);
+				break;
+			}
+			descptr->skb_ptr = NULL;
+			skb_ptr->dev = priv->dev;
+			/* Do not count the CRC */
+			skb_put(skb_ptr, descptr->len - 4);
+			pci_unmap_single(priv->pdev, descptr->buf,
+				MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+			skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
+			/* Send to upper layer */
+			netif_receive_skb(skb_ptr);
+			dev->last_rx = jiffies;
+			priv->dev->stats.rx_packets++;
+			priv->dev->stats.rx_bytes += descptr->len;
+			/* To next descriptor */
+			descptr = descptr->vndescp;
+			priv->rx_free_desc--;
+		}
+		priv->rx_remove_ptr = descptr;
+	}
+	/* Allocate new RX buffer */
+	if (priv->rx_free_desc < RX_DCNT)
+		rx_buf_alloc(priv, priv->dev);
+
+	return count;
+}
+
+static void r6040_tx(struct net_device *dev)
+{
+	struct r6040_private *priv = netdev_priv(dev);
+	struct r6040_descriptor *descptr;
+	void __iomem *ioaddr = priv->base;
+	struct sk_buff *skb_ptr;
+	u16 err;
+
+	spin_lock(&priv->lock);
+	descptr = priv->tx_remove_ptr;
+	while (priv->tx_free_desc < TX_DCNT) {
+		/* Check for errors */
+		err = ioread16(ioaddr + MLSR);
+
+		if (err & 0x0200) priv->stats.rx_fifo_errors++;
+		if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++;
+
+		if (descptr->status & 0x8000)
+			break; /* Not complte */
+		skb_ptr = descptr->skb_ptr;
+		pci_unmap_single(priv->pdev, descptr->buf,
+			skb_ptr->len, PCI_DMA_TODEVICE);
+		/* Free buffer */
+		dev_kfree_skb_irq(skb_ptr);
+		descptr->skb_ptr = NULL;
+		/* To next descriptor */
+		descptr = descptr->vndescp;
+		priv->tx_free_desc++;
+	}
+	priv->tx_remove_ptr = descptr;
+
+	if (priv->tx_free_desc)
+		netif_wake_queue(dev);
+	spin_unlock(&priv->lock);
+}
+
+static int r6040_poll(struct napi_struct *napi, int budget)
+{
+	struct r6040_private *priv =
+		container_of(napi, struct r6040_private, napi);
+	struct net_device *dev = priv->dev;
+	void __iomem *ioaddr = priv->base;
+	int work_done;
+
+	work_done = r6040_rx(dev, budget);
+
+	if (work_done < budget) {
+		netif_rx_complete(dev, napi);
+		/* Enable RX interrupt */
+		iowrite16(ioread16(ioaddr + MIER) | RX_INT, ioaddr + MIER);
+	}
+	return work_done;
+}
+
+/* The RDC interrupt handler. */
+static irqreturn_t r6040_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+	u16 status;
+	int handled = 1;
+
+	/* Mask off RDC MAC interrupt */
+	iowrite16(MSK_INT, ioaddr + MIER);
+	/* Read MISR status and clear */
+	status = ioread16(ioaddr + MISR);
+
+	if (status == 0x0000 || status == 0xffff)
+		return IRQ_NONE;
+
+	/* RX interrupt request */
+	if (status & 0x01) {
+		netif_rx_schedule(dev, &lp->napi);
+		iowrite16(TX_INT, ioaddr + MIER);
+	}
+
+	/* TX interrupt request */
+	if (status & 0x10)
+		r6040_tx(dev);
+
+	return IRQ_RETVAL(handled);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void r6040_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	r6040_interrupt(dev->irq, (void *)dev);
+	enable_irq(dev->irq);
+}
+#endif
+
+
+/* Init RDC MAC */
+static void r6040_up(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	struct r6040_descriptor *descptr;
+	void __iomem *ioaddr = lp->base;
+	int i;
+	__le32 tmp_addr;
+	dma_addr_t desc_dma, start_dma;
+
+	/* Initialize */
+	lp->tx_free_desc = TX_DCNT;
+	lp->rx_free_desc = 0;
+	/* Init descriptor */
+	memset(lp->desc_pool, 0, ALLOC_DESC_SIZE); /* Let all descriptor = 0 */
+	lp->tx_insert_ptr = (struct r6040_descriptor *)lp->desc_pool;
+	lp->tx_remove_ptr = lp->tx_insert_ptr;
+	lp->rx_insert_ptr = (struct r6040_descriptor *)lp->tx_insert_ptr +
+		TX_DCNT;
+	lp->rx_remove_ptr = lp->rx_insert_ptr;
+	/* Init TX descriptor */
+	descptr = lp->tx_insert_ptr;
+	desc_dma = lp->desc_dma;
+	start_dma = desc_dma;
+	for (i = 0; i < TX_DCNT; i++) {
+		descptr->ndesc = cpu_to_le32(desc_dma +
+			sizeof(struct r6040_descriptor));
+		descptr->vndescp = (descptr + 1);
+		descptr = (descptr + 1);
+		desc_dma += sizeof(struct r6040_descriptor);
+	}
+	(descptr - 1)->ndesc = cpu_to_le32(start_dma);
+	(descptr - 1)->vndescp = lp->tx_insert_ptr;
+
+	/* Init RX descriptor */
+	start_dma = desc_dma;
+	descptr = lp->rx_insert_ptr;
+	for (i = 0; i < RX_DCNT; i++) {
+		descptr->ndesc = cpu_to_le32(desc_dma +
+			sizeof(struct r6040_descriptor));
+		descptr->vndescp = (descptr + 1);
+		descptr = (descptr + 1);
+		desc_dma += sizeof(struct r6040_descriptor);
+	}
+	(descptr - 1)->ndesc = cpu_to_le32(start_dma);
+	(descptr - 1)->vndescp = lp->rx_insert_ptr;
+
+	/* Allocate buffer for RX descriptor */
+	rx_buf_alloc(lp, dev);
+
+	/* TX and RX descriptor start Register */
+	tmp_addr = cpu_to_le32((u32)lp->tx_insert_ptr);
+	tmp_addr = virt_to_bus((volatile void *)tmp_addr);
+	/* Lower 16-bits to MTD_SA0 */
+	iowrite16(tmp_addr, ioaddr + MTD_SA0);
+	/* Higher 16-bits to MTD_SA1 */
+	iowrite16((u16)(tmp_addr >> 16), ioaddr + MTD_SA1);
+	tmp_addr = cpu_to_le32((u32)lp->rx_insert_ptr);
+	tmp_addr = virt_to_bus((volatile void *)tmp_addr);
+	iowrite16(tmp_addr, ioaddr + MRD_SA0);
+	iowrite16((u16)(tmp_addr >> 16), ioaddr + MRD_SA1);
+
+	/* Buffer Size Register */
+	iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
+	/* Read the PHY ID */
+	lp->switch_sig = phy_read(ioaddr, 0, 2);
+
+	if (lp->switch_sig  == ICPLUS_PHY_ID) {
+		phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */
+		lp->phy_mode = 0x8000;
+	} else {
+		/* PHY Mode Check */
+		phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP);
+		phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE);
+
+		if (PHY_MODE == 0x3100)
+			lp->phy_mode = phy_mode_chk(dev);
+		else
+			lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
+	}
+	/* MAC Bus Control Register */
+	iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
+
+	/* MAC TX/RX Enable */
+	lp->mcr0 |= lp->phy_mode;
+	iowrite16(lp->mcr0, ioaddr);
+
+	/* set interrupt waiting time and packet numbers */
+	iowrite16(0x0F06, ioaddr + MT_ICR);
+	iowrite16(0x0F06, ioaddr + MR_ICR);
+
+	/* improve performance (by RDC guys) */
+	phy_write(ioaddr, 30, 17, (phy_read(ioaddr, 30, 17) | 0x4000));
+	phy_write(ioaddr, 30, 17, ~((~phy_read(ioaddr, 30, 17)) | 0x2000));
+	phy_write(ioaddr, 0, 19, 0x0000);
+	phy_write(ioaddr, 0, 30, 0x01F0);
+
+	/* Interrupt Mask Register */
+	iowrite16(INT_MASK, ioaddr + MIER);
+}
+
+/*
+  A periodic timer routine
+	Polling PHY Chip Link Status
+*/
+static void r6040_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct r6040_private *lp = netdev_priv(dev->priv);
+	void __iomem *ioaddr = lp->base;
+	u16 phy_mode;
+
+	/* Polling PHY Chip Status */
+	if (PHY_MODE == 0x3100)
+		phy_mode = phy_mode_chk(dev);
+	else
+		phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
+
+	if (phy_mode != lp->phy_mode) {
+		lp->phy_mode = phy_mode;
+		lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode;
+		iowrite16(lp->mcr0, ioaddr);
+		printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr));
+	}
+
+	/* Timer active again */
+	lp->timer.expires = TIMER_WUT;
+	add_timer(&lp->timer);
+}
+
+/* Read/set MAC address routines */
+static void r6040_mac_address(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+	u16 *adrp;
+
+	/* MAC operation register */
+	iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */
+	iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */
+	iowrite16(0, ioaddr + MAC_SM);
+	udelay(5000);
+
+	/* Restore MAC Address */
+	adrp = (u16 *) dev->dev_addr;
+	iowrite16(adrp[0], ioaddr + MID_0L);
+	iowrite16(adrp[1], ioaddr + MID_0M);
+	iowrite16(adrp[2], ioaddr + MID_0H);
+}
+
+static int
+r6040_open(struct net_device *dev)
+{
+	struct r6040_private *lp = dev->priv;
+	int ret;
+
+	/* Request IRQ and Register interrupt handler */
+	ret = request_irq(dev->irq, &r6040_interrupt,
+		IRQF_SHARED, dev->name, dev);
+	if (ret)
+		return ret;
+
+	/* Set MAC address */
+	r6040_mac_address(dev);
+
+	/* Allocate Descriptor memory */
+	lp->desc_pool = pci_alloc_consistent(lp->pdev,
+		ALLOC_DESC_SIZE, &lp->desc_dma);
+	if (!lp->desc_pool)
+		return -ENOMEM;
+
+	r6040_up(dev);
+
+	napi_enable(&lp->napi);
+	netif_start_queue(dev);
+
+	if (lp->switch_sig != ICPLUS_PHY_ID) {
+		/* set and active a timer process */
+		init_timer(&lp->timer);
+		lp->timer.expires = TIMER_WUT;
+		lp->timer.data = (unsigned long)dev;
+		lp->timer.function = &r6040_timer;
+		add_timer(&lp->timer);
+	}
+	return 0;
+}
+
+static int
+r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	struct r6040_descriptor *descptr;
+	void __iomem *ioaddr = lp->base;
+	unsigned long flags;
+	int ret;
+
+	if (!skb)	/* NULL skb directly return */
+		return ret;
+
+	if (skb->len >= MAX_BUF_SIZE) {	/* Packet too long, drop it */
+		dev_kfree_skb(skb);
+		return ret;
+	}
+
+	/* Critical Section */
+	spin_lock_irqsave(&lp->lock, flags);
+
+	/* TX resource check */
+	if (!lp->tx_free_desc) {
+		spin_unlock_irqrestore(&lp->lock, flags);
+		printk(KERN_ERR DRV_NAME ": no tx descriptor\n");
+		ret = 1;
+		return ret;
+	}
+
+	/* Statistic Counter */
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
+	/* Set TX descriptor & Transmit it */
+	lp->tx_free_desc--;
+	descptr = lp->tx_insert_ptr;
+	if (skb->len < MISR)
+		descptr->len = MISR;
+	else
+		descptr->len = skb->len;
+
+	descptr->skb_ptr = skb;
+	descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
+		skb->data, skb->len, PCI_DMA_TODEVICE));
+	descptr->status = 0x8000;
+	/* Trigger the MAC to check the TX descriptor */
+	iowrite16(0x01, ioaddr + MTPR);
+	lp->tx_insert_ptr = descptr->vndescp;
+
+	/* If no tx resource, stop */
+	if (!lp->tx_free_desc)
+		netif_stop_queue(dev);
+
+	dev->trans_start = jiffies;
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return ret;
+}
+
+static void
+r6040_multicast_list(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+	u16 *adrp;
+	u16 reg;
+	unsigned long flags;
+	struct dev_mc_list *dmi = dev->mc_list;
+	int i;
+
+	/* MAC Address */
+	adrp = (u16 *)dev->dev_addr;
+	iowrite16(adrp[0], ioaddr + MID_0L);
+	iowrite16(adrp[1], ioaddr + MID_0M);
+	iowrite16(adrp[2], ioaddr + MID_0H);
+
+	/* Promiscous Mode */
+	spin_lock_irqsave(&lp->lock, flags);
+
+	/* Clear AMCP & PROM bits */
+	reg = ioread16(ioaddr) & ~0x0120;
+	if (dev->flags & IFF_PROMISC) {
+		reg |= 0x0020;
+		lp->mcr0 |= 0x0020;
+	}
+	/* Too many multicast addresses
+	 * accept all traffic */
+	else if ((dev->mc_count > MCAST_MAX)
+		|| (dev->flags & IFF_ALLMULTI))
+		reg |= 0x0020;
+
+	iowrite16(reg, ioaddr);
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	/* Build the hash table */
+	if (dev->mc_count > MCAST_MAX) {
+		u16 hash_table[4];
+		u32 crc;
+
+		for (i = 0; i < 4; i++)
+			hash_table[i] = 0;
+
+		for (i = 0; i < dev->mc_count; i++) {
+			char *addrs = dmi->dmi_addr;
+
+			dmi = dmi->next;
+
+			if (!(*addrs & 1))
+				continue;
+
+			crc = ether_crc_le(6, addrs);
+			crc >>= 26;
+			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
+		}
+		/* Write the index of the hash table */
+		for (i = 0; i < 4; i++)
+			iowrite16(hash_table[i] << 14, ioaddr + MCR1);
+		/* Fill the MAC hash tables with their values */
+		iowrite16(hash_table[0], ioaddr + MAR0);
+		iowrite16(hash_table[1], ioaddr + MAR1);
+		iowrite16(hash_table[2], ioaddr + MAR2);
+		iowrite16(hash_table[3], ioaddr + MAR3);
+	}
+	/* Multicast Address 1~4 case */
+	for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) {
+		adrp = (u16 *)dmi->dmi_addr;
+		iowrite16(adrp[0], ioaddr + MID_1L + 8*i);
+		iowrite16(adrp[1], ioaddr + MID_1M + 8*i);
+		iowrite16(adrp[2], ioaddr + MID_1H + 8*i);
+		dmi = dmi->next;
+	}
+	for (i = dev->mc_count; i < MCAST_MAX; i++) {
+		iowrite16(0xffff, ioaddr + MID_0L + 8*i);
+		iowrite16(0xffff, ioaddr + MID_0M + 8*i);
+		iowrite16(0xffff, ioaddr + MID_0H + 8*i);
+	}
+}
+
+static void netdev_get_drvinfo(struct net_device *dev,
+			struct ethtool_drvinfo *info)
+{
+	struct r6040_private *rp = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->bus_info, pci_name(rp->pdev));
+}
+
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct r6040_private *rp = netdev_priv(dev);
+	int rc;
+
+	spin_lock_irq(&rp->lock);
+	rc = mii_ethtool_gset(&rp->mii_if, cmd);
+	spin_unlock_irq(&rp->mii_if);
+
+	return rc;
+}
+
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct r6040_private *rp = netdev_priv(dev);
+	int rc;
+
+	spin_lock_irq(&rp->lock);
+	rc = mii_ethtool_sset(&rp->mii_if, cmd);
+	spin_unlock_irq(&rp->lock);
+	r6040_set_carrier(&rp->mii_if);
+
+	return rc;
+}
+
+static u32 netdev_get_link(struct net_device *dev)
+{
+	struct r6040_private *rp = netdev_priv(dev);
+
+	return mii_link_ok(&rp->mii_if);
+}
+
+static struct ethtool_ops netdev_ethtool_ops = {
+	.get_drvinfo		= netdev_get_drvinfo,
+	.get_settings		= netdev_get_settings,
+	.set_settings		= netdev_set_settings,
+	.get_link		= netdev_get_link,
+};
+
+
+static int __devinit r6040_init_one(struct pci_dev *pdev,
+					 const struct pci_device_id *ent)
+{
+	struct net_device *dev;
+	struct r6040_private *lp;
+	void __iomem *ioaddr;
+	int err, io_size = R6040_IO_SIZE;
+	static int card_idx = -1;
+	int bar = 0;
+	long pioaddr;
+	u16 *adrp;
+
+	printk(KERN_INFO "%s\n", version);
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+
+	/* this should always be supported */
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+		printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
+				"not supported by the card\n");
+		return -ENODEV;
+	}
+
+	/* IO Size check */
+	if (pci_resource_len(pdev, 0) < io_size) {
+		printk(KERN_ERR "Insufficient PCI resources, aborting\n");
+		return -EIO;
+	}
+
+	pioaddr = pci_resource_start(pdev, 0);	/* IO map base address */
+	pci_set_master(pdev);
+
+	dev = alloc_etherdev(sizeof(struct r6040_private));
+	if (!dev) {
+		printk(KERN_ERR "Failed to allocate etherdev\n");
+		return -ENOMEM;
+	}
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	lp = netdev_priv(dev);
+	lp->pdev = pdev;
+
+	if (pci_request_regions(pdev, DRV_NAME)) {
+		printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
+		err = -ENODEV;
+		goto err_out_disable;
+	}
+
+	ioaddr = pci_iomap(pdev, bar, io_size);
+	if (!ioaddr) {
+		printk(KERN_ERR "ioremap failed for device %s\n",
+			pci_name(pdev));
+		return -EIO;
+	}
+
+	/* Init system & device */
+	dev->base_addr = (unsigned long)ioaddr;
+	lp->base = ioaddr;
+	dev->irq = pdev->irq;
+
+	spin_lock_init(&lp->lock);
+	pci_set_drvdata(pdev, dev);
+
+	/* Set MAC address */
+	card_idx++;
+
+	adrp = (u16 *)dev->dev_addr;
+	adrp[0] = ioread16(ioaddr + MID_0L);
+	adrp[1] = ioread16(ioaddr + MID_0M);
+	adrp[2] = ioread16(ioaddr + MID_0H);
+
+	/* Link new device into r6040_root_dev */
+	lp->pdev = pdev;
+
+	/* Init RDC private data */
+	lp->mcr0 = 0x1002;
+	lp->phy_addr = phy_table[card_idx];
+	lp->switch_sig = 0;
+
+	/* The RDC-specific entries in the device structure. */
+	dev->open = &r6040_open;
+	dev->hard_start_xmit = &r6040_start_xmit;
+	dev->stop = &r6040_close;
+	dev->get_stats = r6040_get_stats;
+	dev->set_multicast_list = &r6040_multicast_list;
+	dev->do_ioctl = &r6040_ioctl;
+	dev->ethtool_ops = &netdev_ethtool_ops;
+	dev->tx_timeout = &r6040_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = r6040_poll_controller;
+#endif
+	netif_napi_add(dev, &lp->napi, r6040_poll, 64);
+	lp->mii_if.dev = dev;
+	lp->mii_if.mdio_read = mdio_read;
+	lp->mii_if.mdio_write = mdio_write;
+	lp->mii_if.phy_id = lp->phy_addr;
+	lp->mii_if.phy_id_mask = 0x1f;
+	lp->mii_if.reg_num_mask = 0x1f;
+
+	/* Register net device. After this dev->name assign */
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR DRV_NAME ": Failed to register net device\n");
+		goto err_out_res;
+	}
+	return 0;
+
+err_out_res:
+	pci_release_regions(pdev);
+err_out_disable:
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+
+	return err;
+}
+
+static void __devexit r6040_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+
+	unregister_netdev(dev);
+	pci_release_regions(pdev);
+	free_netdev(dev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+
+static struct pci_device_id r6040_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6040) },
+	{0 }
+};
+MODULE_DEVICE_TABLE(pci, r6040_pci_tbl);
+
+static struct pci_driver r6040_driver = {
+	.name		= "r6040",
+	.id_table	= r6040_pci_tbl,
+	.probe		= r6040_init_one,
+	.remove		= __devexit_p(r6040_remove_one),
+};
+
+
+static int __init r6040_init(void)
+{
+	return pci_register_driver(&r6040_driver);
+}
+
+
+static void __exit r6040_cleanup(void)
+{
+	pci_unregister_driver(&r6040_driver);
+}
+
+module_init(r6040_init);
+module_exit(r6040_cleanup);

^ permalink raw reply related

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Willy Tarreau @ 2007-11-12 23:32 UTC (permalink / raw)
  To: David Miller
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81, cfriesen, kaber
In-Reply-To: <20071112.151923.77768525.davem@davemloft.net>

On Mon, Nov 12, 2007 at 03:19:23PM -0800, David Miller wrote:
> From: Willy Tarreau <w@1wt.eu>
> Date: Tue, 13 Nov 2007 00:15:16 +0100
> 
> > I can say that sometimes you'd like to be aware that one of your
> > VLANs is wrong and you'd simply like to sniff the wire to guess the
> > correct tag. And on production, you simply cannot remove other
> > VLANs, otherwise you disrupt the service.
> 
> If you were plugged into the wrong physical switch, how might
> you debug that problem in production? :-)

tcpdump on an unfiltered RJ45 tells you a lot of things. Some switches
for instance send keepalive packets (ether proto 9000) with their own
MAC as source+dest, others send CDP packets, etc... I've very rarely
stayed plugged to the wrong switch for too long before discovering it.
But that requires the ability to sniff.

> Really, it's the same issue, just virtualized, as in the name
> for the feature, VLAN.

No, it's not the same, because as soon as you pass through a switch
which is not configured for VLANs, it does not make any distinction,
and the same DMAC is considered on a single port whatever the VLAN.
This is not true with multiple switches. Also, sometimes, being able
to see that your port gets flooded with traffic for a VLAN on which
you're not configured helps you understand why you cannot fill the
port.

I'd like that we can use the hardware correctly without having to
buy TAPs. It reminds me the discussions about TOE. You claim
yourself that TOE is bad in part because you have little if any
control on the bugs on the TCP stack on the chip. This is the same
here. If I know that the chip does not send me what it receives
when configured in promiscuous mode, I can I swear it never received
the missing packet ? There's always a doubt. Maybe sometimes the
filter is buggy, maybe it only passes tags when the remaining bits
are all zero, etc... Promiscuous mode generally means that you're
the closest possible to the wire. We already do not receive pause
frames and sometimes that's annoying. But having no control over
what we want to see is frustrating.

At least, being able to disable the feature at module load time
would be acceptable. Many people who often need to sniff on decent
machines would always keep it disabled.

Regards,
Willy


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* [PATCH] - drivers/net/ppp_* - remove ptr comparisons to 0
From: Joe Perches @ 2007-11-12 23:33 UTC (permalink / raw)
  To: Paul Mackerras, linux-ppp; +Cc: netdev, Jeff Garzik, Andrew Morton

fix sparse warnings "Using plain integer as NULL pointer"

Signed-off-by: Joe Perches <joe@perches.com>

---

 drivers/net/ppp_async.c   |   34 ++++++------
 drivers/net/ppp_generic.c |  126 ++++++++++++++++++++++----------------------
 drivers/net/ppp_synctty.c |   27 +++++-----
 3 files changed, 94 insertions(+), 93 deletions(-)

diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 8d278c8..f023d5b 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -160,7 +160,7 @@ ppp_asynctty_open(struct tty_struct *tty)
 
 	err = -ENOMEM;
 	ap = kzalloc(sizeof(*ap), GFP_KERNEL);
-	if (ap == 0)
+	if (!ap)
 		goto out;
 
 	/* initialize the asyncppp structure */
@@ -215,7 +215,7 @@ ppp_asynctty_close(struct tty_struct *tty)
 	ap = tty->disc_data;
 	tty->disc_data = NULL;
 	write_unlock_irq(&disc_data_lock);
-	if (ap == 0)
+	if (!ap)
 		return;
 
 	/*
@@ -230,10 +230,10 @@ ppp_asynctty_close(struct tty_struct *tty)
 	tasklet_kill(&ap->tsk);
 
 	ppp_unregister_channel(&ap->chan);
-	if (ap->rpkt != 0)
+	if (ap->rpkt)
 		kfree_skb(ap->rpkt);
 	skb_queue_purge(&ap->rqueue);
-	if (ap->tpkt != 0)
+	if (ap->tpkt)
 		kfree_skb(ap->tpkt);
 	kfree(ap);
 }
@@ -285,13 +285,13 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
 	int err, val;
 	int __user *p = (int __user *)arg;
 
-	if (ap == 0)
+	if (!ap)
 		return -ENXIO;
 	err = -EFAULT;
 	switch (cmd) {
 	case PPPIOCGCHAN:
 		err = -ENXIO;
-		if (ap == 0)
+		if (!ap)
 			break;
 		err = -EFAULT;
 		if (put_user(ppp_channel_index(&ap->chan), p))
@@ -301,7 +301,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
 
 	case PPPIOCGUNIT:
 		err = -ENXIO;
-		if (ap == 0)
+		if (!ap)
 			break;
 		err = -EFAULT;
 		if (put_user(ppp_unit_number(&ap->chan), p))
@@ -350,7 +350,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
 	struct asyncppp *ap = ap_get(tty);
 	unsigned long flags;
 
-	if (ap == 0)
+	if (!ap)
 		return;
 	spin_lock_irqsave(&ap->recv_lock, flags);
 	ppp_async_input(ap, buf, cflags, count);
@@ -369,7 +369,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
 	struct asyncppp *ap = ap_get(tty);
 
 	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-	if (ap == 0)
+	if (!ap)
 		return;
 	set_bit(XMIT_WAKEUP, &ap->xmit_flags);
 	tasklet_schedule(&ap->tsk);
@@ -684,7 +684,7 @@ ppp_async_push(struct asyncppp *ap)
 				tty_stuffed = 1;
 			continue;
 		}
-		if (ap->optr >= ap->olim && ap->tpkt != 0) {
+		if (ap->optr >= ap->olim && ap->tpkt) {
 			if (ppp_async_encode(ap)) {
 				/* finished processing ap->tpkt */
 				clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -704,7 +704,7 @@ ppp_async_push(struct asyncppp *ap)
 		clear_bit(XMIT_BUSY, &ap->xmit_flags);
 		/* any more work to do? if not, exit the loop */
 		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-		      || (!tty_stuffed && ap->tpkt != 0)))
+		      || (!tty_stuffed && ap->tpkt)))
 			break;
 		/* more work to do, see if we can do it now */
 		if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
@@ -715,7 +715,7 @@ ppp_async_push(struct asyncppp *ap)
 
 flush:
 	clear_bit(XMIT_BUSY, &ap->xmit_flags);
-	if (ap->tpkt != 0) {
+	if (ap->tpkt) {
 		kfree_skb(ap->tpkt);
 		ap->tpkt = NULL;
 		clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -848,7 +848,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
 		s = 0;
 		for (i = 0; i < count; ++i) {
 			c = buf[i];
-			if (flags != 0 && flags[i] != 0)
+			if (flags && flags[i] != 0)
 				continue;
 			s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0;
 			c = ((c >> 4) ^ c) & 0xf;
@@ -865,7 +865,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
 			n = scan_ordinary(ap, buf, count);
 
 		f = 0;
-		if (flags != 0 && (ap->state & SC_TOSS) == 0) {
+		if (flags && (ap->state & SC_TOSS) == 0) {
 			/* check the flags to see if any char had an error */
 			for (j = 0; j < n; ++j)
 				if ((f = flags[j]) != 0)
@@ -878,9 +878,9 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
 		} else if (n > 0 && (ap->state & SC_TOSS) == 0) {
 			/* stuff the chars in the skb */
 			skb = ap->rpkt;
-			if (skb == 0) {
+			if (!skb) {
 				skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
-				if (skb == 0)
+				if (!skb)
 					goto nomem;
  				ap->rpkt = skb;
  			}
@@ -927,7 +927,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
 		++n;
 
 		buf += n;
-		if (flags != 0)
+		if (flags)
 			flags += n;
 		count -= n;
 	}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 4b49d0e..4f69037 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -367,7 +367,7 @@ static int ppp_release(struct inode *inode, struct file *file)
 	struct ppp_file *pf = file->private_data;
 	struct ppp *ppp;
 
-	if (pf != 0) {
+	if (pf) {
 		file->private_data = NULL;
 		if (pf->kind == INTERFACE) {
 			ppp = PF_TO_PPP(pf);
@@ -398,7 +398,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
 
 	ret = count;
 
-	if (pf == 0)
+	if (!pf)
 		return -ENXIO;
 	add_wait_queue(&pf->rwait, &wait);
 	for (;;) {
@@ -431,7 +431,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&pf->rwait, &wait);
 
-	if (skb == 0)
+	if (!skb)
 		goto out;
 
 	ret = -EOVERFLOW;
@@ -455,11 +455,11 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
 	struct sk_buff *skb;
 	ssize_t ret;
 
-	if (pf == 0)
+	if (!pf)
 		return -ENXIO;
 	ret = -ENOMEM;
 	skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL);
-	if (skb == 0)
+	if (!skb)
 		goto out;
 	skb_reserve(skb, pf->hdrlen);
 	ret = -EFAULT;
@@ -491,11 +491,11 @@ static unsigned int ppp_poll(struct file *file, poll_table *wait)
 	struct ppp_file *pf = file->private_data;
 	unsigned int mask;
 
-	if (pf == 0)
+	if (!pf)
 		return 0;
 	poll_wait(file, &pf->rwait, wait);
 	mask = POLLOUT | POLLWRNORM;
-	if (skb_peek(&pf->rq) != 0)
+	if (skb_peek(&pf->rq))
 		mask |= POLLIN | POLLRDNORM;
 	if (pf->dead)
 		mask |= POLLHUP;
@@ -559,7 +559,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 
-	if (pf == 0)
+	if (!pf)
 		return ppp_unattached_ioctl(pf, file, cmd, arg);
 
 	if (cmd == PPPIOCDETACH) {
@@ -689,13 +689,13 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
 			val &= 0xffff;
 		}
 		vj = slhc_init(val2+1, val+1);
-		if (vj == 0) {
+		if (!vj) {
 			printk(KERN_ERR "PPP: no memory (VJ compressor)\n");
 			err = -ENOMEM;
 			break;
 		}
 		ppp_lock(ppp);
-		if (ppp->vj != 0)
+		if (ppp->vj)
 			slhc_free(ppp->vj);
 		ppp->vj = vj;
 		ppp_unlock(ppp);
@@ -786,7 +786,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
 		if (get_user(unit, p))
 			break;
 		ppp = ppp_create_interface(unit, &err);
-		if (ppp == 0)
+		if (!ppp)
 			break;
 		file->private_data = &ppp->file;
 		ppp->owner = file;
@@ -803,7 +803,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
 		mutex_lock(&all_ppp_mutex);
 		err = -ENXIO;
 		ppp = ppp_find_unit(unit);
-		if (ppp != 0) {
+		if (ppp) {
 			atomic_inc(&ppp->file.refcnt);
 			file->private_data = &ppp->file;
 			err = 0;
@@ -817,7 +817,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
 		spin_lock_bh(&all_channels_lock);
 		err = -ENXIO;
 		chan = ppp_find_channel(unit);
-		if (chan != 0) {
+		if (chan) {
 			atomic_inc(&chan->file.refcnt);
 			file->private_data = &chan->file;
 			err = 0;
@@ -946,9 +946,9 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 	case SIOCGPPPCSTATS:
 		memset(&cstats, 0, sizeof(cstats));
-		if (ppp->xc_state != 0)
+		if (ppp->xc_state)
 			ppp->xcomp->comp_stat(ppp->xc_state, &cstats.c);
-		if (ppp->rc_state != 0)
+		if (ppp->rc_state)
 			ppp->rcomp->decomp_stat(ppp->rc_state, &cstats.d);
 		if (copy_to_user(addr, &cstats, sizeof(cstats)))
 			break;
@@ -993,14 +993,14 @@ ppp_xmit_process(struct ppp *ppp)
 	struct sk_buff *skb;
 
 	ppp_xmit_lock(ppp);
-	if (ppp->dev != 0) {
+	if (ppp->dev) {
 		ppp_push(ppp);
-		while (ppp->xmit_pending == 0
-		       && (skb = skb_dequeue(&ppp->file.xq)) != 0)
+		while (!ppp->xmit_pending
+		       && (skb = skb_dequeue(&ppp->file.xq)))
 			ppp_send_frame(ppp, skb);
 		/* If there's no work left to do, tell the core net
 		   code that we can accept some more. */
-		if (ppp->xmit_pending == 0 && skb_peek(&ppp->file.xq) == 0)
+		if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq))
 			netif_wake_queue(ppp->dev);
 	}
 	ppp_xmit_unlock(ppp);
@@ -1100,12 +1100,12 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
 
 	switch (proto) {
 	case PPP_IP:
-		if (ppp->vj == 0 || (ppp->flags & SC_COMP_TCP) == 0)
+		if (!ppp->vj || (ppp->flags & SC_COMP_TCP) == 0)
 			break;
 		/* try to do VJ TCP header compression */
 		new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2,
 				    GFP_ATOMIC);
-		if (new_skb == 0) {
+		if (!new_skb) {
 			printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n");
 			goto drop;
 		}
@@ -1140,7 +1140,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
 	}
 
 	/* try to do packet compression */
-	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
+	if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state
 	    && proto != PPP_LCP && proto != PPP_CCP) {
 		if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
 			if (net_ratelimit())
@@ -1185,7 +1185,7 @@ ppp_push(struct ppp *ppp)
 	struct channel *pch;
 	struct sk_buff *skb = ppp->xmit_pending;
 
-	if (skb == 0)
+	if (!skb)
 		return;
 
 	list = &ppp->channels;
@@ -1355,7 +1355,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 		if (flen == len && nfree == 0)
 			bits |= E;
 		frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
-		if (frag == 0)
+		if (!frag)
 			goto noskb;
 		q = skb_put(frag, flen + hdrlen);
 
@@ -1425,7 +1425,7 @@ ppp_channel_push(struct channel *pch)
 	struct ppp *ppp;
 
 	spin_lock_bh(&pch->downl);
-	if (pch->chan != 0) {
+	if (pch->chan) {
 		while (!skb_queue_empty(&pch->file.xq)) {
 			skb = skb_dequeue(&pch->file.xq);
 			if (!pch->chan->ops->start_xmit(pch->chan, skb)) {
@@ -1443,7 +1443,7 @@ ppp_channel_push(struct channel *pch)
 	if (skb_queue_empty(&pch->file.xq)) {
 		read_lock_bh(&pch->upl);
 		ppp = pch->ppp;
-		if (ppp != 0)
+		if (ppp)
 			ppp_xmit_process(ppp);
 		read_unlock_bh(&pch->upl);
 	}
@@ -1462,7 +1462,7 @@ ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
 	ppp_recv_lock(ppp);
 	/* ppp->dev == 0 means interface is closing down */
-	if (ppp->dev != 0)
+	if (ppp->dev)
 		ppp_receive_frame(ppp, skb, pch);
 	else
 		kfree_skb(skb);
@@ -1475,19 +1475,19 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
 	struct channel *pch = chan->ppp;
 	int proto;
 
-	if (pch == 0 || skb->len == 0) {
+	if (!pch || skb->len == 0) {
 		kfree_skb(skb);
 		return;
 	}
 
 	proto = PPP_PROTO(skb);
 	read_lock_bh(&pch->upl);
-	if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) {
+	if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
 		/* put it on the channel queue */
 		skb_queue_tail(&pch->file.rq, skb);
 		/* drop old frames if queue too long */
 		while (pch->file.rq.qlen > PPP_MAX_RQLEN
-		       && (skb = skb_dequeue(&pch->file.rq)) != 0)
+		       && (skb = skb_dequeue(&pch->file.rq)))
 			kfree_skb(skb);
 		wake_up_interruptible(&pch->file.rwait);
 	} else {
@@ -1503,13 +1503,13 @@ ppp_input_error(struct ppp_channel *chan, int code)
 	struct channel *pch = chan->ppp;
 	struct sk_buff *skb;
 
-	if (pch == 0)
+	if (!pch)
 		return;
 
 	read_lock_bh(&pch->upl);
-	if (pch->ppp != 0) {
+	if (pch->ppp) {
 		skb = alloc_skb(0, GFP_ATOMIC);
-		if (skb != 0) {
+		if (skb) {
 			skb->len = 0;		/* probably unnecessary */
 			skb->cb[0] = code;
 			ppp_do_recv(pch->ppp, skb, pch);
@@ -1548,7 +1548,7 @@ static void
 ppp_receive_error(struct ppp *ppp)
 {
 	++ppp->stats.rx_errors;
-	if (ppp->vj != 0)
+	if (ppp->vj)
 		slhc_toss(ppp->vj);
 }
 
@@ -1563,7 +1563,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
 	 * Note that some decompressors need to see uncompressed frames
 	 * that come in as well as compressed frames.
 	 */
-	if (ppp->rc_state != 0 && (ppp->rstate & SC_DECOMP_RUN)
+	if (ppp->rc_state && (ppp->rstate & SC_DECOMP_RUN)
 	    && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
 		skb = ppp_decompress_frame(ppp, skb);
 
@@ -1574,13 +1574,13 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
 	switch (proto) {
 	case PPP_VJC_COMP:
 		/* decompress VJ compressed packets */
-		if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
+		if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
 			goto err;
 
 		if (skb_tailroom(skb) < 124 || skb_cloned(skb)) {
 			/* copy to a new sk_buff with more tailroom */
 			ns = dev_alloc_skb(skb->len + 128);
-			if (ns == 0) {
+			if (!ns) {
 				printk(KERN_ERR"PPP: no memory (VJ decomp)\n");
 				goto err;
 			}
@@ -1606,7 +1606,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
 		break;
 
 	case PPP_VJC_UNCOMP:
-		if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
+		if (!ppp->vj || (ppp->flags & SC_REJ_COMP_TCP))
 			goto err;
 
 		/* Until we fix the decompressor need to make sure
@@ -1636,7 +1636,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
 		skb_queue_tail(&ppp->file.rq, skb);
 		/* limit queue length by dropping old frames */
 		while (ppp->file.rq.qlen > PPP_MAX_RQLEN
-		       && (skb = skb_dequeue(&ppp->file.rq)) != 0)
+		       && (skb = skb_dequeue(&ppp->file.rq)))
 			kfree_skb(skb);
 		/* wake up any process polling or blocking on read */
 		wake_up_interruptible(&ppp->file.rwait);
@@ -1718,7 +1718,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb)
 		}
 
 		ns = dev_alloc_skb(obuff_size);
-		if (ns == 0) {
+		if (!ns) {
 			printk(KERN_ERR "ppp_decompress_frame: no memory\n");
 			goto err;
 		}
@@ -1836,7 +1836,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 		ppp->minseq = ppp->mrq.next->sequence;
 
 	/* Pull completed packets off the queue and receive them. */
-	while ((skb = ppp_mp_reconstruct(ppp)) != 0)
+	while ((skb = ppp_mp_reconstruct(ppp)))
 		ppp_receive_nonmp_frame(ppp, skb);
 
 	return;
@@ -2002,7 +2002,7 @@ ppp_register_channel(struct ppp_channel *chan)
 	struct channel *pch;
 
 	pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
-	if (pch == 0)
+	if (!pch)
 		return -ENOMEM;
 	pch->ppp = NULL;
 	pch->chan = chan;
@@ -2030,7 +2030,7 @@ int ppp_channel_index(struct ppp_channel *chan)
 {
 	struct channel *pch = chan->ppp;
 
-	if (pch != 0)
+	if (pch)
 		return pch->file.index;
 	return -1;
 }
@@ -2043,9 +2043,9 @@ int ppp_unit_number(struct ppp_channel *chan)
 	struct channel *pch = chan->ppp;
 	int unit = -1;
 
-	if (pch != 0) {
+	if (pch) {
 		read_lock_bh(&pch->upl);
-		if (pch->ppp != 0)
+		if (pch->ppp)
 			unit = pch->ppp->file.index;
 		read_unlock_bh(&pch->upl);
 	}
@@ -2061,7 +2061,7 @@ ppp_unregister_channel(struct ppp_channel *chan)
 {
 	struct channel *pch = chan->ppp;
 
-	if (pch == 0)
+	if (!pch)
 		return;		/* should never happen */
 	chan->ppp = NULL;
 
@@ -2093,7 +2093,7 @@ ppp_output_wakeup(struct ppp_channel *chan)
 {
 	struct channel *pch = chan->ppp;
 
-	if (pch == 0)
+	if (!pch)
 		return;
 	ppp_channel_push(pch);
 }
@@ -2124,18 +2124,18 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 
 	cp = find_compressor(ccp_option[0]);
 #ifdef CONFIG_KMOD
-	if (cp == 0) {
+	if (!cp) {
 		request_module("ppp-compress-%d", ccp_option[0]);
 		cp = find_compressor(ccp_option[0]);
 	}
 #endif /* CONFIG_KMOD */
-	if (cp == 0)
+	if (!cp)
 		goto out;
 
 	err = -ENOBUFS;
 	if (data.transmit) {
 		state = cp->comp_alloc(ccp_option, data.length);
-		if (state != 0) {
+		if (state) {
 			ppp_xmit_lock(ppp);
 			ppp->xstate &= ~SC_COMP_RUN;
 			ocomp = ppp->xcomp;
@@ -2143,7 +2143,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 			ppp->xcomp = cp;
 			ppp->xc_state = state;
 			ppp_xmit_unlock(ppp);
-			if (ostate != 0) {
+			if (ostate) {
 				ocomp->comp_free(ostate);
 				module_put(ocomp->owner);
 			}
@@ -2153,7 +2153,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 
 	} else {
 		state = cp->decomp_alloc(ccp_option, data.length);
-		if (state != 0) {
+		if (state) {
 			ppp_recv_lock(ppp);
 			ppp->rstate &= ~SC_DECOMP_RUN;
 			ocomp = ppp->rcomp;
@@ -2161,7 +2161,7 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
 			ppp->rcomp = cp;
 			ppp->rc_state = state;
 			ppp_recv_unlock(ppp);
-			if (ostate != 0) {
+			if (ostate) {
 				ocomp->decomp_free(ostate);
 				module_put(ocomp->owner);
 			}
@@ -2228,7 +2228,7 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
 			break;
 		if (inbound) {
 			/* we will start receiving compressed packets */
-			if (ppp->rc_state == 0)
+			if (!ppp->rc_state)
 				break;
 			if (ppp->rcomp->decomp_init(ppp->rc_state, dp, len,
 					ppp->file.index, 0, ppp->mru, ppp->debug)) {
@@ -2237,7 +2237,7 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
 			}
 		} else {
 			/* we will soon start sending compressed packets */
-			if (ppp->xc_state == 0)
+			if (!ppp->xc_state)
 				break;
 			if (ppp->xcomp->comp_init(ppp->xc_state, dp, len,
 					ppp->file.index, 0, ppp->debug))
@@ -2320,11 +2320,11 @@ ppp_register_compressor(struct compressor *cp)
 	int ret;
 	spin_lock(&compressor_list_lock);
 	ret = -EEXIST;
-	if (find_comp_entry(cp->compress_proto) != 0)
+	if (find_comp_entry(cp->compress_proto))
 		goto out;
 	ret = -ENOMEM;
 	ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC);
-	if (ce == 0)
+	if (!ce)
 		goto out;
 	ret = 0;
 	ce->comp = cp;
@@ -2342,7 +2342,7 @@ ppp_unregister_compressor(struct compressor *cp)
 
 	spin_lock(&compressor_list_lock);
 	ce = find_comp_entry(cp->compress_proto);
-	if (ce != 0 && ce->comp == cp) {
+	if (ce && ce->comp == cp) {
 		list_del(&ce->list);
 		kfree(ce);
 	}
@@ -2358,7 +2358,7 @@ find_compressor(int type)
 
 	spin_lock(&compressor_list_lock);
 	ce = find_comp_entry(type);
-	if (ce != 0) {
+	if (ce) {
 		cp = ce->comp;
 		if (!try_module_get(cp->owner))
 			cp = NULL;
@@ -2383,7 +2383,7 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
 	st->p.ppp_opackets = ppp->stats.tx_packets;
 	st->p.ppp_oerrors = ppp->stats.tx_errors;
 	st->p.ppp_obytes = ppp->stats.tx_bytes;
-	if (vj == 0)
+	if (!vj)
 		return;
 	st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed;
 	st->vj.vjs_compressed = vj->sls_o_compressed;
@@ -2604,11 +2604,11 @@ ppp_connect_channel(struct channel *pch, int unit)
 
 	mutex_lock(&all_ppp_mutex);
 	ppp = ppp_find_unit(unit);
-	if (ppp == 0)
+	if (!ppp)
 		goto out;
 	write_lock_bh(&pch->upl);
 	ret = -EINVAL;
-	if (pch->ppp != 0)
+	if (pch->ppp)
 		goto outl;
 
 	ppp_lock(ppp);
@@ -2644,7 +2644,7 @@ ppp_disconnect_channel(struct channel *pch)
 	ppp = pch->ppp;
 	pch->ppp = NULL;
 	write_unlock_bh(&pch->upl);
-	if (ppp != 0) {
+	if (ppp) {
 		/* remove it from the ppp unit's list */
 		ppp_lock(ppp);
 		list_del(&pch->clist);
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 00e2fb4..f0c6a19 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -209,7 +209,7 @@ ppp_sync_open(struct tty_struct *tty)
 
 	ap = kzalloc(sizeof(*ap), GFP_KERNEL);
 	err = -ENOMEM;
-	if (ap == 0)
+	if (!ap)
 		goto out;
 
 	/* initialize the syncppp structure */
@@ -262,7 +262,7 @@ ppp_sync_close(struct tty_struct *tty)
 	ap = tty->disc_data;
 	tty->disc_data = NULL;
 	write_unlock_irq(&disc_data_lock);
-	if (ap == 0)
+	if (!ap)
 		return;
 
 	/*
@@ -278,7 +278,7 @@ ppp_sync_close(struct tty_struct *tty)
 
 	ppp_unregister_channel(&ap->chan);
 	skb_queue_purge(&ap->rqueue);
-	if (ap->tpkt != 0)
+	if (ap->tpkt)
 		kfree_skb(ap->tpkt);
 	kfree(ap);
 }
@@ -325,13 +325,13 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
 	int __user *p = (int __user *)arg;
 	int err, val;
 
-	if (ap == 0)
+	if (!ap)
 		return -ENXIO;
 	err = -EFAULT;
 	switch (cmd) {
 	case PPPIOCGCHAN:
 		err = -ENXIO;
-		if (ap == 0)
+		if (!ap)
 			break;
 		err = -EFAULT;
 		if (put_user(ppp_channel_index(&ap->chan), p))
@@ -341,7 +341,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
 
 	case PPPIOCGUNIT:
 		err = -ENXIO;
-		if (ap == 0)
+		if (!ap)
 			break;
 		err = -EFAULT;
 		if (put_user(ppp_unit_number(&ap->chan), p))
@@ -390,7 +390,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
 	struct syncppp *ap = sp_get(tty);
 	unsigned long flags;
 
-	if (ap == 0)
+	if (!ap)
 		return;
 	spin_lock_irqsave(&ap->recv_lock, flags);
 	ppp_sync_input(ap, buf, cflags, count);
@@ -409,7 +409,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
 	struct syncppp *ap = sp_get(tty);
 
 	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-	if (ap == 0)
+	if (!ap)
 		return;
 	set_bit(XMIT_WAKEUP, &ap->xmit_flags);
 	tasklet_schedule(&ap->tsk);
@@ -651,7 +651,7 @@ ppp_sync_push(struct syncppp *ap)
 	for (;;) {
 		if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))
 			tty_stuffed = 0;
-		if (!tty_stuffed && ap->tpkt != 0) {
+		if (!tty_stuffed && ap->tpkt) {
 			set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 			sent = tty->driver->write(tty, ap->tpkt->data, ap->tpkt->len);
 			if (sent < 0)
@@ -669,7 +669,7 @@ ppp_sync_push(struct syncppp *ap)
 		/* haven't made any progress */
 		spin_unlock_bh(&ap->xmit_lock);
 		if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-		      || (!tty_stuffed && ap->tpkt != 0)))
+		      || (!tty_stuffed && ap->tpkt)))
 			break;
 		if (!spin_trylock_bh(&ap->xmit_lock))
 			break;
@@ -677,7 +677,7 @@ ppp_sync_push(struct syncppp *ap)
 	return done;
 
 flush:
-	if (ap->tpkt != 0) {
+	if (ap->tpkt) {
 		kfree_skb(ap->tpkt);
 		ap->tpkt = NULL;
 		clear_bit(XMIT_FULL, &ap->xmit_flags);
@@ -732,7 +732,8 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
 		ppp_print_buffer ("receive buffer", buf, count);
 
 	/* stuff the chars in the skb */
-	if ((skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2)) == 0) {
+	skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
+	if (!skb) {
 		printk(KERN_ERR "PPPsync: no memory (input pkt)\n");
 		goto err;
 	}
@@ -740,7 +741,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
 	if (buf[0] != PPP_ALLSTATIONS)
 		skb_reserve(skb, 2 + (buf[0] & 1));
 
-	if (flags != 0 && *flags) {
+	if (flags && *flags) {
 		/* error flag set, ignore frame */
 		goto err;
 	} else if (count > skb_tailroom(skb)) {



^ permalink raw reply related

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Kok, Auke @ 2007-11-12 23:38 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: e1000-devel, netdev, djohnson+linux-kernel, linux-kernel,
	joonwpark81, kaber, cfriesen, David Miller
In-Reply-To: <20071112233257.GA15524@1wt.eu>

Willy Tarreau wrote:
> On Mon, Nov 12, 2007 at 03:19:23PM -0800, David Miller wrote:
>> From: Willy Tarreau <w@1wt.eu>
>> Date: Tue, 13 Nov 2007 00:15:16 +0100
>>
>>> I can say that sometimes you'd like to be aware that one of your
>>> VLANs is wrong and you'd simply like to sniff the wire to guess the
>>> correct tag. And on production, you simply cannot remove other
>>> VLANs, otherwise you disrupt the service.
>> If you were plugged into the wrong physical switch, how might
>> you debug that problem in production? :-)
> 
> tcpdump on an unfiltered RJ45 tells you a lot of things. Some switches
> for instance send keepalive packets (ether proto 9000) with their own
> MAC as source+dest, others send CDP packets, etc... I've very rarely
> stayed plugged to the wrong switch for too long before discovering it.
> But that requires the ability to sniff.
> 
>> Really, it's the same issue, just virtualized, as in the name
>> for the feature, VLAN.
> 
> No, it's not the same, because as soon as you pass through a switch
> which is not configured for VLANs, it does not make any distinction,
> and the same DMAC is considered on a single port whatever the VLAN.
> This is not true with multiple switches. Also, sometimes, being able
> to see that your port gets flooded with traffic for a VLAN on which
> you're not configured helps you understand why you cannot fill the
> port.
> 
> I'd like that we can use the hardware correctly without having to
> buy TAPs. It reminds me the discussions about TOE. You claim
> yourself that TOE is bad in part because you have little if any
> control on the bugs on the TCP stack on the chip. This is the same
> here. If I know that the chip does not send me what it receives
> when configured in promiscuous mode, I can I swear it never received
> the missing packet ? There's always a doubt. Maybe sometimes the
> filter is buggy, maybe it only passes tags when the remaining bits
> are all zero, etc... Promiscuous mode generally means that you're
> the closest possible to the wire. We already do not receive pause
> frames and sometimes that's annoying. But having no control over
> what we want to see is frustrating.
> 
> At least, being able to disable the feature at module load time
> would be acceptable. Many people who often need to sniff on decent
> machines would always keep it disabled.

I really do not want to add another module parameter to the driver for this. It
seems bogus as well: if we can agree on one sane choice it's much better, and if
we don't then we should use ethtool to provide a uniform way of implementing this
for all drivers sanely.

Auke

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: David Miller @ 2007-11-12 23:40 UTC (permalink / raw)
  To: w
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, joonwpark81, cfriesen, kaber
In-Reply-To: <20071112233257.GA15524@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Tue, 13 Nov 2007 00:32:57 +0100

> At least, being able to disable the feature at module load time
> would be acceptable. Many people who often need to sniff on decent
> machines would always keep it disabled.

I'm willing to accept the feature, in whatever form, as long
as the performance issue is dealt with properly.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: [Bugme-new] [Bug 9349] New: RTNLGRP_ND_USEROPT does not report ifindex
From: Pierre Ynard @ 2007-11-12 23:44 UTC (permalink / raw)
  To: netdev; +Cc: rdenis
In-Reply-To: <20071111115903.90f0fdc0.akpm@linux-foundation.org>

On Sun, 11 Nov 2007 10:52:41 -0800 (PST) bugme-daemon@bugzilla.kernel.org wrote:
> The RTNLGRP_ND_USEROPT NetLink message introduced in 2.6.24 does not
> seem to include any information as to which netif the user options
> come from. Considering this is meant to carry data that is heavily
> link-layer involved, this seems like a feature bug. Could an ifindex
> field be added there??

Ok, I am seeing to this.

-- 
Pierre Ynard
For hire in Quebec City, Canada, during Fall 2007
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."

^ permalink raw reply

* [PATCH][IPv6] Add ifindex field in ND user option messages
From: Pierre Ynard @ 2007-11-13  0:54 UTC (permalink / raw)
  To: netdev; +Cc: yoshfuji, rdenis

Userland neighbor discovery options are typically heavily involved with
the interface on which thay are received: add a missing ifindex field to
the original struct. Thanks to Rémi Denis-Courmont.

Signed-off-by: Pierre Ynard <linkfanel@yahoo.fr>

diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 5bf6182..4e81836 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -491,9 +491,11 @@ struct nduseroptmsg
 	unsigned char	nduseropt_family;
 	unsigned char	nduseropt_pad1;
 	unsigned short	nduseropt_opts_len;	/* Total length of options */
+	int		nduseropt_ifindex;
 	__u8		nduseropt_icmp_type;
 	__u8		nduseropt_icmp_code;
 	unsigned short	nduseropt_pad2;
+	unsigned int	nduseropt_pad3;
 	/* Followed by one or more ND options */
 };
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 36f7dbf..67997a7 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1037,6 +1037,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
 
 	ndmsg = nlmsg_data(nlh);
 	ndmsg->nduseropt_family = AF_INET6;
+	ndmsg->nduseropt_ifindex = ra->dev->ifindex;
 	ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
 	ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
 	ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;

-- 
Pierre Ynard
For hire in Quebec City, Canada, during Fall 2007
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."

^ permalink raw reply related

* Re: [PATCH][IPv6] Add ifindex field in ND user option messages
From: David Miller @ 2007-11-13  0:56 UTC (permalink / raw)
  To: linkfanel; +Cc: netdev, yoshfuji, rdenis
In-Reply-To: <20071113005413.GA1767@via.ecp.fr>

From: Pierre Ynard <linkfanel@yahoo.fr>
Date: Tue, 13 Nov 2007 01:54:13 +0100

> Userland neighbor discovery options are typically heavily involved with
> the interface on which thay are received: add a missing ifindex field to
> the original struct. Thanks to Rémi Denis-Courmont.
> 
> Signed-off-by: Pierre Ynard <linkfanel@yahoo.fr>

Unfortunately you cannot change the layout of a structure
already exported to userspace, it is part of the ABI.

You'll need to create a new netlink attribute or similar
in order to provide this information.

^ permalink raw reply

* Re: Re : [PATCH][IPv6] Add ifindex field in ND user option messages
From: David Miller @ 2007-11-13  1:13 UTC (permalink / raw)
  To: linkfanel; +Cc: netdev, yoshfuji, rdenis
In-Reply-To: <225828.70511.qm@web25704.mail.ukl.yahoo.com>

From: Pierre Ynard <linkfanel@yahoo.fr>
Date: Tue, 13 Nov 2007 01:08:26 +0000 (GMT)

> > Unfortunately you cannot change the layout of a structure
> > already exported to userspace, it is part of the ABI.
> 
> Well, I thought it would not be a problem, as it is not exactly
> released yet. We are also currently developping the
> corresponding RDNSS daemon and would be totally ready to
> handle this change :)

Was it an interface added to 2.6.24?

^ permalink raw reply

* Re : [PATCH][IPv6] Add ifindex field in ND user option messages
From: Pierre Ynard @ 2007-11-13  1:08 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, yoshfuji, rdenis

> Unfortunately you cannot change the layout of a structure
> already exported to userspace, it is part of the ABI.

Well, I thought it would not be a problem, as it is not exactly
released yet. We are also currently developping the
corresponding RDNSS daemon and would be totally ready to
handle this change :)

-- 
Pierre Ynard





      _____________________________________________________________________________ 
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail 

^ permalink raw reply

* Re : Re : [PATCH][IPv6] Add ifindex field in ND user option messages
From: Pierre Ynard @ 2007-11-13  1:19 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, yoshfuji, rdenis

> > > Unfortunately you cannot change the layout of a structure
> > > already exported to userspace, it is part of the ABI.
> > 
> > Well, I thought it would not be a problem, as it is not exactly
> > released yet. We are also currently developping the
> > corresponding RDNSS daemon and would be totally ready to
> > handle this change :)
> 
> Was it an interface added to 2.6.24?

Yes.

http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=31910575a9de61e78065e93846e8e7a4894a18bf


-- 
Pierre Ynard



      _____________________________________________________________________________ 
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail 

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Joonwoo Park @ 2007-11-13  1:21 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: David Miller, cfriesen, kaber, auke-jan.h.kok, netdev,
	djohnson+linux-kernel, linux-kernel, e1000-devel
In-Reply-To: <20071112231516.GA15227@1wt.eu>

2007/11/13, Willy Tarreau <w@1wt.eu>:
> On Mon, Nov 12, 2007 at 02:57:16PM -0800, David Miller wrote:
> > From: "Chris Friesen" <cfriesen@nortel.com>
> > Date: Mon, 12 Nov 2007 16:43:24 -0600
> >
> > > David Miller wrote:
> > >
> > > > When you select VLAN, you by definition are asking for non-VLAN
> > > > traffic to be elided.  It is like plugging the ethernet cable
> > > > into one switch or another.
> > >
> > > For max functionality it seems like the raw eth device should show
> > > everything on the wire in promiscuous mode.
> > >
> > > If we want to sniff only the traffic for a specific vlan, we can sniff
> > > the vlan device.
> >
> > VLAN settings are a filter of sorts, much like plugging into
> > one switch or another filters traffic physically.
> >
> > If you don't want that filter, turn the VLAN settings off.
>
> I don't really agree with that view. Having spent a lot of time with
> tcpdump on production systems, I can say that sometimes you'd like to
> be aware that one of your VLANs is wrong and you'd simply like to
> sniff the wire to guess the correct tag. And on production, you simply
> cannot remove other VLANs, otherwise you disrupt the service.
>

I agree.
If I had a mis-plugged cable, I can guess it with tcpdump.
Because I cannot see the packets. It means no such packets on the wire 100%.
But if I had a incorrect vlan configuration, it's hard to sure.
In a case both of mis-plugged and mis-configured situation, I cannot
see anything.
Moreover, if I am configuring a machine via vlan interface which is
mis-configured partially, I cannot disable vlan hw acceleration
feature.

Thanks.
Joonwoo

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Joonwoo Park @ 2007-11-13  1:21 UTC (permalink / raw)
  To: David Miller
  Cc: auke-jan.h.kok, e1000-devel, netdev, djohnson+linux-kernel,
	linux-kernel, kaber, cfriesen, w
In-Reply-To: <20071112.154046.117031917.davem@davemloft.net>

2007/11/13, David Miller <davem@davemloft.net>:
> From: Willy Tarreau <w@1wt.eu>
> Date: Tue, 13 Nov 2007 00:32:57 +0100
>
> > At least, being able to disable the feature at module load time
> > would be acceptable. Many people who often need to sniff on decent
> > machines would always keep it disabled.
>
> I'm willing to accept the feature, in whatever form, as long
> as the performance issue is dealt with properly.

I agree with disabling the hw acceleration feature by manually would
be a non-negative solution.
IMO implementation in the ethtool seems better than module param.
As like Auke mentioned.
If you guys confirm it, I'll try it.

Thanks.
Joonwoo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply

* Re: Re : Re : [PATCH][IPv6] Add ifindex field in ND user option messages
From: David Miller @ 2007-11-13  1:52 UTC (permalink / raw)
  To: linkfanel; +Cc: netdev, yoshfuji, rdenis
In-Reply-To: <195892.80996.qm@web25711.mail.ukl.yahoo.com>

From: Pierre Ynard <linkfanel@yahoo.fr>
Date: Tue, 13 Nov 2007 01:19:47 +0000 (GMT)

> > > > Unfortunately you cannot change the layout of a structure
> > > > already exported to userspace, it is part of the ABI.
> > > 
> > > Well, I thought it would not be a problem, as it is not exactly
> > > released yet. We are also currently developping the
> > > corresponding RDNSS daemon and would be totally ready to
> > > handle this change :)
> > 
> > Was it an interface added to 2.6.24?
> 
> Yes.
> 
> http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=31910575a9de61e78065e93846e8e7a4894a18bf

Great, then we can in fact fix it and I will apply your
patch.

Thanks.

^ permalink raw reply

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-13  1:52 UTC (permalink / raw)
  To: ebiederm
  Cc: dlezcano, den, davem, netdev, xemul, containers, benjamin.thery,
	yoshfuji
In-Reply-To: <m16407450i.fsf@ebiederm.dsl.xmission.com>

In article <m16407450i.fsf@ebiederm.dsl.xmission.com> (at Mon, 12 Nov 2007 12:50:53 -0700), ebiederm@xmission.com (Eric W. Biederman) says:

> My opinion is that both your analysis is slightly off (as to the cause
> of your problems) and that your approach to fix your problem is wrong
> because you don't untangle the knot you keep it.
:
> I have register_pernet_subsys and register_per_net_device to ensure
> that when we create a new network namespace all of the subsystems are
> initialized before the network devices are initialize.  So ipv6 should
> be ready before we initialize the new loopback device comes into
> existence.

User may not load ipv6.ko at boot, and then do "modprobe ipv6".
Do you take this into account?

--yoshfuji

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox