svn commit: r258832 - user/ae/inet6/sys/netinet6

Andrey V. Elsukov ae at FreeBSD.org
Mon Dec 2 05:43:24 UTC 2013


Author: ae
Date: Mon Dec  2 05:43:23 2013
New Revision: 258832
URL: http://svnweb.freebsd.org/changeset/base/258832

Log:
  Add sa6_checkzone_pcb function.
  
  Application can specify outgoing interface using advanced socket API.
  E.g. IPV6_PKTINFO or IPV6_MULTICAST_IF socket options. sa6_checkzone_pcb
  can be used to check a passed from application sockaddr_in6 structure and
  to initialize sin6_scope_id, when socket has some of this options set.

Modified:
  user/ae/inet6/sys/netinet6/scope6.c
  user/ae/inet6/sys/netinet6/scope6_var.h

Modified: user/ae/inet6/sys/netinet6/scope6.c
==============================================================================
--- user/ae/inet6/sys/netinet6/scope6.c	Mon Dec  2 05:35:50 2013	(r258831)
+++ user/ae/inet6/sys/netinet6/scope6.c	Mon Dec  2 05:43:23 2013	(r258832)
@@ -519,3 +519,41 @@ sa6_checkzone_ifp(struct ifnet *ifp, str
 	}
 	return (sa6_checkzone(sa6));
 }
+
+int
+sa6_checkzone_pcb(struct inpcb *inp, struct sockaddr_in6 *sa6)
+{
+	struct in6_pktinfo *pi;
+	int scope;
+
+	scope = in6_addrscope(&sa6->sin6_addr);
+	if (scope == IPV6_ADDR_SCOPE_LINKLOCAL ||
+	    scope == IPV6_ADDR_SCOPE_INTFACELOCAL) {
+		if (sa6->sin6_scope_id == 0) {
+			/*
+			 * We requre that sin6_scope_id must be initialized for
+			 * link-local and interface-local addresses. But user
+			 * didn't initialize it. Try to determine zone id from
+			 * socket options.
+			 * XXX: we will do this again in the in6_selectsrc().
+			 */
+			INP_LOCK_ASSERT(inp);
+			if (inp->in6p_outputopts != NULL) {
+				pi = inp->in6p_outputopts->ip6po_pktinfo;
+				if (pi != NULL && pi->ipi6_ifindex != 0) {
+					/* XXX: in6_getscopezone */
+					sa6->sin6_scope_id = pi->ipi6_ifindex;
+					return (0);
+				}
+			}
+			if (inp->in6p_moptions != NULL &&
+			    inp->in6p_moptions->im6o_multicast_ifp != NULL) {
+				sa6->sin6_scope_id = in6_getscopezone(
+				    inp->in6p_moptions->im6o_multicast_ifp,
+				    scope);
+				return (0);
+			}
+		}
+	}
+	return (sa6_checkzone(sa6));
+}

Modified: user/ae/inet6/sys/netinet6/scope6_var.h
==============================================================================
--- user/ae/inet6/sys/netinet6/scope6_var.h	Mon Dec  2 05:35:50 2013	(r258831)
+++ user/ae/inet6/sys/netinet6/scope6_var.h	Mon Dec  2 05:43:23 2013	(r258832)
@@ -57,6 +57,7 @@ int	sa6_embedscope(struct sockaddr_in6 *
 int	sa6_recoverscope(struct sockaddr_in6 *);
 int	sa6_checkzone(struct sockaddr_in6 *);
 int	sa6_checkzone_ifp(struct ifnet *, struct sockaddr_in6 *);
+int	sa6_checkzone_pcb(struct inpcb *, struct sockaddr_in6 *);
 int	in6_setscope(struct in6_addr *, struct ifnet *, u_int32_t *);
 int	in6_clearscope(struct in6_addr *);
 uint16_t in6_getscope(struct in6_addr *);


More information about the svn-src-user mailing list