summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkevlo <kevlo@FreeBSD.org>2012-12-07 02:22:48 +0000
committerkevlo <kevlo@FreeBSD.org>2012-12-07 02:22:48 +0000
commitc71d2848847b4dc9d08aee9ab683b44b1f9a6d19 (patch)
tree89e9a7026108e164c61a88d1df7cb49389545776
parent71dd34a67c96f1199178861ca3bf33b48f8fbaf5 (diff)
downloadFreeBSD-src-c71d2848847b4dc9d08aee9ab683b44b1f9a6d19.zip
FreeBSD-src-c71d2848847b4dc9d08aee9ab683b44b1f9a6d19.tar.gz
- 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
-rw-r--r--sys/kern/uipc_domain.c55
-rw-r--r--sys/kern/uipc_socket.c11
-rw-r--r--sys/sys/protosw.h1
3 files changed, 42 insertions, 25 deletions
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index c133fcb..59a0d30 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -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, int type)
{
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 protosw *npr)
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 protocol, int type)
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. */
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 2d84afe..432ec80 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -425,7 +425,16 @@ socreate(int dom, struct socket **aso, int type, int proto,
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);
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index b55af4b..a74771e 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -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);
OpenPOWER on IntegriCloud