version 1.342, 2016/10/11 05:15:01 |
version 1.345, 2016/12/08 05:16:33 |
Line 101 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 101 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include "opt_mrouting.h" |
#include "opt_mrouting.h" |
#include "opt_mbuftrace.h" |
#include "opt_mbuftrace.h" |
#include "opt_inet_csum.h" |
#include "opt_inet_csum.h" |
|
#include "opt_net_mpsafe.h" |
#endif |
#endif |
|
|
#include "arp.h" |
#include "arp.h" |
Line 294 static struct in_ifaddr *ip_match_our_ad |
|
Line 295 static struct in_ifaddr *ip_match_our_ad |
|
static struct in_ifaddr *ip_match_our_address_broadcast(struct ifnet *, |
static struct in_ifaddr *ip_match_our_address_broadcast(struct ifnet *, |
struct ip *); |
struct ip *); |
|
|
/* XXX: Not yet enabled. */ |
#ifdef NET_MPSAFE |
|
#define SOFTNET_LOCK() mutex_enter(softnet_lock) |
|
#define SOFTNET_UNLOCK() mutex_exit(softnet_lock) |
|
#else |
#define SOFTNET_LOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_LOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) |
|
#endif |
|
|
/* |
/* |
* IP initialization: fill in IP protocol switch table. |
* IP initialization: fill in IP protocol switch table. |
Line 437 ipintr(void *arg __unused) |
|
Line 442 ipintr(void *arg __unused) |
|
|
|
KASSERT(cpu_softintr_p()); |
KASSERT(cpu_softintr_p()); |
|
|
|
#ifndef NET_MPSAFE |
mutex_enter(softnet_lock); |
mutex_enter(softnet_lock); |
|
#endif |
while ((m = pktq_dequeue(ip_pktq)) != NULL) { |
while ((m = pktq_dequeue(ip_pktq)) != NULL) { |
ip_input(m); |
ip_input(m); |
} |
} |
|
#ifndef NET_MPSAFE |
mutex_exit(softnet_lock); |
mutex_exit(softnet_lock); |
|
#endif |
} |
} |
|
|
/* |
/* |
Line 614 ip_input(struct mbuf *m) |
|
Line 623 ip_input(struct mbuf *m) |
|
struct in_addr odst = ip->ip_dst; |
struct in_addr odst = ip->ip_dst; |
bool freed; |
bool freed; |
|
|
SOFTNET_LOCK(); |
|
freed = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_IN) != 0; |
freed = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_IN) != 0; |
SOFTNET_UNLOCK(); |
|
if (freed || m == NULL) { |
if (freed || m == NULL) { |
|
m = NULL; |
goto out; |
goto out; |
} |
} |
ip = mtod(m, struct ip *); |
ip = mtod(m, struct ip *); |
Line 647 ip_input(struct mbuf *m) |
|
Line 655 ip_input(struct mbuf *m) |
|
if ((*altq_input)(m, AF_INET) == 0) { |
if ((*altq_input)(m, AF_INET) == 0) { |
/* Packet dropped by traffic conditioner. */ |
/* Packet dropped by traffic conditioner. */ |
SOFTNET_UNLOCK(); |
SOFTNET_UNLOCK(); |
|
m = NULL; |
goto out; |
goto out; |
} |
} |
SOFTNET_UNLOCK(); |
SOFTNET_UNLOCK(); |
Line 660 ip_input(struct mbuf *m) |
|
Line 669 ip_input(struct mbuf *m) |
|
* to be sent and the original packet to be freed). |
* to be sent and the original packet to be freed). |
*/ |
*/ |
ip_nhops = 0; /* for source routed packets */ |
ip_nhops = 0; /* for source routed packets */ |
if (hlen > sizeof (struct ip) && ip_dooptions(m)) |
if (hlen > sizeof (struct ip) && ip_dooptions(m)) { |
|
m = NULL; |
goto out; |
goto out; |
|
} |
|
|
/* |
/* |
* Check our list of addresses, to see if the packet is for us. |
* Check our list of addresses, to see if the packet is for us. |
Line 1172 ip_rtaddr(struct in_addr dst) |
|
Line 1183 ip_rtaddr(struct in_addr dst) |
|
|
|
sockaddr_in_init(&u.dst4, &dst, 0); |
sockaddr_in_init(&u.dst4, &dst, 0); |
|
|
SOFTNET_LOCK(); |
|
ro = percpu_getref(ipforward_rt_percpu); |
ro = percpu_getref(ipforward_rt_percpu); |
rt = rtcache_lookup(ro, &u.dst); |
rt = rtcache_lookup(ro, &u.dst); |
percpu_putref(ipforward_rt_percpu); |
if (rt == NULL) { |
SOFTNET_UNLOCK(); |
percpu_putref(ipforward_rt_percpu); |
if (rt == NULL) |
|
return NULL; |
return NULL; |
|
} |
|
|
|
rtcache_unref(rt, ro); |
|
percpu_putref(ipforward_rt_percpu); |
|
|
return ifatoia(rt->rt_ifa); |
return ifatoia(rt->rt_ifa); |
} |
} |
Line 1330 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1343 ip_forward(struct mbuf *m, int srcrt, st |
|
return; |
return; |
} |
} |
|
|
SOFTNET_LOCK(); |
|
|
|
if (ip->ip_ttl <= IPTTLDEC) { |
if (ip->ip_ttl <= IPTTLDEC) { |
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0); |
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0); |
SOFTNET_UNLOCK(); |
|
return; |
return; |
} |
} |
|
|
sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); |
sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); |
|
|
ro = percpu_getref(ipforward_rt_percpu); |
ro = percpu_getref(ipforward_rt_percpu); |
if ((rt = rtcache_lookup(ro, &u.dst)) == NULL) { |
rt = rtcache_lookup(ro, &u.dst); |
|
if (rt == NULL) { |
percpu_putref(ipforward_rt_percpu); |
percpu_putref(ipforward_rt_percpu); |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); |
SOFTNET_UNLOCK(); |
|
return; |
return; |
} |
} |
|
|
Line 1386 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1396 ip_forward(struct mbuf *m, int srcrt, st |
|
code = ICMP_REDIRECT_HOST; |
code = ICMP_REDIRECT_HOST; |
} |
} |
} |
} |
|
rtcache_unref(rt, ro); |
|
|
error = ip_output(m, NULL, ro, |
error = ip_output(m, NULL, ro, |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), |
Line 1415 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1426 ip_forward(struct mbuf *m, int srcrt, st |
|
} |
} |
|
|
percpu_putref(ipforward_rt_percpu); |
percpu_putref(ipforward_rt_percpu); |
SOFTNET_UNLOCK(); |
|
return; |
return; |
|
|
redirect: |
redirect: |
error: |
error: |
if (mcopy == NULL) { |
if (mcopy == NULL) { |
percpu_putref(ipforward_rt_percpu); |
percpu_putref(ipforward_rt_percpu); |
SOFTNET_UNLOCK(); |
|
return; |
return; |
} |
} |
|
|
|
|
type = ICMP_UNREACH; |
type = ICMP_UNREACH; |
code = ICMP_UNREACH_NEEDFRAG; |
code = ICMP_UNREACH_NEEDFRAG; |
|
|
if ((rt = rtcache_validate(ro)) != NULL) |
if ((rt = rtcache_validate(ro)) != NULL) { |
destmtu = rt->rt_ifp->if_mtu; |
destmtu = rt->rt_ifp->if_mtu; |
|
rtcache_unref(rt, ro); |
|
} |
#ifdef IPSEC |
#ifdef IPSEC |
if (ipsec_used) |
if (ipsec_used) |
(void)ipsec4_forward(mcopy, &destmtu); |
(void)ipsec4_forward(mcopy, &destmtu); |
|
|
if (mcopy) |
if (mcopy) |
m_freem(mcopy); |
m_freem(mcopy); |
percpu_putref(ipforward_rt_percpu); |
percpu_putref(ipforward_rt_percpu); |
SOFTNET_UNLOCK(); |
|
return; |
return; |
} |
} |
icmp_error(mcopy, type, code, dest, destmtu); |
icmp_error(mcopy, type, code, dest, destmtu); |
percpu_putref(ipforward_rt_percpu); |
percpu_putref(ipforward_rt_percpu); |
SOFTNET_UNLOCK(); |
|
} |
} |
|
|
void |
void |