mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Aquire GIANT in pf_proto_[un]register() before manipulating the protosw.
This commit is contained in:
parent
bf59255f44
commit
480fa3f985
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136819
@ -237,23 +237,36 @@ pf_proto_register(family, npr)
|
||||
npr->pr_domain = dp;
|
||||
fpr = NULL;
|
||||
|
||||
/*
|
||||
* Protect us against races when two protocol registrations for
|
||||
* the same protocol happen at the same time.
|
||||
*/
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/* The new protocol must not yet exist. */
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
||||
if ((pr->pr_type == npr->pr_type) &&
|
||||
(pr->pr_protocol == npr->pr_protocol))
|
||||
(pr->pr_protocol == npr->pr_protocol)) {
|
||||
mtx_unlock(&Giant);
|
||||
return (EEXIST); /* XXX: Check only protocol? */
|
||||
}
|
||||
/* While here, remember the first free spacer. */
|
||||
if ((fpr == NULL) && (pr->pr_protocol == PROTO_SPACER))
|
||||
fpr = pr;
|
||||
}
|
||||
|
||||
/* If no free spacer is found we can't add the new protocol. */
|
||||
if (fpr == NULL)
|
||||
if (fpr == NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* Copy the new struct protosw over the spacer. */
|
||||
bcopy(npr, fpr, sizeof(*fpr));
|
||||
|
||||
/* Job is done, no more protection required. */
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
/* Initialize and activate the protocol. */
|
||||
if (fpr->pr_init)
|
||||
(fpr->pr_init)();
|
||||
@ -291,19 +304,25 @@ pf_proto_unregister(family, protocol, type)
|
||||
found:
|
||||
dpr = NULL;
|
||||
|
||||
/* Lock out everyone else while we are manipulating the protosw. */
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/* The protocol must exist and only once. */
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
||||
if ((pr->pr_type == type) && (pr->pr_protocol == protocol)) {
|
||||
if (dpr != NULL)
|
||||
if (dpr != NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
return (EMLINK); /* Should not happen! */
|
||||
else
|
||||
} else
|
||||
dpr = pr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Protocol does not exist. */
|
||||
if (dpr == NULL)
|
||||
if (dpr == NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
return (EPROTONOSUPPORT);
|
||||
}
|
||||
|
||||
/* De-orbit the protocol and make the slot available again. */
|
||||
dpr->pr_type = 0;
|
||||
@ -321,6 +340,9 @@ pf_proto_unregister(family, protocol, type)
|
||||
dpr->pr_drain = NULL;
|
||||
dpr->pr_usrreqs = &nousrreqs;
|
||||
|
||||
/* Job is done, not more protection required. */
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user