- 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
This commit is contained in:
Kevin Lo 2012-12-07 02:22:48 +00:00
parent c2654dc8fa
commit b08d12d9be
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=243965
3 changed files with 42 additions and 25 deletions

View File

@ -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. */

View File

@ -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);

View File

@ -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);