aboutsummaryrefslogtreecommitdiff
path: root/sys/netatalk/aarp.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2009-06-24 10:32:44 +0000
committerRobert Watson <rwatson@FreeBSD.org>2009-06-24 10:32:44 +0000
commit6c7ffe934027f50fad4ff081336409ba01ba8fe1 (patch)
tree60dc81a23ac68fc8613f2da7a97b2b2686ff4459 /sys/netatalk/aarp.c
parent9087bd79250f5eeef102b34b95e2d2b6d437d4f0 (diff)
downloadsrc-6c7ffe934027f50fad4ff081336409ba01ba8fe1.tar.gz
src-6c7ffe934027f50fad4ff081336409ba01ba8fe1.zip
Break at_ifawithnet() into two variants:
- at_ifawithnet(), which acquires an locks it needs and returns an at_ifaddr reference. - at_ifawithnet_locked(), which relies on the caller locking at_ifaddr_list, and returns a pointer rather than a reference. Update various consumers to prefer one or the other, including ether and fddi output, to properly release at_ifaddr references. Rework at_control() to manage locking and references in a manner identical to in_control(). MFC after: 6 weeks
Notes
Notes: svn path=/head/; revision=194819
Diffstat (limited to 'sys/netatalk/aarp.c')
-rw-r--r--sys/netatalk/aarp.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/sys/netatalk/aarp.c b/sys/netatalk/aarp.c
index 203a0d4dacef..95322986384c 100644
--- a/sys/netatalk/aarp.c
+++ b/sys/netatalk/aarp.c
@@ -142,9 +142,12 @@ aarptimer(void *ignored)
/*
* Search through the network addresses to find one that includes the given
* network. Remember to take netranges into consideration.
+ *
+ * The _locked variant relies on the caller holding the at_ifaddr lock; the
+ * unlocked variant returns a reference that the caller must dispose of.
*/
struct at_ifaddr *
-at_ifawithnet(struct sockaddr_at *sat)
+at_ifawithnet_locked(struct sockaddr_at *sat)
{
struct at_ifaddr *aa;
struct sockaddr_at *sat2;
@@ -163,6 +166,19 @@ at_ifawithnet(struct sockaddr_at *sat)
return (aa);
}
+struct at_ifaddr *
+at_ifawithnet(struct sockaddr_at *sat)
+{
+ struct at_ifaddr *aa;
+
+ AT_IFADDR_RLOCK();
+ aa = at_ifawithnet_locked(sat);
+ if (aa != NULL)
+ ifa_ref(&aa->aa_ifa);
+ AT_IFADDR_RUNLOCK();
+ return (aa);
+}
+
static void
aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
{
@@ -201,9 +217,8 @@ aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
* same address as we're looking for. If the net is phase 2,
* generate an 802.2 and SNAP header.
*/
- AT_IFADDR_RLOCK();
- if ((aa = at_ifawithnet(sat)) == NULL) {
- AT_IFADDR_RUNLOCK();
+ aa = at_ifawithnet(sat);
+ if (aa == NULL) {
m_freem(m);
return;
}
@@ -217,7 +232,7 @@ aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
sizeof(struct ether_aarp));
M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
if (m == NULL) {
- AT_IFADDR_RUNLOCK();
+ ifa_free(&aa->aa_ifa);
return;
}
llc = mtod(m, struct llc *);
@@ -244,7 +259,7 @@ aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
printf("aarp: sending request for %u.%u\n",
ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
#endif /* NETATALKDEBUG */
- AT_IFADDR_RUNLOCK();
+ ifa_free(&aa->aa_ifa);
sa.sa_len = sizeof(struct sockaddr);
sa.sa_family = AF_UNSPEC;
@@ -261,7 +276,7 @@ aarpresolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr_at *destsat,
AT_IFADDR_RLOCK();
if (at_broadcast(destsat)) {
m->m_flags |= M_BCAST;
- if ((aa = at_ifawithnet(destsat)) == NULL) {
+ if ((aa = at_ifawithnet_locked(destsat)) == NULL) {
AT_IFADDR_RUNLOCK();
m_freem(m);
return (0);
@@ -379,14 +394,11 @@ at_aarpinput(struct ifnet *ifp, struct mbuf *m)
sat.sat_len = sizeof(struct sockaddr_at);
sat.sat_family = AF_APPLETALK;
sat.sat_addr.s_net = net;
- AT_IFADDR_RLOCK();
- if ((aa = at_ifawithnet(&sat)) == NULL) {
- AT_IFADDR_RUNLOCK();
+ aa = at_ifawithnet(&sat);
+ if (aa == NULL) {
m_freem(m);
return;
}
- ifa_ref(&aa->aa_ifa);
- AT_IFADDR_RUNLOCK();
bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net));
bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net));
} else {