Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142765262
D1767.id3714.vs3621.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
D1767.id3714.vs3621.diff
View Options
Index: sys/net/pfvar.h
===================================================================
--- sys/net/pfvar.h
+++ sys/net/pfvar.h
@@ -1588,6 +1588,7 @@
int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
void pf_normalize_init(void);
+int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *mtag);
void pf_normalize_cleanup(void);
int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *,
struct pf_pdesc *);
Index: sys/netpfil/pf/pf.h
===================================================================
--- sys/netpfil/pf/pf.h
+++ sys/netpfil/pf/pf.h
@@ -43,7 +43,7 @@
#endif
#endif
-enum { PF_INOUT, PF_IN, PF_OUT };
+enum { PF_INOUT, PF_IN, PF_OUT, PF_FWD };
enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
Index: sys/netpfil/pf/pf.c
===================================================================
--- sys/netpfil/pf/pf.c
+++ sys/netpfil/pf/pf.c
@@ -5496,7 +5496,7 @@
goto bad;
if (oifp != ifp) {
- if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
+ if (pf_test6(PF_FWD, ifp, &m0, NULL) != PF_PASS)
goto bad;
else if (m0 == NULL)
goto done;
@@ -6054,15 +6054,21 @@
struct pfi_kif *kif;
u_short action, reason = 0, log = 0;
struct mbuf *m = *m0, *n = NULL;
+ struct m_tag *mtag;
struct ip6_hdr *h = NULL;
struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr;
struct pf_state *s = NULL;
struct pf_ruleset *ruleset = NULL;
struct pf_pdesc pd;
int off, terminal = 0, dirndx, rh_cnt = 0;
+ int fwdir = dir;
+
M_ASSERTPKTHDR(m);
+ if (ifp != m->m_pkthdr.rcvif)
+ fwdir = PF_FWD;
+
if (!V_pf_status.running)
return (PF_PASS);
@@ -6424,6 +6430,11 @@
if (s)
PF_STATE_UNLOCK(s);
+ /* if reassembled packet passed, create new fragments */
+ if (action == PF_PASS && *m0 && fwdir == PF_FWD &&
+ (mtag = m_tag_find(m, PACKET_TAG_PF_REASSEMBLED, NULL)) != NULL)
+ action = pf_refragment6(ifp, m0, mtag);
+
return (action);
}
#endif /* INET6 */
Index: sys/netpfil/pf/pf_mtag.h
===================================================================
--- sys/netpfil/pf/pf_mtag.h
+++ sys/netpfil/pf/pf_mtag.h
@@ -39,6 +39,7 @@
#define PF_TAG_TRANSLATE_LOCALHOST 0x04
#define PF_PACKET_LOOPED 0x08
#define PF_FASTFWD_OURS_PRESENT 0x10
+#define PACKET_TAG_PF_REASSEMBLED 0x20 /* pf reassembled ipv6 packet */
struct pf_mtag {
void *hdr; /* saved hdr pos in mbuf, for ECN */
Index: sys/netpfil/pf/pf_norm.c
===================================================================
--- sys/netpfil/pf/pf_norm.c
+++ sys/netpfil/pf/pf_norm.c
@@ -675,6 +675,8 @@
struct pf_frent *frent;
struct pf_fragment *frag;
struct pf_fragment_cmp key;
+ struct m_tag *mtag;
+ struct pf_fragment_tag *ftag;
int off;
u_int16_t total, maxlen;
u_int8_t proto;
@@ -748,6 +750,15 @@
m->m_pkthdr.len = plen;
}
+ if ((mtag = m_tag_get(PACKET_TAG_PF_REASSEMBLED, sizeof(struct
+ pf_fragment_tag), M_NOWAIT)) == NULL)
+ goto fail;
+ ftag = (struct pf_fragment_tag *)(mtag + 1);
+ ftag->ft_hdrlen = hdrlen;
+ ftag->ft_extoff = extoff;
+ ftag->ft_maxlen = maxlen;
+ m_tag_prepend(m, mtag);
+
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(hdrlen - sizeof(struct ip6_hdr) + total);
if (extoff) {
@@ -1082,6 +1093,76 @@
}
int
+pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag)
+{
+ struct mbuf *m = *m0, *t;
+ struct pf_fragment_tag *ftag = (struct pf_fragment_tag *)(mtag + 1);
+ struct pf_pdesc pd;
+ u_int16_t hdrlen, extoff, maxlen;
+ u_int8_t proto;
+ int error, action;
+
+ hdrlen = ftag->ft_hdrlen;
+ extoff = ftag->ft_extoff;
+ maxlen = ftag->ft_maxlen;
+ m_tag_delete(m, mtag);
+ mtag = NULL;
+ ftag = NULL;
+
+ if (extoff) {
+ int off;
+
+ /* Use protocol from next field of last extension header */
+ if ((m = m_getptr(m, extoff + offsetof(struct ip6_ext,
+ ip6e_nxt), &off)) == NULL)
+ panic("pf_refragment6: short mbuf chain");
+ proto = *(mtod(m, caddr_t) + off);
+ *(mtod(m, caddr_t) + off) = IPPROTO_FRAGMENT;
+ m = *m0;
+ } else {
+ struct ip6_hdr *hdr;
+
+ hdr = mtod(m, struct ip6_hdr *);
+ proto = hdr->ip6_nxt;
+ hdr->ip6_nxt = IPPROTO_FRAGMENT;
+ }
+
+ /*
+ * Maxlen may be less than 8 iff there was only a single
+ * fragment. As it was fragmented before, add a fragment
+ * header also for a single fragment. If total or maxlen
+ * is less than 8, ip6_fragment() will return EMSGSIZE and
+ * we drop the packet.
+ */
+
+ error = ip6_fragment(ifp, m, hdrlen, proto, maxlen);
+ m = (*m0)->m_nextpkt;
+ (*m0)->m_nextpkt = NULL;
+ if (error == 0) {
+ /* The first mbuf contains the unfragmented packet */
+ m_freem(*m0);
+ *m0 = NULL;
+ action = PF_PASS;
+ } else {
+ /* Drop expects an mbuf to free */
+ DPFPRINTF(("refragment error %d", error));
+ action = PF_DROP;
+ }
+ for (t = m; m; m = t) {
+ t = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ memset(&pd, 0, sizeof(pd));
+ pd.pf_mtag = pf_find_mtag(m);
+ if (error == 0)
+ ip6_forward(m, 0);
+ else
+ m_freem(m);
+ }
+
+ return (action);
+}
+
+int
pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
struct pf_pdesc *pd)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 24, 8:20 AM (6 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27895205
Default Alt Text
D1767.id3714.vs3621.diff (5 KB)
Attached To
Mode
D1767: Refragment packets after defragmenting them in PF
Attached
Detach File
Event Timeline
Log In to Comment