Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/ip6_input.c
Show First 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | sysctl_netinet6_intr_direct_queue_maxlen(SYSCTL_HANDLER_ARGS) | ||||
return (netisr_setqlimit(&ip6_direct_nh, qlimit)); | return (netisr_setqlimit(&ip6_direct_nh, qlimit)); | ||||
} | } | ||||
SYSCTL_PROC(_net_inet6_ip6, IPV6CTL_INTRDQMAXLEN, intr_direct_queue_maxlen, | SYSCTL_PROC(_net_inet6_ip6, IPV6CTL_INTRDQMAXLEN, intr_direct_queue_maxlen, | ||||
CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet6_intr_direct_queue_maxlen, | CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet6_intr_direct_queue_maxlen, | ||||
"I", "Maximum size of the IPv6 direct input queue"); | "I", "Maximum size of the IPv6 direct input queue"); | ||||
#endif | #endif | ||||
VNET_DEFINE(struct pfil_head, inet6_pfil_hook); | VNET_DEFINE(pfil_head_t, inet6_pfil_head); | ||||
VNET_PCPUSTAT_DEFINE(struct ip6stat, ip6stat); | VNET_PCPUSTAT_DEFINE(struct ip6stat, ip6stat); | ||||
VNET_PCPUSTAT_SYSINIT(ip6stat); | VNET_PCPUSTAT_SYSINIT(ip6stat); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
VNET_PCPUSTAT_SYSUNINIT(ip6stat); | VNET_PCPUSTAT_SYSUNINIT(ip6stat); | ||||
#endif /* VIMAGE */ | #endif /* VIMAGE */ | ||||
struct rmlock in6_ifaddr_lock; | struct rmlock in6_ifaddr_lock; | ||||
RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); | RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); | ||||
static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); | static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); | ||||
#ifdef PULLDOWN_TEST | #ifdef PULLDOWN_TEST | ||||
static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); | static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); | ||||
#endif | #endif | ||||
/* | /* | ||||
* IP6 initialization: fill in IP6 protocol switch table. | * IP6 initialization: fill in IP6 protocol switch table. | ||||
* All protocols not implemented in kernel go to raw IP6 protocol handler. | * All protocols not implemented in kernel go to raw IP6 protocol handler. | ||||
*/ | */ | ||||
void | void | ||||
ip6_init(void) | ip6_init(void) | ||||
{ | { | ||||
struct pfil_head_args args; | |||||
struct protosw *pr; | struct protosw *pr; | ||||
int i; | int i; | ||||
TUNABLE_INT_FETCH("net.inet6.ip6.auto_linklocal", | TUNABLE_INT_FETCH("net.inet6.ip6.auto_linklocal", | ||||
&V_ip6_auto_linklocal); | &V_ip6_auto_linklocal); | ||||
TUNABLE_INT_FETCH("net.inet6.ip6.accept_rtadv", &V_ip6_accept_rtadv); | TUNABLE_INT_FETCH("net.inet6.ip6.accept_rtadv", &V_ip6_accept_rtadv); | ||||
TUNABLE_INT_FETCH("net.inet6.ip6.no_radr", &V_ip6_no_radr); | TUNABLE_INT_FETCH("net.inet6.ip6.no_radr", &V_ip6_no_radr); | ||||
CK_STAILQ_INIT(&V_in6_ifaddrhead); | CK_STAILQ_INIT(&V_in6_ifaddrhead); | ||||
V_in6_ifaddrhashtbl = hashinit(IN6ADDR_NHASH, M_IFADDR, | V_in6_ifaddrhashtbl = hashinit(IN6ADDR_NHASH, M_IFADDR, | ||||
&V_in6_ifaddrhmask); | &V_in6_ifaddrhmask); | ||||
/* Initialize packet filter hooks. */ | /* Initialize packet filter hooks. */ | ||||
V_inet6_pfil_hook.ph_type = PFIL_TYPE_AF; | args.pa_version = PFIL_VERSION; | ||||
V_inet6_pfil_hook.ph_af = AF_INET6; | args.pa_flags = PFIL_IN | PFIL_OUT; | ||||
if ((i = pfil_head_register(&V_inet6_pfil_hook)) != 0) | args.pa_type = PFIL_TYPE_IP6; | ||||
printf("%s: WARNING: unable to register pfil hook, " | args.pa_headname = PFIL_INET6_NAME; | ||||
"error %d\n", __func__, i); | V_inet6_pfil_head = pfil_head_register(&args); | ||||
if (hhook_head_register(HHOOK_TYPE_IPSEC_IN, AF_INET6, | if (hhook_head_register(HHOOK_TYPE_IPSEC_IN, AF_INET6, | ||||
&V_ipsec_hhh_in[HHOOK_IPSEC_INET6], | &V_ipsec_hhh_in[HHOOK_IPSEC_INET6], | ||||
HHOOK_WAITOK | HHOOK_HEADISINVNET) != 0) | HHOOK_WAITOK | HHOOK_HEADISINVNET) != 0) | ||||
printf("%s: WARNING: unable to register input helper hook\n", | printf("%s: WARNING: unable to register input helper hook\n", | ||||
__func__); | __func__); | ||||
if (hhook_head_register(HHOOK_TYPE_IPSEC_OUT, AF_INET6, | if (hhook_head_register(HHOOK_TYPE_IPSEC_OUT, AF_INET6, | ||||
&V_ipsec_hhh_out[HHOOK_IPSEC_INET6], | &V_ipsec_hhh_out[HHOOK_IPSEC_INET6], | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | ip6_destroy(void *unused __unused) | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int error; | int error; | ||||
#ifdef RSS | #ifdef RSS | ||||
netisr_unregister_vnet(&ip6_direct_nh); | netisr_unregister_vnet(&ip6_direct_nh); | ||||
#endif | #endif | ||||
netisr_unregister_vnet(&ip6_nh); | netisr_unregister_vnet(&ip6_nh); | ||||
if ((error = pfil_head_unregister(&V_inet6_pfil_hook)) != 0) | pfil_head_unregister(V_inet6_pfil_head); | ||||
printf("%s: WARNING: unable to unregister pfil hook, " | |||||
"error %d\n", __func__, error); | |||||
error = hhook_head_deregister(V_ipsec_hhh_in[HHOOK_IPSEC_INET6]); | error = hhook_head_deregister(V_ipsec_hhh_in[HHOOK_IPSEC_INET6]); | ||||
if (error != 0) { | if (error != 0) { | ||||
printf("%s: WARNING: unable to deregister input helper hook " | printf("%s: WARNING: unable to deregister input helper hook " | ||||
"type HHOOK_TYPE_IPSEC_IN, id HHOOK_IPSEC_INET6: " | "type HHOOK_TYPE_IPSEC_IN, id HHOOK_IPSEC_INET6: " | ||||
"error %d returned\n", __func__, error); | "error %d returned\n", __func__, error); | ||||
} | } | ||||
error = hhook_head_deregister(V_ipsec_hhh_out[HHOOK_IPSEC_INET6]); | error = hhook_head_deregister(V_ipsec_hhh_out[HHOOK_IPSEC_INET6]); | ||||
if (error != 0) { | if (error != 0) { | ||||
▲ Show 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | #endif | ||||
* Run through list of hooks for input packets. | * Run through list of hooks for input packets. | ||||
* | * | ||||
* NB: Beware of the destination address changing | * NB: Beware of the destination address changing | ||||
* (e.g. by NAT rewriting). When this happens, | * (e.g. by NAT rewriting). When this happens, | ||||
* tell ip6_forward to do the right thing. | * tell ip6_forward to do the right thing. | ||||
*/ | */ | ||||
/* Jump over all PFIL processing if hooks are not active. */ | /* Jump over all PFIL processing if hooks are not active. */ | ||||
if (!PFIL_HOOKED(&V_inet6_pfil_hook)) | if (!PFIL_HOOKED_IN(V_inet6_pfil_head)) | ||||
goto passin; | goto passin; | ||||
odst = ip6->ip6_dst; | odst = ip6->ip6_dst; | ||||
if (pfil_run_hooks(&V_inet6_pfil_hook, &m, | if (pfil_run_hooks(V_inet6_pfil_head, &m, m->m_pkthdr.rcvif, PFIL_IN, | ||||
m->m_pkthdr.rcvif, PFIL_IN, 0, NULL)) | NULL) != PFIL_PASS) | ||||
return; | |||||
if (m == NULL) /* consumed by filter */ | |||||
return; | return; | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); | srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); | ||||
if ((m->m_flags & (M_IP6_NEXTHOP | M_FASTFWD_OURS)) == M_IP6_NEXTHOP && | if ((m->m_flags & (M_IP6_NEXTHOP | M_FASTFWD_OURS)) == M_IP6_NEXTHOP && | ||||
m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) { | m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL) { | ||||
/* | /* | ||||
* Directly ship the packet on. This allows forwarding | * Directly ship the packet on. This allows forwarding | ||||
* packets originally destined to us to some other directly | * packets originally destined to us to some other directly | ||||
▲ Show 20 Lines • Show All 1,088 Lines • Show Last 20 Lines |