From: Roy Marples Date: Mon, 15 Jun 2020 21:43:39 +0000 (+0100) Subject: inet6: Add support for reporting Mobile IPv6 RA's X-Git-Tag: v9.1.3~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=774505038c1dbcdd9c8de81a4c0c81b482b566e1;p=thirdparty%2Fdhcpcd.git inet6: Add support for reporting Mobile IPv6 RA's This is RFC6275. dhcpcd is not a client suitable for this, but it will at least decode the information properly. --- diff --git a/src/dhcpcd-definitions-small.conf b/src/dhcpcd-definitions-small.conf index b58ab021..4b626f98 100644 --- a/src/dhcpcd-definitions-small.conf +++ b/src/dhcpcd-definitions-small.conf @@ -57,7 +57,7 @@ definend 2 binhex target_address definend 3 index embed prefix_information embed byte length -embed bitflags=LA flags +embed bitflags=LAH flags embed uint32 vltime embed uint32 pltime embed uint32 reserved diff --git a/src/dhcpcd-definitions.conf b/src/dhcpcd-definitions.conf index 5949be67..d0b64314 100644 --- a/src/dhcpcd-definitions.conf +++ b/src/dhcpcd-definitions.conf @@ -341,7 +341,7 @@ definend 2 binhex target_address definend 3 index embed prefix_information embed byte length -embed bitflags=LA flags +embed bitflags=LAH flags embed uint32 vltime embed uint32 pltime embed uint32 reserved @@ -353,6 +353,12 @@ definend 5 embed mtu embed uint16 reserved embed uint32 mtu +# ND6 Mobile IP, RFC6275 +definend 8 embed homeagent_information +embed uint16 reserved +embed uint16 preference +embed uint16 lifetime + # ND6 options, RFC6101 definend 25 index embed rdnss embed uint16 reserved diff --git a/src/ipv6.h b/src/ipv6.h index 5625d851..8eb4fd00 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -226,8 +226,9 @@ struct ipv6_addr { #define IPV6_AF_RAPFX (1U << 12) #define IPV6_AF_EXTENDED (1U << 13) #define IPV6_AF_REGEN (1U << 14) +#define IPV6_AF_ROUTER (1U << 15) #ifdef IPV6_MANAGETEMPADDR -#define IPV6_AF_TEMPORARY (1U << 15) +#define IPV6_AF_TEMPORARY (1U << 16) #endif struct ll_callback { diff --git a/src/ipv6nd.c b/src/ipv6nd.c index 4e904292..ecec7b6c 100644 --- a/src/ipv6nd.c +++ b/src/ipv6nd.c @@ -61,6 +61,13 @@ /* Debugging Router Solicitations is a lot of spam, so disable it */ //#define DEBUG_RS +#ifndef ND_RA_FLAG_HOME_AGENT +#define ND_RA_FLAG_HOME_AGENT 0x20 /* Home Agent flag in RA */ +#endif +#ifndef ND_OPT_PI_FLAG_ROUTER +#define ND_OPT_PI_FLAG_ROUTER 0x20 /* Router flag in PI */ +#endif + #ifndef ND_OPT_RDNSS #define ND_OPT_RDNSS 25 struct nd_opt_rdnss { /* RDNSS option RFC 6106 */ @@ -1096,6 +1103,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, uint32_t old_lifetime; int ifmtu; int loglevel; + unsigned int flags; #ifdef IPV6_MANAGETEMPADDR bool new_ia; #endif @@ -1299,13 +1307,15 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, case ND_OPT_PREFIX_INFORMATION: loglevel = new_data ? LOG_ERR : LOG_DEBUG; if (ndo.nd_opt_len != 4) { - logmessage(loglevel, "%s: invalid option len for prefix", + logmessage(loglevel, + "%s: invalid option len for prefix", ifp->name); continue; } memcpy(&pi, p, sizeof(pi)); if (pi.nd_opt_pi_prefix_len > 128) { - logmessage(loglevel, "%s: invalid prefix len", ifp->name); + logmessage(loglevel, "%s: invalid prefix len", + ifp->name); continue; } /* nd_opt_pi_prefix is not aligned. */ @@ -1314,29 +1324,41 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, if (IN6_IS_ADDR_MULTICAST(&pi_prefix) || IN6_IS_ADDR_LINKLOCAL(&pi_prefix)) { - logmessage(loglevel, "%s: invalid prefix in RA", ifp->name); + logmessage(loglevel, "%s: invalid prefix in RA", + ifp->name); continue; } if (ntohl(pi.nd_opt_pi_preferred_time) > ntohl(pi.nd_opt_pi_valid_time)) { - logmessage(loglevel, "%s: pltime > vltime", ifp->name); + logmessage(loglevel, "%s: pltime > vltime", + ifp->name); + continue; + } + + flags = 0; + if (pi.nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) + flags |= IPV6_AF_ONLINK; + if (pi.nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO && + rap->iface->options->options & + DHCPCD_IPV6RA_AUTOCONF) + flags |= IPV6_AF_AUTOCONF; + if (pi.nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ROUTER) + flags |= IPV6_AF_ROUTER; + if (flags == 0) { + logmessage(loglevel, + "%s: prefix information option" + " with unknown flags", + ifp->name); continue; } + ia = ipv6nd_rapfindprefix(rap, &pi_prefix, pi.nd_opt_pi_prefix_len); if (ia == NULL) { - unsigned int flags; - - flags = IPV6_AF_RAPFX; - if (pi.nd_opt_pi_flags_reserved & - ND_OPT_PI_FLAG_AUTO && - rap->iface->options->options & - DHCPCD_IPV6RA_AUTOCONF) - flags |= IPV6_AF_AUTOCONF; - ia = ipv6_newaddr(rap->iface, - &pi_prefix, pi.nd_opt_pi_prefix_len, flags); + &pi_prefix, pi.nd_opt_pi_prefix_len, + flags | IPV6_AF_RAPFX); if (ia == NULL) break; ia->prefix = pi_prefix; @@ -1363,12 +1385,10 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, #ifdef IPV6_MANAGETEMPADDR new_ia = false; #endif + ia->flags |= flags; ia->flags &= ~IPV6_AF_STALE; ia->acquired = rap->acquired; } - if (pi.nd_opt_pi_flags_reserved & - ND_OPT_PI_FLAG_ONLINK) - ia->flags |= IPV6_AF_ONLINK; ia->prefix_vltime = ntohl(pi.nd_opt_pi_valid_time); ia->prefix_pltime = @@ -1602,6 +1622,7 @@ ipv6nd_env(FILE *fp, const struct interface *ifp) struct nd_opt_hdr ndo; struct ipv6_addr *ia; struct timespec now; + int pref; clock_gettime(CLOCK_MONOTONIC, &now); i = n = 0; @@ -1618,6 +1639,18 @@ ipv6nd_env(FILE *fp, const struct interface *ifp) if (efprintf(fp, "%s_now=%lld", ndprefix, (long long)now.tv_sec) == -1) return -1; + if (efprintf(fp, "%s_hoplimit=%u", ndprefix, rap->hoplimit) == -1) + return -1; + pref = ipv6nd_rtpref(rap); + if (efprintf(fp, "%s_flags=%s%s%s%s", ndprefix, + rap->flags & ND_RA_FLAG_MANAGED ? "M" : "", + rap->flags & ND_RA_FLAG_OTHER ? "O" : "", + rap->flags & ND_RA_FLAG_HOME_AGENT ? "H" : "", + pref == RTPREF_HIGH ? "h" : pref == RTPREF_LOW ? "l" : "" + ) == -1) + return -1; + if (efprintf(fp, "%s_lifetime=%u", ndprefix, rap->lifetime) == -1) + return -1; /* Zero our indexes */ for (j = 0, opt = rap->iface->ctx->nd_opts;