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: