From: Roy Marples Date: Mon, 10 Jun 2013 00:56:54 +0000 (+0000) Subject: Purge prefix list and routers at start of IPv6 for BSD. X-Git-Tag: v6.0.0~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1f4c1525a51e3dad0481638289ece4e88f5f20e6;p=thirdparty%2Fdhcpcd.git Purge prefix list and routers at start of IPv6 for BSD. Remove link_addr compact function as we now had a LL address list. Fix INET and INET6 seperate compiles. --- diff --git a/compat/linkaddr.c b/compat/linkaddr.c deleted file mode 100644 index c4e6fa54..00000000 --- a/compat/linkaddr.c +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#include - -/* States*/ -#define NAMING 0 -#define GOTONE 1 -#define GOTTWO 2 -#define RESET 3 -/* Inputs */ -#define DIGIT (4*0) -#define END (4*1) -#define DELIM (4*2) -#define LETTER (4*3) - -void -link_addr(addr, sdl) - const char *addr; - struct sockaddr_dl *sdl; -{ - char *cp = sdl->sdl_data; - char *cplim = sdl->sdl_len + (char *)(void *)sdl; - int byte = 0, state = NAMING; - int newaddr = 0; - - (void)memset(&sdl->sdl_family, 0, (size_t)sdl->sdl_len - 1); - sdl->sdl_family = AF_LINK; - do { - state &= ~LETTER; - if ((*addr >= '0') && (*addr <= '9')) { - newaddr = *addr - '0'; - } else if ((*addr >= 'a') && (*addr <= 'f')) { - newaddr = *addr - 'a' + 10; - } else if ((*addr >= 'A') && (*addr <= 'F')) { - newaddr = *addr - 'A' + 10; - } else if (*addr == 0) { - state |= END; - } else if (state == NAMING && - (((*addr >= 'A') && (*addr <= 'Z')) || - ((*addr >= 'a') && (*addr <= 'z')))) - state |= LETTER; - else - state |= DELIM; - addr++; - switch (state /* | INPUT */) { - case NAMING | DIGIT: - case NAMING | LETTER: - *cp++ = addr[-1]; - continue; - case NAMING | DELIM: - state = RESET; - sdl->sdl_nlen = cp - sdl->sdl_data; - continue; - case GOTTWO | DIGIT: - *cp++ = byte; - /* FALLTHROUGH */ - case RESET | DIGIT: - state = GOTONE; - byte = newaddr; - continue; - case GOTONE | DIGIT: - state = GOTTWO; - byte = newaddr + (byte << 4); - continue; - default: /* | DELIM */ - state = RESET; - *cp++ = byte; - byte = 0; - continue; - case GOTONE | END: - case GOTTWO | END: - *cp++ = byte; - /* FALLTHROUGH */ - case RESET | END: - break; - } - break; - } while (cp < cplim); - sdl->sdl_alen = cp - LLADDR(sdl); - newaddr = cp - (char *)(void *)sdl; - if ((size_t) newaddr > sizeof(*sdl)) - sdl->sdl_len = newaddr; - return; -} diff --git a/configure b/configure index 1fe383c0..f106fab0 100755 --- a/configure +++ b/configure @@ -322,7 +322,6 @@ kfreebsd) echo "SRCS+= bpf.c" >>$CONFIG_MK fi echo "SRCS+= if-bsd.c platform-bsd.c" >>$CONFIG_MK - echo "COMPAT_SRCS+= compat/linkaddr.c" >>$CONFIG_MK echo "LDADD+= -lrt" >>$CONFIG_MK ;; *) diff --git a/dhcp.h b/dhcp.h index ccf07a9d..60586988 100644 --- a/dhcp.h +++ b/dhcp.h @@ -286,6 +286,7 @@ int dhcp_dump(const char *); #define dhcp_drop(a, b) #define dhcp_start(a) {} #define dhcp_reboot(a, b) b = b +#define dhcp_reboot_newopts(a, b) #define dhcp_close(a) #define dhcp_free(a) #define dhcp_dump(a) -1 diff --git a/dhcp6.h b/dhcp6.h index 4cd28051..44ad6a59 100644 --- a/dhcp6.h +++ b/dhcp6.h @@ -225,7 +225,7 @@ void dhcp6_drop(struct interface *, const char *); #else #define dhcp6_printoptions() #define dhcp6_addrexists(a) -#define dhcp6_find_delegates(a); +#define dhcp6_find_delegates(a) 0 #define dhcp6_start(a, b) 0 #define dhcp6_reboot(a) #define dhcp6_env(a, b, c, d, e) diff --git a/if-bsd.c b/if-bsd.c index 93bc95a8..8faa4a8d 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -359,6 +359,7 @@ if_route6(const struct rt6 *rt, int action) char *bp = rtm.buffer; size_t l; int retval = 0; + const struct ipv6_addr_l *lla; /* KAME based systems want to store the scope inside the sin6_addr * for link local addreses */ @@ -416,11 +417,10 @@ if_route6(const struct rt6 *rt, int action) ADDADDR(&rt->dest); if (!(rtm.hdr.rtm_flags & RTF_GATEWAY)) { - /* Make us a link layer socket for the host gateway */ - memset(&su, 0, sizeof(su)); - su.sdl.sdl_len = sizeof(struct sockaddr_dl); - link_addr(rt->iface->name, &su.sdl); - ADDSU; + lla = ipv6_linklocal(rt->iface); + if (lla == NULL) /* unlikely as we need a LL to get here */ + return -1; + ADDADDRS(&lla->addr, rt->iface->index); } else ADDADDRS(&rt->gate, rt->iface->index); @@ -450,20 +450,6 @@ if_route6(const struct rt6 *rt, int action) retval = -1; return retval; } - -int -pfx_flush(void) -{ - int s; - char dummy[IFNAMSIZ + 1]; - - s = socket(AF_INET6, SOCK_DGRAM, 0); - if (s != -1) { - strcpy(dummy, "lo0"); - s = ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummy); - } - return s; -} #endif static void @@ -485,6 +471,7 @@ get_addrs(int type, char *cp, struct sockaddr **sa) } } +#ifdef INET6 int in6_addr_flags(const char *ifname, const struct in6_addr *addr) { @@ -504,6 +491,7 @@ in6_addr_flags(const char *ifname, const struct in6_addr *addr) } return flags; } +#endif int manage_link(int fd) @@ -515,13 +503,15 @@ manage_link(int fd) struct if_announcemsghdr *ifan; struct if_msghdr *ifm; struct ifa_msghdr *ifam; - struct rt rt; struct sockaddr *sa, *rti_info[RTAX_MAX]; int len; #ifdef RTM_CHGADDR struct sockaddr_dl sdl; unsigned char *hwaddr; #endif +#ifdef INET + struct rt rt; +#endif #if defined(INET6) && !defined(LISTEN_DAD) struct in6_addr ia6; struct sockaddr_in6 *sin6; diff --git a/if-linux.c b/if-linux.c index 13411518..4882e2e2 100644 --- a/if-linux.c +++ b/if-linux.c @@ -776,14 +776,4 @@ in6_addr_flags(__unused const char *ifname, /* How do I get IPv6 address flags on Linux? */ return 0; } - -int -pfx_flush(void) -{ - - /* Flush prefixes, ip -6 neigh flush equivalent */ - /* There seems to be no need for this on Linux right now though, - * probably due to route metrics */ - return 0; -} #endif diff --git a/if-options.c b/if-options.c index e4290df0..a9f84a47 100644 --- a/if-options.c +++ b/if-options.c @@ -352,10 +352,10 @@ splitv(int *argc, char **argv, const char *arg) return v; } +#ifdef INET static int parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg) { -#ifdef INET char *p; int i; @@ -386,11 +386,17 @@ parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg) else if (net != NULL) net->s_addr = ipv4_getnetmask(addr->s_addr); return 0; +} #else +static int +parse_addr(__unused struct in_addr *addr, __unused struct in_addr *net, + __unused const char *arg) +{ + syslog(LOG_ERR, "No IPv4 support"); return -1; -#endif } +#endif static const char * set_option_space(const char *arg, const struct dhcp_opt **d, @@ -423,19 +429,21 @@ static int parse_option(struct if_options *ifo, int opt, const char *arg) { int i; - long l; char *p = NULL, *fp, *np, **nconf; ssize_t s; - size_t sl; struct in_addr addr, addr2; in_addr_t *naddr; struct rt *rt; const struct dhcp_opt *d; uint8_t *request, *require, *no; +#ifdef INET6 + long l; uint32_t u32; + size_t sl; struct if_iaid *iaid; uint8_t _iaid[4]; struct if_sla *sla, *slap; +#endif i = 0; switch(opt) { diff --git a/ipv6.c b/ipv6.c index f4c1d479..b050d512 100644 --- a/ipv6.c +++ b/ipv6.c @@ -73,7 +73,6 @@ #define EUI64_GROUP(in6) ((in6)->s6_addr[8] & EUI64_GBIT) static struct rt6head *routes; -static uint8_t do_pfx_flush; #ifdef DEBUG_MEMORY static void @@ -419,9 +418,11 @@ ipv6_addaddr(struct ipv6_addr *ap) ap->flags |= IPV6_AF_ADDED; if (ap->delegating_iface) ap->flags |= IPV6_AF_DELEGATED; +#if HAVE_ROUTE_METRIC if (ap->iface->options->options & DHCPCD_IPV6RA_OWN && ipv6_removesubnet(ap->iface, ap) == -1) syslog(LOG_ERR,"ipv6_removesubnet %m"); +#endif if (ap->prefix_pltime == ND6_INFINITE_LIFETIME && ap->prefix_vltime == ND6_INFINITE_LIFETIME) syslog(LOG_DEBUG, @@ -741,8 +742,7 @@ nc_route(int add, struct rt6 *ort, struct rt6 *nrt) desc_route(add ? "adding" : "changing", nrt); /* We delete and add the route so that we can change metric and * prefer the interface. */ - if (del_route6(ort) == 0 && add) - do_pfx_flush = 1; + del_route6(ort); if (add_route6(nrt) == 0) return 0; syslog(LOG_ERR, "%s: add_route6: %m", nrt->iface->name); @@ -814,6 +814,7 @@ make_router(const struct ra *rap) return r; } +#if HAVE_ROUTE_METRIC int ipv6_removesubnet(const struct interface *ifp, struct ipv6_addr *addr) { @@ -852,6 +853,7 @@ ipv6_removesubnet(const struct interface *ifp, struct ipv6_addr *addr) } return r; } +#endif #define RT_IS_DEFAULT(rtp) \ (IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \ @@ -951,7 +953,7 @@ ipv6_buildroutes(void) return; } TAILQ_INIT(nrs); - have_default = do_pfx_flush = 0; + have_default = 0; TAILQ_FOREACH_SAFE(rt, &dnr, next, rtn) { /* Is this route already in our table? */ if (find_route6(nrs, rt) != NULL) @@ -966,7 +968,6 @@ ipv6_buildroutes(void) { if (c_route(or, rt) != 0) continue; - do_pfx_flush = 1; } TAILQ_REMOVE(routes, or, next); free(or); @@ -1006,22 +1007,6 @@ ipv6_buildroutes(void) free(rt); } - if (do_pfx_flush) { - /* We need to flush all entries in our prefix list - * if we changed a route so that we leave via the - * correct interface */ - if (pfx_flush() == -1) - syslog(LOG_ERR, "pfx_flush: %m"); - - /* XXX FIXME - * On multi-homed systems on the same network - * (ie wired and wireless) swapping the active routes - * between interfaces (ie, bringing down the wired and - * back up again while wireless is active) causes the - * ping6 command to emit bogus Network is down errors. - * This could be a kernel bug though */ - } - free(routes); routes = nrs; } diff --git a/ipv6.h b/ipv6.h index ac427407..bd54414b 100644 --- a/ipv6.h +++ b/ipv6.h @@ -37,7 +37,6 @@ #define ROUNDUP8(a) (1 + (((a) - 1) | 7)) -#ifdef INET6 #ifndef ND6_INFINITE_LIFETIME # define ND6_INFINITE_LIFETIME ((uint32_t)~0) #endif @@ -137,6 +136,7 @@ struct ipv6_state { #define IPV6_CSTATE(ifp) \ ((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6]) +#ifdef INET6 int ipv6_init(void); ssize_t ipv6_printaddr(char *, ssize_t, const uint8_t *, const char *); int ipv6_makeaddr(struct in6_addr *, const struct interface *, @@ -159,6 +159,18 @@ void ipv6_free_ll_callbacks(struct interface *); void ipv6_free(struct interface *); int ipv6_removesubnet(const struct interface *, struct ipv6_addr *); void ipv6_buildroutes(void); + +int if_address6(const struct ipv6_addr *, int); +#define add_address6(a) if_address6(a, 1) +#define del_address6(a) if_address6(a, -1) +int in6_addr_flags(const char *, const struct in6_addr *); + +int if_route6(const struct rt6 *rt, int); +#define add_route6(rt) if_route6(rt, 1) +#define change_route6(rt) if_route6(rt, 0) +#define del_route6(rt) if_route6(rt, -1) +#define del_src_route6(rt) if_route6(rt, -2); + #else #define ipv6_init() -1 #define ipv6_free_ll_callbacks(a) diff --git a/net.c b/net.c index d8a8c9c8..23cb2482 100644 --- a/net.c +++ b/net.c @@ -25,6 +25,7 @@ * SUCH DAMAGE. */ +#include #include #include #include diff --git a/net.h b/net.h index 2772e56a..46742ac4 100644 --- a/net.h +++ b/net.h @@ -103,18 +103,6 @@ int up_interface(struct interface *); int if_conf(struct interface *); int if_init(struct interface *); -int if_address6(const struct ipv6_addr *, int); -#define add_address6(a) if_address6(a, 1) -#define del_address6(a) if_address6(a, -1) -int in6_addr_flags(const char *, const struct in6_addr *); - -int if_route6(const struct rt6 *rt, int); -#define add_route6(rt) if_route6(rt, 1) -#define change_route6(rt) if_route6(rt, 0) -#define del_route6(rt) if_route6(rt, -1) -#define del_src_route6(rt) if_route6(rt, -2); -int pfx_flush(void); - int open_link_socket(void); int manage_link(int); int carrier_status(struct interface *); diff --git a/platform-bsd.c b/platform-bsd.c index b3218981..39e61c2c 100644 --- a/platform-bsd.c +++ b/platform-bsd.c @@ -25,14 +25,19 @@ * SUCH DAMAGE. */ +#include #include #include #include #include + +#include #include +#include #include #include +#include #include #include "dhcpcd.h" @@ -57,6 +62,7 @@ hardware_platform(void) return march; } +#ifdef INET6 #define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0) #define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1) static int @@ -89,6 +95,24 @@ restore_kernel_ra(void) syslog(LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m"); } +static int +ipv6_ra_flush(void) +{ + int s; + char dummy[IFNAMSIZ + 8]; + + s = socket(AF_INET6, SOCK_DGRAM, 0); + if (s == -1) + return -1; + strcpy(dummy, "lo0"); + if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummy) == -1) + syslog(LOG_ERR, "SIOSRTRFLUSH_IN6: %m"); + if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummy) == -1) + syslog(LOG_ERR, "SIOSPFXFLUSH_IN6: %m"); + close(s); + return 0; +} + int check_ipv6(const char *ifname) { @@ -132,6 +156,8 @@ check_ipv6(const char *ifname) return 0; } + ipv6_ra_flush(); + return 1; } @@ -143,3 +169,4 @@ ipv6_dadtransmits(__unused const char *ifname) r = get_inet6_sysctl(IPV6CTL_DAD_COUNT); return r < 0 ? 0 : r; } +#endif diff --git a/platform-linux.c b/platform-linux.c index 5d60d5c9..f5bbbfc5 100644 --- a/platform-linux.c +++ b/platform-linux.c @@ -74,8 +74,10 @@ static const char *mproc = #endif ; -char **restore; -ssize_t nrestore; +#ifdef INET6 +static char **restore; +static ssize_t nrestore; +#endif char * hardware_platform(void) @@ -110,6 +112,7 @@ hardware_platform(void) return p; } +#ifdef INET6 static int check_proc_int(const char *path) { @@ -259,3 +262,4 @@ ipv6_dadtransmits(const char *ifname) r = check_proc_int(path); return r < 0 ? 0 : r; } +#endif diff --git a/platform.h b/platform.h index 280e0647..5f469e43 100644 --- a/platform.h +++ b/platform.h @@ -29,7 +29,11 @@ #define PLATFORM_H char *hardware_platform(void); +#ifdef INET6 int check_ipv6(const char *); int ipv6_dadtransmits(const char *); +#else +#define check_ipv6(a) 0 +#endif #endif