Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115661567
D47804.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D47804.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
@@ -1762,6 +1762,13 @@
#define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */
#define PFR_KENTRY_HIWAT 200000 /* Number of table entries */
+struct pf_fragment_tag {
+ uint16_t ft_hdrlen; /* header length of reassembled pkt */
+ uint16_t ft_extoff; /* last extension header offset or 0 */
+ uint16_t ft_maxlen; /* maximum fragment payload length */
+ uint32_t ft_id; /* fragment id */
+};
+
/*
* Limit the length of the fragment queue traversal. Remember
* search entry points based on the fragment offset.
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
@@ -3440,6 +3440,8 @@
struct ip *ip4;
struct ip6_hdr *ip6;
struct icmp6_hdr *icmp;
+ struct m_tag *mtag;
+ struct pf_fragment_tag *ftag;
int hlen;
hlen = pd->naf == AF_INET ? sizeof(*ip4) : sizeof(*ip6);
@@ -3460,7 +3462,6 @@
ip4->ip_hl = hlen >> 2;
ip4->ip_len = htons(hlen + (pd->tot_len - pd->off));
ip_fillid(ip4);
- ip4->ip_off = htons(IP_DF);
ip4->ip_ttl = pd->ttl;
ip4->ip_p = pd->proto;
ip4->ip_src = pd->nsaddr.v4;
@@ -3482,6 +3483,19 @@
ip6->ip6_dst = pd->ndaddr.v6;
pd->src = (struct pf_addr *)&ip6->ip6_src;
pd->dst = (struct pf_addr *)&ip6->ip6_dst;
+
+ /*
+ * If we're dealing with a reassembled packet we need to adjust
+ * the header length from the IPv4 header size to IPv6 header
+ * size.
+ */
+ mtag = m_tag_find(pd->m, PACKET_TAG_PF_REASSEMBLED, NULL);
+ if (mtag) {
+ ftag = (struct pf_fragment_tag *)(mtag + 1);
+ ftag->ft_hdrlen = sizeof(*ip6);
+ ftag->ft_maxlen -= sizeof(struct ip6_hdr) -
+ sizeof(struct ip) + sizeof(struct ip6_frag);
+ }
break;
default:
return (-1);
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -103,13 +103,6 @@
TAILQ_HEAD(pf_fragq, pf_frent) fr_queue;
};
-struct pf_fragment_tag {
- uint16_t ft_hdrlen; /* header length of reassembled pkt */
- uint16_t ft_extoff; /* last extension header offset or 0 */
- uint16_t ft_maxlen; /* maximum fragment payload length */
- uint32_t ft_id; /* fragment id */
-};
-
VNET_DEFINE_STATIC(struct mtx, pf_frag_mtx);
#define V_pf_frag_mtx VNET(pf_frag_mtx)
#define PF_FRAG_LOCK() mtx_lock(&V_pf_frag_mtx)
@@ -750,8 +743,12 @@
struct ip *ip = mtod(m, struct ip *);
struct pf_frent *frent;
struct pf_fragment *frag;
+ struct m_tag *mtag;
+ struct pf_fragment_tag *ftag;
struct pf_fragment_cmp key;
uint16_t total, hdrlen;
+ uint32_t frag_id;
+ uint16_t maxlen;
/* Get an entry for the fragment queue */
if ((frent = pf_create_fragment(reason)) == NULL)
@@ -784,6 +781,8 @@
TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_len;
hdrlen = frent->fe_hdrlen;
+ maxlen = frag->fr_maxlen;
+ frag_id = frag->fr_id;
m = *m0 = pf_join_fragment(frag);
frag = NULL;
@@ -795,6 +794,19 @@
m->m_pkthdr.len = plen;
}
+ if ((mtag = m_tag_get(PACKET_TAG_PF_REASSEMBLED,
+ sizeof(struct pf_fragment_tag), M_NOWAIT)) == NULL) {
+ REASON_SET(reason, PFRES_SHORT);
+ /* PF_DROP requires a valid mbuf *m0 in pf_test() */
+ return (PF_DROP);
+ }
+ ftag = (struct pf_fragment_tag *)(mtag + 1);
+ ftag->ft_hdrlen = hdrlen;
+ ftag->ft_extoff = 0;
+ ftag->ft_maxlen = maxlen;
+ ftag->ft_id = frag_id;
+ m_tag_prepend(m, mtag);
+
ip = mtod(m, struct ip *);
ip->ip_sum = pf_cksum_fixup(ip->ip_sum, ip->ip_len,
htons(hdrlen + total), 0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 27, 6:00 PM (8 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17820571
Default Alt Text
D47804.diff (3 KB)
Attached To
Mode
D47804: pf: handle fragmentation for nat64
Attached
Detach File
Event Timeline
Log In to Comment