Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Dec 2012 02:22:48 +0000 (UTC)
From:      Kevin Lo <kevlo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r243965 - in head/sys: kern sys
Message-ID:  <201212070222.qB72MnNX085679@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevlo
Date: Fri Dec  7 02:22:48 2012
New Revision: 243965
URL: http://svnweb.freebsd.org/changeset/base/243965

Log:
  - according to POSIX, make socket(2) return EAFNOSUPPORT rather than
    EPROTONOSUPPORT if the address family is not supported.
  - introduce pffinddomain() to find a domain by family and use it as
    appropriate.
  
  Reviewed by:	glebius

Modified:
  head/sys/kern/uipc_domain.c
  head/sys/kern/uipc_socket.c
  head/sys/sys/protosw.h

Modified: head/sys/kern/uipc_domain.c
==============================================================================
--- head/sys/kern/uipc_domain.c	Fri Dec  7 01:36:53 2012	(r243964)
+++ head/sys/kern/uipc_domain.c	Fri Dec  7 02:22:48 2012	(r243965)
@@ -270,21 +270,31 @@ domainfinalize(void *dummy)
 	callout_reset(&pfslow_callout, 1, pfslowtimo, NULL);
 }
 
+struct domain *
+pffinddomain(int family)
+{
+	struct domain *dp;
+
+	for (dp = domains; dp != NULL; dp = dp->dom_next)
+		if (dp->dom_family == family)
+			return (dp);
+	return (NULL);
+}
+
 struct protosw *
 pffindtype(int family, int type)
 {
 	struct domain *dp;
 	struct protosw *pr;
 
-	for (dp = domains; dp; dp = dp->dom_next)
-		if (dp->dom_family == family)
-			goto found;
-	return (0);
-found:
+	dp = pffinddomain(family);
+	if (dp == NULL)
+		return (NULL);
+
 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
 		if (pr->pr_type && pr->pr_type == type)
 			return (pr);
-	return (0);
+	return (NULL);
 }
 
 struct protosw *
@@ -292,21 +302,22 @@ pffindproto(int family, int protocol, in
 {
 	struct domain *dp;
 	struct protosw *pr;
-	struct protosw *maybe = 0;
+	struct protosw *maybe;
 
+	maybe = NULL;
 	if (family == 0)
-		return (0);
-	for (dp = domains; dp; dp = dp->dom_next)
-		if (dp->dom_family == family)
-			goto found;
-	return (0);
-found:
+		return (NULL);
+
+	dp = pffinddomain(family);
+	if (dp == NULL)
+		return (NULL);
+
 	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
 		if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
 			return (pr);
 
 		if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
-		    pr->pr_protocol == 0 && maybe == (struct protosw *)0)
+		    pr->pr_protocol == 0 && maybe == NULL)
 			maybe = pr;
 	}
 	return (maybe);
@@ -334,12 +345,10 @@ pf_proto_register(int family, struct pro
 		return (ENXIO);
 
 	/* Try to find the specified domain based on the family. */
-	for (dp = domains; dp; dp = dp->dom_next)
-		if (dp->dom_family == family)
-			goto found;
-	return (EPFNOSUPPORT);
+	dp = pffinddomain(family);
+	if (dp == NULL)
+		return (EPFNOSUPPORT);
 
-found:
 	/* Initialize backpointer to struct domain. */
 	npr->pr_domain = dp;
 	fpr = NULL;
@@ -405,12 +414,10 @@ pf_proto_unregister(int family, int prot
 		return (EPROTOTYPE);
 
 	/* Try to find the specified domain based on the family type. */
-	for (dp = domains; dp; dp = dp->dom_next)
-		if (dp->dom_family == family)
-			goto found;
-	return (EPFNOSUPPORT);
+	dp = pffinddomain(family);
+	if (dp == NULL)
+		return (EPFNOSUPPORT);
 
-found:
 	dpr = NULL;
 
 	/* Lock out everyone else while we are manipulating the protosw. */

Modified: head/sys/kern/uipc_socket.c
==============================================================================
--- head/sys/kern/uipc_socket.c	Fri Dec  7 01:36:53 2012	(r243964)
+++ head/sys/kern/uipc_socket.c	Fri Dec  7 02:22:48 2012	(r243965)
@@ -425,7 +425,16 @@ socreate(int dom, struct socket **aso, i
 	else
 		prp = pffindtype(dom, type);
 
-	if (prp == NULL || prp->pr_usrreqs->pru_attach == NULL ||
+	if (prp == NULL) {
+		/* No support for domain. */
+		if (pffinddomain(dom) == NULL)
+			return (EAFNOSUPPORT);
+		/* No support for socket type. */
+		if (proto == 0 && type != 0)
+			return (EPROTOTYPE);
+		return (EPROTONOSUPPORT);
+	}
+	if (prp->pr_usrreqs->pru_attach == NULL ||
 	    prp->pr_usrreqs->pru_attach == pru_attach_notsupp)
 		return (EPROTONOSUPPORT);
 

Modified: head/sys/sys/protosw.h
==============================================================================
--- head/sys/sys/protosw.h	Fri Dec  7 01:36:53 2012	(r243964)
+++ head/sys/sys/protosw.h	Fri Dec  7 02:22:48 2012	(r243965)
@@ -330,6 +330,7 @@ char	*prcorequests[] = {
 #ifdef _KERNEL
 void	pfctlinput(int, struct sockaddr *);
 void	pfctlinput2(int, struct sockaddr *, void *);
+struct domain *pffinddomain(int family);
 struct protosw *pffindproto(int family, int protocol, int type);
 struct protosw *pffindtype(int family, int type);
 int	pf_proto_register(int family, struct protosw *npr);



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