Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146908230
D54166.1781501514.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D54166.1781501514.diff
View Options
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2518,7 +2518,6 @@
struct pf_state_key *pf_alloc_state_key(int);
int pf_translate(struct pf_pdesc *, struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t, u_int16_t, int);
-int pf_translate_af(struct pf_pdesc *);
bool pf_init_threshold(struct pf_kthreshold *, uint32_t, uint32_t);
uint16_t pf_tagname2tag(const char *);
#ifdef ALTQ
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3605,8 +3605,8 @@
}
}
-int
-pf_translate_af(struct pf_pdesc *pd)
+static int
+pf_translate_af(struct pf_pdesc *pd, struct pf_krule *r)
{
#if defined(INET) && defined(INET6)
struct mbuf *mp;
@@ -3617,6 +3617,21 @@
struct pf_fragment_tag *ftag;
int hlen;
+ if (pd->ttl == 1) {
+ /* We'd generate an ICMP error. Do so now rather than after af translation. */
+ if (pd->af == AF_INET) {
+ pf_send_icmp(pd->m, ICMP_TIMXCEED,
+ ICMP_TIMXCEED_INTRANS, 0, pd->af, r,
+ pd->act.rtableid);
+ } else {
+ pf_send_icmp(pd->m, ICMP6_TIME_EXCEEDED,
+ ICMP6_TIME_EXCEED_TRANSIT, 0, pd->af, r,
+ pd->act.rtableid);
+ }
+
+ return (-1);
+ }
+
hlen = pd->naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
/* trim the old header */
@@ -9186,7 +9201,7 @@
if (pd->dir == PF_IN) {
if (ip->ip_ttl <= IPTTLDEC) {
- if (r->rt != PF_DUPTO)
+ if (r->rt != PF_DUPTO && pd->naf == pd->af)
pf_send_icmp(m0, ICMP_TIMXCEED,
ICMP_TIMXCEED_INTRANS, 0, pd->af, r,
pd->act.rtableid);
@@ -9511,7 +9526,7 @@
if (pd->dir == PF_IN) {
if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
- if (r->rt != PF_DUPTO)
+ if (r->rt != PF_DUPTO && pd->naf == pd->af)
pf_send_icmp(m0, ICMP6_TIME_EXCEEDED,
ICMP6_TIME_EXCEED_TRANSIT, 0, pd->af, r,
pd->act.rtableid);
@@ -11354,7 +11369,7 @@
*m0 = NULL;
break;
case PF_AFRT:
- if (pf_translate_af(&pd)) {
+ if (pf_translate_af(&pd, r)) {
*m0 = pd.m;
action = PF_DROP;
break;
diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py
--- a/tests/sys/netpfil/pf/nat64.py
+++ b/tests/sys/netpfil/pf/nat64.py
@@ -329,6 +329,42 @@
for r in packets:
r.show()
+ @pytest.mark.require_user("root")
+ @pytest.mark.require_progs(["scapy"])
+ def test_ttl_one(self):
+ """
+ PR 291527: invalid ICMP error generated by nat64 router
+ """
+ ifname = self.vnet.iface_alias_map["if1"].name
+ gw_mac = self.vnet.iface_alias_map["if1"].epairb.ether
+ ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")
+
+ import scapy.all as sp
+
+ pkt = sp.Ether(dst=gw_mac) \
+ / sp.IPv6(dst="64:ff9b::198.51.100.2", hlim=1) \
+ / sp.SCTP(sport=1111, dport=2222) \
+ / sp.SCTPChunkInit(init_tag=1, n_in_streams=1, n_out_streams=1, \
+ a_rwnd=1500, params=[])
+ s = DelayedSend(pkt, sendif=ifname)
+
+ found = False
+ packets = sp.sniff(iface=ifname, timeout=5)
+ for r in packets:
+ print("Reply packet:")
+ r.show()
+
+ ip6 = r.getlayer(sp.IPv6)
+ icmp6 = r.getlayer(sp.ICMPv6TimeExceeded)
+ if not ip6 or not icmp6:
+ continue
+ assert ip6.src == "2001:db8::1"
+ assert ip6.dst == "2001:db8::2"
+ assert icmp6.type == 3 # Time exceeded
+ assert icmp6.code == 0 # hop limit exceeded in transit
+ found = True
+ assert found
+
@pytest.mark.require_user("root")
@pytest.mark.require_progs(["scapy"])
def test_ttl_zero(self):
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jun 15, 5:31 AM (2 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28903113
Default Alt Text
D54166.1781501514.diff (3 KB)
Attached To
Mode
D54166: pf: handle TTL expired during nat64
Attached
Detach File
Event Timeline
Log In to Comment