Page MenuHomeFreeBSD

D47804.diff
No OneTemporary

D47804.diff

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

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)

Event Timeline