Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 05 Feb 2012 06:05:17 +0900 (JST)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        melifaro@FreeBSD.org
Cc:        sem@FreeBSD.org, mark@mivok.net, net@FreeBSD.org
Subject:   Re: [CFT] multiple FIB support in route(8)
Message-ID:  <20120205.060517.982494808613553569.hrs@allbsd.org>
In-Reply-To: <4F2DC674.4070401@FreeBSD.org>
References:  <20120205.033532.381149506660559829.hrs@allbsd.org> <4F2DC674.4070401@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
----Security_Multipart0(Sun_Feb__5_06_05_18_2012_027)--
Content-Type: Multipart/Mixed;
	boundary="--Next_Part(Sun_Feb__5_06_05_17_2012_496)--"
Content-Transfer-Encoding: 7bit

----Next_Part(Sun_Feb__5_06_05_17_2012_496)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

"Alexander V. Chernikov" <melifaro@FreeBSD.org> wrote
  in <4F2DC674.4070401@FreeBSD.org>:

me> On 04.02.2012 18:35, Hiroki Sato wrote:
me> > Hello,
me> >
me> >   Can anyone review/test the attached patch to add "-fib number" option
me> >   to route(8)?  This should simplify static route configuration across
me> >   multiple FIBs in rc.conf.  Just adding an -fib option like the
me> >   following will do the trick without changing rc.d/routing:
me> >
me> >    static_routes="foo bar"
me> >    route_foo="10.1.1.1/24 192.168.2.1 -fib 2"
me> >    route_bar="10.1.1.1/24 192.168.2.1 -fib 3"
me> >
me> >   The -fib option is supported in all subcommands but monitor.
me> Why should we leave `monitor` as is?
me>
me> And, even if we really need to do so why "route monitor" silently
me> accepts and ignores -fib X key?

 No specific reason.  The monitor originally supports no flag to
 filter rt messages and silently ignores any flag.

 Is this a suggestion that it should support -fib or just from your
 curiosity?  I do not think we really need to leave it.  The attached
 patch is enough to support it, too.

-- Hiroki

----Next_Part(Sun_Feb__5_06_05_17_2012_496)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="route-fib.20120205-2.diff"

Index: sbin/route/route.c
===================================================================
--- sbin/route/route.c	(revision 230991)
+++ sbin/route/route.c	(working copy)
@@ -99,6 +99,8 @@
 struct	rt_metrics rt_metrics;
 u_long  rtm_inits;
 uid_t	uid;
+int	fib;
+int	numfibs;

 static int	atalk_aton(const char *, struct at_addr *);
 static char	*atalk_ntoa(struct at_addr);
@@ -112,7 +114,7 @@
 #endif
 static void	interfaces(void);
 static void	mask_addr(void);
-static void	monitor(void);
+static void	monitor(int, char*[]);
 static const char	*netname(struct sockaddr *);
 static void	newroute(int, char **);
 static void	pmsg_addrs(char *, int, size_t);
@@ -123,6 +125,8 @@
 static const char	*routename(struct sockaddr *);
 static int	rtmsg(int, int);
 static void	set_metric(char *, int);
+static void	set_sofib(int);
+static void	set_procfib(int);
 static void	sockaddr(char *, struct sockaddr *);
 static void	sodump(sup, const char *);
 extern	char *iso_ntoa(void);
@@ -144,6 +148,7 @@
 main(int argc, char **argv)
 {
 	int ch;
+	size_t len;

 	if (argc < 2)
 		usage(NULL);
@@ -180,6 +185,16 @@
 		s = socket(PF_ROUTE, SOCK_RAW, 0);
 	if (s < 0)
 		err(EX_OSERR, "socket");
+
+	len = sizeof(numfibs);
+	if (sysctlbyname("net.fibs", (void *)&numfibs, &len, NULL, 0) == -1)
+		numfibs = -1;
+
+	len = sizeof(fib);
+	if (numfibs != -1 &&
+	    sysctlbyname("net.my_fibnum", (void *)&fib, &len, NULL, 0) == -1)
+		fib = -1;
+
 	if (*argv != NULL)
 		switch (keyword(*argv)) {
 		case K_GET:
@@ -195,7 +210,7 @@
 			/* NOTREACHED */

 		case K_MONITOR:
-			monitor();
+			monitor(argc, argv);
 			/* NOTREACHED */

 		case K_FLUSH:
@@ -207,6 +222,31 @@
 	/* NOTREACHED */
 }

+static void
+set_sofib(int f)
+{
+	int error;
+
+	if (f > 0) {
+		error = setsockopt(s, SOL_SOCKET, SO_SETFIB, (void *)&f,
+		    sizeof(f));
+		if (error)
+			errx(EX_OSERR, "setsockopt(SO_SETFIB, %d) failed", f);
+	}
+}
+
+static void
+set_procfib(int f)
+{
+	int error;
+
+	if (f > 0) {
+		error = setfib(f);
+		if (error)
+			errx(EX_OSERR, "setfib(%d) failed", f);
+	}
+}
+
 /*
  * Purge all entries in the routing tables not
  * associated with network interfaces.
@@ -223,29 +263,39 @@
 		errx(EX_NOPERM, "must be root to alter routing table");
 	}
 	shutdown(s, SHUT_RD); /* Don't want to read back our messages */
-	if (argc > 1) {
+	while (argc > 1) {
+		argc--;
 		argv++;
-		if (argc == 2 && **argv == '-')
-		    switch (keyword(*argv + 1)) {
-			case K_INET:
-				af = AF_INET;
-				break;
+		if (**argv != '-')
+			usage(*argv);
+		switch (keyword(*argv + 1)) {
+		case K_INET:
+			af = AF_INET;
+			break;
 #ifdef INET6
-			case K_INET6:
-				af = AF_INET6;
-				break;
+		case K_INET6:
+			af = AF_INET6;
+			break;
 #endif
-			case K_ATALK:
-				af = AF_APPLETALK;
-				break;
-			case K_LINK:
-				af = AF_LINK;
-				break;
-			default:
-				goto bad;
-		} else
-bad:			usage(*argv);
+		case K_ATALK:
+			af = AF_APPLETALK;
+			break;
+		case K_LINK:
+			af = AF_LINK;
+			break;
+		case K_FIB:
+			if (!--argc)
+				usage(*argv);
+			fib = strtol(*++argv, NULL, 0);
+			if (fib == 0 && errno == EINVAL)
+				usage(*argv);
+			break;
+		default:
+			usage(*argv);
+		}
 	}
+	set_sofib(fib);
+	set_procfib(-1);
 retry:
 	mib[0] = CTL_NET;
 	mib[1] = PF_ROUTE;
@@ -657,6 +707,13 @@
 			case K_NOSTICK:
 				flags &= ~RTF_STICKY;
 				break;
+			case K_FIB:
+				if (!--argc)
+					usage(NULL);
+				fib = strtol(*++argv, NULL, 0);
+				if (fib == 0 && errno == EINVAL)
+					usage(NULL);
+				break;
 			case K_IFA:
 				if (!--argc)
 					usage(NULL);
@@ -751,6 +808,7 @@
 		so_dst.sinarp.sin_other = SIN_PROXY;
 		flags |= RTF_ANNOUNCE;
 	}
+	set_sofib(fib);
 	for (attempts = 1; ; attempts++) {
 		errno = 0;
 		if ((ret = rtmsg(*cmd, flags)) == 0)
@@ -777,6 +835,9 @@
 			    (void) printf(" (%s)",
 				inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
 		}
+		if (fib > 0)
+			printf(" fib %u", (unsigned int)fib);
+
 		if (ret == 0) {
 			(void) printf("\n");
 		} else {
@@ -1165,11 +1226,30 @@
 }

 static void
-monitor(void)
+monitor(int argc, char *argv[])
 {
 	int n;
 	char msg[2048];

+	while (argc > 1) {
+		argc--;
+		argv++;
+		if (**argv != '-')
+			usage(*argv);
+		switch (keyword(*argv + 1)) {
+		case K_FIB:
+			if (!--argc)
+				usage(*argv);
+			fib = strtol(*++argv, NULL, 0);
+			if (fib == 0 && errno == EINVAL)
+				usage(*argv);
+			break;
+		default:
+			usage(*argv);
+		}
+	}
+	set_sofib(fib);
+
 	verbose = 1;
 	if (debugonly) {
 		interfaces();
@@ -1490,6 +1570,8 @@
 	}
 	if (gate && rtm->rtm_flags & RTF_GATEWAY)
 		(void)printf("    gateway: %s\n", routename(gate));
+	if (fib > 0)
+		(void)printf("        fib: %u\n", (unsigned int)fib);
 	if (ifp)
 		(void)printf("  interface: %.*s\n",
 		    ifp->sdl_nlen, ifp->sdl_data);
Index: sbin/route/route.8
===================================================================
--- sbin/route/route.8	(revision 230991)
+++ sbin/route/route.8	(working copy)
@@ -28,7 +28,7 @@
 .\"     @(#)route.8	8.3 (Berkeley) 3/19/94
 .\" $FreeBSD$
 .\"
-.Dd October 2, 2005
+.Dd January 29, 2012
 .Dt ROUTE 8
 .Os
 .Sh NAME
@@ -124,6 +124,7 @@
 .Op Fl n
 .Cm flush
 .Op Ar family
+.Op Fl fib Ar number
 .Ed
 .Pp
 If the
@@ -140,6 +141,10 @@
 .Fl inet
 modifiers, only routes having destinations with addresses in the
 delineated family will be deleted.
+When an
+.Fl fib
+option is specified, the operation will be applied to
+the specified FIB.
 .Pp
 The other commands have the following syntax:
 .Pp
@@ -310,6 +315,21 @@
 .Fl lockrest
 meta-modifier.
 .Pp
+The optional modifier
+.Fl fib Ar number
+specifies the command will be applied to a different routing table.
+The
+.Ar number
+must be smaller than the
+.Va net.fibs
+.Xr sysctl 8
+MIB.
+When this modifier is not specified,
+the default routing table shown in the
+.Va net.my_fibnum
+.Xr sysctl 8
+MIB will be used.
+.Pp
 In a
 .Cm change
 or
Index: sbin/route/keywords
===================================================================
--- sbin/route/keywords	(revision 230991)
+++ sbin/route/keywords	(working copy)
@@ -10,6 +10,7 @@
 delete
 dst
 expire
+fib
 flush
 gateway
 genmask

----Next_Part(Sun_Feb__5_06_05_17_2012_496)----

----Security_Multipart0(Sun_Feb__5_06_05_18_2012_027)--
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (FreeBSD)

iEYEABECAAYFAk8tnY4ACgkQTyzT2CeTzy1GTQCfco2WYvfhzDCl4UyD/4wf4kED
XAsAoMQgLFJ/tsNDb6VbAtJw6zOWmXae
=V5E/
-----END PGP SIGNATURE-----

----Security_Multipart0(Sun_Feb__5_06_05_18_2012_027)----



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