diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2009-06-24 10:32:44 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2009-06-24 10:32:44 +0000 |
commit | 6c7ffe934027f50fad4ff081336409ba01ba8fe1 (patch) | |
tree | 60dc81a23ac68fc8613f2da7a97b2b2686ff4459 /sys/netatalk/aarp.c | |
parent | 9087bd79250f5eeef102b34b95e2d2b6d437d4f0 (diff) | |
download | src-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.c | 36 |
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 { |