Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150659123
D22631.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D22631.diff
View Options
Index: head/sys/modules/ipfw_nat64/Makefile
===================================================================
--- head/sys/modules/ipfw_nat64/Makefile
+++ head/sys/modules/ipfw_nat64/Makefile
@@ -7,6 +7,7 @@
SRCS+= nat64clat.c nat64clat_control.c
SRCS+= nat64lsn.c nat64lsn_control.c
SRCS+= nat64stl.c nat64stl_control.c
+SRCS+= opt_ipstealth.h
CFLAGS+= -I${SRCTOP}/sys/contrib/ck/include
Index: head/sys/netpfil/ipfw/nat64/nat64_translate.c
===================================================================
--- head/sys/netpfil/ipfw/nat64/nat64_translate.c
+++ head/sys/netpfil/ipfw/nat64/nat64_translate.c
@@ -29,6 +29,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ipstealth.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/counter.h>
@@ -101,14 +103,39 @@
.output = nat64_direct_output,
.output_one = nat64_direct_output_one
};
-VNET_DEFINE_STATIC(const struct nat64_methods *, nat64out) = &nat64_netisr;
-#define V_nat64out VNET(nat64out)
+/* These variables should be initialized explicitly on module loading */
+VNET_DEFINE_STATIC(const struct nat64_methods *, nat64out);
+VNET_DEFINE_STATIC(const int *, nat64ipstealth);
+VNET_DEFINE_STATIC(const int *, nat64ip6stealth);
+#define V_nat64out VNET(nat64out)
+#define V_nat64ipstealth VNET(nat64ipstealth)
+#define V_nat64ip6stealth VNET(nat64ip6stealth)
+
+static const int stealth_on = 1;
+#ifndef IPSTEALTH
+static const int stealth_off = 0;
+#endif
+
void
nat64_set_output_method(int direct)
{
- V_nat64out = direct != 0 ? &nat64_direct: &nat64_netisr;
+ if (direct != 0) {
+ V_nat64out = &nat64_direct;
+#ifdef IPSTEALTH
+ /* Honor corresponding variables, if IPSTEALTH is defined */
+ V_nat64ipstealth = &V_ipstealth;
+ V_nat64ip6stealth = &V_ip6stealth;
+#else
+ /* otherwise we need to decrement HLIM/TTL for direct case */
+ V_nat64ipstealth = V_nat64ip6stealth = &stealth_off;
+#endif
+ } else {
+ V_nat64out = &nat64_netisr;
+ /* Leave TTL/HLIM decrementing to forwarding code */
+ V_nat64ipstealth = V_nat64ip6stealth = &stealth_on;
+ }
}
int
@@ -486,8 +513,7 @@
ip->ip_tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
ip->ip_len = htons(sizeof(*ip) + plen);
ip->ip_ttl = ip6->ip6_hlim;
- /* Forwarding code will decrement TTL for netisr based output. */
- if (V_nat64out == &nat64_direct)
+ if (*V_nat64ip6stealth == 0)
ip->ip_ttl -= IPV6_HLIMDEC;
ip->ip_sum = 0;
ip->ip_p = (proto == IPPROTO_ICMPV6) ? IPPROTO_ICMP: proto;
@@ -623,18 +649,18 @@
struct icmp6_hdr *icmp6;
struct ip6_hdr *ip6, *oip6;
struct mbuf *n;
- int len, plen;
+ int len, plen, proto;
len = 0;
- plen = nat64_getlasthdr(m, &len);
- if (plen < 0) {
+ proto = nat64_getlasthdr(m, &len);
+ if (proto < 0) {
DPRINTF(DP_DROPS, "mbuf isn't contigious");
goto freeit;
}
/*
* Do not send ICMPv6 in reply to ICMPv6 errors.
*/
- if (plen == IPPROTO_ICMPV6) {
+ if (proto == IPPROTO_ICMPV6) {
if (m->m_len < len + sizeof(*icmp6)) {
DPRINTF(DP_DROPS, "mbuf isn't contigious");
goto freeit;
@@ -646,6 +672,21 @@
"ICMPv6 errors");
goto freeit;
}
+ /*
+ * If there are extra headers between IPv6 and ICMPv6,
+ * strip off them.
+ */
+ if (len > sizeof(struct ip6_hdr)) {
+ /*
+ * NOTE: ipfw_chk already did m_pullup() and it is
+ * expected that data is contigious from the start
+ * of IPv6 header up to the end of ICMPv6 header.
+ */
+ bcopy(mtod(m, caddr_t),
+ mtodo(m, len - sizeof(struct ip6_hdr)),
+ sizeof(struct ip6_hdr));
+ m_adj(m, len - sizeof(struct ip6_hdr));
+ }
}
/*
if (icmp6_ratelimit(&ip6->ip6_src, type, code))
@@ -687,7 +728,19 @@
n->m_len = n->m_pkthdr.len = sizeof(struct ip6_hdr) + plen;
oip6 = mtod(n, struct ip6_hdr *);
- oip6->ip6_src = ip6->ip6_dst;
+ /*
+ * Make IPv6 source address selection for reflected datagram.
+ * nat64_check_ip6() doesn't allow scoped addresses, therefore
+ * we use zero scopeid.
+ */
+ if (in6_selectsrc_addr(M_GETFIB(n), &ip6->ip6_src, 0,
+ n->m_pkthdr.rcvif, &oip6->ip6_src, NULL) != 0) {
+ /*
+ * Failed to find proper source address, drop the packet.
+ */
+ m_freem(n);
+ goto freeit;
+ }
oip6->ip6_dst = ip6->ip6_src;
oip6->ip6_nxt = IPPROTO_ICMPV6;
oip6->ip6_flow = 0;
@@ -1182,7 +1235,7 @@
ip = mtod(m, struct ip*);
- if (ip->ip_ttl <= IPTTLDEC) {
+ if (*V_nat64ipstealth == 0 && ip->ip_ttl <= IPTTLDEC) {
nat64_icmp_reflect(m, ICMP_TIMXCEED,
ICMP_TIMXCEED_INTRANS, 0, &cfg->stats, logdata);
return (NAT64RETURN);
@@ -1229,8 +1282,7 @@
ip6.ip6_flow = htonl(ip->ip_tos << 20);
ip6.ip6_vfc |= IPV6_VERSION;
ip6.ip6_hlim = ip->ip_ttl;
- /* Forwarding code will decrement TTL for netisr based output. */
- if (V_nat64out == &nat64_direct)
+ if (*V_nat64ipstealth == 0)
ip6.ip6_hlim -= IPTTLDEC;
ip6.ip6_plen = htons(plen);
ip6.ip6_nxt = (proto == IPPROTO_ICMP) ? IPPROTO_ICMPV6: proto;
@@ -1533,7 +1585,7 @@
return (NAT64MFREE);
}
- if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
+ if (*V_nat64ip6stealth == 0 && ip6->ip6_hlim <= IPV6_HLIMDEC) {
nat64_icmp6_reflect(m, ICMP6_TIME_EXCEEDED,
ICMP6_TIME_EXCEED_TRANSIT, 0, &cfg->stats, logdata);
return (NAT64RETURN);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 4:09 AM (4 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30797649
Default Alt Text
D22631.diff (5 KB)
Attached To
Mode
D22631: Use IPv6 SAS algorithm for reflected ICMPv6 datagrams in NAT64
Attached
Detach File
Event Timeline
Log In to Comment