svn commit: r251724 - stable/9/usr.sbin/route6d
Hiroki Sato
hrs at FreeBSD.org
Fri Jun 14 02:21:32 UTC 2013
Author: hrs
Date: Fri Jun 14 02:21:32 2013
New Revision: 251724
URL: http://svnweb.freebsd.org/changeset/base/251724
Log:
MFC 228990,243232,243233:
Overhaul of route6d(8):
- Use queue(3) for linked-list.
- Use a consistent naming scheme for struct members.
- Use ANSI C style function declaration.
- Add check of RTM_VERSION mismatch.
- 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.
Modified:
stable/9/usr.sbin/route6d/route6d.8
stable/9/usr.sbin/route6d/route6d.c
Directory Properties:
stable/9/usr.sbin/route6d/ (props changed)
Modified: stable/9/usr.sbin/route6d/route6d.8
==============================================================================
--- stable/9/usr.sbin/route6d/route6d.8 Fri Jun 14 01:12:59 2013 (r251723)
+++ stable/9/usr.sbin/route6d/route6d.8 Fri Jun 14 02:21:32 2013 (r251724)
@@ -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
Modified: stable/9/usr.sbin/route6d/route6d.c
==============================================================================
--- stable/9/usr.sbin/route6d/route6d.c Fri Jun 14 01:12:59 2013 (r251723)
+++ stable/9/usr.sbin/route6d/route6d.c Fri Jun 14 02:21:32 2013 (r251724)
@@ -31,13 +31,14 @@
*/
#ifndef lint
-static char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itojun Exp $";
+static const char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itojun Exp $";
#endif
#include <stdio.h>
#include <time.h>
#include <unistd.h>
+#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
@@ -78,6 +79,7 @@ static char _rcsid[] = "$KAME: route6d.c
#include "route6d.h"
#define MAXFILTER 40
+#define RT_DUMP_MAXRETRY 15
#ifdef DEBUG
#define INIT_INTERVAL6 6
@@ -102,9 +104,10 @@ static char _rcsid[] = "$KAME: route6d.c
(addr).s6_addr[3] = (index) & 0xff; \
} while (0)
-struct ifc { /* Configuration of an interface */
- char *ifc_name; /* if name */
- struct ifc *ifc_next;
+struct ifc { /* Configuration of an interface */
+ TAILQ_ENTRY(ifc) ifc_next;
+
+ char ifc_name[IFNAMSIZ]; /* if name */
int ifc_index; /* if index */
int ifc_mtu; /* if mtu */
int ifc_metric; /* if metric */
@@ -112,30 +115,32 @@ struct ifc { /* Configuration of an in
short ifc_cflags; /* IFC_XXX */
struct in6_addr ifc_mylladdr; /* my link-local address */
struct sockaddr_in6 ifc_ripsin; /* rip multicast address */
- struct iff *ifc_filter; /* filter structure */
- struct ifac *ifc_addr; /* list of AF_INET6 addresses */
+ TAILQ_HEAD(, ifac) ifc_ifac_head; /* list of AF_INET6 addrs */
+ TAILQ_HEAD(, iff) ifc_iff_head; /* list of filters */
int ifc_joined; /* joined to ff02::9 */
};
+TAILQ_HEAD(, ifc) ifc_head = TAILQ_HEAD_INITIALIZER(ifc_head);
+
+struct ifac { /* Adddress associated to an interface */
+ TAILQ_ENTRY(ifac) ifac_next;
-struct ifac { /* Adddress associated to an interface */
- struct ifc *ifa_conf; /* back pointer */
- struct ifac *ifa_next;
- struct in6_addr ifa_addr; /* address */
- struct in6_addr ifa_raddr; /* remote address, valid in p2p */
- int ifa_plen; /* prefix length */
+ struct ifc *ifac_ifc; /* back pointer */
+ struct in6_addr ifac_addr; /* address */
+ struct in6_addr ifac_raddr; /* remote address, valid in p2p */
+ int ifac_scope_id; /* scope id */
+ int ifac_plen; /* prefix length */
};
-struct iff {
+struct iff { /* Filters for an interface */
+ TAILQ_ENTRY(iff) iff_next;
+
int iff_type;
struct in6_addr iff_addr;
int iff_plen;
- struct iff *iff_next;
};
-struct ifc *ifc;
-int nifc; /* number of valid ifc's */
struct ifc **index2ifc;
-int nindex2ifc;
+unsigned int nindex2ifc;
struct ifc *loopifcp = NULL; /* pointing to loopback */
#ifdef HAVE_POLL_H
struct pollfd set[2];
@@ -159,11 +164,12 @@ struct rip6 *ripbuf; /* packet buffer fo
* One of the major drawbacks of the linear linked list is the difficulty
* of representing the relationship between a couple of routes. This may
* be a significant problem when we have to support route aggregation with
- * supressing the specifices covered by the aggregate.
+ * suppressing the specifics covered by the aggregate.
*/
-struct riprt {
- struct riprt *rrt_next; /* next destination */
+struct riprt {
+ TAILQ_ENTRY(riprt) rrt_next; /* next destination */
+
struct riprt *rrt_same; /* same destination - future use */
struct netinfo6 rrt_info; /* network info */
struct in6_addr rrt_gw; /* gateway */
@@ -172,8 +178,7 @@ struct riprt {
time_t rrt_t; /* when the route validated */
int rrt_index; /* ifindex from which this route got */
};
-
-struct riprt *riprt = 0;
+TAILQ_HEAD(, riprt) riprt_head = TAILQ_HEAD_INITIALIZER(riprt_head);
int dflag = 0; /* debug flag */
int qflag = 0; /* quiet flag */
@@ -181,6 +186,8 @@ int nflag = 0; /* don't update kernel ro
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 */
@@ -222,7 +229,7 @@ int out_filter(struct riprt *, struct if
void init(void);
void sockopt(struct ifc *);
void ifconfig(void);
-void ifconfig1(const char *, const struct sockaddr *, struct ifc *, int);
+int ifconfig1(const char *, const struct sockaddr *, struct ifc *, int);
void rtrecv(void);
int rt_del(const struct sockaddr_in6 *, const struct sockaddr_in6 *,
const struct sockaddr_in6 *);
@@ -240,12 +247,13 @@ 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);
void riprequest(struct ifc *, struct netinfo6 *, int,
struct sockaddr_in6 *);
-void ripflush(struct ifc *, struct sockaddr_in6 *);
+void ripflush(struct ifc *, struct sockaddr_in6 *, int, struct netinfo6 *np);
void sendrequest(struct ifc *);
int sin6mask2len(const struct sockaddr_in6 *);
int mask2len(const struct in6_addr *, int);
@@ -260,7 +268,7 @@ char *hms(void);
const char *inet6_n2p(const struct in6_addr *);
struct ifac *ifa_match(const struct ifc *, const struct in6_addr *, int);
struct in6_addr *plen2mask(int);
-struct riprt *rtsearch(struct netinfo6 *, struct riprt **);
+struct riprt *rtsearch(struct netinfo6 *);
int ripinterval(int);
time_t ripsuptrig(void);
void fatal(const char *, ...)
@@ -276,16 +284,23 @@ void setindex2ifc(int, struct ifc *);
#define MALLOC(type) ((type *)malloc(sizeof(type)))
+#define IFIL_TYPE_ANY 0x0
+#define IFIL_TYPE_A 'A'
+#define IFIL_TYPE_N 'N'
+#define IFIL_TYPE_T 'T'
+#define IFIL_TYPE_O 'O'
+#define IFIL_TYPE_L 'L'
+
int
-main(argc, argv)
- int argc;
- char **argv;
+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;
@@ -296,7 +311,7 @@ main(argc, 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':
@@ -318,6 +333,41 @@ main(argc, 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");
@@ -372,11 +422,10 @@ main(argc, argv)
init();
ifconfig();
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
if (ifcp->ifc_index < 0) {
- fprintf(stderr,
-"No ifindex found at %s (no link-local address?)\n",
- ifcp->ifc_name);
+ fprintf(stderr, "No ifindex found at %s "
+ "(no link-local address?)\n", ifcp->ifc_name);
error++;
}
}
@@ -386,20 +435,19 @@ main(argc, argv)
fatal("No loopback found");
/*NOTREACHED*/
}
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next)
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
ifrt(ifcp, 0);
+ }
filterconfig();
krtread(0);
if (dflag)
ifrtdump(0);
-#if 1
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);
}
-#endif
if ((ripbuf = (struct rip6 *)malloc(RIP6_MAXMTU)) == NULL) {
fatal("malloc");
@@ -427,8 +475,8 @@ main(argc, argv)
*/
alarm(ripinterval(INIT_INTERVAL6));
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
- if (iff_find(ifcp, 'N'))
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
+ if (iff_find(ifcp, IFIL_TYPE_N) != NULL)
continue;
if (ifcp->ifc_index > 0 && (ifcp->ifc_flags & IFF_UP))
sendrequest(ifcp);
@@ -495,8 +543,7 @@ main(argc, argv)
}
void
-sighandler(signo)
- int signo;
+sighandler(int signo)
{
switch (signo) {
@@ -520,12 +567,12 @@ sighandler(signo)
*/
/* ARGSUSED */
void
-rtdexit()
+rtdexit(void)
{
struct riprt *rrt;
alarm(0);
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (rrt->rrt_rflags & RRTF_AGGREGATE) {
delroute(&rrt->rrt_info, &rrt->rrt_gw);
}
@@ -547,39 +594,27 @@ rtdexit()
*/
/* ARGSUSED */
void
-ripalarm()
+ripalarm(void)
{
struct ifc *ifcp;
- struct riprt *rrt, *rrt_prev, *rrt_next;
+ struct riprt *rrt, *rrt_tmp;
time_t t_lifetime, t_holddown;
/* age the RIP routes */
- rrt_prev = 0;
t_lifetime = time(NULL) - RIP_LIFETIME;
t_holddown = t_lifetime - RIP_HOLDDOWN;
- for (rrt = riprt; rrt; rrt = rrt_next) {
- rrt_next = rrt->rrt_next;
-
- if (rrt->rrt_t == 0) {
- rrt_prev = rrt;
+ TAILQ_FOREACH_SAFE(rrt, &riprt_head, rrt_next, rrt_tmp) {
+ if (rrt->rrt_t == 0)
continue;
- }
- if (rrt->rrt_t < t_holddown) {
- if (rrt_prev) {
- rrt_prev->rrt_next = rrt->rrt_next;
- } else {
- riprt = rrt->rrt_next;
- }
+ else if (rrt->rrt_t < t_holddown) {
+ TAILQ_REMOVE(&riprt_head, rrt, rrt_next);
delroute(&rrt->rrt_info, &rrt->rrt_gw);
free(rrt);
- continue;
- }
- if (rrt->rrt_t < t_lifetime)
+ } else if (rrt->rrt_t < t_lifetime)
rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6;
- rrt_prev = rrt;
}
/* Supply updates */
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
if (ifcp->ifc_index > 0 && (ifcp->ifc_flags & IFF_UP))
ripsend(ifcp, &ifcp->ifc_ripsin, 0);
}
@@ -587,15 +622,14 @@ ripalarm()
}
void
-init()
+init(void)
{
int error;
const int int0 = 0, int1 = 1, int255 = 255;
struct addrinfo hints, *res;
char port[NI_MAXSERV];
- ifc = (struct ifc *)NULL;
- nifc = 0;
+ TAILQ_INIT(&ifc_head);
nindex2ifc = 0; /*initial guess*/
index2ifc = NULL;
snprintf(port, sizeof(port), "%u", RIP6_PORT);
@@ -735,13 +769,8 @@ init()
/*
* ripflush flushes the rip datagram stored in the rip buffer
*/
-static int nrt;
-static struct netinfo6 *np;
-
void
-ripflush(ifcp, sin6)
- struct ifc *ifcp;
- struct sockaddr_in6 *sin6;
+ripflush(struct ifc *ifcp, struct sockaddr_in6 *sin6, int nrt, struct netinfo6 *np)
{
int i;
int error;
@@ -783,21 +812,19 @@ ripflush(ifcp, sin6)
ifcp->ifc_name, inet6_n2p(&ifcp->ifc_ripsin.sin6_addr));
ifcp->ifc_flags &= ~IFF_UP; /* As if down for AF_INET6 */
}
- nrt = 0; np = ripbuf->rip6_nets;
}
/*
* Generate RIP6_RESPONSE packets and send them.
*/
void
-ripsend(ifcp, sin6, flag)
- struct ifc *ifcp;
- struct sockaddr_in6 *sin6;
- int flag;
+ripsend(struct ifc *ifcp, struct sockaddr_in6 *sin6, int flag)
{
struct riprt *rrt;
struct in6_addr *nh; /* next hop */
+ struct netinfo6 *np;
int maxrte;
+ int nrt;
if (qflag)
return;
@@ -811,20 +838,24 @@ ripsend(ifcp, sin6, flag)
sizeof(struct udphdr) -
sizeof(struct rip6) + sizeof(struct netinfo6)) /
sizeof(struct netinfo6);
- nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ nh = NULL;
+ nrt = 0;
+ np = ripbuf->rip6_nets;
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
/* Put the route to the buffer */
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
- ripflush(NULL, sin6);
+ ripflush(NULL, sin6, nrt, np);
nh = NULL;
+ nrt = 0;
+ np = ripbuf->rip6_nets;
}
}
if (nrt) /* Send last packet */
- ripflush(NULL, sin6);
+ ripflush(NULL, sin6, nrt, np);
return;
}
@@ -833,11 +864,11 @@ ripsend(ifcp, sin6, flag)
return;
/* -N: no use */
- if (iff_find(ifcp, 'N') != NULL)
+ if (iff_find(ifcp, IFIL_TYPE_N) != NULL)
return;
/* -T: generate default route only */
- if (iff_find(ifcp, 'T') != NULL) {
+ if (iff_find(ifcp, IFIL_TYPE_T) != NULL) {
struct netinfo6 rrt_info;
memset(&rrt_info, 0, sizeof(struct netinfo6));
rrt_info.rip6_dest = in6addr_any;
@@ -848,7 +879,7 @@ ripsend(ifcp, sin6, flag)
np = ripbuf->rip6_nets;
*np = rrt_info;
nrt = 1;
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt, np);
return;
}
@@ -858,7 +889,7 @@ ripsend(ifcp, sin6, flag)
sizeof(struct netinfo6);
nrt = 0; np = ripbuf->rip6_nets; nh = NULL;
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (rrt->rrt_rflags & RRTF_NOADVERTISE)
continue;
@@ -880,8 +911,13 @@ ripsend(ifcp, sin6, flag)
!IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw) &&
(rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) {
if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw)) {
- if (nrt == maxrte - 2)
- ripflush(ifcp, sin6);
+ if (nrt == maxrte - 2) {
+ ripflush(ifcp, sin6, nrt, np);
+ nh = NULL;
+ nrt = 0;
+ np = ripbuf->rip6_nets;
+ }
+
np->rip6_dest = rrt->rrt_gw;
if (IN6_IS_ADDR_LINKLOCAL(&np->rip6_dest))
SET_IN6_LINKLOCAL_IFINDEX(np->rip6_dest, 0);
@@ -895,8 +931,12 @@ ripsend(ifcp, sin6, flag)
!IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw) ||
rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) {
/* Reset nexthop */
- if (nrt == maxrte - 2)
- ripflush(ifcp, sin6);
+ if (nrt == maxrte - 2) {
+ ripflush(ifcp, sin6, nrt, np);
+ nh = NULL;
+ nrt = 0;
+ np = ripbuf->rip6_nets;
+ }
memset(np, 0, sizeof(struct netinfo6));
np->rip6_metric = NEXTHOP_METRIC;
nh = NULL;
@@ -907,21 +947,21 @@ ripsend(ifcp, sin6, flag)
*np = rrt->rrt_info;
np++; nrt++;
if (nrt == maxrte) {
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt, np);
nh = NULL;
+ nrt = 0;
+ np = ripbuf->rip6_nets;
}
}
if (nrt) /* Send last packet */
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt, np);
}
/*
* outbound filter logic, per-route/interface.
*/
int
-out_filter(rrt, ifcp)
- struct riprt *rrt;
- struct ifc *ifcp;
+out_filter(struct riprt *rrt, struct ifc *ifcp)
{
struct iff *iffp;
struct in6_addr ia;
@@ -931,7 +971,7 @@ out_filter(rrt, ifcp)
* -A: filter out less specific routes, if we have aggregated
* route configured.
*/
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
if (iffp->iff_type != 'A')
continue;
if (rrt->rrt_info.rip6_plen <= iffp->iff_plen)
@@ -948,7 +988,7 @@ out_filter(rrt, ifcp)
*/
if ((rrt->rrt_rflags & RRTF_AGGREGATE) != 0) {
ok = 0;
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
if (iffp->iff_type != 'A')
continue;
if (rrt->rrt_info.rip6_plen == iffp->iff_plen &&
@@ -965,9 +1005,9 @@ out_filter(rrt, ifcp)
/*
* -O: advertise only if prefix matches the configured prefix.
*/
- if (iff_find(ifcp, 'O')) {
+ if (iff_find(ifcp, IFIL_TYPE_O) != NULL) {
ok = 0;
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
if (iffp->iff_type != 'O')
continue;
if (rrt->rrt_info.rip6_plen < iffp->iff_plen)
@@ -992,9 +1032,7 @@ out_filter(rrt, ifcp)
* It checks options specified in the arguments and the split horizon rule.
*/
int
-tobeadv(rrt, ifcp)
- struct riprt *rrt;
- struct ifc *ifcp;
+tobeadv(struct riprt *rrt, struct ifc *ifcp)
{
/* Special care for static routes */
@@ -1019,9 +1057,7 @@ tobeadv(rrt, ifcp)
* Send a rip packet actually.
*/
int
-sendpacket(sin6, len)
- struct sockaddr_in6 *sin6;
- int len;
+sendpacket(struct sockaddr_in6 *sin6, int len)
{
struct msghdr m;
struct cmsghdr *cm;
@@ -1080,7 +1116,7 @@ sendpacket(sin6, len)
* table if necessary.
*/
void
-riprecv()
+riprecv(void)
{
struct ifc *ifcp, *ic;
struct sockaddr_in6 fsock;
@@ -1147,7 +1183,7 @@ riprecv()
if (idx && IN6_IS_ADDR_LINKLOCAL(&fsock.sin6_addr))
SET_IN6_LINKLOCAL_IFINDEX(fsock.sin6_addr, idx);
- if (len < sizeof(struct rip6)) {
+ if ((size_t)len < sizeof(struct rip6)) {
trace(1, "Packet too short\n");
return;
}
@@ -1235,7 +1271,7 @@ riprecv()
}
/* -N: no use */
- if (iff_find(ifcp, 'N') != NULL)
+ if (iff_find(ifcp, IFIL_TYPE_N) != NULL)
return;
tracet(1, "Recv(%s): from %s.%d info(%zd)\n",
@@ -1300,23 +1336,23 @@ riprecv()
/*
* -L: listen only if the prefix matches the configuration
*/
- ok = 1; /* if there's no L filter, it is ok */
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
- if (iffp->iff_type != 'L')
- continue;
- ok = 0;
- if (np->rip6_plen < iffp->iff_plen)
- continue;
- /* special rule: ::/0 means default, not "in /0" */
- if (iffp->iff_plen == 0 && np->rip6_plen > 0)
- continue;
- ia = np->rip6_dest;
- applyplen(&ia, iffp->iff_plen);
- if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) {
- ok = 1;
- break;
- }
- }
+ ok = 1; /* if there's no L filter, it is ok */
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
+ if (iffp->iff_type != IFIL_TYPE_L)
+ continue;
+ ok = 0;
+ if (np->rip6_plen < iffp->iff_plen)
+ continue;
+ /* special rule: ::/0 means default, not "in /0" */
+ if (iffp->iff_plen == 0 && np->rip6_plen > 0)
+ continue;
+ ia = np->rip6_dest;
+ applyplen(&ia, iffp->iff_plen);
+ if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) {
+ ok = 1;
+ break;
+ }
+ }
if (!ok) {
trace(2, " (filtered)\n");
continue;
@@ -1329,7 +1365,7 @@ riprecv()
np->rip6_metric = HOPCNT_INFINITY6;
applyplen(&np->rip6_dest, np->rip6_plen);
- if ((rrt = rtsearch(np, NULL)) != NULL) {
+ if ((rrt = rtsearch(np)) != NULL) {
if (rrt->rrt_t == 0)
continue; /* Intf route has priority */
nq = &rrt->rrt_info;
@@ -1398,20 +1434,20 @@ riprecv()
if (nq->rip6_plen == sizeof(struct in6_addr) * 8)
rrt->rrt_flags |= RTF_HOST;
- /* Put the route to the list */
- rrt->rrt_next = riprt;
- riprt = rrt;
/* Update routing table */
addroute(rrt, &nh, ifcp);
rrt->rrt_rflags |= RRTF_CHANGED;
need_trigger = 1;
rrt->rrt_t = t;
+
+ /* Put the route to the list */
+ TAILQ_INSERT_HEAD(&riprt_head, rrt, rrt_next);
}
}
/* XXX need to care the interval between triggered updates */
if (need_trigger) {
if (nextalarm > time(NULL) + RIP_TRIG_INT6_MAX) {
- for (ic = ifc; ic; ic = ic->ifc_next) {
+ TAILQ_FOREACH(ic, &ifc_head, ifc_next) {
if (ifcp->ifc_index == ic->ifc_index)
continue;
if (ic->ifc_flags & IFF_UP)
@@ -1420,8 +1456,9 @@ riprecv()
}
}
/* Reset the flag */
- for (rrt = riprt; rrt; rrt = rrt->rrt_next)
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
rrt->rrt_rflags &= ~RRTF_CHANGED;
+ }
}
}
@@ -1429,8 +1466,7 @@ riprecv()
* Send all routes request packet to the specified interface.
*/
void
-sendrequest(ifcp)
- struct ifc *ifcp;
+sendrequest(struct ifc *ifcp)
{
struct netinfo6 *np;
int error;
@@ -1458,11 +1494,10 @@ sendrequest(ifcp)
* Process a RIP6_REQUEST packet.
*/
void
-riprequest(ifcp, np, nn, sin6)
- struct ifc *ifcp;
- struct netinfo6 *np;
- int nn;
- struct sockaddr_in6 *sin6;
+riprequest(struct ifc *ifcp,
+ struct netinfo6 *np,
+ int nn,
+ struct sockaddr_in6 *sin6)
{
int i;
struct riprt *rrt;
@@ -1472,7 +1507,7 @@ riprequest(ifcp, np, nn, sin6)
/* Specific response, don't split-horizon */
trace(1, "\tRIP Request\n");
for (i = 0; i < nn; i++, np++) {
- rrt = rtsearch(np, NULL);
+ rrt = rtsearch(np);
if (rrt)
np->rip6_metric = rrt->rrt_info.rip6_metric;
else
@@ -1490,7 +1525,7 @@ riprequest(ifcp, np, nn, sin6)
* Get information of each interface.
*/
void
-ifconfig()
+ifconfig(void)
{
struct ifaddrs *ifap, *ifa;
struct ifc *ifcp;
@@ -1521,14 +1556,14 @@ ifconfig()
/*NOTREACHED*/
}
memset(ifcp, 0, sizeof(*ifcp));
+
ifcp->ifc_index = -1;
- ifcp->ifc_next = ifc;
- ifc = ifcp;
- nifc++;
- ifcp->ifc_name = allocopy(ifa->ifa_name);
- ifcp->ifc_addr = 0;
- ifcp->ifc_filter = 0;
+ strlcpy(ifcp->ifc_name, ifa->ifa_name,
+ sizeof(ifcp->ifc_name));
+ TAILQ_INIT(&ifcp->ifc_ifac_head);
+ TAILQ_INIT(&ifcp->ifc_iff_head);
ifcp->ifc_flags = ifa->ifa_flags;
+ TAILQ_INSERT_HEAD(&ifc_head, ifcp, ifc_next);
trace(1, "newif %s <%s>\n", ifcp->ifc_name,
ifflags(ifcp->ifc_flags));
if (!strcmp(ifcp->ifc_name, LOOPBACK_IF))
@@ -1543,7 +1578,10 @@ ifconfig()
}
ifcp->ifc_flags = ifa->ifa_flags;
}
- ifconfig1(ifa->ifa_name, ifa->ifa_addr, ifcp, s);
+ if (ifconfig1(ifa->ifa_name, ifa->ifa_addr, ifcp, s) < 0) {
+ /* maybe temporary failure */
+ continue;
+ }
if ((ifcp->ifc_flags & (IFF_LOOPBACK | IFF_UP)) == IFF_UP
&& 0 < ifcp->ifc_index && !ifcp->ifc_joined) {
mreq.ipv6mr_multiaddr = ifcp->ifc_ripsin.sin6_addr;
@@ -1561,65 +1599,65 @@ ifconfig()
freeifaddrs(ifap);
}
-void
-ifconfig1(name, sa, ifcp, s)
- const char *name;
- const struct sockaddr *sa;
- struct ifc *ifcp;
- int s;
+int
+ifconfig1(const char *name,
+ const struct sockaddr *sa,
+ struct ifc *ifcp,
+ int s)
{
struct in6_ifreq ifr;
const struct sockaddr_in6 *sin6;
- struct ifac *ifa;
+ struct ifac *ifac;
int plen;
char buf[BUFSIZ];
sin6 = (const struct sockaddr_in6 *)sa;
if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && !lflag)
- return;
+ return (-1);
ifr.ifr_addr = *sin6;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFNETMASK_IN6, (char *)&ifr) < 0) {
- fatal("ioctl: SIOCGIFNETMASK_IN6");
- /*NOTREACHED*/
+ syslog(LOG_INFO, "ioctl: SIOCGIFNETMASK_IN6");
+ return (-1);
}
plen = sin6mask2len(&ifr.ifr_addr);
- if ((ifa = ifa_match(ifcp, &sin6->sin6_addr, plen)) != NULL) {
+ if ((ifac = ifa_match(ifcp, &sin6->sin6_addr, plen)) != NULL) {
/* same interface found */
/* need check if something changed */
/* XXX not yet implemented */
- return;
+ return (-1);
}
/*
* New address is found
*/
- if ((ifa = MALLOC(struct ifac)) == NULL) {
+ if ((ifac = MALLOC(struct ifac)) == NULL) {
fatal("malloc: struct ifac");
/*NOTREACHED*/
}
- memset(ifa, 0, sizeof(*ifa));
- ifa->ifa_conf = ifcp;
- ifa->ifa_next = ifcp->ifc_addr;
- ifcp->ifc_addr = ifa;
- ifa->ifa_addr = sin6->sin6_addr;
- ifa->ifa_plen = plen;
+ memset(ifac, 0, sizeof(*ifac));
+
+ ifac->ifac_ifc = ifcp;
+ ifac->ifac_addr = sin6->sin6_addr;
+ ifac->ifac_plen = plen;
+ ifac->ifac_scope_id = sin6->sin6_scope_id;
if (ifcp->ifc_flags & IFF_POINTOPOINT) {
ifr.ifr_addr = *sin6;
if (ioctl(s, SIOCGIFDSTADDR_IN6, (char *)&ifr) < 0) {
fatal("ioctl: SIOCGIFDSTADDR_IN6");
/*NOTREACHED*/
}
- ifa->ifa_raddr = ifr.ifr_dstaddr.sin6_addr;
- inet_ntop(AF_INET6, (void *)&ifa->ifa_raddr, buf, sizeof(buf));
+ ifac->ifac_raddr = ifr.ifr_dstaddr.sin6_addr;
+ inet_ntop(AF_INET6, (void *)&ifac->ifac_raddr, buf,
+ sizeof(buf));
trace(1, "found address %s/%d -- %s\n",
- inet6_n2p(&ifa->ifa_addr), ifa->ifa_plen, buf);
+ inet6_n2p(&ifac->ifac_addr), ifac->ifac_plen, buf);
} else {
trace(1, "found address %s/%d\n",
- inet6_n2p(&ifa->ifa_addr), ifa->ifa_plen);
+ inet6_n2p(&ifac->ifac_addr), ifac->ifac_plen);
}
- if (ifcp->ifc_index < 0 && IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr)) {
- ifcp->ifc_mylladdr = ifa->ifa_addr;
- ifcp->ifc_index = IN6_LINKLOCAL_IFINDEX(ifa->ifa_addr);
+ if (ifcp->ifc_index < 0 && IN6_IS_ADDR_LINKLOCAL(&ifac->ifac_addr)) {
+ ifcp->ifc_mylladdr = ifac->ifac_addr;
+ ifcp->ifc_index = IN6_LINKLOCAL_IFINDEX(ifac->ifac_addr);
memcpy(&ifcp->ifc_ripsin, &ripsin, ripsin.ss_len);
SET_IN6_LINKLOCAL_IFINDEX(ifcp->ifc_ripsin.sin6_addr,
ifcp->ifc_index);
@@ -1636,6 +1674,34 @@ ifconfig1(name, sa, ifcp, s)
ifcp->ifc_index, ifcp->ifc_mtu, ifcp->ifc_metric);
} else
ifcp->ifc_cflags |= IFC_CHANGED;
+
+ TAILQ_INSERT_HEAD(&ifcp->ifc_ifac_head, ifac, ifac_next);
+
+ 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);
}
/*
@@ -1643,30 +1709,35 @@ ifconfig1(name, sa, ifcp, s)
* Update interface information as necesssary.
*/
void
-rtrecv()
+rtrecv(void)
{
char buf[BUFSIZ];
- char *p, *q;
+ char *p, *q = NULL;
struct rt_msghdr *rtm;
struct ifa_msghdr *ifam;
struct if_msghdr *ifm;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-9
mailing list