From owner-svn-src-stable@FreeBSD.ORG Sun Jul 7 13:07:43 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id C54579E3; Sun, 7 Jul 2013 13:07:43 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id B6BBD13A4; Sun, 7 Jul 2013 13:07:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r67D7hCi092625; Sun, 7 Jul 2013 13:07:43 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r67D7gwQ092619; Sun, 7 Jul 2013 13:07:42 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201307071307.r67D7gwQ092619@svn.freebsd.org> From: Michael Tuexen Date: Sun, 7 Jul 2013 13:07:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r252944 - in stable/9/sys: netinet netinet6 X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Jul 2013 13:07:43 -0000 Author: tuexen Date: Sun Jul 7 13:07:42 2013 New Revision: 252944 URL: http://svnweb.freebsd.org/changeset/base/252944 Log: MFC r243186: Add support for SCTP/UDP/IPV6. his completes the support of http://tools.ietf.org/html/draft-ietf-tsvwg-sctp-udp-encaps Modified: stable/9/sys/netinet/sctp_pcb.h stable/9/sys/netinet/sctp_sysctl.c stable/9/sys/netinet/sctputil.c stable/9/sys/netinet/sctputil.h stable/9/sys/netinet6/sctp6_usrreq.c stable/9/sys/netinet6/sctp6_var.h Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/netinet/sctp_pcb.h ============================================================================== --- stable/9/sys/netinet/sctp_pcb.h Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet/sctp_pcb.h Sun Jul 7 13:07:42 2013 (r252944) @@ -144,7 +144,12 @@ struct sctp_tagblock { struct sctp_epinfo { - struct socket *udp_tun_socket; +#ifdef INET + struct socket *udp4_tun_socket; +#endif +#ifdef INET6 + struct socket *udp6_tun_socket; +#endif struct sctpasochead *sctp_asochash; u_long hashasocmark; Modified: stable/9/sys/netinet/sctp_sysctl.c ============================================================================== --- stable/9/sys/netinet/sctp_sysctl.c Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet/sctp_sysctl.c Sun Jul 7 13:07:42 2013 (r252944) @@ -549,8 +549,6 @@ skip: if ((var) < (min)) { (var) = (min); } \ else if ((var) > (max)) { (var) = (max); } -/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */ -#if !defined(__FreeBSD__) || defined(INET) static int sysctl_sctp_udp_tunneling_check(SYSCTL_HANDLER_ARGS) { @@ -582,8 +580,6 @@ out: return (error); } -#endif - static int sysctl_sctp_check(SYSCTL_HANDLER_ARGS) @@ -1067,12 +1063,9 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUT "Clear SCTP Logging buffer"); #endif -/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */ -#if !defined(__FreeBSD__) || defined(INET) SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port, CTLTYPE_UINT | CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), 0, sysctl_sctp_udp_tunneling_check, "IU", SCTPCTL_UDP_TUNNELING_PORT_DESC); -#endif SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, enable_sack_immediately, CTLTYPE_UINT | CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), 0, sysctl_sctp_check, "IU", Modified: stable/9/sys/netinet/sctputil.c ============================================================================== --- stable/9/sys/netinet/sctputil.c Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet/sctputil.c Sun Jul 7 13:07:42 2013 (r252944) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #ifdef INET6 +#include #endif #include #include @@ -48,6 +49,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #ifndef KTR_SCTP @@ -6769,24 +6773,15 @@ sctp_log_trace(uint32_t subsys, const ch } #endif -/* XXX: Remove the #ifdef after tunneling over IPv6 works also on FreeBSD. */ -#ifdef INET -/* We will need to add support - * to bind the ports and such here - * so we can do UDP tunneling. In - * the mean-time, we return error - */ -#include -#include -#include -#ifdef INET6 -#include -#endif - static void sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored) { struct ip *iph; + +#ifdef INET6 + struct ip6_hdr *ip6; + +#endif struct mbuf *sp, *last; struct udphdr *uhdr; uint16_t port; @@ -6836,10 +6831,10 @@ sctp_recv_udp_tunneled_packet(struct mbu #endif #ifdef INET6 case IPV6_VERSION >> 4: - /* Not yet supported. */ - goto out; + ip6 = mtod(m, struct ip6_hdr *); + ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr)); + sctp6_input_with_port(&m, &off, port); break; - #endif default: goto out; @@ -6853,19 +6848,22 @@ out: void sctp_over_udp_stop(void) { - struct socket *sop; - /* * This function assumes sysctl caller holds sctp_sysctl_info_lock() * for writting! */ - if (SCTP_BASE_INFO(udp_tun_socket) == NULL) { - /* Nothing to do */ - return; +#ifdef INET + if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { + soclose(SCTP_BASE_INFO(udp4_tun_socket)); + SCTP_BASE_INFO(udp4_tun_socket) = NULL; } - sop = SCTP_BASE_INFO(udp_tun_socket); - soclose(sop); - SCTP_BASE_INFO(udp_tun_socket) = NULL; +#endif +#ifdef INET6 + if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { + soclose(SCTP_BASE_INFO(udp6_tun_socket)); + SCTP_BASE_INFO(udp6_tun_socket) = NULL; + } +#endif } int @@ -6873,53 +6871,83 @@ sctp_over_udp_start(void) { uint16_t port; int ret; + +#ifdef INET struct sockaddr_in sin; - struct socket *sop = NULL; - struct thread *th; - struct ucred *cred; +#endif +#ifdef INET6 + struct sockaddr_in6 sin6; + +#endif /* * This function assumes sysctl caller holds sctp_sysctl_info_lock() * for writting! */ port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port); - if (port == 0) { + if (ntohs(port) == 0) { /* Must have a port set */ return (EINVAL); } - if (SCTP_BASE_INFO(udp_tun_socket) != NULL) { +#ifdef INET + if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { + /* Already running -- must stop first */ + return (EALREADY); + } +#endif +#ifdef INET6 + if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { /* Already running -- must stop first */ return (EALREADY); } - th = curthread; - cred = th->td_ucred; - if ((ret = socreate(PF_INET, &sop, - SOCK_DGRAM, IPPROTO_UDP, cred, th))) { +#endif +#ifdef INET + if ((ret = socreate(PF_INET, &SCTP_BASE_INFO(udp4_tun_socket), + SOCK_DGRAM, IPPROTO_UDP, + curthread->td_ucred, curthread))) { + sctp_over_udp_stop(); return (ret); } - SCTP_BASE_INFO(udp_tun_socket) = sop; - /* call the special UDP hook */ - ret = udp_set_kernel_tunneling(sop, sctp_recv_udp_tunneled_packet); - if (ret) { - goto exit_stage_left; - } - /* Ok we have a socket, bind it to the port */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); + /* Call the special UDP hook. */ + if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket), + sctp_recv_udp_tunneled_packet))) { + sctp_over_udp_stop(); + return (ret); + } + /* Ok, we have a socket, bind it to the port. */ + memset(&sin, 0, sizeof(struct sockaddr_in)); + sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; sin.sin_port = htons(port); - ret = sobind(sop, (struct sockaddr *)&sin, th); - if (ret) { - /* Close up we cant get the port */ -exit_stage_left: + if ((ret = sobind(SCTP_BASE_INFO(udp4_tun_socket), + (struct sockaddr *)&sin, curthread))) { sctp_over_udp_stop(); return (ret); } - /* - * Ok we should now get UDP packets directly to our input routine - * sctp_recv_upd_tunneled_packet(). - */ +#endif +#ifdef INET6 + if ((ret = socreate(PF_INET6, &SCTP_BASE_INFO(udp6_tun_socket), + SOCK_DGRAM, IPPROTO_UDP, + curthread->td_ucred, curthread))) { + sctp_over_udp_stop(); + return (ret); + } + /* Call the special UDP hook. */ + if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket), + sctp_recv_udp_tunneled_packet))) { + sctp_over_udp_stop(); + return (ret); + } + /* Ok, we have a socket, bind it to the port. */ + memset(&sin6, 0, sizeof(struct sockaddr_in6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(port); + if ((ret = sobind(SCTP_BASE_INFO(udp6_tun_socket), + (struct sockaddr *)&sin6, curthread))) { + sctp_over_udp_stop(); + return (ret); + } +#endif return (0); } - -#endif Modified: stable/9/sys/netinet/sctputil.h ============================================================================== --- stable/9/sys/netinet/sctputil.h Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet/sctputil.h Sun Jul 7 13:07:42 2013 (r252944) @@ -323,13 +323,9 @@ do { \ } while (0) /* functions to start/stop udp tunneling */ -/* XXX: Remove the #ifdef after tunneling over IPv6 works also on FreeBSD. */ -#ifdef INET void sctp_over_udp_stop(void); int sctp_over_udp_start(void); -#endif - int sctp_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, Modified: stable/9/sys/netinet6/sctp6_usrreq.c ============================================================================== --- stable/9/sys/netinet6/sctp6_usrreq.c Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet6/sctp6_usrreq.c Sun Jul 7 13:07:42 2013 (r252944) @@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$"); extern struct protosw inetsw[]; int -sctp6_input(struct mbuf **i_pak, int *offp, int proto) +sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) { struct mbuf *m; int iphlen; @@ -84,7 +84,6 @@ sctp6_input(struct mbuf **i_pak, int *of #endif uint32_t mflowid; uint8_t use_mflowid; - uint16_t port = 0; iphlen = *offp; if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { @@ -195,6 +194,12 @@ out: } +int +sctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED) +{ + return (sctp6_input_with_port(i_pak, offp, 0)); +} + static void sctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6, struct sctphdr *sh, struct sctp_tcb *stcb, struct sctp_nets *net) Modified: stable/9/sys/netinet6/sctp6_var.h ============================================================================== --- stable/9/sys/netinet6/sctp6_var.h Sun Jul 7 13:04:31 2013 (r252943) +++ stable/9/sys/netinet6/sctp6_var.h Sun Jul 7 13:07:42 2013 (r252944) @@ -42,6 +42,7 @@ SYSCTL_DECL(_net_inet6_sctp6); extern struct pr_usrreqs sctp6_usrreqs; int sctp6_input(struct mbuf **, int *, int); +int sctp6_input_with_port(struct mbuf **, int *, uint16_t); int sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *, struct mbuf *, struct proc *);