version 1.149.4.6, 2016/05/29 08:44:39 |
version 1.150, 2015/01/20 21:27:36 |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#ifdef _KERNEL_OPT |
|
#include "opt_gateway.h" |
#include "opt_gateway.h" |
#include "opt_inet.h" |
#include "opt_inet.h" |
#include "opt_inet6.h" |
#include "opt_inet6.h" |
#include "opt_ipsec.h" |
#include "opt_ipsec.h" |
#include "opt_compat_netbsd.h" |
#include "opt_compat_netbsd.h" |
#endif |
|
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
Line 127 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 125 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <netinet6/ip6protosw.h> |
#include <netinet6/ip6protosw.h> |
|
|
#include "faith.h" |
#include "faith.h" |
|
#include "gif.h" |
|
|
|
#if NGIF > 0 |
|
#include <netinet6/in6_gif.h> |
|
#endif |
|
|
#include <net/net_osdep.h> |
#include <net/net_osdep.h> |
|
|
Line 136 u_char ip6_protox[IPPROTO_MAX]; |
|
Line 139 u_char ip6_protox[IPPROTO_MAX]; |
|
struct in6_ifaddr *in6_ifaddr; |
struct in6_ifaddr *in6_ifaddr; |
pktqueue_t *ip6_pktq __read_mostly; |
pktqueue_t *ip6_pktq __read_mostly; |
|
|
|
extern callout_t in6_tmpaddrtimer_ch; |
|
|
int ip6_forward_srcrt; /* XXX */ |
int ip6_forward_srcrt; /* XXX */ |
int ip6_sourcecheck; /* XXX */ |
int ip6_sourcecheck; /* XXX */ |
int ip6_sourcecheck_interval; /* XXX */ |
int ip6_sourcecheck_interval; /* XXX */ |
Line 144 pfil_head_t *inet6_pfil_hook; |
|
Line 149 pfil_head_t *inet6_pfil_hook; |
|
|
|
percpu_t *ip6stat_percpu; |
percpu_t *ip6stat_percpu; |
|
|
static void ip6_init2(void); |
static void ip6_init2(void *); |
static void ip6intr(void *); |
static void ip6intr(void *); |
static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); |
static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); |
|
|
|
|
frag6_init(); |
frag6_init(); |
ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR; |
ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR; |
|
|
ip6_init2(); |
ip6_init2(NULL); |
#ifdef GATEWAY |
#ifdef GATEWAY |
ip6flow_init(ip6_hashsize); |
ip6flow_init(ip6_hashsize); |
#endif |
#endif |
|
|
} |
} |
|
|
static void |
static void |
ip6_init2(void) |
ip6_init2(void *dummy) |
{ |
{ |
|
|
|
/* nd6_timer_init */ |
|
callout_init(&nd6_timer_ch, CALLOUT_MPSAFE); |
|
callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); |
|
|
/* timer for regeneranation of temporary addresses randomize ID */ |
/* timer for regeneranation of temporary addresses randomize ID */ |
callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE); |
callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE); |
callout_reset(&in6_tmpaddrtimer_ch, |
callout_reset(&in6_tmpaddrtimer_ch, |
Line 248 ip6_input(struct mbuf *m) |
|
Line 257 ip6_input(struct mbuf *m) |
|
struct sockaddr dst; |
struct sockaddr dst; |
struct sockaddr_in6 dst6; |
struct sockaddr_in6 dst6; |
} u; |
} u; |
struct ifnet *rcvif = m->m_pkthdr.rcvif; |
|
|
|
/* |
/* |
* make sure we don't have onion peering information into m_tag. |
* make sure we don't have onion peering information into m_tag. |
Line 266 ip6_input(struct mbuf *m) |
|
Line 274 ip6_input(struct mbuf *m) |
|
} else { |
} else { |
#define M2MMAX 32 |
#define M2MMAX 32 |
if (m->m_next) { |
if (m->m_next) { |
if (m->m_flags & M_LOOP) |
if (m->m_flags & M_LOOP) { |
/*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); |
/*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); |
else if (rcvif->if_index < M2MMAX) |
} else if (m->m_pkthdr.rcvif->if_index < M2MMAX) { |
IP6_STATINC(IP6_STAT_M2M + rcvif->if_index); |
IP6_STATINC(IP6_STAT_M2M + |
else |
m->m_pkthdr.rcvif->if_index); |
|
} else |
IP6_STATINC(IP6_STAT_M2M); |
IP6_STATINC(IP6_STAT_M2M); |
} else |
} else |
IP6_STATINC(IP6_STAT_M1); |
IP6_STATINC(IP6_STAT_M1); |
#undef M2MMAX |
#undef M2MMAX |
} |
} |
|
|
in6_ifstat_inc(rcvif, ifs6_in_receive); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); |
IP6_STATINC(IP6_STAT_TOTAL); |
IP6_STATINC(IP6_STAT_TOTAL); |
|
|
/* |
/* |
Line 287 ip6_input(struct mbuf *m) |
|
Line 296 ip6_input(struct mbuf *m) |
|
* IPv6 header is in the first mbuf of the chain. |
* IPv6 header is in the first mbuf of the chain. |
*/ |
*/ |
if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { |
if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { |
|
struct ifnet *inifp = m->m_pkthdr.rcvif; |
if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
(max_linkhdr + 3) & ~3)) == NULL) { |
(max_linkhdr + 3) & ~3)) == NULL) { |
/* XXXJRT new stat, please */ |
/* XXXJRT new stat, please */ |
IP6_STATINC(IP6_STAT_TOOSMALL); |
IP6_STATINC(IP6_STAT_TOOSMALL); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
return; |
return; |
} |
} |
} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
|
struct ifnet *inifp = m->m_pkthdr.rcvif; |
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
IP6_STATINC(IP6_STAT_TOOSMALL); |
IP6_STATINC(IP6_STAT_TOOSMALL); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
return; |
return; |
} |
} |
} |
} |
Line 306 ip6_input(struct mbuf *m) |
|
Line 317 ip6_input(struct mbuf *m) |
|
|
|
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
IP6_STATINC(IP6_STAT_BADVERS); |
IP6_STATINC(IP6_STAT_BADVERS); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 336 ip6_input(struct mbuf *m) |
|
Line 347 ip6_input(struct mbuf *m) |
|
struct in6_addr odst; |
struct in6_addr odst; |
|
|
odst = ip6->ip6_dst; |
odst = ip6->ip6_dst; |
if (pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN) != 0) |
if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif, |
|
PFIL_IN) != 0) |
return; |
return; |
if (m == NULL) |
if (m == NULL) |
return; |
return; |
Line 362 ip6_input(struct mbuf *m) |
|
Line 374 ip6_input(struct mbuf *m) |
|
* XXX: "badscope" is not very suitable for a multicast source. |
* XXX: "badscope" is not very suitable for a multicast source. |
*/ |
*/ |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
/* |
/* |
Line 380 ip6_input(struct mbuf *m) |
|
Line 392 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
#if 0 |
#if 0 |
Line 394 ip6_input(struct mbuf *m) |
|
Line 406 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || |
IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
#endif |
#endif |
Line 407 ip6_input(struct mbuf *m) |
|
Line 419 ip6_input(struct mbuf *m) |
|
* to the usage conflict. |
* to the usage conflict. |
* in6_setscope() then also checks and rejects the cases where src or |
* in6_setscope() then also checks and rejects the cases where src or |
* dst are the loopback address and the receiving interface |
* dst are the loopback address and the receiving interface |
* is not loopback. |
* is not loopback. |
*/ |
*/ |
if (__predict_false( |
if (__predict_false( |
m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT))) |
m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT))) |
Line 417 ip6_input(struct mbuf *m) |
|
Line 429 ip6_input(struct mbuf *m) |
|
IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ |
IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ |
goto bad; |
goto bad; |
} |
} |
if (in6_setscope(&ip6->ip6_src, rcvif, NULL) || |
if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) || |
in6_setscope(&ip6->ip6_dst, rcvif, NULL)) { |
in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
goto bad; |
goto bad; |
} |
} |
Line 429 ip6_input(struct mbuf *m) |
|
Line 441 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
struct in6_multi *in6m = 0; |
struct in6_multi *in6m = 0; |
|
|
in6_ifstat_inc(rcvif, ifs6_in_mcast); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); |
/* |
/* |
* See if we belong to the destination multicast group on the |
* See if we belong to the destination multicast group on the |
* arrival interface. |
* arrival interface. |
*/ |
*/ |
IN6_LOOKUP_MULTI(ip6->ip6_dst, rcvif, in6m); |
IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); |
if (in6m) |
if (in6m) |
ours = 1; |
ours = 1; |
else if (!ip6_mrouter) { |
else if (!ip6_mrouter) { |
Line 442 ip6_input(struct mbuf *m) |
|
Line 454 ip6_input(struct mbuf *m) |
|
ip6s[IP6_STAT_NOTMEMBER]++; |
ip6s[IP6_STAT_NOTMEMBER]++; |
ip6s[IP6_STAT_CANTFORWARD]++; |
ip6s[IP6_STAT_CANTFORWARD]++; |
IP6_STAT_PUTREF(); |
IP6_STAT_PUTREF(); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
goto bad; |
goto bad; |
} |
} |
deliverifp = rcvif; |
deliverifp = m->m_pkthdr.rcvif; |
goto hbhcheck; |
goto hbhcheck; |
} |
} |
|
|
Line 473 ip6_input(struct mbuf *m) |
|
Line 485 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (rt != NULL && |
if (rt != NULL && |
(rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && |
(rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && |
|
!(rt->rt_flags & RTF_CLONED) && |
#if 0 |
#if 0 |
/* |
/* |
* The check below is redundant since the comparison of |
* The check below is redundant since the comparison of |
Line 496 ip6_input(struct mbuf *m) |
|
Line 509 ip6_input(struct mbuf *m) |
|
goto hbhcheck; |
goto hbhcheck; |
} else { |
} else { |
/* address is not ready, so discard the packet. */ |
/* address is not ready, so discard the packet. */ |
nd6log(LOG_INFO, "packet to an unready address %s->%s\n", |
nd6log((LOG_INFO, |
|
"ip6_input: packet to an unready address %s->%s\n", |
ip6_sprintf(&ip6->ip6_src), |
ip6_sprintf(&ip6->ip6_src), |
ip6_sprintf(&ip6->ip6_dst)); |
ip6_sprintf(&ip6->ip6_dst))); |
|
|
goto bad; |
goto bad; |
} |
} |
Line 527 ip6_input(struct mbuf *m) |
|
Line 541 ip6_input(struct mbuf *m) |
|
* working right. |
* working right. |
*/ |
*/ |
struct ifaddr *ifa; |
struct ifaddr *ifa; |
IFADDR_FOREACH(ifa, rcvif) { |
IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { |
if (ifa->ifa_addr == NULL) |
if (ifa->ifa_addr == NULL) |
continue; /* just for safety */ |
continue; /* just for safety */ |
if (ifa->ifa_addr->sa_family != AF_INET6) |
if (ifa->ifa_addr->sa_family != AF_INET6) |
Line 547 ip6_input(struct mbuf *m) |
|
Line 561 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (!ip6_forwarding) { |
if (!ip6_forwarding) { |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 582 ip6_input(struct mbuf *m) |
|
Line 596 ip6_input(struct mbuf *m) |
|
|
|
if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { |
if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { |
#if 0 /*touches NULL pointer*/ |
#if 0 /*touches NULL pointer*/ |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
#endif |
#endif |
return; /* m have already been freed */ |
return; /* m have already been freed */ |
} |
} |
Line 602 ip6_input(struct mbuf *m) |
|
Line 616 ip6_input(struct mbuf *m) |
|
* (non-zero) payload length to the variable plen. |
* (non-zero) payload length to the variable plen. |
*/ |
*/ |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
icmp6_error(m, ICMP6_PARAM_PROB, |
icmp6_error(m, ICMP6_PARAM_PROB, |
ICMP6_PARAMPROB_HEADER, |
ICMP6_PARAMPROB_HEADER, |
(char *)&ip6->ip6_plen - (char *)ip6); |
(char *)&ip6->ip6_plen - (char *)ip6); |
Line 635 ip6_input(struct mbuf *m) |
|
Line 649 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { |
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
in6_ifstat_inc(rcvif, ifs6_in_truncated); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); |
goto bad; |
goto bad; |
} |
} |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
Line 658 ip6_input(struct mbuf *m) |
|
Line 672 ip6_input(struct mbuf *m) |
|
* ip6_mforward() returns a non-zero value, the packet |
* ip6_mforward() returns a non-zero value, the packet |
* must be discarded, else it may be accepted below. |
* must be discarded, else it may be accepted below. |
*/ |
*/ |
if (ip6_mrouter && ip6_mforward(ip6, rcvif, m)) { |
if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
m_freem(m); |
m_freem(m); |
return; |
return; |
Line 686 ip6_input(struct mbuf *m) |
|
Line 700 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 709 ip6_input(struct mbuf *m) |
|
Line 723 ip6_input(struct mbuf *m) |
|
while (nxt != IPPROTO_DONE) { |
while (nxt != IPPROTO_DONE) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
IP6_STATINC(IP6_STAT_TOOMANYHDR); |
IP6_STATINC(IP6_STAT_TOOMANYHDR); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 719 ip6_input(struct mbuf *m) |
|
Line 733 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (m->m_pkthdr.len < off) { |
if (m->m_pkthdr.len < off) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
in6_ifstat_inc(rcvif, ifs6_in_truncated); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); |
goto bad; |
goto bad; |
} |
} |
|
|
if (nxt == IPPROTO_ROUTING) { |
if (nxt == IPPROTO_ROUTING) { |
if (rh_present++) { |
if (rh_present++) { |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(m->m_pkthdr.rcvif, |
|
ifs6_in_hdrerr); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
goto bad; |
goto bad; |
} |
} |
Line 733 ip6_input(struct mbuf *m) |
|
Line 748 ip6_input(struct mbuf *m) |
|
|
|
#ifdef IPSEC |
#ifdef IPSEC |
if (ipsec_used) { |
if (ipsec_used) { |
|
struct m_tag *mtag; |
|
struct tdb_ident *tdbi; |
|
struct secpolicy *sp; |
|
int s, error; |
|
|
/* |
/* |
* enforce IPsec policy checking if we are seeing last |
* enforce IPsec policy checking if we are seeing last |
* header. note that we do not visit this with |
* header. note that we do not visit this with |
Line 740 ip6_input(struct mbuf *m) |
|
Line 760 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if ((inet6sw[ip_protox[nxt]].pr_flags |
if ((inet6sw[ip_protox[nxt]].pr_flags |
& PR_LASTHDR) != 0) { |
& PR_LASTHDR) != 0) { |
int error = ipsec6_input(m); |
/* |
|
* Check if the packet has already had IPsec |
|
* processing done. If so, then just pass it |
|
* along. This tag gets set during AH, ESP, |
|
* etc. input handling, before the packet is |
|
* returned to the ip input queue for delivery. |
|
*/ |
|
mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, |
|
NULL); |
|
s = splsoftnet(); |
|
if (mtag != NULL) { |
|
tdbi = (struct tdb_ident *)(mtag + 1); |
|
sp = ipsec_getpolicy(tdbi, |
|
IPSEC_DIR_INBOUND); |
|
} else { |
|
sp = ipsec_getpolicybyaddr(m, |
|
IPSEC_DIR_INBOUND, IP_FORWARDING, |
|
&error); |
|
} |
|
if (sp != NULL) { |
|
/* |
|
* Check security policy against packet |
|
* attributes. |
|
*/ |
|
error = ipsec_in_reject(sp, m); |
|
KEY_FREESP(&sp); |
|
} else { |
|
/* XXX error stat??? */ |
|
error = EINVAL; |
|
DPRINTF(("ip6_input: no SP, packet" |
|
" discarded\n"));/*XXX*/ |
|
} |
|
splx(s); |
if (error) |
if (error) |
goto bad; |
goto bad; |
} |
} |
Line 797 ip6_getdstifaddr(struct mbuf *m) |
|
Line 849 ip6_getdstifaddr(struct mbuf *m) |
|
* rtalertp - XXX: should be stored more smart way |
* rtalertp - XXX: should be stored more smart way |
*/ |
*/ |
int |
int |
ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, |
ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, |
struct mbuf **mp, int *offp) |
struct mbuf **mp, int *offp) |
{ |
{ |
struct mbuf *m = *mp; |
struct mbuf *m = *mp; |
Line 842 ip6_hopopts_input(u_int32_t *plenp, u_in |
|
Line 894 ip6_hopopts_input(u_int32_t *plenp, u_in |
|
* opthead + hbhlen is located in continuous memory region. |
* opthead + hbhlen is located in continuous memory region. |
*/ |
*/ |
static int |
static int |
ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, |
ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, |
u_int32_t *rtalertp, u_int32_t *plenp) |
u_int32_t *rtalertp, u_int32_t *plenp) |
{ |
{ |
struct ip6_hdr *ip6; |
struct ip6_hdr *ip6; |
Line 1017 ip6_unknown_opt(u_int8_t *optp, struct m |
|
Line 1069 ip6_unknown_opt(u_int8_t *optp, struct m |
|
* you are using IP6_EXTHDR_CHECK() not m_pulldown()) |
* you are using IP6_EXTHDR_CHECK() not m_pulldown()) |
*/ |
*/ |
void |
void |
ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp, |
ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp, |
struct ip6_hdr *ip6, struct mbuf *m) |
struct ip6_hdr *ip6, struct mbuf *m) |
{ |
{ |
#ifdef RFC2292 |
#ifdef RFC2292 |
Line 1522 ip6_delaux(struct mbuf *m) |
|
Line 1574 ip6_delaux(struct mbuf *m) |
|
} |
} |
|
|
#ifdef GATEWAY |
#ifdef GATEWAY |
/* |
/* |
* sysctl helper routine for net.inet.ip6.maxflows. Since |
* sysctl helper routine for net.inet.ip6.maxflows. Since |
* we could reduce this value, call ip6flow_reap(); |
* we could reduce this value, call ip6flow_reap(); |
*/ |
*/ |
static int |
static int |
sysctl_net_inet6_ip6_maxflows(SYSCTLFN_ARGS) |
sysctl_net_inet6_ip6_maxflows(SYSCTLFN_ARGS) |
{ |
{ |
int error; |
int error; |
|
|
error = sysctl_lookup(SYSCTLFN_CALL(rnode)); |
error = sysctl_lookup(SYSCTLFN_CALL(rnode)); |
if (error || newp == NULL) |
if (error || newp == NULL) |
return (error); |
return (error); |
|
|
mutex_enter(softnet_lock); |
mutex_enter(softnet_lock); |
KERNEL_LOCK(1, NULL); |
KERNEL_LOCK(1, NULL); |
|
|
Line 1542 sysctl_net_inet6_ip6_maxflows(SYSCTLFN_A |
|
Line 1594 sysctl_net_inet6_ip6_maxflows(SYSCTLFN_A |
|
|
|
KERNEL_UNLOCK_ONE(NULL); |
KERNEL_UNLOCK_ONE(NULL); |
mutex_exit(softnet_lock); |
mutex_exit(softnet_lock); |
|
|
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
sysctl_net_inet6_ip6_hashsize(SYSCTLFN_ARGS) |
sysctl_net_inet6_ip6_hashsize(SYSCTLFN_ARGS) |
{ |
{ |
int error, tmp; |
int error, tmp; |
struct sysctlnode node; |
struct sysctlnode node; |
|
|
Line 1575 sysctl_net_inet6_ip6_hashsize(SYSCTLFN_A |
|
Line 1627 sysctl_net_inet6_ip6_hashsize(SYSCTLFN_A |
|
* EINVAL if not a power of 2 |
* EINVAL if not a power of 2 |
*/ |
*/ |
error = EINVAL; |
error = EINVAL; |
} |
} |
|
|
return error; |
return error; |
} |
} |
Line 1594 const u_char inet6ctlerrmap[PRC_NCMDS] = |
|
Line 1646 const u_char inet6ctlerrmap[PRC_NCMDS] = |
|
ENOPROTOOPT |
ENOPROTOOPT |
}; |
}; |
|
|
extern int sysctl_net_inet6_addrctlpolicy(SYSCTLFN_ARGS); |
|
|
|
static int |
static int |
sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS) |
sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS) |
{ |
{ |
Line 1761 sysctl_net_inet6_ip6_setup(struct sysctl |
|
Line 1811 sysctl_net_inet6_ip6_setup(struct sysctl |
|
NULL, 0, &ip6_defmcasthlim, 0, |
NULL, 0, &ip6_defmcasthlim, 0, |
CTL_NET, PF_INET6, IPPROTO_IPV6, |
CTL_NET, PF_INET6, IPPROTO_IPV6, |
IPV6CTL_DEFMCASTHLIM, CTL_EOL); |
IPV6CTL_DEFMCASTHLIM, CTL_EOL); |
|
#if NGIF > 0 |
|
sysctl_createv(clog, 0, NULL, NULL, |
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
|
CTLTYPE_INT, "gifhlim", |
|
SYSCTL_DESCR("Default hop limit for a gif tunnel datagram"), |
|
NULL, 0, &ip6_gif_hlim, 0, |
|
CTL_NET, PF_INET6, IPPROTO_IPV6, |
|
IPV6CTL_GIF_HLIM, CTL_EOL); |
|
#endif /* NGIF */ |
sysctl_createv(clog, 0, NULL, NULL, |
sysctl_createv(clog, 0, NULL, NULL, |
CTLFLAG_PERMANENT, |
CTLFLAG_PERMANENT, |
CTLTYPE_STRING, "kame_version", |
CTLTYPE_STRING, "kame_version", |
Line 1795 sysctl_net_inet6_ip6_setup(struct sysctl |
|
Line 1854 sysctl_net_inet6_ip6_setup(struct sysctl |
|
IPV6CTL_V6ONLY, CTL_EOL); |
IPV6CTL_V6ONLY, CTL_EOL); |
sysctl_createv(clog, 0, NULL, NULL, |
sysctl_createv(clog, 0, NULL, NULL, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
|
CTLTYPE_INT, "auto_linklocal", |
|
SYSCTL_DESCR("Default value of per-interface flag for " |
|
"adding an IPv6 link-local address to " |
|
"interfaces when attached"), |
|
NULL, 0, &ip6_auto_linklocal, 0, |
|
CTL_NET, PF_INET6, IPPROTO_IPV6, |
|
IPV6CTL_AUTO_LINKLOCAL, CTL_EOL); |
|
sysctl_createv(clog, 0, NULL, NULL, |
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLTYPE_INT, "anonportmin", |
CTLTYPE_INT, "anonportmin", |
SYSCTL_DESCR("Lowest ephemeral port number to assign"), |
SYSCTL_DESCR("Lowest ephemeral port number to assign"), |
sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0, |
sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0, |
Line 1827 sysctl_net_inet6_ip6_setup(struct sysctl |
|
Line 1895 sysctl_net_inet6_ip6_setup(struct sysctl |
|
#endif /* IPNOPRIVPORTS */ |
#endif /* IPNOPRIVPORTS */ |
sysctl_createv(clog, 0, NULL, NULL, |
sysctl_createv(clog, 0, NULL, NULL, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLTYPE_INT, "auto_linklocal", |
|
SYSCTL_DESCR("Default value of per-interface flag for " |
|
"adding an IPv6 link-local address to " |
|
"interfaces when attached"), |
|
NULL, 0, &ip6_auto_linklocal, 0, |
|
CTL_NET, PF_INET6, IPPROTO_IPV6, |
|
IPV6CTL_AUTO_LINKLOCAL, CTL_EOL); |
|
sysctl_createv(clog, 0, NULL, NULL, |
|
CTLFLAG_PERMANENT|CTLFLAG_READONLY, |
|
CTLTYPE_STRUCT, "addctlpolicy", |
|
SYSCTL_DESCR("Return the current address control" |
|
" policy"), |
|
sysctl_net_inet6_addrctlpolicy, 0, NULL, 0, |
|
CTL_NET, PF_INET6, IPPROTO_IPV6, |
|
IPV6CTL_ADDRCTLPOLICY, CTL_EOL); |
|
sysctl_createv(clog, 0, NULL, NULL, |
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
|
CTLTYPE_INT, "use_tempaddr", |
CTLTYPE_INT, "use_tempaddr", |
SYSCTL_DESCR("Use temporary address"), |
SYSCTL_DESCR("Use temporary address"), |
NULL, 0, &ip6_use_tempaddr, 0, |
NULL, 0, &ip6_use_tempaddr, 0, |
Line 1899 sysctl_net_inet6_ip6_setup(struct sysctl |
|
Line 1950 sysctl_net_inet6_ip6_setup(struct sysctl |
|
NULL, 0, &ip6_mcast_pmtu, 0, |
NULL, 0, &ip6_mcast_pmtu, 0, |
CTL_NET, PF_INET6, IPPROTO_IPV6, |
CTL_NET, PF_INET6, IPPROTO_IPV6, |
CTL_CREATE, CTL_EOL); |
CTL_CREATE, CTL_EOL); |
#ifdef GATEWAY |
#ifdef GATEWAY |
sysctl_createv(clog, 0, NULL, NULL, |
sysctl_createv(clog, 0, NULL, NULL, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, |
CTLTYPE_INT, "maxflows", |
CTLTYPE_INT, "maxflows", |