svn commit: r231070 - stable/9/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Mon Feb 6 10:22:51 UTC 2012
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;
More information about the svn-src-stable-9
mailing list