version 1.337.2.2, 2016/11/04 14:49:21 |
version 1.340, 2016/08/31 09:14:47 |
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 226 pfil_head_t * inet_pfil_hook __read_mo |
|
Line 225 pfil_head_t * inet_pfil_hook __read_mo |
|
ipid_state_t * ip_ids __read_mostly; |
ipid_state_t * ip_ids __read_mostly; |
percpu_t * ipstat_percpu __read_mostly; |
percpu_t * ipstat_percpu __read_mostly; |
|
|
static struct route ipforward_rt __cacheline_aligned; |
static percpu_t *ipforward_rt_percpu __cacheline_aligned; |
|
|
uint16_t ip_id; |
uint16_t ip_id; |
|
|
Line 295 static struct in_ifaddr *ip_match_our_ad |
|
Line 294 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 *); |
|
|
#ifdef NET_MPSAFE |
/* XXX: Not yet enabled. */ |
#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. |
|
|
#endif /* MBUFTRACE */ |
#endif /* MBUFTRACE */ |
|
|
ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS); |
ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS); |
|
|
|
ipforward_rt_percpu = percpu_alloc(sizeof(struct route)); |
|
if (ipforward_rt_percpu == NULL) |
|
panic("failed to allocate ipforward_rt_percpu"); |
} |
} |
|
|
static struct in_ifaddr * |
static struct in_ifaddr * |
Line 437 ipintr(void *arg __unused) |
|
Line 436 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 618 ip_input(struct mbuf *m) |
|
Line 613 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 650 ip_input(struct mbuf *m) |
|
Line 646 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 664 ip_input(struct mbuf *m) |
|
Line 659 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. |
|
|
* is expensive, so explore ia here again. |
* is expensive, so explore ia here again. |
*/ |
*/ |
s = pserialize_read_enter(); |
s = pserialize_read_enter(); |
_ia = in_get_ia(ip->ip_dst); |
_ia = in_get_ia(ip->ip_dst.s_addr); |
_ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len); |
_ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len); |
pserialize_read_exit(s); |
pserialize_read_exit(s); |
} |
} |
Line 1174 ip_rtaddr(struct in_addr dst) |
|
Line 1167 ip_rtaddr(struct in_addr dst) |
|
struct sockaddr dst; |
struct sockaddr dst; |
struct sockaddr_in dst4; |
struct sockaddr_in dst4; |
} u; |
} u; |
|
struct route *ro; |
|
|
sockaddr_in_init(&u.dst4, &dst, 0); |
sockaddr_in_init(&u.dst4, &dst, 0); |
|
|
SOFTNET_LOCK(); |
SOFTNET_LOCK(); |
rt = rtcache_lookup(&ipforward_rt, &u.dst); |
ro = percpu_getref(ipforward_rt_percpu); |
|
rt = rtcache_lookup(ro, &u.dst); |
|
percpu_putref(ipforward_rt_percpu); |
SOFTNET_UNLOCK(); |
SOFTNET_UNLOCK(); |
if (rt == NULL) |
if (rt == NULL) |
return NULL; |
return NULL; |
Line 1311 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1307 ip_forward(struct mbuf *m, int srcrt, st |
|
struct sockaddr_in dst4; |
struct sockaddr_in dst4; |
} u; |
} u; |
uint64_t *ips; |
uint64_t *ips; |
|
struct route *ro; |
|
|
KASSERTMSG(cpu_softintr_p(), "ip_forward: not in the software " |
KASSERTMSG(cpu_softintr_p(), "ip_forward: not in the software " |
"interrupt handler; synchronization assumptions violated"); |
"interrupt handler; synchronization assumptions violated"); |
Line 1332 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1329 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); |
|
|
if ((rt = rtcache_lookup(&ipforward_rt, &u.dst)) == NULL) { |
ro = percpu_getref(ipforward_rt_percpu); |
|
if ((rt = rtcache_lookup(ro, &u.dst)) == NULL) { |
|
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 1383 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1386 ip_forward(struct mbuf *m, int srcrt, st |
|
} |
} |
} |
} |
|
|
error = ip_output(m, NULL, &ipforward_rt, |
error = ip_output(m, NULL, ro, |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), |
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), |
NULL, NULL); |
NULL, NULL); |
|
|
Line 1405 ip_forward(struct mbuf *m, int srcrt, st |
|
Line 1408 ip_forward(struct mbuf *m, int srcrt, st |
|
if (mcopy) { |
if (mcopy) { |
#ifdef GATEWAY |
#ifdef GATEWAY |
if (mcopy->m_flags & M_CANFASTFWD) |
if (mcopy->m_flags & M_CANFASTFWD) |
ipflow_create(&ipforward_rt, mcopy); |
ipflow_create(ro, mcopy); |
#endif |
#endif |
m_freem(mcopy); |
m_freem(mcopy); |
} |
} |
|
|
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(&ipforward_rt)) != NULL) |
if ((rt = rtcache_validate(ro)) != NULL) |
destmtu = rt->rt_ifp->if_mtu; |
destmtu = rt->rt_ifp->if_mtu; |
#ifdef IPSEC |
#ifdef IPSEC |
if (ipsec_used) |
if (ipsec_used) |
|
|
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 |