Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/ipfw/ip_fw_pfil.c
Show First 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | again: | ||||
case IP_FW_PASS: | case IP_FW_PASS: | ||||
/* next_hop may be set by ipfw_chk */ | /* next_hop may be set by ipfw_chk */ | ||||
if (args.next_hop == NULL && args.next_hop6 == NULL) | if (args.next_hop == NULL && args.next_hop6 == NULL) | ||||
break; /* pass */ | break; /* pass */ | ||||
#if (!defined(INET6) && !defined(INET)) | #if (!defined(INET6) && !defined(INET)) | ||||
ret = EACCES; | ret = EACCES; | ||||
#else | #else | ||||
{ | { | ||||
struct m_tag *fwd_tag; | |||||
size_t len; | |||||
KASSERT(args.next_hop == NULL || args.next_hop6 == NULL, | KASSERT(args.next_hop == NULL || args.next_hop6 == NULL, | ||||
("%s: both next_hop=%p and next_hop6=%p not NULL", __func__, | ("%s: both next_hop=%p and next_hop6=%p not NULL", __func__, | ||||
args.next_hop, args.next_hop6)); | args.next_hop, args.next_hop6)); | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (args.next_hop6 != NULL) | |||||
len = sizeof(struct sockaddr_in6); | |||||
#endif | |||||
#ifdef INET | |||||
if (args.next_hop != NULL) | |||||
len = sizeof(struct sockaddr_in); | |||||
#endif | |||||
/* Incoming packets should not be tagged so we do not | |||||
* m_tag_find. Outgoing packets may be tagged, so we | |||||
* reuse the tag if present. | |||||
*/ | |||||
fwd_tag = (dir == DIR_IN) ? NULL : | |||||
m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL); | |||||
if (fwd_tag != NULL) { | |||||
m_tag_unlink(*m0, fwd_tag); | |||||
} else { | |||||
fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, len, | |||||
M_NOWAIT); | |||||
if (fwd_tag == NULL) { | |||||
ret = EACCES; | |||||
break; /* i.e. drop */ | |||||
} | |||||
} | |||||
#ifdef INET6 | |||||
if (args.next_hop6 != NULL) { | if (args.next_hop6 != NULL) { | ||||
struct sockaddr_in6 *sa6; | if (ip6_set_fwdtag(*m0, args.next_hop6, 0)) { | ||||
sa6 = (struct sockaddr_in6 *)(fwd_tag + 1); | |||||
bcopy(args.next_hop6, sa6, len); | |||||
/* | |||||
* If nh6 address is link-local we should convert | |||||
* it to kernel internal form before doing any | |||||
* comparisons. | |||||
*/ | |||||
if (sa6_embedscope(sa6, V_ip6_use_defzone) != 0) { | |||||
ret = EACCES; | ret = EACCES; | ||||
break; | break; | ||||
} | } | ||||
if (in6_localip(&sa6->sin6_addr)) | |||||
(*m0)->m_flags |= M_FASTFWD_OURS; | |||||
(*m0)->m_flags |= M_IP6_NEXTHOP; | |||||
} | } | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
if (args.next_hop != NULL) { | if (args.next_hop != NULL) { | ||||
bcopy(args.next_hop, (fwd_tag+1), len); | if (ip_set_fwdtag(*m0, args.next_hop, 0)) { | ||||
if (in_localip(args.next_hop->sin_addr)) | ret = EACCES; | ||||
(*m0)->m_flags |= M_FASTFWD_OURS; | break; | ||||
(*m0)->m_flags |= M_IP_NEXTHOP; | |||||
} | } | ||||
} | |||||
#endif | #endif | ||||
m_tag_prepend(*m0, fwd_tag); | |||||
} | } | ||||
#endif /* INET || INET6 */ | #endif /* INET || INET6 */ | ||||
break; | break; | ||||
case IP_FW_DENY: | case IP_FW_DENY: | ||||
ret = EACCES; | ret = EACCES; | ||||
break; /* i.e. drop */ | break; /* i.e. drop */ | ||||
▲ Show 20 Lines • Show All 345 Lines • Show Last 20 Lines |