Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Dec 2008 19:45:25 +0000 (UTC)
From:      Qing Li <qingli@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186500 - in head: sys/net sys/netinet sys/netinet6 usr.sbin/arp usr.sbin/ndp
Message-ID:  <200812261945.mBQJjPCq049254@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: qingli
Date: Fri Dec 26 19:45:24 2008
New Revision: 186500
URL: http://svn.freebsd.org/changeset/base/186500

Log:
  This checkin addresses a couple of issues:
  1. The "route" command allows route insertion through the interface-direct
     option "-iface". During if_attach(), an sockaddr_dl{} entry is created
     for the interface and is part of the interface address list. This
     sockaddr_dl{} entry describes the interface in detail. The "route"
     command selects this entry as the "gateway" object when the "-iface"
     option is present. The "arp" and "ndp" commands also interact with the
     kernel through the routing socket when adding and removing static L2
     entries. The static L2 information is also provided through the
     "gateway" object with an AF_LINK family type, similar to what is
     provided by the "route" command. In order to differentiate between
     these two types of operations, a RTF_LLDATA flag is introduced. This
     flag is set by the "arp" and "ndp" commands when issuing the add and
     delete commands. This flag is also set in each L2 entry returned by the
     kernel. The "arp" and "ndp" command follows a convention where a RTM_GET
     is issued first followed by a RTM_ADD/DELETE. This RTM_GET request fills
     in the fields for a "rtm" object, which is reinjected into the kernel by
     a subsequent RTM_ADD/DELETE command. The entry returend from RTM_GET
     is a prefix route, so the RTF_LLDATA flag must be specified when issuing
     the RTM_ADD/DELETE messages.
  
  2. Enforce the convention that NET_RT_FLAGS with a 0 w_arg is the
     specification for retrieving L2 information. Also optimized the
     code logic.
  
  Reviewed by:   julian

Modified:
  head/sys/net/route.h
  head/sys/net/rtsock.c
  head/sys/netinet/in.c
  head/sys/netinet6/in6.c
  head/usr.sbin/arp/arp.c
  head/usr.sbin/ndp/ndp.c

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/sys/net/route.h	Fri Dec 26 19:45:24 2008	(r186500)
@@ -174,6 +174,7 @@ struct ortentry {
 /*			0x100		   unused, was RTF_CLONING */
 #define RTF_XRESOLVE	0x200		/* external daemon resolves name */
 /*			0x400		   unused, was RTF_LLINFO */
+#define RTF_LLDATA	0x400		/* used by apps to add/del L2 entries */
 #define RTF_STATIC	0x800		/* manually added */
 #define RTF_BLACKHOLE	0x1000		/* just discard pkts (during updates) */
 #define RTF_PROTO2	0x4000		/* protocol specific routing flag */

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/sys/net/rtsock.c	Fri Dec 26 19:45:24 2008	(r186500)
@@ -53,6 +53,7 @@
 #include <sys/vimage.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/if_llatbl.h>
 #include <net/netisr.h>
 #include <net/raw_cb.h>
@@ -514,8 +515,10 @@ route_output(struct mbuf *m, struct sock
 		if (info.rti_info[RTAX_GATEWAY] == NULL)
 			senderr(EINVAL);
 		saved_nrt = NULL;
+
 		/* support for new ARP code */
-		if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
+		if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK &&
+		    (rtm->rtm_flags & RTF_LLDATA) != 0) {
 			error = lla_rt_output(rtm, &info);
 			break;
 		}
@@ -535,7 +538,8 @@ route_output(struct mbuf *m, struct sock
 		saved_nrt = NULL;
 		/* support for new ARP code */
 		if (info.rti_info[RTAX_GATEWAY] && 
-		    (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)) {
+		    (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) &&
+		    (rtm->rtm_flags & RTF_LLDATA) != 0) {
 			error = lla_rt_output(rtm, &info);
 			break;
 		}
@@ -1427,6 +1431,21 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
 			lim = AF_MAX;
 		} else				/* dump only one table */
 			i = lim = af;
+
+		/*
+		 * take care of llinfo entries, the caller must
+		 * specify an AF
+		 */
+		if (w.w_op == NET_RT_FLAGS && w.w_arg == 0) {
+			if (af != 0)
+				error = lltable_sysctl_dumparp(af, w.w_req);
+			else
+				error = EINVAL;
+			break;
+		}
+		/*
+		 * take care of routing entries
+		 */
 		for (error = 0; error == 0 && i <= lim; i++)
 			if ((rnh = V_rt_tables[curthread->td_proc->p_fibnum][i]) != NULL) {
 				RADIX_NODE_HEAD_LOCK(rnh); 
@@ -1435,11 +1454,6 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
 				RADIX_NODE_HEAD_UNLOCK(rnh);
 			} else if (af != 0)
 				error = EAFNOSUPPORT;
-		/*
-		 * take care of llinfo entries
-		 */
-		if (w.w_op == NET_RT_FLAGS)
-			error = lltable_sysctl_dumparp(af, w.w_req);
 		break;
 
 	case NET_RT_IFLIST:

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/sys/netinet/in.c	Fri Dec 26 19:45:24 2008	(r186500)
@@ -1222,7 +1222,7 @@ in_lltable_dump(struct lltable *llt, str
 
 			arpc.rtm.rtm_rmx.rmx_expire =
 			    lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
-			arpc.rtm.rtm_flags |= RTF_HOST;
+			arpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
 			if (lle->la_flags & LLE_STATIC)
 				arpc.rtm.rtm_flags |= RTF_STATIC;
 			arpc.rtm.rtm_index = ifp->if_index;

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/sys/netinet6/in6.c	Fri Dec 26 19:45:24 2008	(r186500)
@@ -2282,7 +2282,7 @@ in6_lltable_dump(struct lltable *llt, st
 			bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
 			ndpc.rtm.rtm_rmx.rmx_expire =
 			    lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
-			ndpc.rtm.rtm_flags |= RTF_HOST;
+			ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
 			if (lle->la_flags & LLE_STATIC)
 				ndpc.rtm.rtm_flags |= RTF_STATIC;
 			ndpc.rtm.rtm_index = ifp->if_index;

Modified: head/usr.sbin/arp/arp.c
==============================================================================
--- head/usr.sbin/arp/arp.c	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/usr.sbin/arp/arp.c	Fri Dec 26 19:45:24 2008	(r186500)
@@ -477,6 +477,7 @@ delete(char *host, int do_proxy)
 		}
 		dst->sin_other = SIN_PROXY;
 	}
+	rtm->rtm_flags |= RTF_LLDATA;
 	if (rtmsg(RTM_DELETE, dst, NULL) != NULL) {
 		printf("%s (%s) deleted\n", host, inet_ntoa(addr->sin_addr));
 		return (0);
@@ -706,7 +707,7 @@ rtmsg(int cmd, struct sockaddr_inarp *ds
 		rtm->rtm_addrs |= RTA_GATEWAY;
 		rtm->rtm_rmx.rmx_expire = expire_time;
 		rtm->rtm_inits = RTV_EXPIRE;
-		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
+		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
 		dst->sin_other = 0;
 		if (doing_proxy) {
 			if (proxy_only)

Modified: head/usr.sbin/ndp/ndp.c
==============================================================================
--- head/usr.sbin/ndp/ndp.c	Fri Dec 26 11:11:30 2008	(r186499)
+++ head/usr.sbin/ndp/ndp.c	Fri Dec 26 19:45:24 2008	(r186500)
@@ -554,6 +554,7 @@ delete:
          * but we want the actual address
          */
 	NEXTADDR(RTA_DST, sin_m);
+	rtm->rtm_flags |= RTF_LLDATA;
 	if (rtmsg(RTM_DELETE) == 0) {
 		struct sockaddr_in6 s6 = *sin; /* XXX: for safety */
 
@@ -895,7 +896,7 @@ rtmsg(cmd)
 			rtm->rtm_rmx.rmx_expire = expire_time;
 			rtm->rtm_inits = RTV_EXPIRE;
 		}
-		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
+		rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
 #if 0 /* we don't support ipv6addr/128 type proxying */
 		if (rtm->rtm_flags & RTF_ANNOUNCE) {
 			rtm->rtm_flags &= ~RTF_HOST;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812261945.mBQJjPCq049254>