Subject: kern/26939: some network drivers don't generate an RTM_IFINFO route(4) message when link-detect changes
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <carton@Ivy.NET>
List: netbsd-bugs
Date: 09/13/2004 16:09:25
>Number:         26939
>Category:       kern
>Synopsis:       some network drivers don't generate an RTM_IFINFO route(4) message when link-detect changes
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 13 20:10:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Miles Nordin
>Release:        NetBSD 2.0_BETA
>Organization:
Le fascisme est la dictature ouverte de la bourgeoisie.
		-- Georg Dimitrov
>Environment:
	
	
System: NetBSD castrovalva 2.0_BETA NetBSD 2.0_BETA (CASTROVALVA-$Revision: 1.7 $) #0: Mon Sep 13 01:45:01 EDT 2004 carton@castrovalva:/scratch/src/sys/arch/alpha/compile/CASTROVALVA alpha
Architecture: alpha
Machine: alpha
>Description:
_______
Problem

There is an interface for userland program to query the link-detect of 
a network interface.  On Ethernet, this is the little green light next 
to the jack.  Routing programs like quagga/zebra can use this information 
to do a better job.  They need to be able to

  (1) poll for the information at startup.
  (2) get asynchronous PF_ROUTE messages when link state changes.

Right now (1) works for more network chip drivers than (2).  I think the 
set of supported cards should be identical for (1) and (2) since it's 
just a logic problem, not support or capability of hardware.

__________
Background

route(4) documents a type of routing message RTM_IFINFO that comes out of 
the PF_ROUTE socket as a struct if_msghdr defined in <net/if.h>

struct if_msghdr ifm;
/* your interface link state is in ifm.ifm_data.ifi_link_state */

______
Detail

Many network drivers will update the link state in this kernel structure, 
but will not call the kernel function rt_ifmsg() to generate a routing 
message.  It's still possible to retrieve the link state of these problem 
drivers using sysctl(), but routing software like quagga needs this 
information to come as routing messages, not poll for it.  Otherwise it 
can't keep its interface lists synchronized with the kernel.

Here is a code fragment to poll for link state, taken from quagga's 
zebra/if_sysctl.c (abbreviated):

-----8<-----
  caddr_t ref, buf, end;
  size_t bufsiz;
  struct if_msghdr *ifm;
  struct interface *ifp;

#define MIBSIZ 6
  int mib[MIBSIZ] =
  { 
    CTL_NET,
    PF_ROUTE,
    0,
    0, /*  AF_INET & AF_INET6 */
    NET_RT_IFLIST,
    0 
  };

  sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0);

  ref = buf = malloc(bufsiz);

  /* Fetch interface informations into allocated buffer. */
  sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0);

  /* Parse both interfaces and addresses. */
  for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) 
    {
      ifm = (struct if_msghdr *) buf;
      if (ifm->ifm_type == RTM_IFINFO)
        {
	/* ifm->ifm_data.ifi_link_state is what the PR is about */
        }
    }
-----8<-----

__________
Experience

I find that gem on a sparc64 Netra T1 200 works.  tlp on an alpha DS10 
doesn't generate route messages.  

The tlp in this alpha is a 21143, a 100Mbit/s chip that works without 
an MII.  grepping in sys/dev kernel sources for rt_ifmsg I find one 
call factored out to mii_physubr.c, and another in wi.c.  From this I 
expect all cards with MII and also wi(4) will generate the RTM_IFINFO 
messages, but no other cards.  I've tested only the two interfaces I 
mention above.

>How-To-Repeat:
Here is an example of an interface that properly generates the 
RTM_IFINFO messages when I unplug and replug its Ethernet cable:

$ sudo route monitor
Password:
got message of size 152 on Mon Sep 13 19:32:23 2004
RTM_IFINFO: iface status change: len 152, if# 2, carrier: no carrier, flags:<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>
got message of size 152 on Mon Sep 13 19:32:27 2004
RTM_IFINFO: iface status change: len 152, if# 2, carrier: active, flags:<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST>

An interface that doesn't generate them will be silent.

>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: