public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Stefan Rompf <srompf@isg.de>
To: linux-kernel@vger.kernel.org, jgarzik@mandrakesoft.com
Subject: Interface operative status detection
Date: Sat, 19 Jan 2002 16:12:09 +0100	[thread overview]
Message-ID: <3C498CC9.6FAED2AF@isg.de> (raw)

Hi Kernel-people,

while playing with the Zebra routing daemon, I realized that neither
Linux nor Zebra are capable of detecting the operative state of an
interface, f.e. the ethernet link beat. This is a major show stopper
against using Linux for "serious" IP routing.

While my Zebra patches still need some testing, I'd like to present my
ideas for Linux to the community and get some feedback if this is the
right way to go.

Under Unix systems, the flag IFF_UP represents the administrative state
of an interface, while IFF_RUNNING should be set whenever the driver is
convinced that it actually can send and receive data.

Currently, IFF_RUNNING in the net_device->flags is not used at all,
rtnetlink and query ioctls use netif_carrier_ok() that tests the
__LINK_STATE_NO_CARRIER bit in net_device->state. Looking back into the
LKML archives, the reason is that the flags element must not be changed
inside interrupts.

So what about the following idea: The network interface drivers use the
netif_carrier_on() and netif_carrier_off() functions to update their
interface card status (a bunch of drivers already do). To get this
information forwarded to user mode via netlink socket, we use a kernel
thread that goes through the device list, and everytime IFF_RUNNING
and netif_carrier_ok() differ, IFF_RUNNING is updated and a message is
sent via netlink.

Attached you'll find a patch against 2.4.17 for the tulip driver to
forward (again) link beat information for MII tranceivers and a small
kernel module for 2.4 that implements the kernel thread. Please forgive
the crude way of unloading, this is my first kernel hacking attempt
since 1.2 ;-)

If this is the right direction, I'll submit a more elegant patch for 2.5
in the next weeks.

Note that there is still sourcecode in drivers/net that plays with
IFF_RUNNING directly. As I don't own these cards, let me just list the
files so that the maintainers can have a look: bmac.c,
wan/lmc/lmc_main.c, wan/comx-proto-fr.c, tlan.c, eepro100.c,
au1000_eth.c, tokenring/ibmtr.c and bonding.c.



diff -urN -X dontdiff linux-2.4.17/drivers/net/tulip/21142.c linux-2.4.17stefan/drivers/net/tulip/21142.c
--- linux-2.4.17/drivers/net/tulip/21142.c	Fri Nov  9 22:45:35 2001
+++ linux-2.4.17stefan/drivers/net/tulip/21142.c	Sat Jan 19 15:28:57 2002
@@ -39,8 +39,12 @@
 		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
 			   dev->name, csr12, medianame[dev->if_port]);
 	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
-		tulip_check_duplex(dev);
-		next_tick = 60*HZ;
+		if (tulip_check_duplex(dev) < 0) {
+			netif_carrier_off(dev);
+		} else {
+			netif_carrier_on(dev);
+		}
+		next_tick = 3*HZ;
 	} else if (tp->nwayset) {
 		/* Don't screw up a negotiated session! */
 		if (tulip_debug > 1)
diff -urN -X dontdiff linux-2.4.17/drivers/net/tulip/timer.c linux-2.4.17stefan/drivers/net/tulip/timer.c
--- linux-2.4.17/drivers/net/tulip/timer.c	Wed Jun 20 20:15:44 2001
+++ linux-2.4.17stefan/drivers/net/tulip/timer.c	Sat Jan 19 15:30:35 2002
@@ -137,10 +137,10 @@
 					       medianame[mleaf->media & MEDIA_MASK]);
 				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
 					goto actually_mii;
-				/* netif_carrier_on(dev); */
+				netif_carrier_on(dev);
 				break;
 			}
-			/* netif_carrier_off(dev); */
+			netif_carrier_off(dev);
 			if (tp->medialock)
 				break;
 	  select_next_media:
@@ -164,10 +164,11 @@
 		}
 		case 1:  case 3:		/* 21140, 21142 MII */
 		actually_mii:
-			if (tulip_check_duplex(dev) < 0)
-				{ /* netif_carrier_off(dev); */ }
-			else
-				{ /* netif_carrier_on(dev); */ }
+			if (tulip_check_duplex(dev) < 0) {
+				netif_carrier_off(dev);
+			} else {
+				netif_carrier_on(dev);
+			}
 			next_tick = 60*HZ;
 			break;
 		case 2:					/* 21142 serial block has no link beat. */



And the module source code dev_watch.c:

/* Linux network device status watcher

   (C) 2002 Stefan Rompf
   GPL Version 2 applies

   compile with something like
    gcc -c -DMODULE -D__KERNEL__ -O2 dev_watch.c
*/

#include <linux/sched.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/rtnetlink.h>

static volatile pid_t me;

static volatile int running = 1;

static int devwatcher(void *dummy)
{
        struct net_device *dev;
	
	daemonize();
	strcpy(current->comm, "devwatchd");

	while(running) {
		write_lock(&dev_base_lock);
		for (dev=dev_base; dev; dev = dev->next) {

			/* State of netif_carrier_ok() is reflected
			   into dev_flags by this loop, and a netlink
			   message is omitted whenever the state
			   changes */

			if (dev->flags & IFF_RUNNING) {
				if (!netif_carrier_ok(dev)) {
					dev->flags &= ~IFF_RUNNING;
					rtnl_lock();
					netdev_state_change(dev);
					rtnl_unlock();
				}
			} else {
				if (netif_carrier_ok(dev)) {
					dev->flags |= IFF_RUNNING;
					rtnl_lock();
					netdev_state_change(dev);
					rtnl_unlock();
				}
			}
		}
		write_unlock(&dev_base_lock);

		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(HZ);
	}
		

	me = 0;
	return 0;
}

static int __init devwatch_init(void) {
	me = kernel_thread(devwatcher, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);

	if (!me) return 1;

	return 0;
}


static void __exit devwatch_cleanup(void) {
	running = 0;
	while(me) schedule();
}


EXPORT_NO_SYMBOLS;

module_init(devwatch_init);
module_exit(devwatch_cleanup);




Cheers, Stefan


             reply	other threads:[~2002-01-19 15:24 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-01-19 15:12 Stefan Rompf [this message]
2002-01-19 15:29 ` Interface operative status detection Jeff Garzik
2002-01-19 18:34 ` Roberto Nibali
2002-02-08 10:16 ` Jeff Garzik
     [not found] <3C498CC9.6FAED2AF@isg.de.suse.lists.linux.kernel>
2002-01-19 17:40 ` Andi Kleen
2002-01-20  0:51   ` Stefan Rompf
2002-02-12 14:52   ` David L. Parsley
2002-02-12 15:58     ` Chris Friesen
2002-02-12 16:08       ` Stefan Rompf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C498CC9.6FAED2AF@isg.de \
    --to=srompf@isg.de \
    --cc=jgarzik@mandrakesoft.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox