diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-04-08 15:37:49 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-05-20 09:58:21 +0200 |
commit | 165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99 (patch) | |
tree | c42072a99573d4d7cc03b2263e2c0c6d53f9c691 /freebsd/sys/netinet6 | |
parent | rtems-bsd-chunk: Include missing header file (diff) | |
download | rtems-libbsd-165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99.tar.bz2 |
Update to FreeBSD Stable/9 2015-04-08
Diffstat (limited to 'freebsd/sys/netinet6')
-rw-r--r-- | freebsd/sys/netinet6/icmp6.c | 2 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6.c | 27 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_mcast.c | 2 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_pcb.c | 12 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_src.c | 10 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_var.h | 1 | ||||
-rw-r--r-- | freebsd/sys/netinet6/ip6_input.c | 29 | ||||
-rw-r--r-- | freebsd/sys/netinet6/ip6_output.c | 17 | ||||
-rw-r--r-- | freebsd/sys/netinet6/ip6_var.h | 3 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6.c | 2 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6.h | 2 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6_nbr.c | 39 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6_rtr.c | 12 | ||||
-rw-r--r-- | freebsd/sys/netinet6/scope6.c | 31 | ||||
-rw-r--r-- | freebsd/sys/netinet6/scope6_var.h | 3 |
15 files changed, 105 insertions, 87 deletions
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index 20b03a21..49b1bd8a 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -363,8 +363,6 @@ icmp6_error(struct mbuf *m, int type, int code, int param) preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); M_PREPEND(m, preplen, M_DONTWAIT); /* FIB is also copied over. */ - if (m && m->m_len < preplen) - m = m_pullup(m, preplen); if (m == NULL) { nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__)); return; diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c index f68f21f2..8dc4d29f 100644 --- a/freebsd/sys/netinet6/in6.c +++ b/freebsd/sys/netinet6/in6.c @@ -286,7 +286,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP); } - switch(cmd) { + switch (cmd) { case SIOCAADDRCTL_POLICY: case SIOCDADDRCTL_POLICY: if (td != NULL) { @@ -358,14 +358,10 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) return (error); } - return (scope6_set(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + /* FALLTHROUGH */ case SIOCGSCOPE6: - return (scope6_get(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6DEF: - return (scope6_get_default((struct scope6_id *) - ifr->ifr_ifru.ifru_scope_id)); + return (scope6_ioctl(cmd, data, ifp)); } switch (cmd) { @@ -496,6 +492,13 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) goto out; } + /* FALLTHROUGH */ + case SIOCGIFSTAT_IN6: + case SIOCGIFSTAT_ICMP6: + if (ifp->if_afdata[AF_INET6] == NULL) { + error = EPFNOSUPPORT; + goto out; + } break; case SIOCGIFADDR_IN6: @@ -571,10 +574,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_IN6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_stat, sizeof(ifr->ifr_ifru.ifru_stat)); ifr->ifr_ifru.ifru_stat = @@ -582,10 +581,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_ICMP6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_icmp6stat, sizeof(ifr->ifr_ifru.ifru_icmp6stat)); ifr->ifr_ifru.ifru_icmp6stat = @@ -801,7 +796,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, } default: - if (ifp == NULL || ifp->if_ioctl == 0) { + if (ifp->if_ioctl == NULL) { error = EOPNOTSUPP; goto out; } diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c index e5457707..d32d57c6 100644 --- a/freebsd/sys/netinet6/in6_mcast.c +++ b/freebsd/sys/netinet6/in6_mcast.c @@ -1077,6 +1077,8 @@ in6m_purge(struct in6_multi *inm) free(ims, M_IP6MSOURCE); inm->in6m_nsrc--; } + /* Free state-change requests that might be queued. */ + _IF_DRAIN(&inm->in6m_scq); } /* diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index 4b0b3389..8a7581c9 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -638,18 +638,12 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst, /* * If the error designates a new path MTU for a destination * and the application (associated with this socket) wanted to - * know the value, notify. Note that we notify for all - * disconnected sockets if the corresponding application - * wanted. This is because some UDP applications keep sending - * sockets disconnected. + * know the value, notify. * XXX: should we avoid to notify the value to TCP sockets? */ - if (cmd == PRC_MSGSIZE && (inp->inp_flags & IN6P_MTU) != 0 && - (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) || - IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &sa6_dst->sin6_addr))) { + if (cmd == PRC_MSGSIZE && cmdarg != NULL) ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst, - (u_int32_t *)cmdarg); - } + *(u_int32_t *)cmdarg); /* * Detect if we should notify the error. If no source and diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c index cc2f5ee5..79beb703 100644 --- a/freebsd/sys/netinet6/in6_src.c +++ b/freebsd/sys/netinet6/in6_src.c @@ -445,6 +445,16 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, REPLACE(8); /* + * Rule 10: prefer address with `prefer_source' flag. + */ + if ((ia_best->ia6_flags & IN6_IFF_PREFER_SOURCE) == 0 && + (ia->ia6_flags & IN6_IFF_PREFER_SOURCE) != 0) + REPLACE(10); + if ((ia_best->ia6_flags & IN6_IFF_PREFER_SOURCE) != 0 && + (ia->ia6_flags & IN6_IFF_PREFER_SOURCE) == 0) + NEXT(10); + + /* * Rule 14: Use longest matching prefix. * Note: in the address selection draft, this rule is * documented as "Rule 8". However, since it is also diff --git a/freebsd/sys/netinet6/in6_var.h b/freebsd/sys/netinet6/in6_var.h index c7ebe523..90530a68 100644 --- a/freebsd/sys/netinet6/in6_var.h +++ b/freebsd/sys/netinet6/in6_var.h @@ -473,6 +473,7 @@ struct in6_rrenumreq { */ #define IN6_IFF_AUTOCONF 0x40 /* autoconfigurable address. */ #define IN6_IFF_TEMPORARY 0x80 /* temporary (anonymous) address. */ +#define IN6_IFF_PREFER_SOURCE 0x0100 /* preferred address for SAS */ #define IN6_IFF_NOPFX 0x8000 /* skip kernel prefix management. * XXX: this should be temporary. */ diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c index 0de64eb7..17420faf 100644 --- a/freebsd/sys/netinet6/ip6_input.c +++ b/freebsd/sys/netinet6/ip6_input.c @@ -1605,24 +1605,28 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) #undef IS2292 void -ip6_notify_pmtu(struct inpcb *in6p, struct sockaddr_in6 *dst, u_int32_t *mtu) +ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu) { struct socket *so; struct mbuf *m_mtu; struct ip6_mtuinfo mtuctl; - so = in6p->inp_socket; - - if (mtu == NULL) + KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); + /* + * Notify the error by sending IPV6_PATHMTU ancillary data if + * application wanted to know the MTU value. + * NOTE: we notify disconnected sockets, because some udp + * applications keep sending sockets disconnected. + * NOTE: our implementation doesn't notify connected sockets that has + * foreign address that is different than given destination addresses + * (this is permitted by RFC 3542). + */ + if ((inp->inp_flags & IN6P_MTU) == 0 || ( + !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && + !IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &dst->sin6_addr))) return; -#ifdef DIAGNOSTIC - if (so == NULL) /* I believe this is impossible */ - panic("ip6_notify_pmtu: socket is NULL"); -#endif - - bzero(&mtuctl, sizeof(mtuctl)); /* zero-clear for safety */ - mtuctl.ip6m_mtu = *mtu; + mtuctl.ip6m_mtu = mtu; mtuctl.ip6m_addr = *dst; if (sa6_recoverscope(&mtuctl.ip6m_addr)) return; @@ -1631,14 +1635,13 @@ ip6_notify_pmtu(struct inpcb *in6p, struct sockaddr_in6 *dst, u_int32_t *mtu) IPV6_PATHMTU, IPPROTO_IPV6)) == NULL) return; + so = inp->inp_socket; if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu) == 0) { m_freem(m_mtu); /* XXX: should count statistics */ } else sorwakeup(so); - - return; } #ifdef PULLDOWN_TEST diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c index 06f1246a..95231631 100644 --- a/freebsd/sys/netinet6/ip6_output.c +++ b/freebsd/sys/netinet6/ip6_output.c @@ -998,19 +998,12 @@ passout: * Even if the DONTFRAG option is specified, we cannot send the * packet when the data length is larger than the MTU of the * outgoing interface. - * Notify the error by sending IPV6_PATHMTU ancillary data as - * well as returning an error code (the latter is not described - * in the API spec.) + * Notify the error by sending IPV6_PATHMTU ancillary data if + * application wanted to know the MTU value. Also return an + * error code (this is not described in the API spec). */ - u_int32_t mtu32; - struct ip6ctlparam ip6cp; - - mtu32 = (u_int32_t)mtu; - bzero(&ip6cp, sizeof(ip6cp)); - ip6cp.ip6c_cmdarg = (void *)&mtu32; - pfctlinput2(PRC_MSGSIZE, (struct sockaddr *)&ro_pmtu->ro_dst, - (void *)&ip6cp); - + if (inp != NULL) + ip6_notify_pmtu(inp, &dst_sa, (u_int32_t)mtu); error = EMSGSIZE; goto bad; } diff --git a/freebsd/sys/netinet6/ip6_var.h b/freebsd/sys/netinet6/ip6_var.h index 4a094d42..4e8c42bd 100644 --- a/freebsd/sys/netinet6/ip6_var.h +++ b/freebsd/sys/netinet6/ip6_var.h @@ -406,8 +406,7 @@ int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, struct mbuf **ip6_savecontrol_v4(struct inpcb *, struct mbuf *, struct mbuf **, int *); void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); -void ip6_notify_pmtu(struct inpcb *, struct sockaddr_in6 *, - u_int32_t *); +void ip6_notify_pmtu(struct inpcb *, struct sockaddr_in6 *, u_int32_t); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); void ip6_forward(struct mbuf *, int); diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c index 9233bef5..1b855cae 100644 --- a/freebsd/sys/netinet6/nd6.c +++ b/freebsd/sys/netinet6/nd6.c @@ -2283,6 +2283,8 @@ SYSCTL_NODE(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist, CTLFLAG_RD, nd6_sysctl_prlist, ""); SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen, CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, ""); +SYSCTL_VNET_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer, + CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), ""); static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS) diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h index 79e41e38..94202e10 100644 --- a/freebsd/sys/netinet6/nd6.h +++ b/freebsd/sys/netinet6/nd6.h @@ -79,7 +79,7 @@ struct nd_ifinfo { #define ND6_IFF_PERFORMNUD 0x1 #define ND6_IFF_ACCEPT_RTADV 0x2 -#define ND6_IFF_PREFER_SOURCE 0x4 /* XXX: not related to ND. */ +#define ND6_IFF_PREFER_SOURCE 0x4 /* Not used in FreeBSD. */ #define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to * DAD failure. (XXX: not ND-specific) */ diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c index 09011b7e..ce26d54f 100644 --- a/freebsd/sys/netinet6/nd6_nbr.c +++ b/freebsd/sys/netinet6/nd6_nbr.c @@ -234,41 +234,28 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) /* (2) check. */ if (ifa == NULL) { - struct rtentry *rt; - struct sockaddr_in6 tsin6; - int need_proxy; -#ifdef RADIX_MPATH struct route_in6 ro; -#endif + int need_proxy; - bzero(&tsin6, sizeof tsin6); - tsin6.sin6_len = sizeof(struct sockaddr_in6); - tsin6.sin6_family = AF_INET6; - tsin6.sin6_addr = taddr6; + bzero(&ro, sizeof(ro)); + ro.ro_dst.sin6_len = sizeof(struct sockaddr_in6); + ro.ro_dst.sin6_family = AF_INET6; + ro.ro_dst.sin6_addr = taddr6; /* Always use the default FIB. */ #ifdef RADIX_MPATH - bzero(&ro, sizeof(ro)); - ro.ro_dst = tsin6; rtalloc_mpath_fib((struct route *)&ro, RTF_ANNOUNCE, RT_DEFAULT_FIB); - rt = ro.ro_rt; #else - rt = in6_rtalloc1((struct sockaddr *)&tsin6, 0, 0, - RT_DEFAULT_FIB); + in6_rtalloc(&ro, RT_DEFAULT_FIB); #endif - need_proxy = (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 && - rt->rt_gateway->sa_family == AF_LINK); - if (rt != NULL) { - /* - * Make a copy while we can be sure that rt_gateway - * is still stable before unlocking to avoid lock - * order problems. proxydl will only be used if - * proxy will be set in the next block. - */ + need_proxy = (ro.ro_rt && + (ro.ro_rt->rt_flags & RTF_ANNOUNCE) != 0 && + ro.ro_rt->rt_gateway->sa_family == AF_LINK); + if (ro.ro_rt != NULL) { if (need_proxy) - proxydl = *SDL(rt->rt_gateway); - RTFREE_LOCKED(rt); + proxydl = *SDL(ro.ro_rt->rt_gateway); + RTFREE(ro.ro_rt); } if (need_proxy) { /* @@ -711,8 +698,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) */ if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) { - ifa_free(ifa); nd6_dad_na_input(ifa); + ifa_free(ifa); goto freeit; } diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c index bd6fa33b..030cac3d 100644 --- a/freebsd/sys/netinet6/nd6_rtr.c +++ b/freebsd/sys/netinet6/nd6_rtr.c @@ -298,8 +298,16 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) } if (nd_ra->nd_ra_retransmit) ndi->retrans = ntohl(nd_ra->nd_ra_retransmit); - if (nd_ra->nd_ra_curhoplimit) - ndi->chlim = nd_ra->nd_ra_curhoplimit; + if (nd_ra->nd_ra_curhoplimit) { + if (ndi->chlim < nd_ra->nd_ra_curhoplimit) + ndi->chlim = nd_ra->nd_ra_curhoplimit; + else if (ndi->chlim != nd_ra->nd_ra_curhoplimit) { + log(LOG_ERR, "RA with a lower CurHopLimit sent from " + "%s on %s (current = %d, received = %d). " + "Ignored.\n", ip6_sprintf(ip6bufs, &ip6->ip6_src), + if_name(ifp), ndi->chlim, nd_ra->nd_ra_curhoplimit); + } + } dr = defrtrlist_update(&dr0); } diff --git a/freebsd/sys/netinet6/scope6.c b/freebsd/sys/netinet6/scope6.c index f891c9ce..2ccd2f7a 100644 --- a/freebsd/sys/netinet6/scope6.c +++ b/freebsd/sys/netinet6/scope6.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> +#include <sys/sockio.h> #include <sys/systm.h> #include <sys/queue.h> #include <sys/syslog.h> @@ -74,6 +75,9 @@ static VNET_DEFINE(struct scope6_id, sid_default); #define SID(ifp) \ (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id) +static int scope6_get(struct ifnet *, struct scope6_id *); +static int scope6_set(struct ifnet *, struct scope6_id *); + void scope6_init(void) { @@ -117,6 +121,30 @@ scope6_ifdetach(struct scope6_id *sid) } int +scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) +{ + struct in6_ifreq *ifr; + + if (ifp->if_afdata[AF_INET6] == NULL) + return (EPFNOSUPPORT); + + ifr = (struct in6_ifreq *)data; + switch (cmd) { + case SIOCSSCOPE6: + return (scope6_set(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6: + return (scope6_get(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6DEF: + return (scope6_get_default( + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + default: + return (EOPNOTSUPP); + } +} + +static int scope6_set(struct ifnet *ifp, struct scope6_id *idlist) { int i; @@ -179,7 +207,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) return (error); } -int +static int scope6_get(struct ifnet *ifp, struct scope6_id *idlist) { struct scope6_id *sid; @@ -198,7 +226,6 @@ scope6_get(struct ifnet *ifp, struct scope6_id *idlist) return (0); } - /* * Get a scope of the address. Node-local, link-local, site-local or global. */ diff --git a/freebsd/sys/netinet6/scope6_var.h b/freebsd/sys/netinet6/scope6_var.h index ae337b86..990325e9 100644 --- a/freebsd/sys/netinet6/scope6_var.h +++ b/freebsd/sys/netinet6/scope6_var.h @@ -45,8 +45,7 @@ struct scope6_id { void scope6_init(void); struct scope6_id *scope6_ifattach(struct ifnet *); void scope6_ifdetach(struct scope6_id *); -int scope6_set(struct ifnet *, struct scope6_id *); -int scope6_get(struct ifnet *, struct scope6_id *); +int scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *); void scope6_setdefault(struct ifnet *); int scope6_get_default(struct scope6_id *); u_int32_t scope6_addr2default(struct in6_addr *); |