diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-04-19 22:34:35 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-04-19 22:34:35 +0000 |
commit | 901df80bd6c9ba48f4bffb8142404a90874361d4 (patch) | |
tree | b213850c429465ae5fefe519620ca30b7c5629af | |
parent | ee528abe4691b42f196e602746c8b74a3fa38b00 (diff) | |
download | FreeBSD-src-901df80bd6c9ba48f4bffb8142404a90874361d4.zip FreeBSD-src-901df80bd6c9ba48f4bffb8142404a90874361d4.tar.gz |
Lock the interface address list when searching for a matching interface
by address, or when implementing 'me' rules on IPv6. Prefer the field
name if_addrhead to the macro if_addrlist.
MFC after: 2 weeks
-rw-r--r-- | sys/netinet/ip_fw2.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index fa6e6f1..2c949a9 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -480,14 +480,17 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd) } else { struct ifaddr *ia; - /* XXX lock? */ + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) { if (ia->ifa_addr->sa_family != AF_INET) continue; if (cmd->p.ip.s_addr == ((struct sockaddr_in *) - (ia->ifa_addr))->sin_addr.s_addr) + (ia->ifa_addr))->sin_addr.s_addr) { + IF_ADDR_UNLOCK(ifp); return(1); /* match */ + } } + IF_ADDR_UNLOCK(ifp); } return(0); /* no match, fail ... */ } @@ -589,17 +592,22 @@ search_ip6_addr_net (struct in6_addr * ip6_addr) struct in6_ifaddr *fdm; struct in6_addr copia; - TAILQ_FOREACH(mdc, &V_ifnet, if_link) - TAILQ_FOREACH(mdc2, &mdc->if_addrlist, ifa_list) { + TAILQ_FOREACH(mdc, &V_ifnet, if_link) { + IF_ADDR_LOCK(mdc); + TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_list) { if (mdc2->ifa_addr->sa_family == AF_INET6) { fdm = (struct in6_ifaddr *)mdc2; copia = fdm->ia_addr.sin6_addr; /* need for leaving scope_id in the sock_addr */ in6_clearscope(&copia); - if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) + if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) { + IF_ADDR_UNLOCK(mdc); return 1; + } } } + IF_ADDR_UNLOCK(mdc); + } return 0; } |