diff options
author | 2017-08-10 19:07:14 +0000 | |
---|---|---|
committer | 2017-08-10 19:07:14 +0000 | |
commit | efb50b01005b3f1a2f886158c8ae8ff749c59918 (patch) | |
tree | 113f40f802b66d4814cb715113ebe885f8af8dea | |
parent | the userland crypto interface died long ago, can clean up the header (diff) | |
download | wireguard-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.c | 130 | ||||
-rw-r--r-- | usr.sbin/rtadvd/if.h | 4 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.c | 248 |
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); } } |