summaryrefslogtreecommitdiffstats
path: root/usr.sbin/route6d
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2012-11-18 15:48:02 +0000
committerhrs <hrs@FreeBSD.org>2012-11-18 15:48:02 +0000
commit1617f53d51625afc6ae1af36b7223b13ac61c673 (patch)
treec21f802139559ce2d37f9ff56f9a31b79059884b /usr.sbin/route6d
parentf3c2433c95ce485eb3ffc9498706d13adbfdd13a (diff)
downloadFreeBSD-src-1617f53d51625afc6ae1af36b7223b13ac61c673.zip
FreeBSD-src-1617f53d51625afc6ae1af36b7223b13ac61c673.tar.gz
- Increase the number of retry for NET_RT_DUMP from 5 to 15.
- Use 2001:db8:: as an example instead of deprecated 3ffe:: address block. - Add check for connected routes. - Add support of RTM_IFANNOUNCE for dyanmically-added/removed interfaces. - Add support of *, ?, and [ in the interface list. - Add -P number to specify route flag which will never expire. - Add -Q number to specify route flag which route6d will add to routes via RIP. - Add -p pidfile to specify the process ID file.
Diffstat (limited to 'usr.sbin/route6d')
-rw-r--r--usr.sbin/route6d/route6d.846
-rw-r--r--usr.sbin/route6d/route6d.c103
2 files changed, 140 insertions, 9 deletions
diff --git a/usr.sbin/route6d/route6d.8 b/usr.sbin/route6d/route6d.8
index 121f5f2..0d3226b 100644
--- a/usr.sbin/route6d/route6d.8
+++ b/usr.sbin/route6d/route6d.8
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 31, 1997
+.Dd November 18, 2012
.Dt ROUTE6D 8
.Os
.Sh NAME
@@ -41,6 +41,15 @@
.Op Fl O Ar prefix/preflen,if1[,if2...\&]
.Ek
.Bk -words
+.Op Fl P Ar number
+.Ek
+.Bk -words
+.Op Fl p Ar pidfile
+.Ek
+.Bk -words
+.Op Fl Q Ar number
+.Ek
+.Bk -words
.Op Fl T Ar if1[,if2...\&]
.Ek
.Bk -words
@@ -80,6 +89,12 @@ and advertises the aggregated route
.Ar prefix/preflen ,
to the interfaces specified in the comma-separated interface list,
.Ar if1[,if2...] .
+The characters
+.Qq Li * ,
+.Qq Li \&? ,
+and
+.Qq Li [
+in the interface list will be interpreted as shell-style pattern.
The
.Nm
utility creates a static route to
@@ -143,7 +158,7 @@ option.
For example, with
.Do
.Fl L
-.Li 3ffe::/16,if1
+.Li 2001:db8::/16,if1
.Fl L
.Li ::/0,if1
.Dc
@@ -164,6 +179,33 @@ With this option
.Nm
will only advertise routes that matches
.Ar prefix/preflen .
+.It Fl P Ar number
+Specifies routes to be ignored in calculation of expiration timer.
+The
+.Ar number
+must be
+.Li 1 ,
+.Li 2 ,
+or
+.Li 3
+and it means route flags of
+.Li RTF_PROTO1 ,
+.Li RTF_PROTO2 ,
+or
+.Li RTF_PROTO3 .
+When
+.Li 1
+is specified, routes with
+.Li RTF_PROTO1
+will never expire.
+.It Fl p Ar pidfile
+Specifies an alternative file in which to store the process ID.
+The default is
+.Pa /var/run/route6d.pid .
+.It Fl Q Ar number
+Specifies flag which will be used for routes added by RIP protocol.
+The default is
+.Li 2 Pq Li RTF_PROTO2 .
.\"
.It Fl q
Makes
diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c
index b5f334c..421ac1a 100644
--- a/usr.sbin/route6d/route6d.c
+++ b/usr.sbin/route6d/route6d.c
@@ -38,6 +38,7 @@ static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itoju
#include <time.h>
#include <unistd.h>
+#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
@@ -78,6 +79,7 @@ static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itoju
#include "route6d.h"
#define MAXFILTER 40
+#define RT_DUMP_MAXRETRY 15
#ifdef DEBUG
#define INIT_INTERVAL6 6
@@ -172,6 +174,8 @@ int nflag = 0; /* don't update kernel routing table */
int aflag = 0; /* age out even the statically defined routes */
int hflag = 0; /* don't split horizon */
int lflag = 0; /* exchange site local routes */
+int Pflag = 0; /* don't age out routes with RTF_PROTO[123] */
+int Qflag = RTF_PROTO2; /* set RTF_PROTO[123] flag to routes by RIPng */
int sflag = 0; /* announce static routes w/ split horizon */
int Sflag = 0; /* announce static routes to every interface */
unsigned long routetag = 0; /* route tag attached on originating case */
@@ -231,6 +235,7 @@ void applyplen(struct in6_addr *, int);
void ifrtdump(int);
void ifdump(int);
void ifdump0(FILE *, const struct ifc *);
+void ifremove(int);
void rtdump(int);
void rt_entry(struct rt_msghdr *, int);
void rtdexit(void);
@@ -279,9 +284,11 @@ main(int argc, char *argv[])
{
int ch;
int error = 0;
+ unsigned long proto;
struct ifc *ifcp;
sigset_t mask, omask;
- FILE *pidfile;
+ const char *pidfile = ROUTE6D_PID;
+ FILE *pidfh;
char *progname;
char *ep;
@@ -292,7 +299,7 @@ main(int argc, char *argv[])
progname = *argv;
pid = getpid();
- while ((ch = getopt(argc, argv, "A:N:O:R:T:L:t:adDhlnqsS")) != -1) {
+ while ((ch = getopt(argc, argv, "A:N:O:R:T:L:t:adDhlnp:P:Q:qsS")) != -1) {
switch (ch) {
case 'A':
case 'N':
@@ -314,6 +321,41 @@ main(int argc, char *argv[])
/*NOTREACHED*/
}
break;
+ case 'p':
+ pidfile = optarg;
+ break;
+ case 'P':
+ ep = NULL;
+ proto = strtoul(optarg, &ep, 0);
+ if (!ep || *ep != '\0' || 3 < proto) {
+ fatal("invalid P flag");
+ /*NOTREACHED*/
+ }
+ if (proto == 0)
+ Pflag = 0;
+ if (proto == 1)
+ Pflag |= RTF_PROTO1;
+ if (proto == 2)
+ Pflag |= RTF_PROTO2;
+ if (proto == 3)
+ Pflag |= RTF_PROTO3;
+ break;
+ case 'Q':
+ ep = NULL;
+ proto = strtoul(optarg, &ep, 0);
+ if (!ep || *ep != '\0' || 3 < proto) {
+ fatal("invalid Q flag");
+ /*NOTREACHED*/
+ }
+ if (proto == 0)
+ Qflag = 0;
+ if (proto == 1)
+ Qflag |= RTF_PROTO1;
+ if (proto == 2)
+ Qflag |= RTF_PROTO2;
+ if (proto == 3)
+ Qflag |= RTF_PROTO3;
+ break;
case 'R':
if ((rtlog = fopen(optarg, "w")) == NULL) {
fatal("Can not write to routelog");
@@ -390,9 +432,9 @@ main(int argc, char *argv[])
ifrtdump(0);
pid = getpid();
- if ((pidfile = fopen(ROUTE6D_PID, "w")) != NULL) {
- fprintf(pidfile, "%d\n", pid);
- fclose(pidfile);
+ if ((pidfh = fopen(pidfile, "w")) != NULL) {
+ fprintf(pidfh, "%d\n", pid);
+ fclose(pidfh);
}
if ((ripbuf = (struct rip6 *)malloc(RIP6_MAXMTU)) == NULL) {
@@ -1617,6 +1659,30 @@ ifconfig1(const char *name,
return 0;
}
+void
+ifremove(int ifindex)
+{
+ struct ifc *ifcp;
+ struct riprt *rrt;
+
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
+ if (ifcp->ifc_index == ifindex)
+ break;
+ }
+ if (ifcp == NULL)
+ return;
+
+ tracet(1, "ifremove: %s is departed.\n", ifcp->ifc_name);
+ TAILQ_REMOVE(&ifc_head, ifcp, ifc_next);
+
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
+ if (rrt->rrt_index == ifcp->ifc_index &&
+ rrt->rrt_rflags & RRTF_AGGREGATE)
+ delroute(&rrt->rrt_info, &rrt->rrt_gw);
+ }
+ free(ifcp);
+}
+
/*
* Receive and process routing messages.
* Update interface information as necesssary.
@@ -1629,6 +1695,7 @@ rtrecv(void)
struct rt_msghdr *rtm;
struct ifa_msghdr *ifam;
struct if_msghdr *ifm;
+ struct if_announcemsghdr *ifan;
int len;
struct ifc *ifcp, *ic;
int iface = 0, rtable = 0;
@@ -1684,6 +1751,18 @@ rtrecv(void)
addrs = ifm->ifm_addrs;
q = (char *)(ifm + 1);
break;
+ case RTM_IFANNOUNCE:
+ ifan = (struct if_announcemsghdr *)p;
+ switch (ifan->ifan_what) {
+ case IFAN_ARRIVAL:
+ iface++;
+ break;
+ case IFAN_DEPARTURE:
+ ifremove(ifan->ifan_index);
+ iface++;
+ break;
+ }
+ break;
default:
rtm = (struct rt_msghdr *)p;
addrs = rtm->rtm_addrs;
@@ -2560,7 +2639,7 @@ krtread(int again)
errmsg = "sysctl NET_RT_DUMP";
continue;
}
- } while (retry < 5 && errmsg != NULL);
+ } while (retry < RT_DUMP_MAXRETRY && errmsg != NULL);
if (errmsg) {
fatal("%s (with %d retries, msize=%lu)", errmsg, retry,
(u_long)msize);
@@ -2600,6 +2679,9 @@ rt_entry(struct rt_msghdr *rtm, int again)
if (rtm->rtm_flags & RTF_CLONED)
return;
#endif
+ /* XXX: Ignore connected routes. */
+ if (!(rtm->rtm_flags & (RTF_GATEWAY|RTF_HOST|RTF_STATIC)))
+ return;
/*
* do not look at dynamic routes.
* netbsd/openbsd cloned routes have UGHD.
@@ -2649,6 +2731,8 @@ rt_entry(struct rt_msghdr *rtm, int again)
rrt->rrt_t = time(NULL);
if (aflag == 0 && (rtm->rtm_flags & RTF_STATIC))
rrt->rrt_t = 0; /* Don't age static routes */
+ if (rtm->rtm_flags & Pflag)
+ rrt->rrt_t = 0; /* Don't age PROTO[123] routes */
if ((rtm->rtm_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST)
rrt->rrt_t = 0; /* Don't age non-gateway host routes */
np->rip6_tag = 0;
@@ -2763,6 +2847,7 @@ addroute(struct riprt *rrt,
rtm->rtm_seq = ++seq;
rtm->rtm_pid = pid;
rtm->rtm_flags = rrt->rrt_flags;
+ rtm->rtm_flags |= Qflag;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtm->rtm_rmx.rmx_hopcount = np->rip6_metric - 1;
rtm->rtm_inits = RTV_HOPCOUNT;
@@ -2828,6 +2913,7 @@ delroute(struct netinfo6 *np, struct in6_addr *gw)
rtm->rtm_seq = ++seq;
rtm->rtm_pid = pid;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
+ rtm->rtm_flags |= Qflag;
if (np->rip6_plen == sizeof(struct in6_addr) * 8)
rtm->rtm_flags |= RTF_HOST;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
@@ -3133,7 +3219,7 @@ ifonly:
*iflp++ = '\0';
TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
- if (strcmp(ifname, ifcp->ifc_name) != 0)
+ if (fnmatch(ifname, ifcp->ifc_name, 0) != 0)
continue;
iffp = malloc(sizeof(*iffp));
@@ -3142,6 +3228,9 @@ ifonly:
/*NOTREACHED*/
}
memcpy(iffp, &iff, sizeof(*iffp));
+#if 0
+ syslog(LOG_INFO, "Add filter: type %d, ifname %s.", iffp->iff_type, ifname);
+#endif
TAILQ_INSERT_HEAD(&ifcp->ifc_iff_head, iffp, iff_next);
}
}
OpenPOWER on IntegriCloud