tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

RTF_BROADCAST



Hi

FreeBSD added RTF_BROADCAST a very long time ago.
I'd like to add it to NetBSD to make it clear what the route is for and
to avoid a potentially expensive call to in_broadcast() in ip_output().
It also avoids a needless allocation for the storage of llinfo_arp and
thus vanishes from the output of arp(8) - it always showed as incomplete
so this is a nice side effect.

FreeBSD also uses RTF_BROADCAST as a check to drop packets in
ip_fastforward() .... the closest match I can find is our
ipflow_fastforward() where I made a similar change and ensuring the
route is not RTF_BLACKHOLE either.
Oddly FreeBSD does not have the same functionality for IPv6 as I can
find, but we do so I added a check there as well.
If you are wondering why there is not a check for RTF_BROADCAST in
ip6_fastforward() it's because broadcast addresses are a IPv4 only concept.

I've been running this patch on a few machines, including my router, for
a few days now without any adverse effects.
Commentary welcome.

Roy
Index: sys/net/route.h
===================================================================
RCS file: /cvsroot/src/sys/net/route.h,v
retrieving revision 1.87
diff -u -r1.87 route.h
--- sys/net/route.h	26 Feb 2015 09:54:46 -0000	1.87
+++ sys/net/route.h	19 Mar 2015 19:42:25 -0000
@@ -156,6 +156,7 @@
 #define RTF_SRC		0x10000		/* route has fixed source address */
 #define RTF_ANNOUNCE	0x20000		/* announce new ARP or NDP entry */
 #define RTF_LOCAL	0x40000		/* route represents a local address */
+#define RTF_BROADCAST	0x80000		/* route represents a bcast address */
 
 /*
  * Routing statistics.
Index: sys/netinet/if_arp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/if_arp.c,v
retrieving revision 1.161
diff -u -r1.161 if_arp.c
--- sys/netinet/if_arp.c	26 Feb 2015 09:54:46 -0000	1.161
+++ sys/netinet/if_arp.c	19 Mar 2015 19:42:26 -0000
@@ -613,10 +613,24 @@
 			log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
 			break;
 		}
+
 		satosdl(gate)->sdl_type = ifp->if_type;
 		satosdl(gate)->sdl_index = ifp->if_index;
 		if (la != NULL)
 			break; /* This happens on a route change */
+
+		/* If the route is for a broadcast address mark it as such.
+		 * This way we can avoid an expensive call to in_broadcast()
+		 * in ip_output() most of the time (because the route passed
+		 * to ip_output() is almost always a host route). */
+		if (rt->rt_flags & RTF_HOST &&
+		    !(rt->rt_flags & RTF_BROADCAST) &&
+		    in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp))
+			rt->rt_flags |= RTF_BROADCAST;
+		/* There is little point in resolving the broadcast address */
+		if (rt->rt_flags & RTF_BROADCAST)
+			break;
+
 		/*
 		 * Case 2:  This route may come from cloning, or a manual route
 		 * add with a LL address.
Index: sys/netinet/ip_flow.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_flow.c,v
retrieving revision 1.65
diff -u -r1.65 ip_flow.c
--- sys/netinet/ip_flow.c	18 Oct 2014 08:33:29 -0000	1.65
+++ sys/netinet/ip_flow.c	19 Mar 2015 19:42:26 -0000
@@ -234,7 +234,8 @@
 	 * Route and interface still up?
 	 */
 	if ((rt = rtcache_validate(&ipf->ipf_ro)) == NULL ||
-	    (rt->rt_ifp->if_flags & IFF_UP) == 0)
+	    (rt->rt_ifp->if_flags & IFF_UP) == 0 ||
+	    (rt->rt_flags & (RTF_BLACKHOLE | RTF_BROADCAST)) != 0)
 		return 0;
 
 	/*
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.233
diff -u -r1.233 ip_output.c
--- sys/netinet/ip_output.c	26 Nov 2014 10:18:37 -0000	1.233
+++ sys/netinet/ip_output.c	19 Mar 2015 19:42:27 -0000
@@ -163,6 +163,7 @@
 	struct route iproute;
 	const struct sockaddr_in *dst;
 	struct in_ifaddr *ia;
+	int isbroadcast;
 	struct mbuf *opt;
 	struct route *ro;
 	int flags, sw_csum;
@@ -257,12 +258,14 @@
 		ifp = ia->ia_ifp;
 		mtu = ifp->if_mtu;
 		ip->ip_ttl = 1;
+		isbroadcast = in_broadcast(dst->sin_addr, ifp);
 	} else if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
 	    ip->ip_dst.s_addr == INADDR_BROADCAST) &&
 	    imo != NULL && imo->imo_multicast_ifp != NULL) {
 		ifp = imo->imo_multicast_ifp;
 		mtu = ifp->if_mtu;
 		IFP_TO_IA(ifp, ia);
+		isbroadcast = 0;
 	} else {
 		if (rt == NULL)
 			rt = rtcache_init(ro);
@@ -278,6 +281,10 @@
 		rt->rt_use++;
 		if (rt->rt_flags & RTF_GATEWAY)
 			dst = satosin(rt->rt_gateway);
+		if (rt->rt_flags & RTF_HOST)
+			isbroadcast = rt->rt_flags & RTF_BROADCAST;
+		else
+			isbroadcast = in_broadcast(dst->sin_addr, ifp);
 	}
 	rtmtu_nolock = rt && (rt->rt_rmx.rmx_locks & RTV_MTU) == 0;
 
@@ -412,7 +419,7 @@
 	 * Look for broadcast address and and verify user is allowed to
 	 * send such a packet.
 	 */
-	if (in_broadcast(dst->sin_addr, ifp)) {
+	if (isbroadcast) {
 		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
 			error = EADDRNOTAVAIL;
 			goto bad;
Index: sys/netinet6/ip6_flow.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_flow.c,v
retrieving revision 1.23
diff -u -r1.23 ip6_flow.c
--- sys/netinet6/ip6_flow.c	20 May 2014 20:23:56 -0000	1.23
+++ sys/netinet6/ip6_flow.c	19 Mar 2015 19:42:29 -0000
@@ -275,10 +275,9 @@
 	 * Route and interface still up?
 	 */
 	if ((rt = rtcache_validate(&ip6f->ip6f_ro)) == NULL ||
-	    (rt->rt_ifp->if_flags & IFF_UP) == 0) {
-	    	/* Route or interface is down */
+	    (rt->rt_ifp->if_flags & IFF_UP) == 0 ||
+	    (rt->rt_flags & RTF_BLACKHOLE) != 0)
 		return 0;
-	}
 
 	/*
 	 * Packet size greater than MTU?
Index: share/man/man4/route.4
===================================================================
RCS file: /cvsroot/src/share/man/man4/route.4,v
retrieving revision 1.24
diff -u -r1.24 route.4
--- share/man/man4/route.4	26 Feb 2015 09:58:39 -0000	1.24
+++ share/man/man4/route.4	19 Mar 2015 19:42:34 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)route.4	8.6 (Berkeley) 4/19/94
 .\"
-.Dd February 26, 2015
+.Dd March 19, 2015
 .Dt ROUTE 4
 .Os
 .Sh NAME
@@ -311,6 +311,7 @@
 #define	RTF_SRC       0x10000   /* route has fixed source address */
 #define	RTF_ANNOUNCE  0x20000   /* announce new ARP or NDP entry */
 #define	RTF_LOCAL     0x40000   /* route represents a local address */
+#define	RTF_BROADCAST 0x80000   /* route represents a bcast address */
 .Ed
 .Pp
 Specifiers for metric values in rmx_locks and rtm_inits are:
Index: sbin/route/route.8
===================================================================
RCS file: /cvsroot/src/sbin/route/route.8,v
retrieving revision 1.54
diff -u -r1.54 route.8
--- sbin/route/route.8	26 Feb 2015 09:56:11 -0000	1.54
+++ sbin/route/route.8	19 Mar 2015 19:42:35 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)route.8	8.4 (Berkeley) 6/1/94
 .\"
-.Dd February 26, 2015
+.Dd March 19, 2015
 .Dt ROUTE 8
 .Os
 .Sh NAME
@@ -295,6 +295,7 @@
 .It Li 1 Ta -proto1 Ta " RTF_PROTO1" Ta set protocol specific flag #1
 .It Li 2 Ta -proto2 Ta " RTF_PROTO2" Ta set protocol specific flag #2
 .It Li B Ta -blackhole Ta " RTF_BLACKHOLE" Ta discard pkts (during updates)
+.It Li b Ta "" Ta " RTF_BROADCAST" Ta Route represents a broadcast address
 .It Li " " Ta -noblackhole Ta ~RTF_BLACKHOLE Ta clear blackhole flag
 .It Li C Ta -cloning Ta " RTF_CLONING" Ta  generates a new route on use
 .It Li " " Ta -nocloning Ta ~RTF_CLONING Ta stop generating new routes on use
Index: sbin/route/route.c
===================================================================
RCS file: /cvsroot/src/sbin/route/route.c,v
retrieving revision 1.150
diff -u -r1.150 route.c
--- sbin/route/route.c	26 Feb 2015 09:56:11 -0000	1.150
+++ sbin/route/route.c	19 Mar 2015 19:42:36 -0000
@@ -1292,7 +1292,7 @@
 const char metricnames[] =
 "\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";
 const char routeflags[] =
-"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016CLONED\017PROTO2\020PROTO1\023LOCAL";
+"\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE\016CLONED\017PROTO2\020PROTO1\023LOCAL\024BROADCAST";
 const char ifnetflags[] =
 "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST";
 const char addrnames[] =
Index: sbin/route/rtutil.c
===================================================================
RCS file: /cvsroot/src/sbin/route/rtutil.c,v
retrieving revision 1.5
diff -u -r1.5 rtutil.c
--- sbin/route/rtutil.c	26 Feb 2015 09:56:11 -0000	1.5
+++ sbin/route/rtutil.c	19 Mar 2015 19:42:36 -0000
@@ -93,6 +93,7 @@
 	/* { RTF_JUMBO,	'J' }, */
 	{ RTF_ANNOUNCE,	'p' },
 	{ RTF_LOCAL, 'l'},
+	{ RTF_BROADCAST, 'b'},
 	{ 0, 0 }
 };
 
Index: sbin/route/show.c
===================================================================
RCS file: /cvsroot/src/sbin/route/show.c,v
retrieving revision 1.47
diff -u -r1.47 show.c
--- sbin/route/show.c	26 Feb 2015 09:56:11 -0000	1.47
+++ sbin/route/show.c	19 Mar 2015 19:42:36 -0000
@@ -137,7 +137,7 @@
 {
 	int af, rflags;
 	static int interesting = RTF_UP | RTF_GATEWAY | RTF_HOST |
-	    RTF_REJECT | RTF_LLINFO | RTF_LOCAL;
+	    RTF_REJECT | RTF_LLINFO | RTF_LOCAL | RTF_BROADCAST;
 
 	parse_show_opts(argc, argv, &af, &rflags, NULL, true);
 	p_rttables(af, flags, rflags, interesting);
Index: usr.bin/netstat/netstat.1
===================================================================
RCS file: /cvsroot/src/usr.bin/netstat/netstat.1,v
retrieving revision 1.71
diff -u -r1.71 netstat.1
--- usr.bin/netstat/netstat.1	26 Feb 2015 09:58:12 -0000	1.71
+++ usr.bin/netstat/netstat.1	19 Mar 2015 19:42:36 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"	@(#)netstat.1	8.8 (Berkeley) 4/18/94
 .\"
-.Dd February 26, 2015
+.Dd March 19, 2015
 .Dt NETSTAT 1
 .Os
 .Sh NAME
@@ -372,6 +372,7 @@
 .It 1	RTF_PROTO1	Protocol specific routing flag #1
 .It 2	RTF_PROTO2	Protocol specific routing flag #2
 .It B	RTF_BLACKHOLE	Just discard pkts (during updates)
+.It b	RTF_BROADCAST	Route represents a broadcast address
 .It C	RTF_CLONING	Generate new routes on use
 .It c	RTF_CLONED	Cloned routes (generated from RTF_CLONING)
 .It D	RTF_DYNAMIC	Created dynamically (by redirect)


Home | Main Index | Thread Index | Old Index