summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-04-20 14:35:42 +0000
committerrwatson <rwatson@FreeBSD.org>2009-04-20 14:35:42 +0000
commitcbaf9d767f795c296978513820436005cb0fa14d (patch)
tree5fbe132ea8c16d105352b162d310bd77dad49bd0 /sys/netinet/ip_input.c
parent32441d8ae9e5b1339f6279b54e943467f1fe6194 (diff)
downloadFreeBSD-src-cbaf9d767f795c296978513820436005cb0fa14d.zip
FreeBSD-src-cbaf9d767f795c296978513820436005cb0fa14d.tar.gz
In ip_input(), cache the received mbuf's network interface in a local
variable. Acquire the interface address list lock when iterating over the interface address list searching for a matching received broadcast address. MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 2db3afb..a294d0a 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -371,6 +371,7 @@ ip_input(struct mbuf *m)
struct ip *ip = NULL;
struct in_ifaddr *ia = NULL;
struct ifaddr *ifa;
+ struct ifnet *ifp;
int checkif, hlen = 0;
u_short sum;
int dchg = 0; /* dest changed after fw */
@@ -421,9 +422,10 @@ ip_input(struct mbuf *m)
}
/* 127/8 must not appear on wire - RFC1122 */
+ ifp = m->m_pkthdr.rcvif;
if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
(ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
- if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
+ if ((ifp->if_flags & IFF_LOOPBACK) == 0) {
IPSTAT_INC(ips_badaddr);
goto bad;
}
@@ -498,14 +500,14 @@ tooshort:
goto passin;
odst = ip->ip_dst;
- if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif,
- PFIL_IN, NULL) != 0)
+ if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_IN, NULL) != 0)
return;
if (m == NULL) /* consumed by filter */
return;
ip = mtod(m, struct ip *);
dchg = (odst.s_addr != ip->ip_dst.s_addr);
+ ifp = m->m_pkthdr.rcvif;
#ifdef IPFIREWALL_FORWARD
if (m->m_flags & M_FASTFWD_OURS) {
@@ -571,10 +573,9 @@ passin:
* checked with carp_iamatch() and carp_forus().
*/
checkif = V_ip_checkinterface && (V_ipforwarding == 0) &&
- m->m_pkthdr.rcvif != NULL &&
- ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) &&
+ ifp != NULL && ((ifp->if_flags & IFF_LOOPBACK) == 0) &&
#ifdef DEV_CARP
- !m->m_pkthdr.rcvif->if_carp &&
+ !ifp->if_carp &&
#endif
(dchg == 0);
@@ -588,7 +589,7 @@ passin:
* enabled.
*/
if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr &&
- (!checkif || ia->ia_ifp == m->m_pkthdr.rcvif))
+ (!checkif || ia->ia_ifp == ifp))
goto ours;
}
/*
@@ -599,22 +600,29 @@ passin:
* be handled via ip_forward() and ether_output() with the loopback
* into the stack for SIMPLEX interfaces handled by ether_output().
*/
- if (m->m_pkthdr.rcvif != NULL &&
- m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
- TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
+ if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) {
+ IF_ADDR_LOCK(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = ifatoia(ifa);
if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
- ip->ip_dst.s_addr)
+ ip->ip_dst.s_addr) {
+ IF_ADDR_UNLOCK(ifp);
goto ours;
- if (ia->ia_netbroadcast.s_addr == ip->ip_dst.s_addr)
+ }
+ if (ia->ia_netbroadcast.s_addr == ip->ip_dst.s_addr) {
+ IF_ADDR_UNLOCK(ifp);
goto ours;
+ }
#ifdef BOOTP_COMPAT
- if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY)
+ if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY) {
+ IF_ADDR_UNLOCK(ifp);
goto ours;
+ }
#endif
}
+ IF_ADDR_UNLOCK(ifp);
}
/* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */
if (IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) {
@@ -632,8 +640,7 @@ passin:
* ip_mforward() returns a non-zero value, the packet
* must be discarded, else it may be accepted below.
*/
- if (ip_mforward &&
- ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
+ if (ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) {
IPSTAT_INC(ips_cantforward);
m_freem(m);
return;
@@ -663,7 +670,7 @@ passin:
/*
* FAITH(Firewall Aided Internet Translator)
*/
- if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
+ if (ifp && ifp->if_type == IFT_FAITH) {
if (V_ip_keepfaith) {
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_ICMP)
goto ours;
OpenPOWER on IntegriCloud