Date: Mon, 6 Feb 2012 10:22:50 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r231070 - stable/9/sys/netinet Message-ID: <201202061022.q16AMohM031434@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Mon Feb 6 10:22:50 2012 New Revision: 231070 URL: http://svn.freebsd.org/changeset/base/231070 Log: MFC r227755: Add support for the SCTP_REMOTE_UDP_ENCAPS_PORT socket option. Retire the the now unused sctp_udp_tunneling_for_client_enable sysctl variable. Modified: stable/9/sys/netinet/sctp.h stable/9/sys/netinet/sctp_output.c stable/9/sys/netinet/sctp_pcb.c stable/9/sys/netinet/sctp_pcb.h stable/9/sys/netinet/sctp_structs.h stable/9/sys/netinet/sctp_sysctl.c stable/9/sys/netinet/sctp_sysctl.h stable/9/sys/netinet/sctp_uio.h stable/9/sys/netinet/sctp_usrreq.c stable/9/sys/netinet/sctputil.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/netinet/sctp.h ============================================================================== --- stable/9/sys/netinet/sctp.h Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp.h Mon Feb 6 10:22:50 2012 (r231070) @@ -120,6 +120,7 @@ struct sctp_paramhdr { #define SCTP_DEFAULT_SNDINFO 0x00000021 #define SCTP_DEFAULT_PRINFO 0x00000022 #define SCTP_PEER_ADDR_THLDS 0x00000023 +#define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024 /* * read-only options Modified: stable/9/sys/netinet/sctp_output.c ============================================================================== --- stable/9/sys/netinet/sctp_output.c Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_output.c Mon Feb 6 10:22:50 2012 (r231070) @@ -4054,6 +4054,12 @@ sctp_lowlevel_chunk_output(struct sctp_i } } if (port) { + if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { + sctp_handle_no_route(stcb, net, so_locked); + SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH); + sctp_m_freem(m); + return (EHOSTUNREACH); + } udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip)); udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); udp->uh_dport = port; @@ -4405,6 +4411,12 @@ sctp_lowlevel_chunk_output(struct sctp_i ip6h->ip6_src = lsa6->sin6_addr; if (port) { + if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { + sctp_handle_no_route(stcb, net, so_locked); + SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH); + sctp_m_freem(m); + return (EHOSTUNREACH); + } udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr)); udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); udp->uh_dport = port; @@ -10949,6 +10961,10 @@ sctp_send_shutdown_complete2(struct mbuf return; } if (port) { + if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { + sctp_m_freem(mout); + return; + } udp = (struct udphdr *)comp_cp; udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); udp->uh_dport = port; @@ -11909,6 +11925,10 @@ sctp_send_abort(struct mbuf *m, int iphl udp = (struct udphdr *)abm; if (port) { + if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { + sctp_m_freem(mout); + return; + } udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); udp->uh_dport = port; /* set udp->uh_ulen later */ @@ -12170,6 +12190,10 @@ sctp_send_operr_to(struct mbuf *m, int i udp = (struct udphdr *)sh_out; if (port) { + if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) { + sctp_m_freem(mout); + return; + } udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); udp->uh_dport = port; /* set udp->uh_ulen later */ Modified: stable/9/sys/netinet/sctp_pcb.c ============================================================================== --- stable/9/sys/netinet/sctp_pcb.c Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_pcb.c Mon Feb 6 10:22:50 2012 (r231070) @@ -2651,6 +2651,7 @@ sctp_inpcb_alloc(struct socket *so, uint #ifdef INET6 m->default_flowlabel = 0; #endif + m->port = 0; /* encapsulation disabled by default */ sctp_auth_set_default_chunks(m->local_auth_chunks); LIST_INIT(&m->shared_keys); /* add default NULL key as key id 0 */ @@ -3990,13 +3991,9 @@ sctp_add_remote_addr(struct sctp_tcb *st net->RTO = 0; net->RTO_measured = 0; stcb->asoc.numnets++; - *(&net->ref_count) = 1; + net->ref_count = 1; net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1; - if (SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable)) { - net->port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); - } else { - net->port = 0; - } + net->port = stcb->asoc.port; net->dscp = stcb->asoc.default_dscp; #ifdef INET6 net->flowlabel = stcb->asoc.default_flowlabel; Modified: stable/9/sys/netinet/sctp_pcb.h ============================================================================== --- stable/9/sys/netinet/sctp_pcb.h Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_pcb.h Mon Feb 6 10:22:50 2012 (r231070) @@ -328,6 +328,7 @@ struct sctp_pcb { uint8_t default_dscp; char current_secret_number; char last_secret_number; + uint16_t port; /* remote UDP encapsulation port */ }; #ifndef SCTP_ALIGNMENT Modified: stable/9/sys/netinet/sctp_structs.h ============================================================================== --- stable/9/sys/netinet/sctp_structs.h Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_structs.h Mon Feb 6 10:22:50 2012 (r231070) @@ -416,7 +416,7 @@ TAILQ_HEAD(sctpchunk_listhead, sctp_tmit #define CHUNK_FLAGS_PR_SCTP_BUF SCTP_PR_SCTP_BUF #define CHUNK_FLAGS_PR_SCTP_RTX SCTP_PR_SCTP_RTX -/* The upper byte is used as a bit mask */ +/* The upper byte is used a a bit mask */ #define CHUNK_FLAGS_FRAGMENT_OK 0x0100 struct chk_id { @@ -1213,6 +1213,7 @@ struct sctp_association { uint8_t sctp_cmt_pf; uint8_t use_precise_time; uint32_t sctp_features; + uint16_t port; /* remote UDP encapsulation port */ /* * The mapping array is used to track out of order sequences above * last_acked_seq. 0 indicates packet missing 1 indicates packet Modified: stable/9/sys/netinet/sctp_sysctl.c ============================================================================== --- stable/9/sys/netinet/sctp_sysctl.c Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_sysctl.c Mon Feb 6 10:22:50 2012 (r231070) @@ -122,7 +122,6 @@ sctp_init_sysctls() #if defined(SCTP_LOCAL_TRACE_BUF) memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log)); #endif - SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable) = SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = SCTPCTL_UDP_TUNNELING_PORT_DEFAULT; SCTP_BASE_SYSCTL(sctp_enable_sack_immediately) = SCTPCTL_SACK_IMMEDIATELY_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly) = SCTPCTL_NAT_FRIENDLY_INITS_DEFAULT; @@ -665,10 +664,6 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS) RANGECHK(SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), SCTPCTL_RTTVAR_DCCCECN_MIN, SCTPCTL_RTTVAR_DCCCECN_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX); -/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */ -#if !defined(__FreeBSD__) || defined(INET) - RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN, SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MAX); -#endif RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX); @@ -1085,10 +1080,6 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUT /* 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_for_client_enable, CTLTYPE_UINT | CTLFLAG_RW, - &SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), 0, sysctl_sctp_check, "IU", - SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_DESC); - 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); Modified: stable/9/sys/netinet/sctp_sysctl.h ============================================================================== --- stable/9/sys/netinet/sctp_sysctl.h Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_sysctl.h Mon Feb 6 10:22:50 2012 (r231070) @@ -109,7 +109,6 @@ struct sctp_sysctl { #if defined(SCTP_LOCAL_TRACE_BUF) struct sctp_log sctp_log; #endif - uint32_t sctp_udp_tunneling_for_client_enable; uint32_t sctp_udp_tunneling_port; uint32_t sctp_enable_sack_immediately; uint32_t sctp_vtag_time_wait; @@ -458,12 +457,6 @@ struct sctp_sysctl { #define SCTPCTL_MOBILITY_FASTHANDOFF_MAX 1 #define SCTPCTL_MOBILITY_FASTHANDOFF_DEFAULT SCTP_DEFAULT_MOBILITY_FASTHANDOFF -/* Enable SCTP/UDP tunneling for clients*/ -#define SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_DESC "Enable SCTP/UDP tunneling for client" -#define SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN 0 -#define SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MAX 1 -#define SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_DEFAULT SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN - /* Enable SCTP/UDP tunneling port */ #define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port" #define SCTPCTL_UDP_TUNNELING_PORT_MIN 0 Modified: stable/9/sys/netinet/sctp_uio.h ============================================================================== --- stable/9/sys/netinet/sctp_uio.h Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_uio.h Mon Feb 6 10:22:50 2012 (r231070) @@ -671,6 +671,12 @@ struct sctp_timeouts { uint32_t stimo_shutdownack; }; +struct sctp_udpencaps { + sctp_assoc_t sue_assoc_id; + struct sockaddr_storage sue_address; + uint16_t sue_port; +}; + struct sctp_cwnd_args { struct sctp_nets *net; /* network to *//* FIXME: LP64 issue */ uint32_t cwnd_new_value;/* cwnd in k */ Modified: stable/9/sys/netinet/sctp_usrreq.c ============================================================================== --- stable/9/sys/netinet/sctp_usrreq.c Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctp_usrreq.c Mon Feb 6 10:22:50 2012 (r231070) @@ -3204,6 +3204,92 @@ flags_out: } break; } + case SCTP_REMOTE_UDP_ENCAPS_PORT: + { + struct sctp_udpencaps *encaps; + struct sctp_nets *net; + + SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize); + SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); + + if (stcb) { + net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); + } else { + /* + * We increment here since + * sctp_findassociation_ep_addr() wil do a + * decrement if it finds the stcb as long as + * the locked tcb (last argument) is NOT a + * TCB.. aka NULL. + */ + net = NULL; + SCTP_INP_INCR_REF(inp); + stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); + if (stcb == NULL) { + SCTP_INP_DECR_REF(inp); + } + } + if (stcb && (net == NULL)) { + struct sockaddr *sa; + + sa = (struct sockaddr *)&encaps->sue_address; +#ifdef INET + if (sa->sa_family == AF_INET) { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)sa; + if (sin->sin_addr.s_addr) { + error = EINVAL; + SCTP_TCB_UNLOCK(stcb); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); + break; + } + } else +#endif +#ifdef INET6 + if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)sa; + if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { + error = EINVAL; + SCTP_TCB_UNLOCK(stcb); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); + break; + } + } else +#endif + { + error = EAFNOSUPPORT; + SCTP_TCB_UNLOCK(stcb); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); + break; + } + } + if (stcb) { + if (net) { + encaps->sue_port = net->port; + } else { + encaps->sue_port = stcb->asoc.port; + } + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_RLOCK(inp); + encaps->sue_port = inp->sctp_ep.port; + SCTP_INP_RUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + if (error == 0) { + *optsize = sizeof(struct sctp_paddrparams); + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; @@ -4522,7 +4608,6 @@ sctp_setopt(struct socket *so, int optna break; } case SCTP_PEER_ADDR_PARAMS: - /* Applies to the specific association */ { struct sctp_paddrparams *paddrp; struct sctp_nets *net; @@ -5580,6 +5665,89 @@ sctp_setopt(struct socket *so, int optna } break; } + case SCTP_REMOTE_UDP_ENCAPS_PORT: + { + struct sctp_udpencaps *encaps; + struct sctp_nets *net; + + SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize); + SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); + if (stcb) { + net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); + } else { + /* + * We increment here since + * sctp_findassociation_ep_addr() wil do a + * decrement if it finds the stcb as long as + * the locked tcb (last argument) is NOT a + * TCB.. aka NULL. + */ + net = NULL; + SCTP_INP_INCR_REF(inp); + stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); + if (stcb == NULL) { + SCTP_INP_DECR_REF(inp); + } + } + if (stcb && (net == NULL)) { + struct sockaddr *sa; + + sa = (struct sockaddr *)&encaps->sue_address; +#ifdef INET + if (sa->sa_family == AF_INET) { + + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)sa; + if (sin->sin_addr.s_addr) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + SCTP_TCB_UNLOCK(stcb); + error = EINVAL; + break; + } + } else +#endif +#ifdef INET6 + if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)sa; + if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + SCTP_TCB_UNLOCK(stcb); + error = EINVAL; + break; + } + } else +#endif + { + error = EAFNOSUPPORT; + SCTP_TCB_UNLOCK(stcb); + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); + break; + } + } + if (stcb) { + if (net) { + net->port = encaps->sue_port; + } else { + stcb->asoc.port = encaps->sue_port; + } + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_WLOCK(inp); + inp->sctp_ep.port = encaps->sue_port; + SCTP_INP_WUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; Modified: stable/9/sys/netinet/sctputil.c ============================================================================== --- stable/9/sys/netinet/sctputil.c Mon Feb 6 10:19:18 2012 (r231069) +++ stable/9/sys/netinet/sctputil.c Mon Feb 6 10:22:50 2012 (r231070) @@ -1105,6 +1105,7 @@ sctp_init_asoc(struct sctp_inpcb *m, str asoc->authinfo.recv_keyid = 0; LIST_INIT(&asoc->shared_keys); asoc->marked_retrans = 0; + asoc->port = m->sctp_ep.port; asoc->timoinit = 0; asoc->timodata = 0; asoc->timosack = 0;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202061022.q16AMohM031434>