diff options
author | kevlo <kevlo@FreeBSD.org> | 2012-12-07 02:22:48 +0000 |
---|---|---|
committer | kevlo <kevlo@FreeBSD.org> | 2012-12-07 02:22:48 +0000 |
commit | c71d2848847b4dc9d08aee9ab683b44b1f9a6d19 (patch) | |
tree | 89e9a7026108e164c61a88d1df7cb49389545776 | |
parent | 71dd34a67c96f1199178861ca3bf33b48f8fbaf5 (diff) | |
download | FreeBSD-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.c | 55 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 11 | ||||
-rw-r--r-- | sys/sys/protosw.h | 1 |
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); |