Netdev List
 help / color / mirror / Atom feed
* [PATCH 14/14] Fix memory leak in discard case of sctp_sf_abort_violation()
From: Vlad Yasevich @ 2007-11-12 16:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, lksctp-developers, Jesper Juhl, Vlad Yasevich
In-Reply-To: <11948855091808-git-send-email-vladislav.yasevich@hp.com>

From: Jesper Juhl <jesper.juhl@gmail.com>

In net/sctp/sm_statefuns.c::sctp_sf_abort_violation() we may leak
the storage allocated for 'abort' by returning from the function
without using or freeing it. This happens in case
"sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)" is true and we jump to
the 'discard' label.
Spotted by the Coverity checker.

The simple fix is to simply move the creation of the "abort chunk"
to after the possible jump to the 'discard' label. This way we don't
even have to allocate the memory at all in the problem case.

Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 net/sctp/sm_statefuns.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index a66075a..5ebbe80 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4064,11 +4064,6 @@ static sctp_disposition_t sctp_sf_abort_violation(
 	struct sctp_chunk *chunk =  arg;
 	struct sctp_chunk *abort = NULL;
 
-	/* Make the abort chunk. */
-	abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
-	if (!abort)
-		goto nomem;
-
 	/* SCTP-AUTH, Section 6.3:
 	 *    It should be noted that if the receiver wants to tear
 	 *    down an association in an authenticated way only, the
@@ -4083,6 +4078,11 @@ static sctp_disposition_t sctp_sf_abort_violation(
 	if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
 		goto discard;
 
+	/* Make the abort chunk. */
+	abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
+	if (!abort)
+		goto nomem;
+
 	if (asoc) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
 		SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
-- 
1.5.2.4


^ permalink raw reply related

* [PATCH 12/14] SCTP: Clean-up some defines for regressions tests.
From: Vlad Yasevich @ 2007-11-12 16:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, lksctp-developers, Vlad Yasevich
In-Reply-To: <11948855091808-git-send-email-vladislav.yasevich@hp.com>

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 include/net/sctp/sctp.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 67c997c..34318a3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -65,7 +65,6 @@
 
 
 #ifdef TEST_FRAME
-#undef CONFIG_PROC_FS
 #undef CONFIG_SCTP_DBG_OBJCNT
 #undef CONFIG_SYSCTL
 #endif /* TEST_FRAME */
-- 
1.5.2.4


^ permalink raw reply related

* [PATCH 10/14] SCTP: Make sctp_verify_param return multiple indications.
From: Vlad Yasevich @ 2007-11-12 16:38 UTC (permalink / raw)
  To: davem; +Cc: netdev, lksctp-developers, Vlad Yasevich
In-Reply-To: <11948855091808-git-send-email-vladislav.yasevich@hp.com>

SCTP-AUTH and future ADD-IP updates have a requirement to
do additional verification of parameters and an ability to
ABORT the association if verification fails.  So, introduce
additional return code so that we can clear signal a required
action.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
---
 include/net/sctp/constants.h |    2 +
 net/sctp/sm_make_chunk.c     |  149 +++++++++++++++++++++---------------------
 2 files changed, 77 insertions(+), 74 deletions(-)

diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 73fbdf6..f30b537 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -186,6 +186,8 @@ typedef enum {
 	SCTP_IERROR_AUTH_BAD_HMAC,
 	SCTP_IERROR_AUTH_BAD_KEYID,
 	SCTP_IERROR_PROTO_VIOLATION,
+	SCTP_IERROR_ERROR,
+	SCTP_IERROR_ABORT,
 } sctp_ierror_t;
 
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 43e8de1..5a9783c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1788,9 +1788,14 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
 						sizeof(sctp_paramhdr_t);
 
 
+	/* This is a fatal error.  Any accumulated non-fatal errors are
+	 * not reported.
+	 */
+	if (*errp)
+		sctp_chunk_free(*errp);
+
 	/* Create an error chunk and fill it in with our payload. */
-	if (!*errp)
-		*errp = sctp_make_op_error_space(asoc, chunk, payload_len);
+	*errp = sctp_make_op_error_space(asoc, chunk, payload_len);
 
 	if (*errp) {
 		sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
@@ -1813,9 +1818,15 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
 {
 	__u16 len = ntohs(param.p->length);
 
-	/* Make an ERROR chunk. */
-	if (!*errp)
-		*errp = sctp_make_op_error_space(asoc, chunk, len);
+	/* Processing of the HOST_NAME parameter will generate an
+	 * ABORT.  If we've accumulated any non-fatal errors, they
+	 * would be unrecognized parameters and we should not include
+	 * them in the ABORT.
+	 */
+	if (*errp)
+		sctp_chunk_free(*errp);
+
+	*errp = sctp_make_op_error_space(asoc, chunk, len);
 
 	if (*errp) {
 		sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len);
@@ -1862,56 +1873,40 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
  * taken if the processing endpoint does not recognize the
  * Parameter Type.
  *
- * 00 - Stop processing this SCTP chunk and discard it,
- *	do not process any further chunks within it.
+ * 00 - Stop processing this parameter; do not process any further
+ * 	parameters within this chunk
  *
- * 01 - Stop processing this SCTP chunk and discard it,
- *	do not process any further chunks within it, and report
- *	the unrecognized parameter in an 'Unrecognized
- *	Parameter Type' (in either an ERROR or in the INIT ACK).
+ * 01 - Stop processing this parameter, do not process any further
+ *	parameters within this chunk, and report the unrecognized
+ *	parameter in an 'Unrecognized Parameter' ERROR chunk.
  *
  * 10 - Skip this parameter and continue processing.
  *
  * 11 - Skip this parameter and continue processing but
  *	report the unrecognized parameter in an
- *	'Unrecognized Parameter Type' (in either an ERROR or in
- *	the INIT ACK).
+ *	'Unrecognized Parameter' ERROR chunk.
  *
  * Return value:
- * 	0 - discard the chunk
- * 	1 - continue with the chunk
+ * 	SCTP_IERROR_NO_ERROR - continue with the chunk
+ * 	SCTP_IERROR_ERROR    - stop and report an error.
+ * 	SCTP_IERROR_NOMEME   - out of memory.
  */
-static int sctp_process_unk_param(const struct sctp_association *asoc,
-				  union sctp_params param,
-				  struct sctp_chunk *chunk,
-				  struct sctp_chunk **errp)
+static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
+					    union sctp_params param,
+					    struct sctp_chunk *chunk,
+					    struct sctp_chunk **errp)
 {
-	int retval = 1;
+	int retval = SCTP_IERROR_NO_ERROR;
 
 	switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
 	case SCTP_PARAM_ACTION_DISCARD:
-		retval =  0;
-		break;
-	case SCTP_PARAM_ACTION_DISCARD_ERR:
-		retval =  0;
-		/* Make an ERROR chunk, preparing enough room for
-		 * returning multiple unknown parameters.
-		 */
-		if (NULL == *errp)
-			*errp = sctp_make_op_error_space(asoc, chunk,
-					ntohs(chunk->chunk_hdr->length));
-
-		if (*errp) {
-			sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
-					WORD_ROUND(ntohs(param.p->length)));
-			sctp_addto_chunk(*errp,
-					WORD_ROUND(ntohs(param.p->length)),
-					param.v);
-		}
-
+		retval =  SCTP_IERROR_ERROR;
 		break;
 	case SCTP_PARAM_ACTION_SKIP:
 		break;
+	case SCTP_PARAM_ACTION_DISCARD_ERR:
+		retval =  SCTP_IERROR_ERROR;
+		/* Fall through */
 	case SCTP_PARAM_ACTION_SKIP_ERR:
 		/* Make an ERROR chunk, preparing enough room for
 		 * returning multiple unknown parameters.
@@ -1932,9 +1927,8 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
 			 * to the peer and the association won't be
 			 * established.
 			 */
-			retval = 0;
+			retval = SCTP_IERROR_NOMEM;
 		}
-
 		break;
 	default:
 		break;
@@ -1943,18 +1937,20 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
 	return retval;
 }
 
-/* Find unrecognized parameters in the chunk.
+/* Verify variable length parameters
  * Return values:
- * 	0 - discard the chunk
- * 	1 - continue with the chunk
+ * 	SCTP_IERROR_ABORT - trigger an ABORT
+ * 	SCTP_IERROR_NOMEM - out of memory (abort)
+ *	SCTP_IERROR_ERROR - stop processing, trigger an ERROR
+ * 	SCTP_IERROR_NO_ERROR - continue with the chunk
  */
-static int sctp_verify_param(const struct sctp_association *asoc,
-			     union sctp_params param,
-			     sctp_cid_t cid,
-			     struct sctp_chunk *chunk,
-			     struct sctp_chunk **err_chunk)
+static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
+					union sctp_params param,
+					sctp_cid_t cid,
+					struct sctp_chunk *chunk,
+					struct sctp_chunk **err_chunk)
 {
-	int retval = 1;
+	int retval = SCTP_IERROR_NO_ERROR;
 
 	/* FIXME - This routine is not looking at each parameter per the
 	 * chunk type, i.e., unrecognized parameters should be further
@@ -1976,7 +1972,9 @@ static int sctp_verify_param(const struct sctp_association *asoc,
 
 	case SCTP_PARAM_HOST_NAME_ADDRESS:
 		/* Tell the peer, we won't support this param.  */
-		return sctp_process_hn_param(asoc, param, chunk, err_chunk);
+		sctp_process_hn_param(asoc, param, chunk, err_chunk);
+		retval = SCTP_IERROR_ABORT;
+		break;
 
 	case SCTP_PARAM_FWD_TSN_SUPPORT:
 		if (sctp_prsctp_enable)
@@ -1993,9 +1991,11 @@ static int sctp_verify_param(const struct sctp_association *asoc,
 		 * cause 'Protocol Violation'.
 		 */
 		if (SCTP_AUTH_RANDOM_LENGTH !=
-			ntohs(param.p->length) - sizeof(sctp_paramhdr_t))
-			return sctp_process_inv_paramlength(asoc, param.p,
+			ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) {
+			sctp_process_inv_paramlength(asoc, param.p,
 							chunk, err_chunk);
+			retval = SCTP_IERROR_ABORT;
+		}
 		break;
 
 	case SCTP_PARAM_CHUNKS:
@@ -2007,9 +2007,11 @@ static int sctp_verify_param(const struct sctp_association *asoc,
 		 *  INIT-ACK chunk if the sender wants to receive authenticated
 		 *  chunks.  Its maximum length is 260 bytes.
 		 */
-		if (260 < ntohs(param.p->length))
-			return sctp_process_inv_paramlength(asoc, param.p,
-							chunk, err_chunk);
+		if (260 < ntohs(param.p->length)) {
+			sctp_process_inv_paramlength(asoc, param.p,
+						     chunk, err_chunk);
+			retval = SCTP_IERROR_ABORT;
+		}
 		break;
 
 	case SCTP_PARAM_HMAC_ALGO:
@@ -2020,8 +2022,7 @@ fallthrough:
 	default:
 		SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
 				ntohs(param.p->type), cid);
-		return sctp_process_unk_param(asoc, param, chunk, err_chunk);
-
+		retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
 		break;
 	}
 	return retval;
@@ -2036,6 +2037,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 {
 	union sctp_params param;
 	int has_cookie = 0;
+	int result;
 
 	/* Verify stream values are non-zero. */
 	if ((0 == peer_init->init_hdr.num_outbound_streams) ||
@@ -2043,8 +2045,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	    (0 == peer_init->init_hdr.init_tag) ||
 	    (SCTP_DEFAULT_MINWINDOW > ntohl(peer_init->init_hdr.a_rwnd))) {
 
-		sctp_process_inv_mandatory(asoc, chunk, errp);
-		return 0;
+		return sctp_process_inv_mandatory(asoc, chunk, errp);
 	}
 
 	/* Check for missing mandatory parameters.  */
@@ -2062,29 +2063,29 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	 * VIOLATION error.  We build the ERROR chunk here and let the normal
 	 * error handling code build and send the packet.
 	 */
-	if (param.v != (void*)chunk->chunk_end) {
-		sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
-		return 0;
-	}
+	if (param.v != (void*)chunk->chunk_end)
+		return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
 
 	/* The only missing mandatory param possible today is
 	 * the state cookie for an INIT-ACK chunk.
 	 */
-	if ((SCTP_CID_INIT_ACK == cid) && !has_cookie) {
-		sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
-					   chunk, errp);
-		return 0;
-	}
-
-	/* Find unrecognized parameters. */
+	if ((SCTP_CID_INIT_ACK == cid) && !has_cookie)
+		return sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
+						  chunk, errp);
 
+	/* Verify all the variable length parameters */
 	sctp_walk_params(param, peer_init, init_hdr.params) {
 
-		if (!sctp_verify_param(asoc, param, cid, chunk, errp)) {
-			if (SCTP_PARAM_HOST_NAME_ADDRESS == param.p->type)
+		result = sctp_verify_param(asoc, param, cid, chunk, errp);
+		switch (result) {
+		    case SCTP_IERROR_ABORT:
+		    case SCTP_IERROR_NOMEM:
 				return 0;
-			else
+		    case SCTP_IERROR_ERROR:
 				return 1;
+		    case SCTP_IERROR_NO_ERROR:
+		    default:
+				break;
 		}
 
 	} /* for (loop through all parameters) */
-- 
1.5.2.4


^ permalink raw reply related

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: Eric W. Biederman @ 2007-11-12 16:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: davem, netdev, den, xemul, containers, yoshfuji, Benjamin Thery
In-Reply-To: <20071112152403.273795630@mai.toulouse-stg.fr.ibm.com>

Daniel Lezcano <dlezcano@fr.ibm.com> writes:

> The loopback is now dynamically allocated. The ipv6 code was written
> considering the loopback is allocated before the ipv6 protocol 
> initialization. This is still the case when we don't use multiple
> network namespaces.


You do know that register_netdevice_notifier delivers events 
REGISTER and UP events for devices that are already up?

Thinking about it I wonder if unregister_netdevice_notifier should
actually deliver UNREGISTER events.  It wouldn't change the ipv6
case as I don't believe you can unregister ipv6.

> In the case of the network namespaces, ipv6 notification handler is
> already setup and active (done by the initial network namespace), 
> so when a network namespace is created, a new instance of the 
> loopback device, via dynamic allocation, will trigger a REGISTER event
> to addrconf_notify and this one will try to setup the network device
> while the ipv6 protocol is not yet initialized for the network namespace.

Ok.  This sounds like a race in ipv6 that should get fixed.

I know last time my patchset covered ipv6 I did send patches for several
reference counting problems.  I'm surprised something bad still exists.

Anyway let's not patch around this and fix whatever the real problem.

> Because the ipv6 is relying on the fact that the loopback device will
> not trigger REGISTER/UNREGISTER events, I just protect the addrconf_notify
> function when the loopback register event is triggered.

This can't be the case REGISTER events happen.

> In the case of multiple network namespaces, the usual ipv6 protocol 
> initialization will be done after the loopback initialization with 
> the subsystem registration mechanism.
>
> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
> Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
> ---
>  net/ipv6/addrconf.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> Index: linux-2.6-netns/net/ipv6/addrconf.c
> ===================================================================
> --- linux-2.6-netns.orig/net/ipv6/addrconf.c
> +++ linux-2.6-netns/net/ipv6/addrconf.c
> @@ -2272,7 +2272,8 @@ static int addrconf_notify(struct notifi
>  
>  	switch(event) {
>  	case NETDEV_REGISTER:
> -		if (!idev && dev->mtu >= IPV6_MIN_MTU) {
> +		if (!(dev->flags & IFF_LOOPBACK) &&
> +		    !idev && dev->mtu >= IPV6_MIN_MTU) {
>  			idev = ipv6_add_dev(dev);
>  			if (!idev)
>  				return notifier_from_errno(-ENOMEM);

This hunk is clearly bogus.

> @@ -2366,11 +2367,15 @@ static int addrconf_notify(struct notifi
>  		/* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this
> interface. */
>  
>  	case NETDEV_DOWN:
> +		addrconf_ifdown(dev, 0);
> +		break;
> +
>  	case NETDEV_UNREGISTER:
>  		/*
>  		 *	Remove all addresses from this interface.
>  		 */
> -		addrconf_ifdown(dev, event != NETDEV_DOWN);
> +		if (!(dev->flags & IFF_LOOPBACK))
> +			addrconf_ifdown(dev, 1);

I can see how this could be a problem.
>  		break;
>  
>  	case NETDEV_CHANGENAME:
>
> -- 

^ permalink raw reply

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: Denis V. Lunev @ 2007-11-12 16:49 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: davem, netdev, xemul, ebiederm, containers, yoshfuji,
	Benjamin Thery
In-Reply-To: <47387B31.20805@fr.ibm.com>

>> why should we care on down? we are destroying the device. It should
>> gone. All references to it should also gone. So, we should perform the
>> cleaning and remove all IPv6 addresses, so notifier should also work.
> 
> We need to take care of netdev down, someone can put the loopback down
> if he wants.
> 
>> The code relies on the "persistent" loopback and this is a _bad_ thing.
>> This is longstanding bug in the code, that the dst_entry should have a
>> valid reference to a device. This is the only purpose for a loopback
>> persistence. Though, at the namespace death no such entries must be and
>> this will be checked during unregister process. This patch definitely
>> breaks this assumption :(
>>
>> Namespaces are good to catch leakage using standard codepaths, so they
>> should be preserved as much as possible. So, _all_ normal down code
>> should be called for a loopback device in other than init_net context.
> 
> I agree with you, this is a bug in ipv6 and the loopback; when playing
> with ipv6 we found that the loopback is still referenced 9 times when
> the system is shutdown.

Pff...  I can't guess right now where the error can be :( We have
correct behavior of loopback even for IPv6 within OpenVZ. On down the
count is 0 and device is destroyed correctly without these kludges. So,
something is definitely wrong.

> The purpose of this patch is to protect the __actual__ code from the new
> loopback behavior. We are looking at a more generic approach with the
> namespace for ipv6, as you mentioned, namespaces are good for network
> leakage detection as we create several instances of the network stack.

The only kludge required is already in place. addrconf_ifdown has a
protection for init_net.
        if (dev == init_net.loopback_dev && how == 1)
                how = 0;
Other places should be untouched.

Unregister for a loopback in !init_net is a _valid_ operation and should
be clean, i.e. without kludges in the path. This is the only way to
check the ref-counting.

^ permalink raw reply

* Re: Problem with frame time stamping
From: Eric Dumazet @ 2007-11-12 16:47 UTC (permalink / raw)
  To: Antoine Zen-Ruffinen; +Cc: netdev, linux-net, netfilter-devel, patrik.arlos
In-Reply-To: <2cbbd8de0711120742h35f27441p5f096e5e99e1d7dc@mail.gmail.com>

On Mon, 12 Nov 2007 16:42:34 +0100
"Antoine Zen-Ruffinen" <antoine.zen@gmail.com> wrote:

> Dear all,
> 
> I'm writing a network analyzer software using Linux and I need a VERY
> precise frame time stamping. Therefor I am planing to add my own time
> stamping algorithm on a modified network driver. For test purpose I
> did so :
> 
> 	skb->tstamp.tv64 = 0x00010002;
> 	netif_rx(skb);
> 
> On the user side, I ask for the timestamp that way :
> 
> 	...
> 	sock = socket(AF_PACKET, SOCK_RAW, type);
> 	...
> 	//bind this socket with the interface using my modified driver.
> 	...
> 	recvByteCount = recv(sock, buffer, 1514, 0);
>     	ioctl(sock, SIOCGSTAMP, &timeStamp);
> 
> I was surprised to see that the var timeStamp was still holding a
> count of second since  year 1970.
> 
> Investigating a bit into the kernel code, I found that ioctl(sock,
> SIOCGSTAMP, ...) was giving just the current kernel time using
> ktime_get_real().
> 
> Are my investigation wrong ?
> Is that a bug in kernel code ?
> Is there an other way to access skb.tstamp from user side ?
> 
> Thank's to any one that can help me !

If your kernel is recent enough, you can already get nanosecond precision from skb tstamp, using SIOCGSTAMPNS ioctl or SO_TIMESTAMPNS / SCM_TIMESTAMPNS

(changes where done in March/April this year)

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

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

http://git2.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=92f37fd2ee805aa77925c1e64fd56088b46094fc


No need to modify a network driver :)



^ permalink raw reply

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: Eric W. Biederman @ 2007-11-12 16:51 UTC (permalink / raw)
  To: Denis V. Lunev
  Cc: yoshfuji-VfPWfsRibaP+Ru+s062T9g, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-qjLDD68F18O7TbgM5vRIOg, Benjamin Thery,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, xemul-GEFAQzZX7r8dnm+yROfE0A
In-Reply-To: <473879C3.5020301-3ImXcnM4P+0@public.gmane.org>

"Denis V. Lunev" <den-3ImXcnM4P+0@public.gmane.org> writes:

>> Index: linux-2.6-netns/net/ipv6/addrconf.c
>> ===================================================================
>> --- linux-2.6-netns.orig/net/ipv6/addrconf.c
>> +++ linux-2.6-netns/net/ipv6/addrconf.c
>> @@ -2272,7 +2272,8 @@ static int addrconf_notify(struct notifi
>>  
>>  	switch(event) {
>>  	case NETDEV_REGISTER:
>> -		if (!idev && dev->mtu >= IPV6_MIN_MTU) {
>> +		if (!(dev->flags & IFF_LOOPBACK) &&
>> +		    !idev && dev->mtu >= IPV6_MIN_MTU) {

It is idev being true here for the loopback device that would
prevent things not missing the REGISTER event.

Hmm.  But we do call ipv6_add_dev on loopback and now the loopback
device is practically guaranteed to be the first device so we can
probably just remove the special case in addrconf_init.

Anyway Daniels patch makes increasingly less sense the more I look
at it.


> Namespaces are good to catch leakage using standard codepaths, so they
> should be preserved as much as possible. So, _all_ normal down code
> should be called for a loopback device in other than init_net context.

In any context. After the code path is aware of multiple network namespaces
init_net should not be special in any way.

I completely agree about the ability to catch weird leakage scenarios.

Eric

^ permalink raw reply

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: Eric W. Biederman @ 2007-11-12 16:59 UTC (permalink / raw)
  To: Denis V. Lunev
  Cc: Daniel Lezcano, davem, netdev, xemul, ebiederm, containers,
	yoshfuji, Benjamin Thery
In-Reply-To: <473883FF.5010505@sw.ru>

"Denis V. Lunev" <den@sw.ru> writes:

>>> why should we care on down? we are destroying the device. It should
>>> gone. All references to it should also gone. So, we should perform the
>>> cleaning and remove all IPv6 addresses, so notifier should also work.
>> 
>> We need to take care of netdev down, someone can put the loopback down
>> if he wants.
>> 
>>> The code relies on the "persistent" loopback and this is a _bad_ thing.
>>> This is longstanding bug in the code, that the dst_entry should have a
>>> valid reference to a device. This is the only purpose for a loopback
>>> persistence. Though, at the namespace death no such entries must be and
>>> this will be checked during unregister process. This patch definitely
>>> breaks this assumption :(
>>>
>>> Namespaces are good to catch leakage using standard codepaths, so they
>>> should be preserved as much as possible. So, _all_ normal down code
>>> should be called for a loopback device in other than init_net context.
>> 
>> I agree with you, this is a bug in ipv6 and the loopback; when playing
>> with ipv6 we found that the loopback is still referenced 9 times when
>> the system is shutdown.
>
> Pff...  I can't guess right now where the error can be :( We have
> correct behavior of loopback even for IPv6 within OpenVZ. On down the
> count is 0 and device is destroyed correctly without these kludges. So,
> something is definitely wrong.
>
>> The purpose of this patch is to protect the __actual__ code from the new
>> loopback behavior. We are looking at a more generic approach with the
>> namespace for ipv6, as you mentioned, namespaces are good for network
>> leakage detection as we create several instances of the network stack.
>
> The only kludge required is already in place. addrconf_ifdown has a
> protection for init_net.
>         if (dev == init_net.loopback_dev && how == 1)
>                 how = 0;
> Other places should be untouched.
>
> Unregister for a loopback in !init_net is a _valid_ operation and should
> be clean, i.e. without kludges in the path. This is the only way to
> check the ref-counting.

Oh.  Speaking of.  One way to catch this kind of thing during debugging
is to instrument dev_put and dev_hold to add a print statement.  Something
like:

/**
 *	dev_put - release reference to device
 *	@dev: network device
 *
 * Release reference to device to allow it to be freed.
 */
static inline void __dev_put(struct net_device *dev, char *file, char *func, int line)
{
        if (dev->flags & IFF_LOOPBACK)
        	printk("%s: %s.%s.%d\n", __func__, file, file, line);
	atomic_dec(&dev->refcnt);
}

#define dev_put(DEV) __dev_put(DEV, __FILE__, __func__, __LINE__)

/**
 *	dev_hold - get reference to device
 *	@dev: network device
 *
 * Hold reference to device to keep it from being freed.
 */
static inline void __dev_hold(struct net_device *dev, char *file, char *func, int line)
{
        if (dev->flags & IFF_LOOPBACK)
        	printk("%s: %s.%s.%d\n", __func__, file, file, line);
	atomic_inc(&dev->refcnt);
}

#define dev_hold(DEV) __dev_hold(DEV, __FILE__, __func__, __LINE__)


^ permalink raw reply

* Re: [patch 1/1][NETNS][IPV6] protect addrconf from loopback registration
From: Daniel Lezcano @ 2007-11-12 17:01 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Denis V. Lunev, davem, netdev, xemul, containers, yoshfuji,
	Benjamin Thery
In-Reply-To: <m1ejev4dap.fsf@ebiederm.dsl.xmission.com>

Eric W. Biederman wrote:
> "Denis V. Lunev" <den@sw.ru> writes:
> 
>>> Index: linux-2.6-netns/net/ipv6/addrconf.c
>>> ===================================================================
>>> --- linux-2.6-netns.orig/net/ipv6/addrconf.c
>>> +++ linux-2.6-netns/net/ipv6/addrconf.c
>>> @@ -2272,7 +2272,8 @@ static int addrconf_notify(struct notifi
>>>  
>>>  	switch(event) {
>>>  	case NETDEV_REGISTER:
>>> -		if (!idev && dev->mtu >= IPV6_MIN_MTU) {
>>> +		if (!(dev->flags & IFF_LOOPBACK) &&
>>> +		    !idev && dev->mtu >= IPV6_MIN_MTU) {
> 
> It is idev being true here for the loopback device that would
> prevent things not missing the REGISTER event.
> 
> Hmm.  But we do call ipv6_add_dev on loopback and now the loopback
> device is practically guaranteed to be the first device so we can
> probably just remove the special case in addrconf_init.
> 
> Anyway Daniels patch makes increasingly less sense the more I look
> at it.

Let me try to clarify:

  * when the init network namespace is created, the loopback is created 
first, before ipv6, and the notifier call chain for ipv6 is not setup, 
so the protocol does not receive the REGISTER event

  * when the init network namespace is destroyed during shutdown, the 
loopback is not unregistered, so there is no UNREGISTER event

  * when we create a new network namespace, a new instance of the 
loopback is created and a NETDEV_REGISTER is sent to ipv6 because the 
notifier call chain has been setup by the init netns (while ipv6 
protocol is not yet configured for the namespace which is being created)

  * when the network namespace exits, the loopback is unregistered after 
the ipv6 protocol but the NETDEV_UNREGISTER is sent to addrconf_notify 
while the ipv6 protocol has been destroyed.


The objective of the patch is to discard these events because they were 
never taken into account and they are not expected to be receive by ipv6 
protocol.

^ permalink raw reply

* Re: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Kok, Auke @ 2007-11-12 17:12 UTC (permalink / raw)
  To: Joonwoo Park
  Cc: 'David Miller', netdev, 'Dave Johnson',
	linux-kernel, e1000-devel
In-Reply-To: <47365200.0f10240a.0686.2173@mx.google.com>

Joonwoo Park wrote:
> IMHO even though netdevice is in the promiscuous mode, we should receive all of ingress packets.
> This disable the vlan filtering feature when a vlan hw accel configured e1000 device goes into promiscuous mode.
> This make packets visible to sniffers though it's not vlan id of itself.
> Any check, comments will be appreciated.

Actually I think this patch removes a choice from the user.

Before this patch, the user can sniff all traffic by disabling vlans, or a
specific vlan only by leaving vlans on when going into promisc mode.

After this patch, the user has no choice but to sniff all vlans at all times.

I don't think that that is such a good improvement.

Auke


> Thanks.
> 
> Signed-off-by: Joonwoo Park <joonwpark81@gmail.com>
> ---
>  drivers/net/e1000/e1000_main.c |   26 ++++++++++++++++++++------
>  1 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 72deff0..cdd5c84 100644
> --- a/drivers/net/e1000/e1000_main.c
> +++ b/drivers/net/e1000/e1000_main.c
> @@ -2424,7 +2424,7 @@ e1000_set_multi(struct net_device *netdev)
>  	struct e1000_adapter *adapter = netdev_priv(netdev);
>  	struct e1000_hw *hw = &adapter->hw;
>  	struct dev_mc_list *mc_ptr;
> -	uint32_t rctl;
> +	uint32_t rctl, ctrl;
>  	uint32_t hash_value;
>  	int i, rar_entries = E1000_RAR_ENTRIES;
>  	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
> @@ -2441,14 +2441,25 @@ e1000_set_multi(struct net_device *netdev)
>  	/* Check for Promiscuous and All Multicast modes */
>  
>  	rctl = E1000_READ_REG(hw, RCTL);
> +	ctrl = E1000_READ_REG(&adapter->hw, CTRL);
>  
>  	if (netdev->flags & IFF_PROMISC) {
>  		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
> -	} else if (netdev->flags & IFF_ALLMULTI) {
> -		rctl |= E1000_RCTL_MPE;
> -		rctl &= ~E1000_RCTL_UPE;
> +		if (adapter->hw.mac_type != e1000_ich8lan) {
> +			if (ctrl & E1000_CTRL_VME)
> +				rctl &= ~E1000_RCTL_VFE;
> +		}
>  	} else {
> -		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
> +		if (adapter->hw.mac_type != e1000_ich8lan) {
> +			if (ctrl & E1000_CTRL_VME)
> +				rctl |= E1000_RCTL_VFE;
> +		}
> +		if (netdev->flags & IFF_ALLMULTI) {
> +			rctl |= E1000_RCTL_MPE;
> +			rctl &= ~E1000_RCTL_UPE;
> +		} else {
> +			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
> +		}
>  	}
>  
>  	E1000_WRITE_REG(hw, RCTL, rctl);
> @@ -4952,7 +4963,10 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
>  		if (adapter->hw.mac_type != e1000_ich8lan) {
>  			/* enable VLAN receive filtering */
>  			rctl = E1000_READ_REG(&adapter->hw, RCTL);
> -			rctl |= E1000_RCTL_VFE;
> +			if (netdev->flags & IFF_PROMISC)
> +				rctl &= ~E1000_RCTL_VFE;
> +			else
> +				rctl |= E1000_RCTL_VFE;
>  			rctl &= ~E1000_RCTL_CFIEN;
>  			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
>  			e1000_update_mng_vlan(adapter);
> ---
> 
> -
> 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: [PATCH 2/2] [e1000 VLAN] Disable vlan hw accel when promiscuous mode
From: Patrick McHardy @ 2007-11-12 17:21 UTC (permalink / raw)
  To: Kok, Auke
  Cc: e1000-devel, netdev, 'Dave Johnson', linux-kernel,
	Joonwoo Park, 'David Miller'
In-Reply-To: <47388988.1000506@intel.com>

Kok, Auke wrote:
> Joonwoo Park wrote:
>> IMHO even though netdevice is in the promiscuous mode, we should receive all of ingress packets.
>> This disable the vlan filtering feature when a vlan hw accel configured e1000 device goes into promiscuous mode.
>> This make packets visible to sniffers though it's not vlan id of itself.
>> Any check, comments will be appreciated.
> 
> Actually I think this patch removes a choice from the user.
> 
> Before this patch, the user can sniff all traffic by disabling vlans, or a
> specific vlan only by leaving vlans on when going into promisc mode.
> 
> After this patch, the user has no choice but to sniff all vlans at all times.
> 
> I don't think that that is such a good improvement.


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.

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.

-------------------------------------------------------------------------
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] sungem: fix suspend regression due to NAPI changes
From: Johannes Berg @ 2007-11-12 17:45 UTC (permalink / raw)
  To: David S. Miller
  Cc: Benjamin Herrenschmidt, netdev, linuxppc-dev list,
	Stephen Hemminger

Commit bea3348e (the NAPI changes) made sungem unconditionally enable
NAPI when resuming and unconditionally disable when suspending, this,
however, makes napi_disable() hang when suspending when the interface
was taken down before suspend because taking the interface down also
disables NAPI. This patch makes touching the napi struct in
suspend/resume code paths depend on having the interface up, thereby
fixing the hang on suspend.

The patch also moves the napi_disable() in gem_close() under the lock so
that the NAPI state is always modified atomically together with the
"opened" variable.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 drivers/net/sungem.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

--- everything.orig/drivers/net/sungem.c	2007-11-12 18:22:49.948748047 +0100
+++ everything/drivers/net/sungem.c	2007-11-12 18:24:30.708748481 +0100
@@ -2333,10 +2333,10 @@ static int gem_close(struct net_device *
 {
 	struct gem *gp = dev->priv;
 
-	napi_disable(&gp->napi);
-
 	mutex_lock(&gp->pm_mutex);
 
+	napi_disable(&gp->napi);
+
 	gp->opened = 0;
 	if (!gp->asleep)
 		gem_do_stop(dev, 0);
@@ -2355,8 +2355,6 @@ static int gem_suspend(struct pci_dev *p
 
 	mutex_lock(&gp->pm_mutex);
 
-	napi_disable(&gp->napi);
-
 	printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
 	       dev->name,
 	       (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
@@ -2370,6 +2368,8 @@ static int gem_suspend(struct pci_dev *p
 
 	/* If the driver is opened, we stop the MAC */
 	if (gp->opened) {
+		napi_disable(&gp->napi);
+
 		/* Stop traffic, mark us closed */
 		netif_device_detach(dev);
 
@@ -2460,6 +2460,7 @@ static int gem_resume(struct pci_dev *pd
 		/* Re-attach net device */
 		netif_device_attach(dev);
 
+		napi_enable(&gp->napi);
 	}
 
 	spin_lock_irqsave(&gp->lock, flags);
@@ -2479,8 +2480,6 @@ static int gem_resume(struct pci_dev *pd
 	spin_unlock(&gp->tx_lock);
 	spin_unlock_irqrestore(&gp->lock, flags);
 
-	napi_enable(&gp->napi);
-
 	mutex_unlock(&gp->pm_mutex);
 
 	return 0;



^ permalink raw reply

* [PATCH 05/05] ipv6: RFC4214 Support (4)
From: Templin, Fred L @ 2007-11-12 17:48 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / ????, osprey67
In-Reply-To: <4734FCEF.3080301@yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 255 bytes --]

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

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

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

[-- Attachment #2: isatap_linux.txt --]
[-- Type: text/plain, Size: 11705 bytes --]

--- 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-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+/* 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));
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig	2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig	2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO
 
 	  If unsure, say N.
 
+config IPV6_ISATAP
+	bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+	depends on IPV6 && EXPERIMENTAL
+	---help---
+	  This is experimental support for the Intra-Site Automatic
+	  Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
+	  the SIT module, and is configured using the "ip" utility
+	  with device names beginning with: "isatap".
+
+	  If unsure, say N.
+
 config IPV6_OPTIMISTIC_DAD
 	bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL
--- 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 07:04:27.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,22 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+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;
+}
+#endif
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1451,11 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
 	}
 	return -1;
 }
@@ -1470,8 +1491,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 - remove??
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2221,31 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* 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;
+	}
+#endif
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2576,19 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+#if defined(CONFIG_IPV6_ISATAP)
+		/* 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);
+			}
+		}
+#endif
 		goto out;
 	}
 
@@ -2545,10 +2603,32 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* 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
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+#if defined(CONFIG_IPV6_ISATAP)
+		/* 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);
+			}
+		}
+#endif
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2674,9 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+	    dev->priv_flags&IFF_ISATAP ||
+#endif
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2773,17 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* 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
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		/*
--- 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 07:13:13.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,11 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+#if defined(CONFIG_IPV6_ISATAP)
+	if (parms->i_key)
+		dev->priv_flags |= IFF_ISATAP;
+#endif
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -382,6 +388,48 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+		/* 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:
+#endif
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +492,31 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* 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;
+	}
+#endif
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +724,10 @@ 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;
+#if defined(CONFIG_IPV6_ISATAP)
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
+#endif
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +740,10 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
+#endif
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply

* [PATCH 04/05] ipv6: RFC4214 Support (4)
From: osprey67 @ 2007-11-12 15:55 UTC (permalink / raw)
  To: netdev
In-Reply-To: <4734FCEF.3080301@yahoo.com>

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

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

---

--- 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 07:13:13.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,11 @@ static struct ip_tunnel * ipip6_tunnel_l
         dev->init = ipip6_tunnel_init;
         nt->parms = *parms;

+#if defined(CONFIG_IPV6_ISATAP)
+       if (parms->i_key)
+               dev->priv_flags |= IFF_ISATAP;
+#endif
+
         if (register_netdevice(dev) < 0) {
                 free_netdev(dev);
                 goto failed;
@@ -382,6 +388,48 @@ static int ipip6_rcv(struct sk_buff *skb
                 IPCB(skb)->flags = 0;
                 skb->protocol = htons(ETH_P_IPV6);
                 skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+               /* 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:
+#endif
                 tunnel->stat.rx_packets++;
                 tunnel->stat.rx_bytes += skb->len;
                 skb->dev = tunnel->dev;
@@ -444,6 +492,31 @@ static int ipip6_tunnel_xmit(struct sk_b
         if (skb->protocol != htons(ETH_P_IPV6))
                 goto tx_error;

+#if defined(CONFIG_IPV6_ISATAP)
+       /* 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;
+       }
+#endif
+
         if (!dst)
                 dst = try_6to4(&iph6->daddr);

@@ -651,6 +724,10 @@ 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;
+#if defined(CONFIG_IPV6_ISATAP)
+                               t->parms.i_key = p.i_key;
+                               t->parms.o_key = p.o_key;
+#endif
                                 memcpy(dev->dev_addr, &p.iph.saddr, 4);
                                 memcpy(dev->broadcast, &p.iph.daddr, 4);
                                 ipip6_tunnel_link(t);
@@ -663,6 +740,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                         if (cmd == SIOCCHGTUNNEL) {
                                 t->parms.iph.ttl = p.iph.ttl;
                                 t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+                               t->parms.i_key = p.i_key;
+                               t->parms.o_key = p.o_key;
+#endif
                         }
                         if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                 err = -EFAULT;

^ permalink raw reply

* [PATCH 03/05] ipv6: RFC4214 Support (4)
From: osprey67 @ 2007-11-12 15:54 UTC (permalink / raw)
  To: netdev
In-Reply-To: <4734FCEF.3080301@yahoo.com>

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

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

---

--- 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 07:04:27.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,22 @@ static int addrconf_ifid_infiniband(u8 *
         return 0;
  }

+#if defined(CONFIG_IPV6_ISATAP)
+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;
+}
+#endif
+
  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
  {
         switch (dev->type) {
@@ -1435,6 +1451,11 @@ static int ipv6_generate_eui64(u8 *eui,
                 return addrconf_ifid_arcnet(eui, dev);
         case ARPHRD_INFINIBAND:
                 return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+       case ARPHRD_SIT:
+               if (dev->priv_flags & IFF_ISATAP)
+                       return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
         }
         return -1;
  }
@@ -1470,8 +1491,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 - remove??
          *  - value 0
          *  - XXX: already assigned to an address on the device
          */
@@ -2201,6 +2221,31 @@ static void addrconf_sit_config(struct n
                 return;
         }

+#if defined(CONFIG_IPV6_ISATAP)
+       /* 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;
+       }
+#endif
+
         sit_add_v4_addrs(idev);

         if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2576,19 @@ static void addrconf_rs_timer(unsigned l
                  *      Announcement received after solicitation
                  *      was sent
                  */
+#if defined(CONFIG_IPV6_ISATAP)
+               /* 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);
+                       }
+               }
+#endif
                 goto out;
         }

@@ -2545,10 +2603,32 @@ static void addrconf_rs_timer(unsigned l
                                    ifp->idev->cnf.rtr_solicit_interval);
                 spin_unlock(&ifp->lock);

+#if defined(CONFIG_IPV6_ISATAP)
+               /* 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
+#endif
                 ipv6_addr_all_routers(&all_routers);

                 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
         } else {
+#if defined(CONFIG_IPV6_ISATAP)
+               /* 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);
+                       }
+               }
+#endif
                 spin_unlock(&ifp->lock);
                 /*
                  * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2674,9 @@ static void addrconf_dad_start(struct in
         spin_lock_bh(&ifp->lock);

         if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+           dev->priv_flags&IFF_ISATAP ||
+#endif
             !(ifp->flags&IFA_F_TENTATIVE) ||
             ifp->flags & IFA_F_NODAD) {
                 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2773,17 @@ static void addrconf_dad_completed(struc
             (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
                 struct in6_addr all_routers;

+#if defined(CONFIG_IPV6_ISATAP)
+               /* 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
+#endif
                 ipv6_addr_all_routers(&all_routers);

                 /*

^ permalink raw reply

* [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (4)
From: Templin, Fred L @ 2007-11-12 17:55 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明, osprey67
In-Reply-To: <4734FE8D.5070107@yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 315 bytes --]

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. The
attached file includes diffs that are specific to the
iproute2-2.6.23 software distribution.

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

[-- Attachment #2: isatap_iproute2.txt --]
[-- Type: text/plain, Size: 3013 bytes --]

--- 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: Kok, Auke @ 2007-11-12 18:01 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: e1000-devel, netdev, 'Dave Johnson', linux-kernel,
	Joonwoo Park, 'David Miller'
In-Reply-To: <47388B9F.7050308@trash.net>

Patrick McHardy wrote:
> Kok, Auke wrote:
>> Joonwoo Park wrote:
>>> IMHO even though netdevice is in the promiscuous mode, we should receive all of ingress packets.
>>> This disable the vlan filtering feature when a vlan hw accel configured e1000 device goes into promiscuous mode.
>>> This make packets visible to sniffers though it's not vlan id of itself.
>>> Any check, comments will be appreciated.
>> Actually I think this patch removes a choice from the user.
>>
>> Before this patch, the user can sniff all traffic by disabling vlans, or a
>> specific vlan only by leaving vlans on when going into promisc mode.
>>
>> After this patch, the user has no choice but to sniff all vlans at all times.
>>
>> I don't think that that is such a good improvement.
> 
> 
> 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.

right, I had not thought of that.

> 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.

OK, Joonwoo: can you submit a patch against e1000e as well?

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: 2.6.24-rc1-gb4f5550 oops
From: Peter Zijlstra @ 2007-11-12 18:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Grant Wilson, Ingo Molnar, lkml, Andrew Morton, netdev, vatsa
In-Reply-To: <200711082349.19344.rjw@sisk.pl>


On Thu, 2007-11-08 at 23:49 +0100, Rafael J. Wysocki wrote:
> On Thursday, 8 of November 2007, Grant Wilson wrote:
> > On Thu, 8 Nov 2007 22:42:21 +0100
> > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > 
> > > On Thursday, 8 of November 2007, Grant Wilson wrote:
> > > > On Thu, 8 Nov 2007 16:53:10 +0100
> > > > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > > > 
> > > > > On Thursday, 8 of November 2007, Grant Wilson wrote:
> > > > > > On Thu, 8 Nov 2007 01:06:21 +0100
> > > > > > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > > > > > 
> > > > > > > On Monday, 5 of November 2007, Grant Wilson wrote:
> > > > > > > > Hi,
> > > > > > > > I got this oops on 2.6.24-rc1-641-gb4f5550:
> > > > > > > 
> > > > > > > (1) Is this reproducible?
> > > > > > > (2) Did it happen previously on your system?
> > > > > > >
> > > > > > > [18073.371126] Unable to handle kernel NULL pointer dereference at 0000000000000120 RIP: 
> > > > > > > [18073.371134]  [<ffffffff8023572e>] check_preempt_wakeup+0x6e/0x110
> > > > > > 
> > > > > > This has now happened twice - the second time was last night when
> > > > > > running 2.6.24-rc2.
> > > > > > 
> > > > > > Here's that second occurrence:
> > > > > > 
> > > > [snip]
> > > > > 
> > > > > Hmm.
> > > > > 
> > > > > Please run "gdb vmlinux" and see what code corresponds to
> > > > > check_preempt_wakeup+0x6e in your kernel.
> > > >
> > > > 
> > > > Dump of assembler code for function check_preempt_wakeup:
> > > 
> > > Well, thanks, but I meant the source code.  Please do "gdb vmlinux" and then
> > > "l *check_preempt_wakeup+0x6e" in gdb.
> > 
> > Here's the requested output:
> > 
> > (gdb) l *check_preempt_wakeup+0x6e
> > 0xffffffff802329ae is in check_preempt_wakeup (kernel/sched_fair.c:668).
> > 663
> > 664     /* Do the two (enqueued) entities belong to the same group ? */
> > 665     static inline int
> > 666     is_same_group(struct sched_entity *se, struct sched_entity *pse)
> > 667     {
> > 668             if (se->cfs_rq == pse->cfs_rq)
> > 669                     return 1;
> > 670
> > 671             return 0;
> > 672     }
> 
> Well, it looks like either se or pse is NULL.
> 
> Ingo, can you please have a look?

Most puzzling this, it should be guaranteed that the top sched_entities
are of the same group, therefore avoiding this loop into NULL. Obviously
something has gone wrong.

Grant, is there anything specific you can tell us about how to reproduce
this?



^ permalink raw reply

* [PATCH 02/05] ipv6: RFC4214 Support (4)
From: osprey67 @ 2007-11-12 15:54 UTC (permalink / raw)
  To: netdev
In-Reply-To: <4734FCEF.3080301@yahoo.com>

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

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

---

--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig      2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig   2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO

           If unsure, say N.

+config IPV6_ISATAP
+       bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+       depends on IPV6 && EXPERIMENTAL
+       ---help---
+         This is experimental support for the Intra-Site Automatic
+         Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
+         the SIT module, and is configured using the "ip" utility
+         with device names beginning with: "isatap".
+
+         If unsure, say N.
+
  config IPV6_OPTIMISTIC_DAD
         bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
         depends on IPV6 && EXPERIMENTAL


^ permalink raw reply

* [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (4)
From: osprey67 @ 2007-11-12 15:57 UTC (permalink / raw)
  To: netdev
In-Reply-To: <4734FE8D.5070107@yahoo.com>

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the iproute2-2.6.23
software distribution. The diff text file itself is also
attached and should be suitable for use with the patch
utility.

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

* [PATCH] ethtool: Fix coalesce settings copy+paste typo
From: Auke Kok @ 2007-11-12 18:28 UTC (permalink / raw)
  To: jeff, davem; +Cc: netdev

Coalesce setting errors use the same error messages as the
descriptor ring errors.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 ethtool.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 6c7a2e3..bb9dd59 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1470,7 +1470,7 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
 		       &changed);
 
 	if (!changed) {
-		fprintf(stderr, "no ring parameters changed, aborting\n");
+		fprintf(stderr, "no coalesce parameters changed, aborting\n");
 		return 80;
 	}
 
@@ -1478,7 +1478,7 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
 	ifr->ifr_data = (caddr_t)&ecoal;
 	err = ioctl(fd, SIOCETHTOOL, ifr);
 	if (err) {
-		perror("Cannot set device ring parameters");
+		perror("Cannot set device coalesce parameters");
 		return 81;
 	}
 

^ permalink raw reply related

* Re: 2.6.24-rc1-gb4f5550 oops
From: Grant Wilson @ 2007-11-12 18:28 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Rafael J. Wysocki, Ingo Molnar, lkml, Andrew Morton, netdev,
	vatsa
In-Reply-To: <1194890749.9713.17.camel@twins>

On Mon, 12 Nov 2007 19:05:49 +0100
Peter Zijlstra <peterz@infradead.org> wrote:

> 
> On Thu, 2007-11-08 at 23:49 +0100, Rafael J. Wysocki wrote:
> > On Thursday, 8 of November 2007, Grant Wilson wrote:
> > > On Thu, 8 Nov 2007 22:42:21 +0100
> > > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > > 
> > > > On Thursday, 8 of November 2007, Grant Wilson wrote:
> > > > > On Thu, 8 Nov 2007 16:53:10 +0100
> > > > > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > > > > 
> > > > > > On Thursday, 8 of November 2007, Grant Wilson wrote:
> > > > > > > On Thu, 8 Nov 2007 01:06:21 +0100
> > > > > > > "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > > > > > > 
> > > > > > > > On Monday, 5 of November 2007, Grant Wilson wrote:
> > > > > > > > > Hi,
> > > > > > > > > I got this oops on 2.6.24-rc1-641-gb4f5550:
> > > > > > > > 
> > > > > > > > (1) Is this reproducible?
> > > > > > > > (2) Did it happen previously on your system?
> > > > > > > >
> > > > > > > > [18073.371126] Unable to handle kernel NULL pointer dereference at 0000000000000120 RIP: 
> > > > > > > > [18073.371134]  [<ffffffff8023572e>] check_preempt_wakeup+0x6e/0x110
> > > > > > > 
> > > > > > > This has now happened twice - the second time was last night when
> > > > > > > running 2.6.24-rc2.
> > > > > > > 
> > > > > > > Here's that second occurrence:
> > > > > > > 
> > > > > [snip]
> > > > > > 
> > > > > > Hmm.
> > > > > > 
> > > > > > Please run "gdb vmlinux" and see what code corresponds to
> > > > > > check_preempt_wakeup+0x6e in your kernel.
> > > > >
> > > > > 
> > > > > Dump of assembler code for function check_preempt_wakeup:
> > > > 
> > > > Well, thanks, but I meant the source code.  Please do "gdb vmlinux" and then
> > > > "l *check_preempt_wakeup+0x6e" in gdb.
> > > 
> > > Here's the requested output:
> > > 
> > > (gdb) l *check_preempt_wakeup+0x6e
> > > 0xffffffff802329ae is in check_preempt_wakeup (kernel/sched_fair.c:668).
> > > 663
> > > 664     /* Do the two (enqueued) entities belong to the same group ? */
> > > 665     static inline int
> > > 666     is_same_group(struct sched_entity *se, struct sched_entity *pse)
> > > 667     {
> > > 668             if (se->cfs_rq == pse->cfs_rq)
> > > 669                     return 1;
> > > 670
> > > 671             return 0;
> > > 672     }
> > 
> > Well, it looks like either se or pse is NULL.
> > 
> > Ingo, can you please have a look?
> 
> Most puzzling this, it should be guaranteed that the top sched_entities
> are of the same group, therefore avoiding this loop into NULL. Obviously
> something has gone wrong.
> 
> Grant, is there anything specific you can tell us about how to reproduce
> this?

I'm afraid not.  It has only happened twice and both times I was away
from the box in question at the time of failure, so it wasn't doing a
great deal.

I'm running 2.6.24-rc2 on two boxes and both times it happened on the
box running a quad core processor.

Grant


^ permalink raw reply

* [PATCH 01/05] ipv6: RFC4214 Support (4)
From: osprey67 @ 2007-11-12 15:54 UTC (permalink / raw)
  To: netdev
In-Reply-To: <4734FCEF.3080301@yahoo.com>

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

This is experimental support for the Intra-Site Automatic
Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses
the SIT module, and is configured using the unmodified
"ip" utility with device names beginning with: "isatap".

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

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-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
                 addr->s6_addr32[3] == htonl(0x00000002));
  }

+#if defined(CONFIG_IPV6_ISATAP)
+/* 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));
+}
+#endif
+
  #ifdef CONFIG_PROC_FS
  extern int if6_proc_init(void);
  extern void if6_proc_exit(void);





^ permalink raw reply

* Problems with ULI 526x driver
From: Timur Tabi @ 2007-11-12 18:41 UTC (permalink / raw)
  To: peerchen, netdev

Hi,

I'm trying to get the ULI 526x driver working on a Freescale 8610 reference 
board, and it can't connect.  When I turn on debug, I see this:

Configuring network interfaces...uli526x: uli526x_open 0
uli526x: uli526x_init() 0
uli526x: uli526x_descriptor_init() 0
uli526x: send_filter_frame() 0
uli526x: uli526x_set_filter_mode() 0
uli526x: Set multicast address 1
uli526x: send_filter_frame() 0
uli526x: uli526x_get_stats 0
uli526x: uli526x_set_filter_mode() 0
uli526x: Set multicast address 2
uli526x: send_filter_frame() 0
ADDRCONF(NETDEV_UP): eth0: link is not ready
uli526x: uli526x_set_filter_mode() 0
uli526x: Set multicast address 2
uli526x: send_filter_frame() 0
uli526x: uli526x_get_stats 0
uli526x: uli526x_set_filter_mode() 0
uli526x: Set multicast address 2
uli526x: send_filter_frame() 0
done.

and then some time later, I see thisL

uli526x: Link link OK 3
uli526x: eth0 NIC Link is Up 100 Mbps Full duplex
ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
uli526x: uli526x_set_filter_mode() 0
uli526x: Set multicast address 3
uli526x: send_filter_frame() 0
uli526x: uli526x_get_stats 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0

If I try to ping, I get this:

  ping 10.82.48.106
PING 10.82.48.106 (10.82.48.106) 56(84) bytes of data.
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0
 From 10.82.19.159 icmp_seq=2 Destination Host Unreachable
 From 10.82.19.159 icmp_seq=3 Destination Host Unreachable
 From 10.82.19.159 icmp_seq=4 Destination Host Unreachable
uli526x: uli526x_start_xmit 0
uli526x: uli526x_start_xmit 0


A long time ago, there was a patch for the Tulip driver that added support for 
the ULI 526x.  This support was removed in commit 
ea8f400c98ec9ae0604bc5a6721174ef68635815:

http://git.kernel.org/?p=linux/kernel/git/jgarzik/netdev-2.6.git;a=commit;h=ea8f400c98ec9ae0604bc5a6721174ef68635815

Now, if I revert those changes, the Tulip driver works for me.  So there's 
something that the tulip+uli526x driver does that the stand-alone uli526x driver 
doesn't do.

Unfortunately, I don't really know anything about the tulip or uli526x drivers. 
  Is there anyone who can give me a clue as to what could be wrong?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: Problems with ULI 526x driver
From: Timur Tabi @ 2007-11-12 19:21 UTC (permalink / raw)
  To: peerchen, netdev
In-Reply-To: <47389E72.7050907@freescale.com>

Timur Tabi wrote:
> Hi,
> 
> I'm trying to get the ULI 526x driver working on a Freescale 8610 
> reference board, and it can't connect.  When I turn on debug, I see this:

Update: I can ping anything on my subnet, but nothing else.  Also, it looks like 
my MAC address is hosed:

eth0      Link encap:Ethernet  HWaddr 00:00:00:00:00:00
           inet addr:10.82.19.159  Bcast:10.82.19.255  Mask:255.255.255.0
           inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:5 errors:0 dropped:0 overruns:0 frame:0
           TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:414 (414.0 b)  TX bytes:1224 (1.1 KiB)
           Interrupt:18 Base address:0x1000

It turns out that the driver is getting the MAC address from the ID table:

	if(((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0)		/* SROM 
absent, so read MAC address from ID Table */
	{


In my case, the address that is returned is all zeros.  I don't know anything 
about the ULI 526x hardware.  Is it possible that there's a missing EEPROM on my 
board that's supposed to hold the MAC address?  Are these registers user-writable?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ 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