summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2012-11-18 15:37:27 +0000
committerhrs <hrs@FreeBSD.org>2012-11-18 15:37:27 +0000
commitf3c2433c95ce485eb3ffc9498706d13adbfdd13a (patch)
tree6971133bb650026f0a8a933b9b57ca87b321c9ba /usr.sbin
parentf4d6af058c4347509c4a485449dcd62458d2589a (diff)
downloadFreeBSD-src-f3c2433c95ce485eb3ffc9498706d13adbfdd13a.zip
FreeBSD-src-f3c2433c95ce485eb3ffc9498706d13adbfdd13a.tar.gz
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. There is no functional change.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/route6d/route6d.c837
1 files changed, 392 insertions, 445 deletions
diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c
index e888534..b5f334c 100644
--- a/usr.sbin/route6d/route6d.c
+++ b/usr.sbin/route6d/route6d.c
@@ -31,7 +31,7 @@
*/
#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>
@@ -90,9 +90,10 @@ static char _rcsid[] = "$KAME: route6d.c,v 1.104 2003/10/31 00:30:20 itojun Exp
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-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 */
@@ -100,31 +101,32 @@ struct ifc { /* Configuration of an interface */
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_scope_id; /* scope id */
- 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];
@@ -151,8 +153,9 @@ struct rip6 *ripbuf; /* packet buffer for sending */
* 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 */
@@ -161,8 +164,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 */
@@ -211,7 +213,7 @@ int out_filter(struct riprt *, struct ifc *);
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 *);
@@ -234,7 +236,7 @@ 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);
@@ -249,7 +251,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 *, ...)
@@ -265,10 +267,15 @@ 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;
@@ -361,11 +368,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++;
}
}
@@ -375,20 +381,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);
}
-#endif
if ((ripbuf = (struct rip6 *)malloc(RIP6_MAXMTU)) == NULL) {
fatal("malloc");
@@ -416,8 +421,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);
@@ -484,8 +489,7 @@ main(argc, argv)
}
void
-sighandler(signo)
- int signo;
+sighandler(int signo)
{
switch (signo) {
@@ -509,12 +513,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);
}
@@ -536,39 +540,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);
}
@@ -576,15 +568,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);
@@ -724,13 +715,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;
@@ -772,21 +758,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;
@@ -800,20 +784,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;
}
@@ -822,11 +810,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;
@@ -837,7 +825,7 @@ ripsend(ifcp, sin6, flag)
np = ripbuf->rip6_nets;
*np = rrt_info;
nrt = 1;
- ripflush(ifcp, sin6);
+ ripflush(ifcp, sin6, nrt, np);
return;
}
@@ -847,7 +835,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;
@@ -869,8 +857,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;
np->rip6_plen = 0;
np->rip6_tag = 0;
@@ -882,8 +875,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;
@@ -894,21 +891,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;
@@ -918,7 +915,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)
@@ -935,7 +932,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 &&
@@ -952,9 +949,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)
@@ -979,9 +976,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 */
@@ -1006,9 +1001,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;
@@ -1064,7 +1057,7 @@ sendpacket(sin6, len)
* table if necessary.
*/
void
-riprecv()
+riprecv(void)
{
struct ifc *ifcp, *ic;
struct sockaddr_in6 fsock;
@@ -1129,7 +1122,7 @@ riprecv()
}
}
- if (len < sizeof(struct rip6)) {
+ if ((size_t)len < sizeof(struct rip6)) {
trace(1, "Packet too short\n");
return;
}
@@ -1217,7 +1210,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",
@@ -1281,23 +1274,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;
@@ -1310,7 +1303,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;
@@ -1379,20 +1372,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)
@@ -1401,8 +1394,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;
+ }
}
}
@@ -1410,8 +1404,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;
@@ -1439,11 +1432,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;
@@ -1453,7 +1445,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
@@ -1471,7 +1463,7 @@ riprequest(ifcp, np, nn, sin6)
* Get information of each interface.
*/
void
-ifconfig()
+ifconfig(void)
{
struct ifaddrs *ifap, *ifa;
struct ifc *ifcp;
@@ -1502,14 +1494,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))
@@ -1524,7 +1516,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;
@@ -1542,66 +1537,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;
- ifa->ifa_scope_id= sin6->sin6_scope_id;
+ 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 = ifa->ifa_scope_id;
+ if (ifcp->ifc_index < 0 && IN6_IS_ADDR_LINKLOCAL(&ifac->ifac_addr)) {
+ ifcp->ifc_mylladdr = ifac->ifac_addr;
+ ifcp->ifc_index = ifac->ifac_scope_id;
memcpy(&ifcp->ifc_ripsin, &ripsin, ripsin.ss_len);
ifcp->ifc_ripsin.sin6_scope_id = ifcp->ifc_index;
setindex2ifc(ifcp->ifc_index, ifcp);
@@ -1617,6 +1611,10 @@ 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;
}
/*
@@ -1624,10 +1622,10 @@ 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;
@@ -1636,18 +1634,22 @@ rtrecv()
int iface = 0, rtable = 0;
struct sockaddr_in6 *rta[RTAX_MAX];
struct sockaddr_in6 mask;
- int i, addrs;
+ int i, addrs = 0;
struct riprt *rrt;
if ((len = read(rtsock, buf, sizeof(buf))) < 0) {
perror("read from rtsock");
exit(1);
}
+ if (len == 0)
+ return;
+#if 0
if (len < sizeof(*rtm)) {
trace(1, "short read from rtsock: %d (should be > %lu)\n",
len, (u_long)sizeof(*rtm));
return;
}
+#endif
if (dflag >= 2) {
fprintf(stderr, "rtmsg:\n");
for (i = 0; i < len; i++) {
@@ -1658,6 +1660,9 @@ rtrecv()
}
for (p = buf; p - buf < len; p += ((struct rt_msghdr *)p)->rtm_msglen) {
+ if (((struct rt_msghdr *)p)->rtm_version != RTM_VERSION)
+ continue;
+
/* safety against bogus message */
if (((struct rt_msghdr *)p)->rtm_msglen <= 0) {
trace(1, "bogus rtmsg: length=%d\n",
@@ -1828,10 +1833,10 @@ rtrecv()
if (iface) {
trace(1, "rtsock: reconfigure interfaces, refresh interface routes\n");
ifconfig();
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next)
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
if (ifcp->ifc_cflags & IFC_CHANGED) {
if (ifrt(ifcp, 1)) {
- 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)
@@ -1839,11 +1844,13 @@ rtrecv()
RRTF_CHANGED);
}
/* Reset the flag */
- for (rrt = riprt; rrt; rrt = rrt->rrt_next)
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
rrt->rrt_rflags &= ~RRTF_CHANGED;
+ }
}
ifcp->ifc_cflags &= ~IFC_CHANGED;
}
+ }
}
if (rtable) {
trace(1, "rtsock: read routing table again\n");
@@ -1855,10 +1862,9 @@ rtrecv()
* remove specified route from the internal routing table.
*/
int
-rt_del(sdst, sgw, smask)
- const struct sockaddr_in6 *sdst;
- const struct sockaddr_in6 *sgw;
- const struct sockaddr_in6 *smask;
+rt_del(const struct sockaddr_in6 *sdst,
+ const struct sockaddr_in6 *sgw,
+ const struct sockaddr_in6 *smask)
{
const struct in6_addr *dst = NULL;
const struct in6_addr *gw = NULL;
@@ -1894,7 +1900,7 @@ rt_del(sdst, sgw, smask)
trace(1, "\t%s is an interface route, guessing prefixlen\n",
inet6_n2p(dst));
longest = NULL;
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest,
&sdst->sin6_addr)
&& IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw)) {
@@ -1927,7 +1933,7 @@ rt_del(sdst, sgw, smask)
applyplen(&ni6.rip6_dest, ni6.rip6_plen); /*to be sure*/
trace(1, "\tfind route %s/%d\n", inet6_n2p(&ni6.rip6_dest),
ni6.rip6_plen);
- if (!rrt && (rrt = rtsearch(&ni6, NULL)) == NULL) {
+ if (!rrt && (rrt = rtsearch(&ni6)) == NULL) {
trace(1, "\tno route found\n");
return -1;
}
@@ -1954,14 +1960,13 @@ rt_del(sdst, sgw, smask)
* remove specified address from internal interface/routing table.
*/
int
-rt_deladdr(ifcp, sifa, smask)
- struct ifc *ifcp;
- const struct sockaddr_in6 *sifa;
- const struct sockaddr_in6 *smask;
+rt_deladdr(struct ifc *ifcp,
+ const struct sockaddr_in6 *sifa,
+ const struct sockaddr_in6 *smask)
{
const struct in6_addr *addr = NULL;
int prefix;
- struct ifac *ifa = NULL;
+ struct ifac *ifac = NULL;
struct netinfo6 ni6;
struct riprt *rrt = NULL;
time_t t_lifetime;
@@ -1976,41 +1981,28 @@ rt_deladdr(ifcp, sifa, smask)
trace(1, "\tdeleting %s/%d from %s\n",
inet6_n2p(addr), prefix, ifcp->ifc_name);
- ifa = ifa_match(ifcp, addr, prefix);
- if (!ifa) {
+ ifac = ifa_match(ifcp, addr, prefix);
+ if (!ifac) {
trace(1, "\tno matching ifa found for %s/%d on %s\n",
inet6_n2p(addr), prefix, ifcp->ifc_name);
return -1;
}
- if (ifa->ifa_conf != ifcp) {
+ if (ifac->ifac_ifc != ifcp) {
trace(1, "\taddress table corrupt: back pointer does not match "
"(%s != %s)\n",
- ifcp->ifc_name, ifa->ifa_conf->ifc_name);
+ ifcp->ifc_name, ifac->ifac_ifc->ifc_name);
return -1;
}
- /* remove ifa from interface */
- if (ifcp->ifc_addr == ifa)
- ifcp->ifc_addr = ifa->ifa_next;
- else {
- struct ifac *p;
- for (p = ifcp->ifc_addr; p; p = p->ifa_next) {
- if (p->ifa_next == ifa) {
- p->ifa_next = ifa->ifa_next;
- break;
- }
- }
- }
- ifa->ifa_next = NULL;
- ifa->ifa_conf = NULL;
+ TAILQ_REMOVE(&ifcp->ifc_ifac_head, ifac, ifac_next);
t_lifetime = time(NULL) - RIP_LIFETIME;
/* age route for interface address */
memset(&ni6, 0, sizeof(ni6));
- ni6.rip6_dest = ifa->ifa_addr;
- ni6.rip6_plen = ifa->ifa_plen;
+ ni6.rip6_dest = ifac->ifac_addr;
+ ni6.rip6_plen = ifac->ifac_plen;
applyplen(&ni6.rip6_dest, ni6.rip6_plen);
trace(1, "\tfind interface route %s/%d on %d\n",
inet6_n2p(&ni6.rip6_dest), ni6.rip6_plen, ifcp->ifc_index);
- if ((rrt = rtsearch(&ni6, NULL)) != NULL) {
+ if ((rrt = rtsearch(&ni6)) != NULL) {
struct in6_addr none;
memset(&none, 0, sizeof(none));
if (rrt->rrt_index == ifcp->ifc_index &&
@@ -2033,15 +2025,16 @@ rt_deladdr(ifcp, sifa, smask)
/* age route for p2p destination */
if (ifcp->ifc_flags & IFF_POINTOPOINT) {
memset(&ni6, 0, sizeof(ni6));
- ni6.rip6_dest = ifa->ifa_raddr;
+ ni6.rip6_dest = ifac->ifac_raddr;
ni6.rip6_plen = 128;
applyplen(&ni6.rip6_dest, ni6.rip6_plen); /*to be sure*/
trace(1, "\tfind p2p route %s/%d on %d\n",
inet6_n2p(&ni6.rip6_dest), ni6.rip6_plen,
ifcp->ifc_index);
- if ((rrt = rtsearch(&ni6, NULL)) != NULL) {
+ if ((rrt = rtsearch(&ni6)) != NULL) {
if (rrt->rrt_index == ifcp->ifc_index &&
- IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, &ifa->ifa_addr)) {
+ IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw,
+ &ifac->ifac_addr)) {
trace(1, "\troute found, age it\n");
if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) {
rrt->rrt_t = t_lifetime;
@@ -2058,7 +2051,9 @@ rt_deladdr(ifcp, sifa, smask)
} else
trace(1, "\tno p2p route found\n");
}
- return updated ? 0 : -1;
+ free(ifac);
+
+ return ((updated) ? 0 : -1);
}
/*
@@ -2066,12 +2061,10 @@ rt_deladdr(ifcp, sifa, smask)
* list.
*/
int
-ifrt(ifcp, again)
- struct ifc *ifcp;
- int again;
+ifrt(struct ifc *ifcp, int again)
{
- struct ifac *ifa;
- struct riprt *rrt = NULL, *search_rrt, *prev_rrt, *loop_rrt;
+ struct ifac *ifac;
+ struct riprt *rrt = NULL, *search_rrt, *loop_rrt;
struct netinfo6 *np;
time_t t_lifetime;
int need_trigger = 0;
@@ -2086,23 +2079,23 @@ ifrt(ifcp, again)
return 0;
}
- for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
- if (IN6_IS_ADDR_LINKLOCAL(&ifa->ifa_addr)) {
+ TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) {
+ if (IN6_IS_ADDR_LINKLOCAL(&ifac->ifac_addr)) {
#if 0
trace(1, "route: %s on %s: "
"skip linklocal interface address\n",
- inet6_n2p(&ifa->ifa_addr), ifcp->ifc_name);
+ inet6_n2p(&ifac->ifac_addr), ifcp->ifc_name);
#endif
continue;
}
- if (IN6_IS_ADDR_UNSPECIFIED(&ifa->ifa_addr)) {
+ if (IN6_IS_ADDR_UNSPECIFIED(&ifac->ifac_addr)) {
#if 0
trace(1, "route: %s: skip unspec interface address\n",
ifcp->ifc_name);
#endif
continue;
}
- if (IN6_IS_ADDR_LOOPBACK(&ifa->ifa_addr)) {
+ if (IN6_IS_ADDR_LOOPBACK(&ifac->ifac_addr)) {
#if 0
trace(1, "route: %s: skip loopback address\n",
ifcp->ifc_name);
@@ -2116,17 +2109,17 @@ ifrt(ifcp, again)
rrt->rrt_same = NULL;
rrt->rrt_index = ifcp->ifc_index;
rrt->rrt_t = 0; /* don't age */
- rrt->rrt_info.rip6_dest = ifa->ifa_addr;
+ rrt->rrt_info.rip6_dest = ifac->ifac_addr;
rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric;
- rrt->rrt_info.rip6_plen = ifa->ifa_plen;
+ rrt->rrt_info.rip6_plen = ifac->ifac_plen;
rrt->rrt_flags = RTF_HOST;
rrt->rrt_rflags |= RRTF_CHANGED;
- applyplen(&rrt->rrt_info.rip6_dest, ifa->ifa_plen);
+ applyplen(&rrt->rrt_info.rip6_dest, ifac->ifac_plen);
memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr));
- rrt->rrt_gw = ifa->ifa_addr;
+ rrt->rrt_gw = ifac->ifac_addr;
np = &rrt->rrt_info;
- search_rrt = rtsearch(np, &prev_rrt);
+ search_rrt = rtsearch(np);
if (search_rrt != NULL) {
if (search_rrt->rrt_info.rip6_metric <=
rrt->rrt_info.rip6_metric) {
@@ -2140,25 +2133,21 @@ ifrt(ifcp, again)
goto next;
}
- if (prev_rrt)
- prev_rrt->rrt_next = rrt->rrt_next;
- else
- riprt = rrt->rrt_next;
+ TAILQ_REMOVE(&riprt_head, rrt, rrt_next);
delroute(&rrt->rrt_info, &rrt->rrt_gw);
}
/* Attach the route to the list */
trace(1, "route: %s/%d: register route (%s)\n",
inet6_n2p(&np->rip6_dest), np->rip6_plen,
ifcp->ifc_name);
- rrt->rrt_next = riprt;
- riprt = rrt;
+ TAILQ_INSERT_HEAD(&riprt_head, rrt, rrt_next);
addroute(rrt, &rrt->rrt_gw, ifcp);
rrt = NULL;
sendrequest(ifcp);
ripsend(ifcp, &ifcp->ifc_ripsin, 0);
need_trigger = 1;
} else {
- for (loop_rrt = riprt; loop_rrt; loop_rrt = loop_rrt->rrt_next) {
+ TAILQ_FOREACH(loop_rrt, &riprt_head, rrt_next) {
if (loop_rrt->rrt_index == ifcp->ifc_index) {
t_lifetime = time(NULL) - RIP_LIFETIME;
if (loop_rrt->rrt_t == 0 || loop_rrt->rrt_t > t_lifetime) {
@@ -2183,12 +2172,10 @@ ifrt(ifcp, again)
* since BSD kernels do not look at prefix length on p2p interfaces.
*/
void
-ifrt_p2p(ifcp, again)
- struct ifc *ifcp;
- int again;
+ifrt_p2p(struct ifc *ifcp, int again)
{
- struct ifac *ifa;
- struct riprt *rrt, *orrt, *prevrrt;
+ struct ifac *ifac;
+ struct riprt *rrt, *orrt;
struct netinfo6 *np;
struct in6_addr addr, dest;
int advert, ignore, i;
@@ -2200,11 +2187,11 @@ ifrt_p2p(ifcp, again)
const char *category = "";
const char *noadv;
- for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
- addr = ifa->ifa_addr;
- dest = ifa->ifa_raddr;
- applyplen(&addr, ifa->ifa_plen);
- applyplen(&dest, ifa->ifa_plen);
+ TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) {
+ addr = ifac->ifac_addr;
+ dest = ifac->ifac_raddr;
+ applyplen(&addr, ifac->ifac_plen);
+ applyplen(&dest, ifac->ifac_plen);
advert = ignore = 0;
switch (behavior) {
case CISCO:
@@ -2249,7 +2236,7 @@ ifrt_p2p(ifcp, again)
* A/64 -> A/64
* A B/128 -> A/128 and B/128
*/
- if (!IN6_IS_ADDR_UNSPECIFIED(&ifa->ifa_raddr)) {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&ifac->ifac_raddr)) {
if (IN6_ARE_ADDR_EQUAL(&addr, &dest))
advert |= P2PADVERT_NETWORK;
else {
@@ -2275,22 +2262,22 @@ ifrt_p2p(ifcp, again)
rrt->rrt_t = 0; /* don't age */
switch (i) {
case P2PADVERT_NETWORK:
- rrt->rrt_info.rip6_dest = ifa->ifa_addr;
- rrt->rrt_info.rip6_plen = ifa->ifa_plen;
+ rrt->rrt_info.rip6_dest = ifac->ifac_addr;
+ rrt->rrt_info.rip6_plen = ifac->ifac_plen;
applyplen(&rrt->rrt_info.rip6_dest,
- ifa->ifa_plen);
+ ifac->ifac_plen);
category = "network";
break;
case P2PADVERT_ADDR:
- rrt->rrt_info.rip6_dest = ifa->ifa_addr;
+ rrt->rrt_info.rip6_dest = ifac->ifac_addr;
rrt->rrt_info.rip6_plen = 128;
rrt->rrt_gw = in6addr_loopback;
category = "addr";
break;
case P2PADVERT_DEST:
- rrt->rrt_info.rip6_dest = ifa->ifa_raddr;
+ rrt->rrt_info.rip6_dest = ifac->ifac_raddr;
rrt->rrt_info.rip6_plen = 128;
- rrt->rrt_gw = ifa->ifa_addr;
+ rrt->rrt_gw = ifac->ifac_addr;
category = "dest";
break;
}
@@ -2311,23 +2298,19 @@ ifrt_p2p(ifcp, again)
rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric;
np = &rrt->rrt_info;
- orrt = rtsearch(np, &prevrrt);
+ orrt = rtsearch(np);
if (!orrt) {
/* Attach the route to the list */
trace(1, "route: %s/%d: register route "
"(%s on %s%s)\n",
inet6_n2p(&np->rip6_dest), np->rip6_plen,
category, ifcp->ifc_name, noadv);
- rrt->rrt_next = riprt;
- riprt = rrt;
+ TAILQ_INSERT_HEAD(&riprt_head, rrt, rrt_next);
} else if (rrt->rrt_index != orrt->rrt_index ||
rrt->rrt_info.rip6_metric != orrt->rrt_info.rip6_metric) {
- /* swap route */
- rrt->rrt_next = orrt->rrt_next;
- if (prevrrt)
- prevrrt->rrt_next = rrt;
- else
- riprt = rrt;
+ /* replace route */
+ TAILQ_INSERT_BEFORE(orrt, rrt, rrt_next);
+ TAILQ_REMOVE(&riprt_head, orrt, rrt_next);
free(orrt);
trace(1, "route: %s/%d: update (%s on %s%s)\n",
@@ -2353,8 +2336,7 @@ ifrt_p2p(ifcp, again)
}
int
-getifmtu(ifindex)
- int ifindex;
+getifmtu(int ifindex)
{
int mib[6];
char *buf;
@@ -2391,8 +2373,7 @@ getifmtu(ifindex)
}
const char *
-rttypes(rtm)
- struct rt_msghdr *rtm;
+rttypes(struct rt_msghdr *rtm)
{
#define RTTYPE(s, f) \
do { \
@@ -2435,8 +2416,7 @@ do { \
}
const char *
-rtflags(rtm)
- struct rt_msghdr *rtm;
+rtflags(struct rt_msghdr *rtm)
{
static char buf[BUFSIZ];
@@ -2505,8 +2485,7 @@ do { \
}
const char *
-ifflags(flags)
- int flags;
+ifflags(int flags)
{
static char buf[BUFSIZ];
@@ -2545,8 +2524,7 @@ do { \
}
void
-krtread(again)
- int again;
+krtread(int again)
{
int mib[6];
size_t msize;
@@ -2564,6 +2542,8 @@ krtread(again)
mib[4] = NET_RT_DUMP; /* Dump the kernel routing table */
mib[5] = 0; /* No flags */
do {
+ if (retry)
+ sleep(1);
retry++;
errmsg = NULL;
if (buf)
@@ -2597,16 +2577,14 @@ krtread(again)
}
void
-rt_entry(rtm, again)
- struct rt_msghdr *rtm;
- int again;
+rt_entry(struct rt_msghdr *rtm, int again)
{
struct sockaddr_in6 *sin6_dst, *sin6_gw, *sin6_mask;
struct sockaddr_in6 *sin6_genmask, *sin6_ifp;
char *rtmp, *ifname = NULL;
struct riprt *rrt, *orrt;
struct netinfo6 *np;
- int s;
+ int ifindex;
sin6_dst = sin6_gw = sin6_mask = sin6_genmask = sin6_ifp = 0;
if ((rtm->rtm_flags & RTF_UP) == 0 || rtm->rtm_flags &
@@ -2688,7 +2666,7 @@ rt_entry(rtm, again)
else
np->rip6_plen = 0;
- orrt = rtsearch(np, NULL);
+ orrt = rtsearch(np);
if (orrt && orrt->rrt_info.rip6_metric != HOPCNT_INFINITY6) {
/* Already found */
if (!again) {
@@ -2716,16 +2694,16 @@ rt_entry(rtm, again)
trace(1, " gw %s", inet6_n2p(&rrt->rrt_gw));
/* Interface */
- s = rtm->rtm_index;
- if (s < nindex2ifc && index2ifc[s])
- ifname = index2ifc[s]->ifc_name;
+ ifindex = rtm->rtm_index;
+ if ((unsigned int)ifindex < nindex2ifc && index2ifc[ifindex])
+ ifname = index2ifc[ifindex]->ifc_name;
else {
trace(1, " not configured\n");
free(rrt);
return;
}
- trace(1, " if %s sock %d", ifname, s);
- rrt->rrt_index = s;
+ trace(1, " if %s sock %d", ifname, ifindex);
+ rrt->rrt_index = ifindex;
trace(1, "\n");
@@ -2743,23 +2721,21 @@ rt_entry(rtm, again)
/* Put it to the route list */
if (orrt && orrt->rrt_info.rip6_metric == HOPCNT_INFINITY6) {
/* replace route list */
- rrt->rrt_next = orrt->rrt_next;
- *orrt = *rrt;
+ TAILQ_INSERT_BEFORE(orrt, rrt, rrt_next);
+ TAILQ_REMOVE(&riprt_head, orrt, rrt_next);
+
trace(1, "route: %s/%d flags %s: replace new route\n",
inet6_n2p(&np->rip6_dest), np->rip6_plen,
rtflags(rtm));
- free(rrt);
- } else {
- rrt->rrt_next = riprt;
- riprt = rrt;
- }
+ free(orrt);
+ } else
+ TAILQ_INSERT_HEAD(&riprt_head, rrt, rrt_next);
}
int
-addroute(rrt, gw, ifcp)
- struct riprt *rrt;
- const struct in6_addr *gw;
- struct ifc *ifcp;
+addroute(struct riprt *rrt,
+ const struct in6_addr *gw,
+ struct ifc *ifcp)
{
struct netinfo6 *np;
u_char buf[BUFSIZ], buf1[BUFSIZ], buf2[BUFSIZ];
@@ -2829,9 +2805,7 @@ addroute(rrt, gw, ifcp)
}
int
-delroute(np, gw)
- struct netinfo6 *np;
- struct in6_addr *gw;
+delroute(struct netinfo6 *np, struct in6_addr *gw)
{
u_char buf[BUFSIZ], buf2[BUFSIZ];
struct rt_msghdr *rtm;
@@ -2896,9 +2870,7 @@ delroute(np, gw)
}
struct in6_addr *
-getroute(np, gw)
- struct netinfo6 *np;
- struct in6_addr *gw;
+getroute(struct netinfo6 *np, struct in6_addr *gw)
{
u_char buf[BUFSIZ];
int myseq;
@@ -2945,8 +2917,7 @@ getroute(np, gw)
}
const char *
-inet6_n2p(p)
- const struct in6_addr *p;
+inet6_n2p(const struct in6_addr *p)
{
static char buf[BUFSIZ];
@@ -2954,8 +2925,7 @@ inet6_n2p(p)
}
void
-ifrtdump(sig)
- int sig;
+ifrtdump(int sig)
{
ifdump(sig);
@@ -2963,12 +2933,11 @@ ifrtdump(sig)
}
void
-ifdump(sig)
- int sig;
+ifdump(int sig)
{
struct ifc *ifcp;
FILE *dump;
- int i;
+ int nifc = 0;
if (sig == 0)
dump = stderr;
@@ -2977,21 +2946,25 @@ ifdump(sig)
dump = stderr;
fprintf(dump, "%s: Interface Table Dump\n", hms());
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next)
+ nifc++;
fprintf(dump, " Number of interfaces: %d\n", nifc);
- for (i = 0; i < 2; i++) {
- fprintf(dump, " %sadvertising interfaces:\n", i ? "non-" : "");
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
- if (i == 0) {
- if ((ifcp->ifc_flags & IFF_UP) == 0)
- continue;
- if (iff_find(ifcp, 'N') != NULL)
- continue;
- } else {
- if (ifcp->ifc_flags & IFF_UP)
- continue;
- }
- ifdump0(dump, ifcp);
- }
+
+ fprintf(dump, " advertising interfaces:\n");
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
+ if ((ifcp->ifc_flags & IFF_UP) == 0)
+ continue;
+ if (iff_find(ifcp, IFIL_TYPE_N) != NULL)
+ continue;
+ ifdump0(dump, ifcp);
+ }
+ fprintf(dump, "\n");
+ fprintf(dump, " non-advertising interfaces:\n");
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
+ if ((ifcp->ifc_flags & IFF_UP) &&
+ (iff_find(ifcp, IFIL_TYPE_N) == NULL))
+ continue;
+ ifdump0(dump, ifcp);
}
fprintf(dump, "\n");
if (dump != stderr)
@@ -2999,11 +2972,9 @@ ifdump(sig)
}
void
-ifdump0(dump, ifcp)
- FILE *dump;
- const struct ifc *ifcp;
+ifdump0(FILE *dump, const struct ifc *ifcp)
{
- struct ifac *ifa;
+ struct ifac *ifac;
struct iff *iffp;
char buf[BUFSIZ];
const char *ft;
@@ -3013,53 +2984,51 @@ ifdump0(dump, ifcp)
ifcp->ifc_name, ifcp->ifc_index, ifflags(ifcp->ifc_flags),
inet6_n2p(&ifcp->ifc_mylladdr),
ifcp->ifc_mtu, ifcp->ifc_metric);
- for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
+ TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) {
if (ifcp->ifc_flags & IFF_POINTOPOINT) {
- inet_ntop(AF_INET6, (void *)&ifa->ifa_raddr,
+ inet_ntop(AF_INET6, (void *)&ifac->ifac_raddr,
buf, sizeof(buf));
fprintf(dump, "\t%s/%d -- %s\n",
- inet6_n2p(&ifa->ifa_addr),
- ifa->ifa_plen, buf);
+ inet6_n2p(&ifac->ifac_addr),
+ ifac->ifac_plen, buf);
} else {
fprintf(dump, "\t%s/%d\n",
- inet6_n2p(&ifa->ifa_addr),
- ifa->ifa_plen);
- }
- }
- if (ifcp->ifc_filter) {
- fprintf(dump, "\tFilter:");
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
- addr = 0;
- switch (iffp->iff_type) {
- case 'A':
- ft = "Aggregate"; addr++; break;
- case 'N':
- ft = "No-use"; break;
- case 'O':
- ft = "Advertise-only"; addr++; break;
- case 'T':
- ft = "Default-only"; break;
- case 'L':
- ft = "Listen-only"; addr++; break;
- default:
- snprintf(buf, sizeof(buf), "Unknown-%c", iffp->iff_type);
- ft = buf;
- addr++;
- break;
- }
- fprintf(dump, " %s", ft);
- if (addr) {
- fprintf(dump, "(%s/%d)", inet6_n2p(&iffp->iff_addr),
- iffp->iff_plen);
- }
+ inet6_n2p(&ifac->ifac_addr),
+ ifac->ifac_plen);
+ }
+ }
+
+ fprintf(dump, "\tFilter:\n");
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
+ addr = 0;
+ switch (iffp->iff_type) {
+ case IFIL_TYPE_A:
+ ft = "Aggregate"; addr++; break;
+ case IFIL_TYPE_N:
+ ft = "No-use"; break;
+ case IFIL_TYPE_O:
+ ft = "Advertise-only"; addr++; break;
+ case IFIL_TYPE_T:
+ ft = "Default-only"; break;
+ case IFIL_TYPE_L:
+ ft = "Listen-only"; addr++; break;
+ default:
+ snprintf(buf, sizeof(buf), "Unknown-%c", iffp->iff_type);
+ ft = buf;
+ addr++;
+ break;
}
+ fprintf(dump, "\t\t%s", ft);
+ if (addr)
+ fprintf(dump, "(%s/%d)", inet6_n2p(&iffp->iff_addr),
+ iffp->iff_plen);
fprintf(dump, "\n");
}
+ fprintf(dump, "\n");
}
void
-rtdump(sig)
- int sig;
+rtdump(int sig)
{
struct riprt *rrt;
char buf[BUFSIZ];
@@ -3074,7 +3043,7 @@ rtdump(sig)
t = time(NULL);
fprintf(dump, "\n%s: Routing Table Dump\n", hms());
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (rrt->rrt_t == 0)
age = 0;
else
@@ -3108,11 +3077,11 @@ rtdump(sig)
* -O 5f09:c400::/32,ef0,ef1 (only when match)
*/
void
-filterconfig()
+filterconfig(void)
{
int i;
char *p, *ap, *iflp, *ifname, *ep;
- struct iff ftmp, *iff_obj;
+ struct iff iff, *iffp;
struct ifc *ifcp;
struct riprt *rrt;
#if 0
@@ -3123,7 +3092,8 @@ filterconfig()
for (i = 0; i < nfilter; i++) {
ap = filter[i];
iflp = NULL;
- ifcp = NULL;
+ iffp = &iff;
+ memset(iffp, 0, sizeof(*iffp));
if (filtertype[i] == 'N' || filtertype[i] == 'T') {
iflp = ap;
goto ifonly;
@@ -3137,22 +3107,21 @@ filterconfig()
/*NOTREACHED*/
}
*p++ = '\0';
- if (inet_pton(AF_INET6, ap, &ftmp.iff_addr) != 1) {
+ if (inet_pton(AF_INET6, ap, &iffp->iff_addr) != 1) {
fatal("invalid prefix specified for '%s'", ap);
/*NOTREACHED*/
}
errno = 0;
ep = NULL;
plen = strtoul(p, &ep, 10);
- if (errno || !*p || *ep || plen > sizeof(ftmp.iff_addr) * 8) {
+ if (errno || !*p || *ep || plen > sizeof(iffp->iff_addr) * 8) {
fatal("invalid prefix length specified for '%s'", ap);
/*NOTREACHED*/
}
- ftmp.iff_plen = plen;
- ftmp.iff_next = NULL;
- applyplen(&ftmp.iff_addr, ftmp.iff_plen);
+ iffp->iff_plen = plen;
+ applyplen(&iffp->iff_addr, iffp->iff_plen);
ifonly:
- ftmp.iff_type = filtertype[i];
+ iffp->iff_type = filtertype[i];
if (iflp == NULL || *iflp == '\0') {
fatal("no interface specified for '%s'", ap);
/*NOTREACHED*/
@@ -3162,27 +3131,25 @@ ifonly:
ifname = iflp;
if ((iflp = strchr(iflp, ',')) != NULL)
*iflp++ = '\0';
- ifcp = ifc_find(ifname);
- if (ifcp == NULL) {
- fatal("no interface %s exists", ifname);
- /*NOTREACHED*/
- }
- iff_obj = (struct iff *)malloc(sizeof(struct iff));
- if (iff_obj == NULL) {
- fatal("malloc of iff_obj");
- /*NOTREACHED*/
+
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
+ if (strcmp(ifname, ifcp->ifc_name) != 0)
+ continue;
+
+ iffp = malloc(sizeof(*iffp));
+ if (iffp == NULL) {
+ fatal("malloc of iff");
+ /*NOTREACHED*/
+ }
+ memcpy(iffp, &iff, sizeof(*iffp));
+ TAILQ_INSERT_HEAD(&ifcp->ifc_iff_head, iffp, iff_next);
}
- memcpy((void *)iff_obj, (void *)&ftmp,
- sizeof(struct iff));
- /* link it to the interface filter */
- iff_obj->iff_next = ifcp->ifc_filter;
- ifcp->ifc_filter = iff_obj;
}
/*
* -A: aggregate configuration.
*/
- if (filtertype[i] != 'A')
+ if (filtertype[i] != IFIL_TYPE_A)
continue;
/* put the aggregate to the kernel routing table */
rrt = (struct riprt *)malloc(sizeof(struct riprt));
@@ -3191,8 +3158,8 @@ ifonly:
/*NOTREACHED*/
}
memset(rrt, 0, sizeof(struct riprt));
- rrt->rrt_info.rip6_dest = ftmp.iff_addr;
- rrt->rrt_info.rip6_plen = ftmp.iff_plen;
+ rrt->rrt_info.rip6_dest = iff.iff_addr;
+ rrt->rrt_info.rip6_plen = iff.iff_plen;
rrt->rrt_info.rip6_metric = 1;
rrt->rrt_info.rip6_tag = htons(routetag & 0xffff);
rrt->rrt_gw = in6addr_loopback;
@@ -3220,11 +3187,10 @@ ifonly:
}
#endif
/* Put the route to the list */
- rrt->rrt_next = riprt;
- riprt = rrt;
+ TAILQ_INSERT_HEAD(&riprt_head, rrt, rrt_next);
trace(1, "Aggregate: %s/%d for %s\n",
- inet6_n2p(&ftmp.iff_addr), ftmp.iff_plen,
- ifcp->ifc_name);
+ inet6_n2p(&iff.iff_addr), iff.iff_plen,
+ loopifcp->ifc_name);
/* Add this route to the kernel */
if (nflag) /* do not modify kernel routing table */
continue;
@@ -3239,19 +3205,19 @@ ifonly:
* with the address and prefix length specified in the arguments.
*/
struct ifac *
-ifa_match(ifcp, ia, plen)
- const struct ifc *ifcp;
- const struct in6_addr *ia;
- int plen;
+ifa_match(const struct ifc *ifcp,
+ const struct in6_addr *ia,
+ int plen)
{
- struct ifac *ifa;
+ struct ifac *ifac;
- for (ifa = ifcp->ifc_addr; ifa; ifa = ifa->ifa_next) {
- if (IN6_ARE_ADDR_EQUAL(&ifa->ifa_addr, ia) &&
- ifa->ifa_plen == plen)
+ TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) {
+ if (IN6_ARE_ADDR_EQUAL(&ifac->ifac_addr, ia) &&
+ ifac->ifac_plen == plen)
break;
}
- return ifa;
+
+ return (ifac);
}
/*
@@ -3260,30 +3226,22 @@ ifa_match(ifcp, ia, plen)
* Note: This is not a rtalloc(). Therefore exact match is necessary.
*/
struct riprt *
-rtsearch(np, prev_rrt)
- struct netinfo6 *np;
- struct riprt **prev_rrt;
+rtsearch(struct netinfo6 *np)
{
struct riprt *rrt;
- if (prev_rrt)
- *prev_rrt = NULL;
- for (rrt = riprt; rrt; rrt = rrt->rrt_next) {
+ TAILQ_FOREACH(rrt, &riprt_head, rrt_next) {
if (rrt->rrt_info.rip6_plen == np->rip6_plen &&
IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest,
&np->rip6_dest))
- return rrt;
- if (prev_rrt)
- *prev_rrt = rrt;
+ break;
}
- if (prev_rrt)
- *prev_rrt = NULL;
- return 0;
+
+ return (rrt);
}
int
-sin6mask2len(sin6)
- const struct sockaddr_in6 *sin6;
+sin6mask2len(const struct sockaddr_in6 *sin6)
{
return mask2len(&sin6->sin6_addr,
@@ -3291,9 +3249,7 @@ sin6mask2len(sin6)
}
int
-mask2len(addr, lenlim)
- const struct in6_addr *addr;
- int lenlim;
+mask2len(const struct in6_addr *addr, int lenlim)
{
int i = 0, j;
const u_char *p = (const u_char *)addr;
@@ -3320,8 +3276,7 @@ mask2len(addr, lenlim)
}
void
-applymask(addr, mask)
- struct in6_addr *addr, *mask;
+applymask(struct in6_addr *addr, struct in6_addr *mask)
{
int i;
u_long *p, *q;
@@ -3336,9 +3291,7 @@ static const u_char plent[8] = {
};
void
-applyplen(ia, plen)
- struct in6_addr *ia;
- int plen;
+applyplen(struct in6_addr *ia, int plen)
{
u_char *p;
int i;
@@ -3358,8 +3311,7 @@ static const int pl2m[9] = {
};
struct in6_addr *
-plen2mask(n)
- int n;
+plen2mask(int n)
{
static struct in6_addr ia;
u_char *p;
@@ -3379,8 +3331,7 @@ plen2mask(n)
}
char *
-allocopy(p)
- char *p;
+allocopy(char *p)
{
int len = strlen(p) + 1;
char *q = (char *)malloc(len);
@@ -3395,7 +3346,7 @@ allocopy(p)
}
char *
-hms()
+hms(void)
{
static char buf[BUFSIZ];
time_t t;
@@ -3414,8 +3365,7 @@ hms()
#define RIPRANDDEV 1.0 /* 30 +- 15, max - min = 30 */
int
-ripinterval(timer)
- int timer;
+ripinterval(int timer)
{
double r = rand();
@@ -3425,7 +3375,7 @@ ripinterval(timer)
}
time_t
-ripsuptrig()
+ripsuptrig(void)
{
time_t t;
@@ -3535,7 +3485,7 @@ trace(level, fmt, va_alist)
}
unsigned int
-if_maxindex()
+if_maxindex(void)
{
struct if_nameindex *p, *p0;
unsigned int max = 0;
@@ -3550,36 +3500,33 @@ if_maxindex()
}
struct ifc *
-ifc_find(name)
- char *name;
+ifc_find(char *name)
{
struct ifc *ifcp;
- for (ifcp = ifc; ifcp; ifcp = ifcp->ifc_next) {
+ TAILQ_FOREACH(ifcp, &ifc_head, ifc_next) {
if (strcmp(name, ifcp->ifc_name) == 0)
- return ifcp;
+ break;
}
- return (struct ifc *)NULL;
+ return (ifcp);
}
struct iff *
-iff_find(ifcp, type)
- struct ifc *ifcp;
- int type;
+iff_find(struct ifc *ifcp, int type)
{
struct iff *iffp;
- for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) {
- if (iffp->iff_type == type)
- return iffp;
+ TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) {
+ if (type == IFIL_TYPE_ANY ||
+ type == iffp->iff_type)
+ break;
}
- return NULL;
+
+ return (iffp);
}
void
-setindex2ifc(idx, ifcp)
- int idx;
- struct ifc *ifcp;
+setindex2ifc(int idx, struct ifc *ifcp)
{
int n, nsize;
struct ifc **p;
OpenPOWER on IntegriCloud