From jr@opal.com  Wed Dec  8 16:55:31 2010
Return-Path: <jr@opal.com>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id C18261065786
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  8 Dec 2010 16:55:31 +0000 (UTC)
	(envelope-from jr@opal.com)
Received: from mho-02-ewr.mailhop.org (mho-02-ewr.mailhop.org [204.13.248.72])
	by mx1.freebsd.org (Postfix) with ESMTP id 7A6EF8FC21
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  8 Dec 2010 16:55:31 +0000 (UTC)
Received: from pool-151-203-7-204.bos.east.verizon.net ([151.203.7.204] helo=homobox.opal.com)
	by mho-02-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256)
	(Exim 4.68)
	(envelope-from <jr@opal.com>)
	id 1PQN3C-000EoD-JB
	for FreeBSD-gnats-submit@freebsd.org; Wed, 08 Dec 2010 16:39:30 +0000
Received: from opal.com (localhost [IPv6:::1])
	(authenticated bits=0)
	by homobox.opal.com (8.14.4/8.14.4) with ESMTP id oB8GdSaS044584
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 8 Dec 2010 11:39:28 -0500 (EST)
	(envelope-from jr@opal.com)
Received: from shibato.opal.com ([192.168.3.246] helo=shibato.opal.com)
	with IPv4:587 by opal.com; 8 Dec 2010 11:39:28 -0500
Received: from shibato.opal.com (localhost [127.0.0.1])
	by shibato.opal.com (8.14.4/8.14.4) with ESMTP id oB8GdQ0I067359
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 8 Dec 2010 11:39:26 -0500 (EST)
	(envelope-from jr@opal.com)
Received: (from jr@localhost)
	by shibato.opal.com (8.14.4/8.14.4/Submit) id oB8GdQWb067358;
	Wed, 8 Dec 2010 11:39:26 -0500 (EST)
	(envelope-from jr)
Message-Id: <201012081639.oB8GdQWb067358@shibato.opal.com>
Date: Wed, 8 Dec 2010 11:39:26 -0500 (EST)
From: "J.R. Oldroyd" <fbsd@opal.com>
Reply-To: "J.R. Oldroyd" <fbsd@opal.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] rtadvd don't send RA on i/f that's down
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         152928
>Category:       bin
>Synopsis:       [patch] rtadvd(8) don't send RA on i/f that's down
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    hrs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 08 17:00:23 UTC 2010
>Closed-Date:    
>Last-Modified:  Sat Jun 04 14:01:42 UTC 2011
>Originator:     J.R. Oldroyd
>Release:        FreeBSD 8.1-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD xx.opal.com 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:36:49 UTC 2010 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
rtadvd looks to see if an interface is UP and doesn't send RAs if it's not.
However, if the interface is marked up but the media is down at the moment,
it does still send an RA.  This causes endless syslog messages of the form:

rtadvd[1619]: <ra_output> sendmsg on vge0: No buffer space available

The attached patch adds a check to see if the media is up and only sends
the RA if it is. 
>How-To-Repeat:
Run rtadvd on an interface of your choice.
Unplug the media cable from the interface.
Observe repeated syslog error messages.
>Fix:
--- usr.sbin/rtadvd/if.h.orig	2010-07-29 09:59:22.000000000 -0400
+++ usr.sbin/rtadvd/if.h	2010-12-08 11:07:48.000000000 -0500
@@ -40,6 +40,7 @@
 struct sockaddr_dl *if_nametosdl(char *);
 int if_getmtu(char *);
 int if_getflags(int, int);
+int if_getifmstatus(char *);
 int lladdropt_length(struct sockaddr_dl *);
 void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *);
 int rtbuf_len(void);
--- usr.sbin/rtadvd/if.c.orig	2010-07-29 09:59:22.000000000 -0400
+++ usr.sbin/rtadvd/if.c	2010-12-08 11:13:13.000000000 -0500
@@ -35,6 +35,7 @@
 #include <sys/sysctl.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
+#include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/ethernet.h>
 #include <ifaddrs.h>
@@ -203,6 +204,31 @@
 	return (ifr.ifr_flags);
 }
 
+/* get interface media status */
+int
+if_getifmstatus(char *name)
+{
+	struct ifmediareq ifmr;
+	int s;
+
+	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+		syslog(LOG_ERR, "<%s> socket: %s", __func__,
+		       strerror(errno));
+		return (~IFM_AVALID);
+	}
+
+	(void) memset(&ifmr, 0, sizeof(ifmr));
+	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+		syslog(LOG_ERR, "<%s> ioctl:SIOCGIFMEDIA: failed for %s",
+		       __func__, ifmr.ifm_name);
+		close(s);
+		return (~IFM_AVALID);
+	}
+	close(s);
+	return (ifmr.ifm_status);
+}
+
 #define ROUNDUP8(a) (1 + (((a) - 1) | 7))
 int
 lladdropt_length(struct sockaddr_dl *sdl)
@@ -503,7 +529,7 @@
 
 /*
  * alloc buffer and parse if_msghdrs block passed as arg,
- * and init the buffer as list of pointers ot each of the if_msghdr.
+ * and init the buffer as list of pointers to each of the if_msghdr.
  */
 static void
 parse_iflist(struct if_msghdr ***ifmlist_p, char *buf, size_t bufsize)
--- usr.sbin/rtadvd/rtadvd.c.orig	2010-07-29 09:59:22.000000000 -0400
+++ usr.sbin/rtadvd/rtadvd.c	2010-12-08 11:22:35.000000000 -0500
@@ -37,6 +37,7 @@
 #include <sys/queue.h>
 
 #include <net/if.h>
+#include <net/if_media.h>
 #include <net/route.h>
 #include <net/if_dl.h>
 #include <netinet/in.h>
@@ -1556,6 +1557,7 @@
 	struct cmsghdr *cm;
 	struct in6_pktinfo *pi;
 	struct soliciter *sol, *nextsol;
+	struct ifmediareq ifmr;
 
 	if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) {
 		syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA",
@@ -1563,6 +1565,14 @@
 		return;
 	}
 
+	if ((if_getifmstatus(rainfo->ifname) & (IFM_AVALID | IFM_ACTIVE))
+	    != (IFM_AVALID | IFM_ACTIVE)) {
+		syslog(LOG_DEBUG,
+		    "<%s> %s media is not active, skip sending RA",
+		    __func__, rainfo->ifname);
+		return;
+	}
+
 	make_packet(rainfo);	/* XXX: inefficient */
 
 	sndmhdr.msg_name = (caddr_t)&sin6_allnodes;
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->bz 
Responsible-Changed-By: bz 
Responsible-Changed-When: Wed Dec 8 21:07:37 UTC 2010 
Responsible-Changed-Why:  
Claim. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152928 
Responsible-Changed-From-To: bz->hrs 
Responsible-Changed-By: bz 
Responsible-Changed-When: Sat Jun 4 14:01:14 UTC 2011 
Responsible-Changed-Why:  
hrs, given you are doing the complete code overhaul, let me 
assign that to you as well. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152928 
>Unformatted:
