summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjca <jca@openbsd.org>2017-08-10 19:07:14 +0000
committerjca <jca@openbsd.org>2017-08-10 19:07:14 +0000
commitefb50b01005b3f1a2f886158c8ae8ff749c59918 (patch)
tree113f40f802b66d4814cb715113ebe885f8af8dea
parentthe userland crypto interface died long ago, can clean up the header (diff)
downloadwireguard-openbsd-efb50b01005b3f1a2f886158c8ae8ff749c59918.tar.xz
wireguard-openbsd-efb50b01005b3f1a2f886158c8ae8ff749c59918.zip
No need to handle multiple routing messages here.
route(4) sockets only ever ship a single routing message per read(2) call, so simplify this. Mostly mechanical diff for now, some further cleanups will follow. ok rob@ florian@
-rw-r--r--usr.sbin/rtadvd/if.c130
-rw-r--r--usr.sbin/rtadvd/if.h4
-rw-r--r--usr.sbin/rtadvd/rtadvd.c248
3 files changed, 176 insertions, 206 deletions
diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c
index 43ad552e238..9c6acd0e049 100644
--- a/usr.sbin/rtadvd/if.c
+++ b/usr.sbin/rtadvd/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.44 2017/07/12 06:11:45 florian Exp $ */
+/* $OpenBSD: if.c,v 1.45 2017/08/10 19:07:14 jca Exp $ */
/* $KAME: if.c,v 1.17 2001/01/21 15:27:30 itojun Exp $ */
/*
@@ -186,80 +186,70 @@ lladdropt_fill(struct sockaddr_dl *sdl, struct nd_opt_hdr *ndopt)
}
#define SIN6(s) ((struct sockaddr_in6 *)(s))
-char *
-get_next_msg(char *buf, char *lim, size_t *lenp)
+int
+validate_msg(char *buf)
{
- struct rt_msghdr *rtm;
+ struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
struct ifa_msghdr *ifam;
struct sockaddr *sa, *dst, *ifa, *rti_info[RTAX_MAX];
- *lenp = 0;
- for (rtm = (struct rt_msghdr *)buf;
- rtm < (struct rt_msghdr *)lim;
- rtm = (struct rt_msghdr *)((char *)rtm + rtm->rtm_msglen)) {
- /* just for safety */
- if (!rtm->rtm_msglen) {
- log_warnx("rtm_msglen is 0 (buf=%p lim=%p rtm=%p)",
- buf, lim, rtm);
- break;
- }
- if (rtm->rtm_version != RTM_VERSION)
- continue;
-
- switch (rtm->rtm_type) {
- case RTM_ADD:
- case RTM_DELETE:
- if (rtm->rtm_tableid != 0)
- continue;
-
- /* address related checks */
- sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
- if ((dst = rti_info[RTAX_DST]) == NULL ||
- dst->sa_family != AF_INET6)
- continue;
-
- if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) ||
- IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr))
- continue;
-
- if (rti_info[RTAX_NETMASK] == NULL)
- continue;
-
- /* found */
- *lenp = rtm->rtm_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- case RTM_NEWADDR:
- case RTM_DELADDR:
- ifam = (struct ifa_msghdr *)rtm;
-
- /* address related checks */
- sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
- get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
- if ((ifa = rti_info[RTAX_IFA]) == NULL ||
- (ifa->sa_family != AF_INET &&
- ifa->sa_family != AF_INET6))
- continue;
-
- if (ifa->sa_family == AF_INET6 &&
- (IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) ||
- IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr)))
- continue;
-
- /* found */
- *lenp = rtm->rtm_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- case RTM_IFINFO:
- /* found */
- *lenp = rtm->rtm_msglen;
- return (char *)rtm;
- /* NOTREACHED */
- }
+ /* just for safety */
+ if (!rtm->rtm_msglen) {
+ log_warnx("rtm_msglen is 0 (rtm=%p)", rtm);
+ return -1;
}
-
- return (char *)rtm;
+ if (rtm->rtm_version != RTM_VERSION)
+ return -1;
+
+ switch (rtm->rtm_type) {
+ case RTM_ADD:
+ case RTM_DELETE:
+ if (rtm->rtm_tableid != 0)
+ return -1;
+
+ /* address related checks */
+ sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
+ get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+ if ((dst = rti_info[RTAX_DST]) == NULL ||
+ dst->sa_family != AF_INET6)
+ return -1;
+
+ if (IN6_IS_ADDR_LINKLOCAL(&SIN6(dst)->sin6_addr) ||
+ IN6_IS_ADDR_MULTICAST(&SIN6(dst)->sin6_addr))
+ return -1;
+
+ if (rti_info[RTAX_NETMASK] == NULL)
+ return -1;
+
+ /* found */
+ return 0;
+ /* NOTREACHED */
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ ifam = (struct ifa_msghdr *)rtm;
+
+ /* address related checks */
+ sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
+ get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
+ if ((ifa = rti_info[RTAX_IFA]) == NULL ||
+ (ifa->sa_family != AF_INET &&
+ ifa->sa_family != AF_INET6))
+ return -1;
+
+ if (ifa->sa_family == AF_INET6 &&
+ (IN6_IS_ADDR_LINKLOCAL(&SIN6(ifa)->sin6_addr) ||
+ IN6_IS_ADDR_MULTICAST(&SIN6(ifa)->sin6_addr)))
+ return -1;
+
+ /* found */
+ return 0;
+ /* NOTREACHED */
+ case RTM_IFINFO:
+ /* found */
+ return 0;
+ /* NOTREACHED */
+ }
+ return -1;
}
struct in6_addr *
diff --git a/usr.sbin/rtadvd/if.h b/usr.sbin/rtadvd/if.h
index afa3637a995..9b621e13f52 100644
--- a/usr.sbin/rtadvd/if.h
+++ b/usr.sbin/rtadvd/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.13 2016/06/29 14:19:38 jca Exp $ */
+/* $OpenBSD: if.h,v 1.14 2017/08/10 19:07:14 jca Exp $ */
/* $KAME: if.h,v 1.6 2001/01/21 15:37:14 itojun Exp $ */
/*
@@ -40,7 +40,7 @@ int if_getmtu(char *);
int if_getflags(int, int);
int lladdropt_length(struct sockaddr_dl *);
void lladdropt_fill(struct sockaddr_dl *, struct nd_opt_hdr *);
-char *get_next_msg(char *, char *, size_t *);
+int validate_msg(char *);
struct in6_addr *get_addr(char *);
int get_rtm_ifindex(char *);
int get_ifm_ifindex(char *);
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
index 3bed55756c9..5214a8bb6ec 100644
--- a/usr.sbin/rtadvd/rtadvd.c
+++ b/usr.sbin/rtadvd/rtadvd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtadvd.c,v 1.87 2017/07/12 06:11:07 florian Exp $ */
+/* $OpenBSD: rtadvd.c,v 1.88 2017/08/10 19:07:14 jca Exp $ */
/* $KAME: rtadvd.c,v 1.66 2002/05/29 14:18:36 itojun Exp $ */
/*
@@ -303,9 +303,8 @@ die_cb(int sig, short event, void *arg)
static void
rtsock_cb(int fd, short event, void *arg)
{
- int n, type, ifindex = 0, plen;
- size_t len;
- char *next, *lim;
+ int n, type, ifindex = 0, oldifflags, plen;
+ char *next;
u_char ifname[IF_NAMESIZE];
struct prefix *prefix;
struct rainfo *rai;
@@ -315,148 +314,129 @@ rtsock_cb(int fd, short event, void *arg)
n = read(rtsock, rtsockbuf, rtsockbuflen);
log_debug("received a routing message "
"(type = %d, len = %d)", rtmsg_type(rtsockbuf), n);
- if (n > rtmsg_len(rtsockbuf)) {
- /*
- * This usually won't happen for messages received on
- * a routing socket.
- */
- log_debug("received data length is larger than "
- "1st routing message len. multiple messages? "
- "read %d bytes, but 1st msg len = %d",
- n, rtmsg_len(rtsockbuf));
-#if 0
- /* adjust length */
- n = rtmsg_len(rtsockbuf);
-#endif
- }
- lim = rtsockbuf + n;
- for (next = rtsockbuf; next < lim; next += len) {
- int oldifflags;
+ next = rtsockbuf;
+ if (validate_msg(next) == -1)
+ return;
- next = get_next_msg(next, lim, &len);
+ type = rtmsg_type(next);
+ switch (type) {
+ case RTM_ADD:
+ case RTM_DELETE:
+ ifindex = get_rtm_ifindex(next);
+ break;
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ ifindex = get_ifam_ifindex(next);
+ break;
+ case RTM_IFINFO:
+ ifindex = get_ifm_ifindex(next);
+ break;
+ default:
+ /* should not reach here */
+ log_debug("unknown rtmsg %d on %s",
+ type, if_indextoname(ifindex, ifname));
+ return;
+ }
- if (len == 0)
- break;
- type = rtmsg_type(next);
- switch (type) {
- case RTM_ADD:
- case RTM_DELETE:
- ifindex = get_rtm_ifindex(next);
- break;
- case RTM_NEWADDR:
- case RTM_DELADDR:
- ifindex = get_ifam_ifindex(next);
+ if ((rai = if_indextorainfo(ifindex)) == NULL) {
+ log_debug("route changed on "
+ "non advertising interface(%s)",
+ if_indextoname(ifindex, ifname));
+ return;
+ }
+ oldifflags = iflist[ifindex]->ifm_flags;
+
+ switch (type) {
+ case RTM_ADD:
+ /* init ifflags because it may have changed */
+ iflist[ifindex]->ifm_flags =
+ if_getflags(ifindex, iflist[ifindex]->ifm_flags);
+
+ if (sflag)
+ break; /* we aren't interested in prefixes */
+
+ addr = get_addr(next);
+ plen = get_prefixlen(next);
+ /* sanity check for plen */
+ /* as RFC2373, prefixlen is at least 4 */
+ if (plen < 4 || plen > 127) {
+ log_info("new interface route's"
+ " plen %d is invalid for a prefix", plen);
break;
- case RTM_IFINFO:
- ifindex = get_ifm_ifindex(next);
+ }
+ prefix = find_prefix(rai, addr, plen);
+ if (prefix) {
+ log_debug("new prefix(%s/%d) "
+ "added on %s, "
+ "but it was already in list",
+ inet_ntop(AF_INET6, addr,
+ addrbuf, INET6_ADDRSTRLEN),
+ plen, rai->ifname);
break;
- default:
- /* should not reach here */
- log_debug("unknown rtmsg %d on %s",
- type, if_indextoname(ifindex, ifname));
- continue;
}
+ make_prefix(rai, ifindex, addr, plen);
+ break;
+ case RTM_DELETE:
+ /* init ifflags because it may have changed */
+ iflist[ifindex]->ifm_flags =
+ if_getflags(ifindex, iflist[ifindex]->ifm_flags);
- if ((rai = if_indextorainfo(ifindex)) == NULL) {
- log_debug("route changed on "
- "non advertising interface(%s)",
- if_indextoname(ifindex, ifname));
- continue;
- }
- oldifflags = iflist[ifindex]->ifm_flags;
-
- switch (type) {
- case RTM_ADD:
- /* init ifflags because it may have changed */
- iflist[ifindex]->ifm_flags =
- if_getflags(ifindex, iflist[ifindex]->ifm_flags);
-
- if (sflag)
- break; /* we aren't interested in prefixes */
-
- addr = get_addr(next);
- plen = get_prefixlen(next);
- /* sanity check for plen */
- /* as RFC2373, prefixlen is at least 4 */
- if (plen < 4 || plen > 127) {
- log_info("new interface route's"
- " plen %d is invalid for a prefix", plen);
- break;
- }
- prefix = find_prefix(rai, addr, plen);
- if (prefix) {
- log_debug("new prefix(%s/%d) "
- "added on %s, "
- "but it was already in list",
- inet_ntop(AF_INET6, addr,
- addrbuf, INET6_ADDRSTRLEN),
- plen, rai->ifname);
- break;
- }
- make_prefix(rai, ifindex, addr, plen);
- break;
- case RTM_DELETE:
- /* init ifflags because it may have changed */
- iflist[ifindex]->ifm_flags =
- if_getflags(ifindex, iflist[ifindex]->ifm_flags);
-
- if (sflag)
- break;
-
- addr = get_addr(next);
- plen = get_prefixlen(next);
- /* sanity check for plen */
- /* as RFC2373, prefixlen is at least 4 */
- if (plen < 4 || plen > 127) {
- log_info("deleted interface route's "
- "plen %d is invalid for a prefix", plen);
- break;
- }
- prefix = find_prefix(rai, addr, plen);
- if (prefix == NULL) {
- log_debug("prefix(%s/%d) was "
- "deleted on %s, "
- "but it was not in list",
- inet_ntop(AF_INET6, addr,
- addrbuf, INET6_ADDRSTRLEN),
- plen, rai->ifname);
- break;
- }
- delete_prefix(rai, prefix);
+ if (sflag)
break;
- case RTM_NEWADDR:
- case RTM_DELADDR:
- /* init ifflags because it may have changed */
- iflist[ifindex]->ifm_flags =
- if_getflags(ifindex, iflist[ifindex]->ifm_flags);
+
+ addr = get_addr(next);
+ plen = get_prefixlen(next);
+ /* sanity check for plen */
+ /* as RFC2373, prefixlen is at least 4 */
+ if (plen < 4 || plen > 127) {
+ log_info("deleted interface route's "
+ "plen %d is invalid for a prefix", plen);
break;
- case RTM_IFINFO:
- iflist[ifindex]->ifm_flags = get_ifm_flags(next);
+ }
+ prefix = find_prefix(rai, addr, plen);
+ if (prefix == NULL) {
+ log_debug("prefix(%s/%d) was "
+ "deleted on %s, "
+ "but it was not in list",
+ inet_ntop(AF_INET6, addr,
+ addrbuf, INET6_ADDRSTRLEN),
+ plen, rai->ifname);
break;
- default:
- /* should not reach here */
- log_debug("unknown rtmsg %d on %s",
- type, if_indextoname(ifindex, ifname));
- return;
}
+ delete_prefix(rai, prefix);
+ break;
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ /* init ifflags because it may have changed */
+ iflist[ifindex]->ifm_flags =
+ if_getflags(ifindex, iflist[ifindex]->ifm_flags);
+ break;
+ case RTM_IFINFO:
+ iflist[ifindex]->ifm_flags = get_ifm_flags(next);
+ break;
+ default:
+ /* should not reach here */
+ log_debug("unknown rtmsg %d on %s",
+ type, if_indextoname(ifindex, ifname));
+ return;
+ }
- /* check if an interface flag is changed */
- if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */
- (iflist[ifindex]->ifm_flags & IFF_UP) == 0) {
- log_info("interface %s becomes down. stop timer.",
- rai->ifname);
- evtimer_del(&rai->timer.ev);
- } else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */
- (iflist[ifindex]->ifm_flags & IFF_UP) != 0) {
- log_info("interface %s becomes up. restart timer.",
- rai->ifname);
-
- rai->initcounter = 0; /* reset the counter */
- rai->waiting = 0; /* XXX */
- ra_timer_update(rai);
- evtimer_add(&rai->timer.ev, &rai->timer.tm);
- }
+ /* check if an interface flag is changed */
+ if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */
+ (iflist[ifindex]->ifm_flags & IFF_UP) == 0) {
+ log_info("interface %s becomes down. stop timer.",
+ rai->ifname);
+ evtimer_del(&rai->timer.ev);
+ } else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */
+ (iflist[ifindex]->ifm_flags & IFF_UP) != 0) {
+ log_info("interface %s becomes up. restart timer.",
+ rai->ifname);
+
+ rai->initcounter = 0; /* reset the counter */
+ rai->waiting = 0; /* XXX */
+ ra_timer_update(rai);
+ evtimer_add(&rai->timer.ev, &rai->timer.tm);
}
}