plan9fox/sys/src/9/ip/nullmedium.c
cinap_lenrek 7289f371a0 devip: dont hold ifc wlock during medium bind/unbind
Wlock()'ing the ifc causes a deadlock with Medium
bind/unbind as the routine can walk /net, while
ndb/dns or ndb/cs are currently blocked enumerating
/net/ipifc/*.

The fix is to have a fake medium, called "unbound",
that is set temporarily during the call of Medium
bind and unbind.

That way, the interface rwlock can be released while
bind/unbind is in progress.

The ipifcunbind() routine will refuse to unbind a
ifc that is currently assigned to the "unbound"
medium, preventing any accidents.
2022-02-16 22:31:31 +00:00

50 lines
691 B
C

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "ip.h"
static void
nullbind(Ipifc*, int, char**)
{
error("cannot bind null device");
}
static void
nullunbind(Ipifc*)
{
}
static void
nullbwrite(Ipifc*, Block *bp, int, uchar*, Routehint*)
{
freeb(bp);
error("nullbwrite");
}
Medium nullmedium =
{
.name= "null",
.bind= nullbind,
.unbind= nullunbind,
.bwrite= nullbwrite,
};
/* used in ipifc to prevent unbind while bind is in progress */
Medium unboundmedium =
{
.name= "unbound",
.bind= nullbind,
.unbind= nullunbind,
.bwrite= nullbwrite,
};
void
nullmediumlink(void)
{
addipmedium(&nullmedium);
}