MFC:
fixed memory leak for IPv6 multicast membership information associated with interface addresses. Approved by: gnn (mentor) src/sys/netinet6/in6.c: 1.71 src/sys/netinet6/in6_ifattach.c: 1.36 src/sys/netinet6/in6_var.h: 1.31
This commit is contained in:
parent
2903a43579
commit
f3d7053114
@ -901,6 +901,7 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
if (ia == NULL)
|
||||
return (ENOBUFS);
|
||||
bzero((caddr_t)ia, sizeof(*ia));
|
||||
LIST_INIT(&ia->ia6_memberships);
|
||||
/* Initialize the address and masks, and put time stamp */
|
||||
IFA_LOCK_INIT(&ia->ia_ifa);
|
||||
ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
|
||||
@ -1058,7 +1059,7 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
(MAX_RTR_SOLICITATION_DELAY * hz);
|
||||
}
|
||||
imm = in6_joingroup(ifp, &llsol, &error, delay);
|
||||
if (error != 0) {
|
||||
if (imm == NULL) {
|
||||
nd6log((LOG_WARNING,
|
||||
"in6_update_ifa: addmulti failed for "
|
||||
"%s on %s (errno=%d)\n",
|
||||
@ -1067,6 +1068,8 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
in6_purgeaddr((struct ifaddr *)ia);
|
||||
return (error);
|
||||
}
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships,
|
||||
imm, i6mm_chain);
|
||||
in6m_sol = imm->i6mm_maddr;
|
||||
|
||||
bzero(&mltmask, sizeof(mltmask));
|
||||
@ -1148,6 +1151,7 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
if_name(ifp), error));
|
||||
goto cleanup;
|
||||
}
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
|
||||
|
||||
/*
|
||||
* join node information group address
|
||||
@ -1173,6 +1177,9 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
ip6_sprintf(&mltaddr.sin6_addr),
|
||||
if_name(ifp), error));
|
||||
/* XXX not very fatal, go on... */
|
||||
} else {
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships,
|
||||
imm, i6mm_chain);
|
||||
}
|
||||
}
|
||||
#undef hostnamelen
|
||||
@ -1235,6 +1242,7 @@ in6_update_ifa(ifp, ifra, ia, flags)
|
||||
if_name(ifp), error));
|
||||
goto cleanup;
|
||||
}
|
||||
LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
|
||||
#undef MLTMASK_LEN
|
||||
}
|
||||
|
||||
@ -1298,6 +1306,7 @@ in6_purgeaddr(ifa)
|
||||
{
|
||||
struct ifnet *ifp = ifa->ifa_ifp;
|
||||
struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
|
||||
struct in6_multi_mship *imm;
|
||||
|
||||
/* stop DAD processing */
|
||||
nd6_dad_stop(ifa);
|
||||
@ -1324,24 +1333,12 @@ in6_purgeaddr(ifa)
|
||||
/* Remove ownaddr's loopback rtentry, if it exists. */
|
||||
in6_ifremloop(&(ia->ia_ifa));
|
||||
|
||||
if (ifp->if_flags & IFF_MULTICAST) {
|
||||
/*
|
||||
* delete solicited multicast addr for deleting host id
|
||||
*/
|
||||
struct in6_multi *in6m;
|
||||
struct in6_addr llsol;
|
||||
bzero(&llsol, sizeof(struct in6_addr));
|
||||
llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
|
||||
llsol.s6_addr32[1] = 0;
|
||||
llsol.s6_addr32[2] = htonl(1);
|
||||
llsol.s6_addr32[3] =
|
||||
ia->ia_addr.sin6_addr.s6_addr32[3];
|
||||
llsol.s6_addr8[12] = 0xff;
|
||||
(void)in6_setscope(&llsol, ifp, NULL); /* XXX proceed anyway */
|
||||
|
||||
IN6_LOOKUP_MULTI(llsol, ifp, in6m);
|
||||
if (in6m)
|
||||
in6_delmulti(in6m);
|
||||
/*
|
||||
* leave from multicast groups we have joined for the interface
|
||||
*/
|
||||
while ((imm = ia->ia6_memberships.lh_first) != NULL) {
|
||||
LIST_REMOVE(imm, i6mm_chain);
|
||||
in6_leavegroup(imm);
|
||||
}
|
||||
|
||||
in6_unlink_ifa(ia, ifp);
|
||||
|
@ -733,8 +733,8 @@ in6_ifdetach(ifp)
|
||||
struct rtentry *rt;
|
||||
short rtflags;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct in6_multi *in6m;
|
||||
struct in6_multi *in6m_next;
|
||||
struct in6_multi *in6m, *in6m_next;
|
||||
struct in6_multi_mship *imm;
|
||||
|
||||
/* remove neighbor management table */
|
||||
nd6_purge(ifp);
|
||||
@ -758,6 +758,14 @@ in6_ifdetach(ifp)
|
||||
|
||||
ia = (struct in6_ifaddr *)ifa;
|
||||
|
||||
/*
|
||||
* leave from multicast groups we have joined for the interface
|
||||
*/
|
||||
while ((imm = ia->ia6_memberships.lh_first) != NULL) {
|
||||
LIST_REMOVE(imm, i6mm_chain);
|
||||
in6_leavegroup(imm);
|
||||
}
|
||||
|
||||
/* remove from the routing table */
|
||||
if ((ia->ia_flags & IFA_ROUTE) &&
|
||||
(rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
|
||||
@ -803,6 +811,8 @@ in6_ifdetach(ifp)
|
||||
in6m_next = LIST_NEXT(in6m, in6m_entry);
|
||||
if (in6m->in6m_ifp != ifp)
|
||||
continue;
|
||||
printf("in6_ifdetach: in6m=%p (ref=%d), ifp=%p\n", in6m,
|
||||
in6m->in6m_ifma->ifma_refcount, ifp);
|
||||
in6_delmulti(in6m);
|
||||
in6m = NULL;
|
||||
}
|
||||
|
@ -115,6 +115,9 @@ struct in6_ifaddr {
|
||||
|
||||
/* back pointer to the ND prefix (for autoconfigured addresses only) */
|
||||
struct nd_prefix *ia6_ndpr;
|
||||
|
||||
/* multicast addresses joined from the kernel */
|
||||
LIST_HEAD(, in6_multi_mship) ia6_memberships;
|
||||
};
|
||||
|
||||
/* control structure to manage address selection policy */
|
||||
|
Loading…
Reference in New Issue
Block a user