diff options
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 51 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 11 | ||||
-rw-r--r-- | sys/netinet6/tcp6_var.h | 7 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 13 |
4 files changed, 69 insertions, 13 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index acc155e9e6a6..d55ed96fee19 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -71,6 +71,7 @@ #include <sys/systm.h> #include <sys/malloc.h> #include <sys/mbuf.h> +#include <sys/domain.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -90,6 +91,7 @@ #include <netinet/in_var.h> #include <netinet/in_systm.h> #include <netinet6/ip6.h> +#include <netinet/ip_var.h> #include <netinet6/ip6_var.h> #include <netinet6/nd6.h> #include <netinet/in_pcb.h> @@ -211,7 +213,7 @@ in6_pcbbind(inp, nam, p) return(EACCES); if (so->so_cred->cr_uid != 0 && !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { - t = in6_pcblookup_local(inp->inp_pcbinfo, + t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, lport, INPLOOKUP_WILDCARD); if (t && @@ -222,11 +224,44 @@ in6_pcbbind(inp, nam, p) (so->so_cred->cr_uid != t->inp_socket->so_cred->cr_uid)) return (EADDRINUSE); + if (ip6_mapped_addr_on != 0 && + IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { + struct sockaddr_in sin; + + in6_sin6_2_sin(&sin, sin6); + t = in_pcblookup_local(pcbinfo, + sin.sin_addr, lport, + INPLOOKUP_WILDCARD); + if (t && + (so->so_cred->cr_uid != + t->inp_socket->so_cred->cr_uid) && + (ntohl(t->inp_laddr.s_addr) != + INADDR_ANY || + INP_SOCKAF(so) == + INP_SOCKAF(t->inp_socket))) + return (EADDRINUSE); + } } t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, lport, wild); if (t && (reuseport & t->inp_socket->so_options) == 0) return(EADDRINUSE); + if (ip6_mapped_addr_on != 0 && + IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { + struct sockaddr_in sin; + + in6_sin6_2_sin(&sin, sin6); + t = in_pcblookup_local(pcbinfo, sin.sin_addr, + lport, wild); + if (t && + (reuseport & t->inp_socket->so_options) + == 0 && + (ntohl(t->inp_laddr.s_addr) + != INADDR_ANY || + INP_SOCKAF(so) == + INP_SOCKAF(t->inp_socket))) + return (EADDRINUSE); + } } inp->in6p_laddr = sin6->sin6_addr; } @@ -455,6 +490,12 @@ in6_pcbconnect(inp, nam, p) * but if this line is missing, the garbage value remains. */ inp->in6p_flowinfo = sin6->sin6_flowinfo; +#ifdef INET6 + if ((inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) == 0 && + ip6_auto_flowlable != 0) + inp->in6p_flowinfo |= + (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK); +#endif in_pcbrehash(inp); return (0); @@ -701,6 +742,14 @@ in6_pcbdetach(inp) if (inp->in6p_route.ro_rt) rtfree(inp->in6p_route.ro_rt); ip6_freemoptions(inp->in6p_moptions); + + /* Check and free IPv4 related resources in case of mapped addr */ + if (inp->inp_options) + (void)m_free(inp->inp_options); + if (inp->inp_route.ro_rt) + rtfree(inp->inp_route.ro_rt); + ip_freemoptions(inp->inp_moptions); + inp->inp_vflag = 0; zfreei(ipi->ipi_zone, inp); } diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 60c3fcf01723..ea43e53c277a 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -64,6 +64,7 @@ * @(#)in_proto.c 8.1 (Berkeley) 6/10/93 */ +#include "opt_inet.h" #include "opt_ipsec.h" #include <sys/param.h> @@ -144,6 +145,16 @@ struct ip6protosw inet6sw[] = { 0, 0, 0, 0, &udp6_usrreqs, }, +{ SOCK_STREAM, &inet6domain, IPPROTO_TCP, PR_CONNREQUIRED | PR_WANTRCVD, + tcp6_input, 0, tcp6_ctlinput, tcp_ctloutput, + 0, +#ifdef INET /* don't call timeout routines twice */ + tcp_init, 0, 0, tcp_drain, +#else + tcp_init, 0, tcp_slowtimo, tcp_drain, +#endif + &tcp6_usrreqs, +}, { SOCK_RAW, &inet6domain, IPPROTO_RAW, PR_ATOMIC | PR_ADDR, rip6_input, rip6_output, 0, rip6_ctloutput, 0, diff --git a/sys/netinet6/tcp6_var.h b/sys/netinet6/tcp6_var.h index b2665c154588..820c49be741e 100644 --- a/sys/netinet6/tcp6_var.h +++ b/sys/netinet6/tcp6_var.h @@ -69,6 +69,11 @@ #define _NETINET_TCP6_VAR_H_ #ifdef _KERNEL +#ifdef SYSCTL_DECL +SYSCTL_DECL(_net_inet6_tcp6); +#endif + +extern int tcp_v6mssdflt; /* XXX */ struct ip6_hdr; void tcp6_ctlinput __P((int, struct sockaddr *, void *)); @@ -78,6 +83,6 @@ struct rtentry *tcp_rtlookup6 __P((struct inpcb *)); extern struct pr_usrreqs tcp6_usrreqs; -#endif +#endif /* _KERNEL */ #endif /* _NETINET_TCP6_VAR_H_ */ diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 936bac9292fc..9e5c65da7a88 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -705,7 +705,6 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct proc *p) inp = sotoinpcb(so); if (inp == 0) return EINVAL; - if (ip6_mapped_addr_on) { struct sockaddr_in6 *sin6_p; @@ -727,22 +726,14 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct proc *p) return error; } } - if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) return EISCONN; s = splnet(); error = in6_pcbconnect(inp, nam, p); - if (ip6_auto_flowlabel) { - inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; - inp->in6p_flowinfo |= - (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK); - } splx(s); if (error == 0) { - if (ip6_mapped_addr_on) { /* should be non mapped addr */ - inp->inp_vflag &= ~INP_IPV4; - inp->inp_vflag |= INP_IPV6; - } + inp->inp_vflag &= ~INP_IPV4; + inp->inp_vflag |= INP_IPV6; soisconnected(so); } return error; |