Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Feb 2013 17:26:14 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r246595 - head/sys/netinet
Message-ID:  <201302091726.r19HQEZZ009488@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sat Feb  9 17:26:14 2013
New Revision: 246595
URL: http://svnweb.freebsd.org/changeset/base/246595

Log:
  Cleanup the handling of address scopes. Announce in the INIT/INIT-ACK
  only the supported address types. While there, do some whitespace
  cleanups.
  
  MFC after: 1 week

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_asconf.c
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_output.h
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctputil.c

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp.h	Sat Feb  9 17:26:14 2013	(r246595)
@@ -500,12 +500,12 @@ struct sctp_error_unrecognized_chunk {
 #define SCTP_PCB_FLAGS_SOCKET_GONE	0x10000000
 #define SCTP_PCB_FLAGS_SOCKET_ALLGONE	0x20000000
 #define SCTP_PCB_FLAGS_SOCKET_CANT_READ	0x40000000
+
 /* flags to copy to new PCB */
 #define SCTP_PCB_COPY_FLAGS		(SCTP_PCB_FLAGS_BOUNDALL|\
 					 SCTP_PCB_FLAGS_WAKEINPUT|\
 					 SCTP_PCB_FLAGS_BOUND_V6)
 
-
 /*
  * PCB Features (in sctp_features bitmask)
  */

Modified: head/sys/netinet/sctp_asconf.c
==============================================================================
--- head/sys/netinet/sctp_asconf.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_asconf.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -1916,7 +1916,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *
 				return;
 			}
 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-				if (stcb->asoc.local_scope == 0) {
+				if (stcb->asoc.scope.local_scope == 0) {
 					return;
 				}
 				/* is it the right link local scope? */
@@ -1924,7 +1924,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *
 					return;
 				}
 			}
-			if (stcb->asoc.site_scope == 0 &&
+			if (stcb->asoc.scope.site_scope == 0 &&
 			    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
 				return;
 			}
@@ -1948,7 +1948,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *
 				/* we skip unspecifed addresses */
 				return;
 			}
-			if (stcb->asoc.ipv4_local_scope == 0 &&
+			if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 			    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 				return;
 			}
@@ -2106,7 +2106,7 @@ sctp_asconf_iterator_stcb(struct sctp_in
 					continue;
 				}
 				if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-					if (stcb->asoc.local_scope == 0) {
+					if (stcb->asoc.scope.local_scope == 0) {
 						continue;
 					}
 					/* is it the right link local scope? */
@@ -2135,7 +2135,7 @@ sctp_asconf_iterator_stcb(struct sctp_in
 					/* we skip unspecifed addresses */
 					continue;
 				}
-				if (stcb->asoc.ipv4_local_scope == 0 &&
+				if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 				    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 					continue;
 				}
@@ -2198,13 +2198,7 @@ sctp_asconf_iterator_stcb(struct sctp_in
 				}
 			} else {
 				/* Need to check scopes for this guy */
-				if (sctp_is_address_in_scope(ifa,
-				    stcb->asoc.ipv4_addr_legal,
-				    stcb->asoc.ipv6_addr_legal,
-				    stcb->asoc.loopback_scope,
-				    stcb->asoc.ipv4_local_scope,
-				    stcb->asoc.local_scope,
-				    stcb->asoc.site_scope, 0) == 0) {
+				if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
 					continue;
 				}
 			}
@@ -2437,7 +2431,7 @@ sctp_find_valid_localaddr(struct sctp_tc
 		return (NULL);
 	}
 	LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
-		if (stcb->asoc.loopback_scope == 0 &&
+		if (stcb->asoc.scope.loopback_scope == 0 &&
 		    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
 			/* Skip if loopback_scope not set */
 			continue;
@@ -2446,7 +2440,7 @@ sctp_find_valid_localaddr(struct sctp_tc
 			switch (sctp_ifa->address.sa.sa_family) {
 #ifdef INET
 			case AF_INET:
-				if (stcb->asoc.ipv4_addr_legal) {
+				if (stcb->asoc.scope.ipv4_addr_legal) {
 					struct sockaddr_in *sin;
 
 					sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
@@ -2454,7 +2448,7 @@ sctp_find_valid_localaddr(struct sctp_tc
 						/* skip unspecifed addresses */
 						continue;
 					}
-					if (stcb->asoc.ipv4_local_scope == 0 &&
+					if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 					    IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
 						continue;
 
@@ -2473,7 +2467,7 @@ sctp_find_valid_localaddr(struct sctp_tc
 #endif
 #ifdef INET6
 			case AF_INET6:
-				if (stcb->asoc.ipv6_addr_legal) {
+				if (stcb->asoc.scope.ipv6_addr_legal) {
 					struct sockaddr_in6 *sin6;
 
 					if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
@@ -2487,10 +2481,10 @@ sctp_find_valid_localaddr(struct sctp_tc
 						 */
 						continue;
 					}
-					if (stcb->asoc.local_scope == 0 &&
+					if (stcb->asoc.scope.local_scope == 0 &&
 					    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
 						continue;
-					if (stcb->asoc.site_scope == 0 &&
+					if (stcb->asoc.scope.site_scope == 0 &&
 					    IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
 						continue;
 

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_input.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -2130,13 +2130,13 @@ sctp_process_cookie_new(struct mbuf *m, 
 
 	asoc = &stcb->asoc;
 	/* get scope variables out of cookie */
-	asoc->ipv4_local_scope = cookie->ipv4_scope;
-	asoc->site_scope = cookie->site_scope;
-	asoc->local_scope = cookie->local_scope;
-	asoc->loopback_scope = cookie->loopback_scope;
+	asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
+	asoc->scope.site_scope = cookie->site_scope;
+	asoc->scope.local_scope = cookie->local_scope;
+	asoc->scope.loopback_scope = cookie->loopback_scope;
 
-	if ((asoc->ipv4_addr_legal != cookie->ipv4_addr_legal) ||
-	    (asoc->ipv6_addr_legal != cookie->ipv6_addr_legal)) {
+	if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
+	    (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
 		struct mbuf *op_err;
 
 		/*

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_output.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -1863,15 +1863,10 @@ struct sack_track sack_array[256] = {
 
 int
 sctp_is_address_in_scope(struct sctp_ifa *ifa,
-    int ipv4_addr_legal,
-    int ipv6_addr_legal,
-    int loopback_scope,
-    int ipv4_local_scope,
-    int local_scope SCTP_UNUSED,/* XXX */
-    int site_scope,
+    struct sctp_scoping *scope,
     int do_update)
 {
-	if ((loopback_scope == 0) &&
+	if ((scope->loopback_scope == 0) &&
 	    (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) {
 		/*
 		 * skip loopback if not in scope *
@@ -1881,7 +1876,7 @@ sctp_is_address_in_scope(struct sctp_ifa
 	switch (ifa->address.sa.sa_family) {
 #ifdef INET
 	case AF_INET:
-		if (ipv4_addr_legal) {
+		if (scope->ipv4_addr_legal) {
 			struct sockaddr_in *sin;
 
 			sin = (struct sockaddr_in *)&ifa->address.sin;
@@ -1889,7 +1884,7 @@ sctp_is_address_in_scope(struct sctp_ifa
 				/* not in scope , unspecified */
 				return (0);
 			}
-			if ((ipv4_local_scope == 0) &&
+			if ((scope->ipv4_local_scope == 0) &&
 			    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
 				/* private address not in scope */
 				return (0);
@@ -1901,7 +1896,7 @@ sctp_is_address_in_scope(struct sctp_ifa
 #endif
 #ifdef INET6
 	case AF_INET6:
-		if (ipv6_addr_legal) {
+		if (scope->ipv6_addr_legal) {
 			struct sockaddr_in6 *sin6;
 
 			/*
@@ -1924,7 +1919,7 @@ sctp_is_address_in_scope(struct sctp_ifa
 			    (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
 				return (0);
 			}
-			if ((site_scope == 0) &&
+			if ((scope->site_scope == 0) &&
 			    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
 				return (0);
 			}
@@ -2063,13 +2058,7 @@ sctp_add_addresses_to_i_ia(struct sctp_i
 				if (sctp_is_addr_restricted(stcb, sctp_ifap)) {
 					continue;
 				}
-				if (sctp_is_address_in_scope(sctp_ifap,
-				    scope->ipv4_addr_legal,
-				    scope->ipv6_addr_legal,
-				    scope->loopback_scope,
-				    scope->ipv4_local_scope,
-				    scope->local_scope,
-				    scope->site_scope, 1) == 0) {
+				if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) {
 					continue;
 				}
 				cnt++;
@@ -2099,12 +2088,7 @@ skip_count:
 						continue;
 					}
 					if (sctp_is_address_in_scope(sctp_ifap,
-					    scope->ipv4_addr_legal,
-					    scope->ipv6_addr_legal,
-					    scope->loopback_scope,
-					    scope->ipv4_local_scope,
-					    scope->local_scope,
-					    scope->site_scope, 0) == 0) {
+					    scope, 0) == 0) {
 						continue;
 					}
 					if ((chunk_len != NULL) &&
@@ -2157,12 +2141,7 @@ skip_count:
 				continue;
 			}
 			if (sctp_is_address_in_scope(laddr->ifa,
-			    scope->ipv4_addr_legal,
-			    scope->ipv6_addr_legal,
-			    scope->loopback_scope,
-			    scope->ipv4_local_scope,
-			    scope->local_scope,
-			    scope->site_scope, 1) == 0) {
+			    scope, 1) == 0) {
 				continue;
 			}
 			cnt++;
@@ -2182,12 +2161,7 @@ skip_count:
 					continue;
 				}
 				if (sctp_is_address_in_scope(laddr->ifa,
-				    scope->ipv4_addr_legal,
-				    scope->ipv6_addr_legal,
-				    scope->loopback_scope,
-				    scope->ipv4_local_scope,
-				    scope->local_scope,
-				    scope->site_scope, 0) == 0) {
+				    scope, 0) == 0) {
 					continue;
 				}
 				if ((chunk_len != NULL) &&
@@ -2801,13 +2775,7 @@ sctp_select_nth_preferred_addr_from_ifn_
 		}
 #endif
 		if (stcb) {
-			if (sctp_is_address_in_scope(ifa,
-			    stcb->asoc.ipv4_addr_legal,
-			    stcb->asoc.ipv6_addr_legal,
-			    stcb->asoc.loopback_scope,
-			    stcb->asoc.ipv4_local_scope,
-			    stcb->asoc.local_scope,
-			    stcb->asoc.site_scope, 0) == 0) {
+			if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
 				continue;
 			}
 			if (((non_asoc_addr_ok == 0) &&
@@ -2853,13 +2821,7 @@ sctp_count_num_preferred_boundall(struct
 			continue;
 		}
 		if (stcb) {
-			if (sctp_is_address_in_scope(ifa,
-			    stcb->asoc.ipv4_addr_legal,
-			    stcb->asoc.ipv6_addr_legal,
-			    stcb->asoc.loopback_scope,
-			    stcb->asoc.ipv4_local_scope,
-			    stcb->asoc.local_scope,
-			    stcb->asoc.site_scope, 0) == 0) {
+			if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
 				continue;
 			}
 			if (((non_asoc_addr_ok == 0) &&
@@ -3055,13 +3017,7 @@ again_with_private_addresses_allowed:
 			continue;
 		}
 		if (stcb) {
-			if (sctp_is_address_in_scope(sifa,
-			    stcb->asoc.ipv4_addr_legal,
-			    stcb->asoc.ipv6_addr_legal,
-			    stcb->asoc.loopback_scope,
-			    stcb->asoc.ipv4_local_scope,
-			    stcb->asoc.local_scope,
-			    stcb->asoc.site_scope, 0) == 0) {
+			if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
 				SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n");
 				sifa = NULL;
 				continue;
@@ -3108,13 +3064,7 @@ plan_d:
 			if (sifa == NULL)
 				continue;
 			if (stcb) {
-				if (sctp_is_address_in_scope(sifa,
-				    stcb->asoc.ipv4_addr_legal,
-				    stcb->asoc.ipv6_addr_legal,
-				    stcb->asoc.loopback_scope,
-				    stcb->asoc.ipv4_local_scope,
-				    stcb->asoc.local_scope,
-				    stcb->asoc.site_scope, 0) == 0) {
+				if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) {
 					sifa = NULL;
 					continue;
 				}
@@ -3135,12 +3085,12 @@ plan_d:
 		}
 	}
 #ifdef INET
-	if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) {
-		stcb->asoc.ipv4_local_scope = 1;
+	if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
+		stcb->asoc.scope.ipv4_local_scope = 1;
 		retried = 1;
 		goto again_with_private_addresses_allowed;
 	} else if (retried == 1) {
-		stcb->asoc.ipv4_local_scope = 0;
+		stcb->asoc.scope.ipv4_local_scope = 0;
 	}
 #endif
 out:
@@ -3169,12 +3119,7 @@ out:
 					}
 					if (stcb) {
 						if (sctp_is_address_in_scope(tmp_sifa,
-						    stcb->asoc.ipv4_addr_legal,
-						    stcb->asoc.ipv6_addr_legal,
-						    stcb->asoc.loopback_scope,
-						    stcb->asoc.ipv4_local_scope,
-						    stcb->asoc.local_scope,
-						    stcb->asoc.site_scope, 0) == 0) {
+						    &stcb->asoc.scope, 0) == 0) {
 							continue;
 						}
 						if (((non_asoc_addr_ok == 0) &&
@@ -4595,7 +4540,6 @@ sctp_send_initiate(struct sctp_inpcb *in
 #endif
 )
 {
-	struct sctp_scoping scp;
 	struct mbuf *m;
 	struct sctp_nets *net;
 	struct sctp_init_chunk *init;
@@ -4675,37 +4619,29 @@ sctp_send_initiate(struct sctp_inpcb *in
 	init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
 	init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
 
-#if defined(INET) || defined(INET6)
-	/* now the address restriction */
-	/* XXX Should we take the address family of the socket into account? */
-	sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len);
-	sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
-#ifdef INET6
-#ifdef INET
-	/* we support 2 types: IPv4/IPv6 */
-	parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + 2 * sizeof(uint16_t));
-	sup_addr->ph.param_length = htons(parameter_len);
-	sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
-	sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS);
-	padding_len = 0;
-#else
-	/* we support 1 type: IPv6 */
-	parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
-	sup_addr->ph.param_length = htons(parameter_len);
-	sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS);
-	sup_addr->addr_type[1] = htons(0);	/* this is the padding */
-	padding_len = (uint16_t) sizeof(uint16_t);
-#endif
-#else
-	/* we support 1 type: IPv4 */
-	parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t));
-	sup_addr->ph.param_length = htons(parameter_len);
-	sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
-	sup_addr->addr_type[1] = htons(0);	/* this is the padding */
-	padding_len = (uint16_t) sizeof(uint16_t);
-#endif
-	chunk_len += parameter_len;
-#endif
+	if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
+		uint8_t i;
+
+		parameter_len = (uint16_t) sizeof(struct sctp_paramhdr);
+		if (stcb->asoc.scope.ipv4_addr_legal) {
+			parameter_len += (uint16_t) sizeof(uint16_t);
+		}
+		if (stcb->asoc.scope.ipv6_addr_legal) {
+			parameter_len += (uint16_t) sizeof(uint16_t);
+		}
+		sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len);
+		sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
+		sup_addr->ph.param_length = htons(parameter_len);
+		i = 0;
+		if (stcb->asoc.scope.ipv4_addr_legal) {
+			sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
+		}
+		if (stcb->asoc.scope.ipv6_addr_legal) {
+			sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
+		}
+		padding_len = 4 - 2 * i;
+		chunk_len += parameter_len;
+	}
 	/* Adaptation layer indication parameter */
 	/* XXX: Should we include this always? */
 	if (padding_len > 0) {
@@ -4860,13 +4796,7 @@ sctp_send_initiate(struct sctp_inpcb *in
 	 * we could just sifa in the address within the stcb. But for now
 	 * this is a quick hack to get the address stuff teased apart.
 	 */
-	scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal;
-	scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal;
-	scp.loopback_scope = stcb->asoc.loopback_scope;
-	scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope;
-	scp.local_scope = stcb->asoc.local_scope;
-	scp.site_scope = stcb->asoc.site_scope;
-	sctp_add_addresses_to_i_ia(inp, stcb, &scp, m, cnt_inits_to, &padding_len, &chunk_len);
+	sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len);
 
 	init->ch.chunk_length = htons(chunk_len);
 	if (padding_len > 0) {
@@ -5507,24 +5437,16 @@ do_a_abort:
 	 */
 	stc.site_scope = stc.local_scope = stc.loopback_scope = 0;
 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
-		struct inpcb *in_inp;
-
-		/* Its a V6 socket */
-		in_inp = (struct inpcb *)inp;
 		stc.ipv6_addr_legal = 1;
-		/* Now look at the binding flag to see if V4 will be legal */
-		if (SCTP_IPV6_V6ONLY(in_inp) == 0) {
-			stc.ipv4_addr_legal = 1;
-		} else {
-			/* V4 addresses are NOT legal on the association */
+		if (SCTP_IPV6_V6ONLY(inp)) {
 			stc.ipv4_addr_legal = 0;
+		} else {
+			stc.ipv4_addr_legal = 1;
 		}
 	} else {
-		/* Its a V4 socket, no - V6 */
-		stc.ipv4_addr_legal = 1;
 		stc.ipv6_addr_legal = 0;
+		stc.ipv4_addr_legal = 1;
 	}
-
 #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
 	stc.ipv4_scope = 1;
 #else
@@ -5629,10 +5551,10 @@ do_a_abort:
 
 #endif
 
-		stc.loopback_scope = asoc->loopback_scope;
-		stc.ipv4_scope = asoc->ipv4_local_scope;
-		stc.site_scope = asoc->site_scope;
-		stc.local_scope = asoc->local_scope;
+		stc.loopback_scope = asoc->scope.loopback_scope;
+		stc.ipv4_scope = asoc->scope.ipv4_local_scope;
+		stc.site_scope = asoc->scope.site_scope;
+		stc.local_scope = asoc->scope.local_scope;
 #ifdef INET6
 		/* Why do we not consider IPv4 LL addresses? */
 		TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {

Modified: head/sys/netinet/sctp_output.h
==============================================================================
--- head/sys/netinet/sctp_output.h	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_output.h	Sat Feb  9 17:26:14 2013	(r246595)
@@ -55,13 +55,9 @@ int sctp_is_addr_restricted(struct sctp_
 
 int
 sctp_is_address_in_scope(struct sctp_ifa *ifa,
-    int ipv4_addr_legal,
-    int ipv6_addr_legal,
-    int loopback_scope,
-    int ipv4_local_scope,
-    int local_scope,
-    int site_scope,
+    struct sctp_scoping *scope,
     int do_update);
+
 int
     sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa);
 

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_pcb.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -94,11 +94,10 @@ sctp_fill_pcbinfo(struct sctp_pcbinfo *s
 	spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq);
 	spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq);
 	spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks);
-
 	SCTP_INP_INFO_RUNLOCK();
 }
 
-/*
+/*-
  * Addresses are added to VRF's (Virtual Router's). For BSD we
  * have only the default VRF 0. We maintain a hash list of
  * VRF's. Each VRF has its own list of sctp_ifn's. Each of
@@ -214,7 +213,6 @@ sctp_find_ifn(void *ifn, uint32_t ifn_in
 }
 
 
-
 struct sctp_vrf *
 sctp_find_vrf(uint32_t vrf_id)
 {
@@ -230,6 +228,7 @@ sctp_find_vrf(uint32_t vrf_id)
 	return (NULL);
 }
 
+
 void
 sctp_free_vrf(struct sctp_vrf *vrf)
 {
@@ -245,6 +244,7 @@ sctp_free_vrf(struct sctp_vrf *vrf)
 	}
 }
 
+
 void
 sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
 {
@@ -258,6 +258,7 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp
 	}
 }
 
+
 void
 sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
 {
@@ -283,6 +284,7 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap
 	}
 }
 
+
 static void
 sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
 {
@@ -305,12 +307,13 @@ sctp_delete_ifn(struct sctp_ifn *sctp_if
 	sctp_free_ifn(sctp_ifnp);
 }
 
+
 void
 sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
     const char *if_name, uint32_t ifn_index)
 {
 	struct sctp_vrf *vrf;
-	struct sctp_ifa *sctp_ifap = NULL;
+	struct sctp_ifa *sctp_ifap;
 
 	SCTP_IPI_ADDR_RLOCK();
 	vrf = sctp_find_vrf(vrf_id);
@@ -348,12 +351,13 @@ out:
 	SCTP_IPI_ADDR_RUNLOCK();
 }
 
+
 void
 sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
     const char *if_name, uint32_t ifn_index)
 {
 	struct sctp_vrf *vrf;
-	struct sctp_ifa *sctp_ifap = NULL;
+	struct sctp_ifa *sctp_ifap;
 
 	SCTP_IPI_ADDR_RLOCK();
 	vrf = sctp_find_vrf(vrf_id);
@@ -391,6 +395,7 @@ out:
 	SCTP_IPI_ADDR_RUNLOCK();
 }
 
+
 /*-
  * Add an ifa to an ifn.
  * Register the interface as necessary.
@@ -428,6 +433,7 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sct
 	}
 }
 
+
 /*-
  * Remove an ifa from its ifn.
  * If no more addresses exist, remove the ifn too. Otherwise, re-register
@@ -479,6 +485,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa
 	}
 }
 
+
 struct sctp_ifa *
 sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
     uint32_t ifn_type, const char *if_name, void *ifa,
@@ -1027,6 +1034,7 @@ sctp_tcb_special_locate(struct sctp_inpc
 	return (NULL);
 }
 
+
 static int
 sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
 {
@@ -1036,19 +1044,12 @@ sctp_does_stcb_own_this_addr(struct sctp
 	struct sctp_ifn *sctp_ifn;
 	struct sctp_ifa *sctp_ifa;
 
-	loopback_scope = stcb->asoc.loopback_scope;
-	ipv4_local_scope = stcb->asoc.ipv4_local_scope;
-	local_scope = stcb->asoc.local_scope;
-	site_scope = stcb->asoc.site_scope;
-	ipv4_addr_legal = ipv6_addr_legal = 0;
-	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
-		ipv6_addr_legal = 1;
-		if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) {
-			ipv4_addr_legal = 1;
-		}
-	} else {
-		ipv4_addr_legal = 1;
-	}
+	loopback_scope = stcb->asoc.scope.loopback_scope;
+	ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+	local_scope = stcb->asoc.scope.local_scope;
+	site_scope = stcb->asoc.scope.site_scope;
+	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+	ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
 
 	SCTP_IPI_ADDR_RLOCK();
 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
@@ -1183,6 +1184,7 @@ sctp_does_stcb_own_this_addr(struct sctp
 	return (0);
 }
 
+
 /*
  * rules for use
  *
@@ -1471,11 +1473,11 @@ null_return:
 	return (NULL);
 }
 
+
 /*
  * Find an association for a specific endpoint using the association id given
  * out in the COMM_UP notification
  */
-
 struct sctp_tcb *
 sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
 {
@@ -1536,6 +1538,9 @@ sctp_findassociation_ep_asocid(struct sc
 }
 
 
+/*
+ * Endpoint probe expects that the INP_INFO is locked.
+ */
 static struct sctp_inpcb *
 sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
     uint16_t lport, uint32_t vrf_id)
@@ -1552,12 +1557,8 @@ sctp_endpoint_probe(struct sockaddr *nam
 	struct sockaddr_in6 *intf_addr6;
 
 #endif
-
 	int fnd;
 
-	/*
-	 * Endpoint probe expects that the INP_INFO is locked.
-	 */
 #ifdef INET
 	sin = NULL;
 #endif
@@ -1893,6 +1894,7 @@ sctp_pcb_findep(struct sockaddr *nam, in
 	return (inp);
 }
 
+
 /*
  * Find an association for an endpoint with the pointer to whom you want to
  * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
@@ -2144,6 +2146,7 @@ sctp_findassoc_by_vtag(struct sockaddr *
 	return (NULL);
 }
 
+
 /*
  * Find an association with the pointer to the inbound IP packet. This can be
  * a IPv4 or IPv6 packet.
@@ -3743,13 +3746,13 @@ sctp_add_remote_addr(struct sctp_tcb *st
 				stcb->ipv4_local_scope = 1;
 #else
 				if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
-					stcb->asoc.ipv4_local_scope = 1;
+					stcb->asoc.scope.ipv4_local_scope = 1;
 				}
 #endif				/* SCTP_DONT_DO_PRIVADDR_SCOPE */
 			} else {
 				/* Validate the address is in scope */
 				if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
-				    (stcb->asoc.ipv4_local_scope == 0)) {
+				    (stcb->asoc.scope.ipv4_local_scope == 0)) {
 					addr_inscope = 0;
 				}
 			}
@@ -3770,10 +3773,10 @@ sctp_add_remote_addr(struct sctp_tcb *st
 			sin6->sin6_len = sizeof(struct sockaddr_in6);
 			if (set_scope) {
 				if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
-					stcb->asoc.loopback_scope = 1;
-					stcb->asoc.local_scope = 0;
-					stcb->asoc.ipv4_local_scope = 1;
-					stcb->asoc.site_scope = 1;
+					stcb->asoc.scope.loopback_scope = 1;
+					stcb->asoc.scope.local_scope = 0;
+					stcb->asoc.scope.ipv4_local_scope = 1;
+					stcb->asoc.scope.site_scope = 1;
 				} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 					/*
 					 * If the new destination is a
@@ -3785,26 +3788,26 @@ sctp_add_remote_addr(struct sctp_tcb *st
 					 * also be on our private network
 					 * for v4 too.
 					 */
-					stcb->asoc.ipv4_local_scope = 1;
-					stcb->asoc.site_scope = 1;
+					stcb->asoc.scope.ipv4_local_scope = 1;
+					stcb->asoc.scope.site_scope = 1;
 				} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
 					/*
 					 * If the new destination is
 					 * SITE_LOCAL then we must have site
 					 * scope in common.
 					 */
-					stcb->asoc.site_scope = 1;
+					stcb->asoc.scope.site_scope = 1;
 				}
 			} else {
 				/* Validate the address is in scope */
 				if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
-				    (stcb->asoc.loopback_scope == 0)) {
+				    (stcb->asoc.scope.loopback_scope == 0)) {
 					addr_inscope = 0;
 				} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
-				    (stcb->asoc.local_scope == 0)) {
+				    (stcb->asoc.scope.local_scope == 0)) {
 					addr_inscope = 0;
 				} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
-				    (stcb->asoc.site_scope == 0)) {
+				    (stcb->asoc.scope.site_scope == 0)) {
 					addr_inscope = 0;
 				}
 			}
@@ -3839,10 +3842,10 @@ sctp_add_remote_addr(struct sctp_tcb *st
 	}
 	net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
 	if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
-		stcb->asoc.loopback_scope = 1;
-		stcb->asoc.ipv4_local_scope = 1;
-		stcb->asoc.local_scope = 0;
-		stcb->asoc.site_scope = 1;
+		stcb->asoc.scope.loopback_scope = 1;
+		stcb->asoc.scope.ipv4_local_scope = 1;
+		stcb->asoc.scope.local_scope = 0;
+		stcb->asoc.scope.site_scope = 1;
 		addr_inscope = 1;
 	}
 	net->failure_threshold = stcb->asoc.def_net_failure;
@@ -6071,7 +6074,7 @@ sctp_load_addresses_from_init(struct sct
 		switch (sa->sa_family) {
 #ifdef INET
 		case AF_INET:
-			if (stcb->asoc.ipv4_addr_legal) {
+			if (stcb->asoc.scope.ipv4_addr_legal) {
 				if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
 					return (-1);
 				}
@@ -6080,7 +6083,7 @@ sctp_load_addresses_from_init(struct sct
 #endif
 #ifdef INET6
 		case AF_INET6:
-			if (stcb->asoc.ipv6_addr_legal) {
+			if (stcb->asoc.scope.ipv6_addr_legal) {
 				if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
 					return (-2);
 				}
@@ -6127,7 +6130,7 @@ sctp_load_addresses_from_init(struct sct
 		}
 #ifdef INET
 		if (ptype == SCTP_IPV4_ADDRESS) {
-			if (stcb->asoc.ipv4_addr_legal) {
+			if (stcb->asoc.scope.ipv4_addr_legal) {
 				struct sctp_ipv4addr_param *p4, p4_buf;
 
 				/* ok get the v4 address and check/add */
@@ -6213,7 +6216,7 @@ sctp_load_addresses_from_init(struct sct
 #endif
 #ifdef INET6
 		if (ptype == SCTP_IPV6_ADDRESS) {
-			if (stcb->asoc.ipv6_addr_legal) {
+			if (stcb->asoc.scope.ipv6_addr_legal) {
 				/* ok get the v6 address and check/add */
 				struct sctp_ipv6addr_param *p6, p6_buf;
 

Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_structs.h	Sat Feb  9 17:26:14 2013	(r246595)
@@ -1177,17 +1177,7 @@ struct sctp_association {
 	 */
 	uint8_t peer_supports_pktdrop;
 
-	/* Do we allow V6/V4? */
-	uint8_t ipv4_addr_legal;
-	uint8_t ipv6_addr_legal;
-	/* Address scoping flags */
-	/* scope value for IPv4 */
-	uint8_t ipv4_local_scope;
-	/* scope values for IPv6 */
-	uint8_t local_scope;
-	uint8_t site_scope;
-	/* loopback scope */
-	uint8_t loopback_scope;
+	struct sctp_scoping scope;
 	/* flags to handle send alternate net tracking */
 	uint8_t used_alt_onsack;
 	uint8_t used_alt_asconfack;

Modified: head/sys/netinet/sctp_sysctl.c
==============================================================================
--- head/sys/netinet/sctp_sysctl.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_sysctl.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -197,29 +197,29 @@ copy_out_local_addresses(struct sctp_inp
 	/* Turn on all the appropriate scope */
 	if (stcb) {
 		/* use association specific values */
-		loopback_scope = stcb->asoc.loopback_scope;
-		ipv4_local_scope = stcb->asoc.ipv4_local_scope;
-		local_scope = stcb->asoc.local_scope;
-		site_scope = stcb->asoc.site_scope;
+		loopback_scope = stcb->asoc.scope.loopback_scope;
+		ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+		local_scope = stcb->asoc.scope.local_scope;
+		site_scope = stcb->asoc.scope.site_scope;
+		ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+		ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
 	} else {
-		/* use generic values for endpoints */
+		/* Use generic values for endpoints. */
 		loopback_scope = 1;
 		ipv4_local_scope = 1;
 		local_scope = 1;
 		site_scope = 1;
-	}
-
-	/* use only address families of interest */
-	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
-		ipv6_addr_legal = 1;
-		if (SCTP_IPV6_V6ONLY(inp)) {
-			ipv4_addr_legal = 0;
+		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
+			ipv6_addr_legal = 1;
+			if (SCTP_IPV6_V6ONLY(inp)) {
+				ipv4_addr_legal = 0;
+			} else {
+				ipv4_addr_legal = 1;
+			}
 		} else {
+			ipv6_addr_legal = 0;
 			ipv4_addr_legal = 1;
 		}
-	} else {
-		ipv4_addr_legal = 1;
-		ipv6_addr_legal = 0;
 	}
 
 	/* neither Mac OS X nor FreeBSD support mulitple routing functions */

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctp_usrreq.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -1143,23 +1143,29 @@ sctp_fill_up_addresses_vrf(struct sctp_i
 
 	if (stcb) {
 		/* Turn on all the appropriate scope */
-		loopback_scope = stcb->asoc.loopback_scope;
-		ipv4_local_scope = stcb->asoc.ipv4_local_scope;
-		local_scope = stcb->asoc.local_scope;
-		site_scope = stcb->asoc.site_scope;
+		loopback_scope = stcb->asoc.scope.loopback_scope;
+		ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
+		local_scope = stcb->asoc.scope.local_scope;
+		site_scope = stcb->asoc.scope.site_scope;
+		ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
+		ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
 	} else {
-		/* Turn on ALL scope, since we look at the EP */
-		loopback_scope = ipv4_local_scope = local_scope =
-		    site_scope = 1;
-	}
-	ipv4_addr_legal = ipv6_addr_legal = 0;
-	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
-		ipv6_addr_legal = 1;
-		if (SCTP_IPV6_V6ONLY(inp) == 0) {
+		/* Use generic values for endpoints. */
+		loopback_scope = 1;
+		ipv4_local_scope = 1;
+		local_scope = 1;
+		site_scope = 1;
+		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
+			ipv6_addr_legal = 1;
+			if (SCTP_IPV6_V6ONLY(inp)) {
+				ipv4_addr_legal = 0;
+			} else {
+				ipv4_addr_legal = 1;
+			}
+		} else {
+			ipv6_addr_legal = 0;
 			ipv4_addr_legal = 1;
 		}
-	} else {
-		ipv4_addr_legal = 1;
 	}
 	vrf = sctp_find_vrf(vrf_id);
 	if (vrf == NULL) {
@@ -1298,8 +1304,21 @@ sctp_fill_up_addresses_vrf(struct sctp_i
 			}
 			if (sctp_fill_user_address(sas, &laddr->ifa->address.sa))
 				continue;
-
-			((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
+			switch (laddr->ifa->address.sa.sa_family) {
+#ifdef INET
+			case AF_INET:
+				((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
+				break;
+#endif
+#ifdef INET6
+			case AF_INET6:
+				((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
+				break;
+#endif
+			default:
+				/* TSNH */
+				break;
+			}
 			sas = (struct sockaddr_storage *)((caddr_t)sas +
 			    laddr->ifa->address.sa.sa_len);
 			actual += laddr->ifa->address.sa.sa_len;
@@ -5948,7 +5967,7 @@ sctp_connect(struct socket *so, struct s
 		error = EINVAL;
 		goto out_now;
 	}
-#endif				/* INET6 */
+#endif
 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
 	    SCTP_PCB_FLAGS_UNBOUND) {
 		/* Bind a ephemeral port */
@@ -6242,8 +6261,8 @@ sctp_accept(struct socket *so, struct so
 				return (ENOMEM);
 			sin->sin_family = AF_INET;
 			sin->sin_len = sizeof(*sin);
-			sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
-			sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
+			sin->sin_port = store.sin.sin_port;
+			sin->sin_addr = store.sin.sin_addr;
 			*addr = (struct sockaddr *)sin;
 			break;
 		}
@@ -6258,9 +6277,8 @@ sctp_accept(struct socket *so, struct so
 				return (ENOMEM);
 			sin6->sin6_family = AF_INET6;
 			sin6->sin6_len = sizeof(*sin6);
-			sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
-
-			sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
+			sin6->sin6_port = store.sin6.sin6_port;
+			sin6->sin6_addr = store.sin6.sin6_addr;
 			if ((error = sa6_recoverscope(sin6)) != 0) {
 				SCTP_FREE_SONAME(sin6);
 				return (error);

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Sat Feb  9 17:13:54 2013	(r246594)
+++ head/sys/netinet/sctputil.c	Sat Feb  9 17:26:14 2013	(r246595)
@@ -878,7 +878,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp
 }
 
 int
-sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
+sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
     uint32_t override_tag, uint32_t vrf_id)
 {
 	struct sctp_association *asoc;
@@ -899,23 +899,23 @@ sctp_init_asoc(struct sctp_inpcb *m, str
 	asoc = &stcb->asoc;
 	/* init all variables to a known value. */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302091726.r19HQEZZ009488>