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 | |||||