Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109924605
D47684.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D47684.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
@@ -70,6 +70,8 @@
#ifdef _KERNEL
+#define PF_PFIL_NOREFRAGMENT 0x80000000
+
#if defined(__arm__)
#define PF_WANT_32_TO_64_COUNTER
#endif
@@ -2372,7 +2374,8 @@
struct pf_addr *, struct pf_addr *, sa_family_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);
int pf_max_frag_size(struct mbuf *);
-int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *, bool);
+int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *,
+ struct ifnet *, bool);
#endif /* INET6 */
int pf_multihome_scan_init(int, int, struct pf_pdesc *);
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
@@ -7927,6 +7927,7 @@
struct pf_kstate *s, struct pf_pdesc *pd, struct inpcb *inp)
{
struct mbuf *m0, *md;
+ struct m_tag *mtag;
struct sockaddr_in6 dst;
struct ip6_hdr *ip6;
struct pfi_kkif *nkif = NULL;
@@ -8053,8 +8054,8 @@
}
if (pd->dir == PF_IN) {
- if (pf_test(AF_INET6, PF_OUT, PFIL_FWD, ifp, &m0, inp,
- &pd->act) != PF_PASS) {
+ if (pf_test(AF_INET6, PF_OUT, PFIL_FWD | PF_PFIL_NOREFRAGMENT,
+ ifp, &m0, inp, &pd->act) != PF_PASS) {
SDT_PROBE1(pf, ip6, route_to, drop, __LINE__);
goto bad;
} else if (m0 == NULL) {
@@ -8087,6 +8088,14 @@
*/
if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr))
dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+ mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL);
+ if (mtag != NULL) {
+ int ret;
+ ret = pf_refragment6(ifp, &m0, mtag, ifp, true);
+ SDT_PROBE2(pf, ip6, route_to, output, ifp, ret);
+ goto done;
+ }
+
if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
md = m0;
pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md);
@@ -9474,14 +9483,15 @@
if (s)
PF_STATE_UNLOCK(s);
+out:
#ifdef INET6
/* If reassembled packet passed, create new fragments. */
if (af == AF_INET6 && action == PF_PASS && *m0 && dir == PF_OUT &&
+ (! (pflags & PF_PFIL_NOREFRAGMENT)) &&
(mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)) != NULL)
- action = pf_refragment6(ifp, m0, mtag, pflags & PFIL_FWD);
+ action = pf_refragment6(ifp, m0, mtag, NULL, pflags & PFIL_FWD);
#endif
-out:
pf_sctp_multihome_delayed(&pd, kif, s, action);
return (action);
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
@@ -42,6 +42,7 @@
#include <sys/socket.h>
#include <net/if.h>
+#include <net/if_var.h>
#include <net/vnet.h>
#include <net/pfvar.h>
#include <net/if_pflog.h>
@@ -49,6 +50,8 @@
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/scope6_var.h>
#include <netinet/tcp.h>
@@ -958,7 +961,7 @@
int
pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag,
- bool forward)
+ struct ifnet *rt, bool forward)
{
struct mbuf *m = *m0, *t;
struct ip6_hdr *hdr;
@@ -1029,16 +1032,27 @@
m->m_flags |= M_SKIP_FIREWALL;
memset(&pd, 0, sizeof(pd));
pd.pf_mtag = pf_find_mtag(m);
- if (error == 0)
- if (forward) {
- MPASS(m->m_pkthdr.rcvif != NULL);
- ip6_forward(m, 0);
- } else {
- (void)ip6_output(m, NULL, NULL, 0, NULL, NULL,
- NULL);
- }
- else
+ if (error != 0) {
m_freem(m);
+ continue;
+ }
+ if (rt != NULL) {
+ struct sockaddr_in6 dst;
+ hdr = mtod(m, struct ip6_hdr *);
+
+ bzero(&dst, sizeof(dst));
+ dst.sin6_family = AF_INET6;
+ dst.sin6_len = sizeof(dst);
+ dst.sin6_addr = hdr->ip6_dst;
+
+ nd6_output_ifp(rt, rt, m, &dst, NULL);
+ } else if (forward) {
+ MPASS(m->m_pkthdr.rcvif != NULL);
+ ip6_forward(m, 0);
+ } else {
+ (void)ip6_output(m, NULL, NULL, 0, NULL, NULL,
+ NULL);
+ }
}
return (action);
diff --git a/tests/sys/netpfil/pf/fragmentation_pass.sh b/tests/sys/netpfil/pf/fragmentation_pass.sh
--- a/tests/sys/netpfil/pf/fragmentation_pass.sh
+++ b/tests/sys/netpfil/pf/fragmentation_pass.sh
@@ -155,6 +155,75 @@
pft_cleanup
}
+atf_test_case "v6_route_to" "cleanup"
+v6_route_to_head()
+{
+ atf_set descr 'Test IPv6 reassembly combined with route-to'
+ atf_set require.user root
+}
+
+v6_route_to_body()
+{
+ pft_init
+}
+
+v6_route_to_cleanup()
+{
+ pft_cleanup
+
+ epair_send=$(vnet_mkepair)
+ epair_link=$(vnet_mkepair)
+
+ vnet_mkjail alcatraz ${epair_send}b ${epair_link}a
+ vnet_mkjail singsing ${epair_link}b
+
+ ifconfig ${epair_send}a inet6 2001:db8:42::1/64 no_dad up
+
+ jexec alcatraz ifconfig ${epair_send}b inet6 2001:db8:42::2/64 no_dad up
+ jexec alcatraz ifconfig ${epair_link}a inet6 2001:db8:43::2/64 no_dad up
+ jexec alcatraz sysctl net.inet6.ip6.forwarding=1
+
+ jexec singsing ifconfig ${epair_link}b inet6 2001:db8:43::3/64 no_dad up
+ jexec singsing route add -6 2001:db8:42::/64 2001:db8:43::2
+ route add -6 2001:db8:43::/64 2001:db8:42::2
+
+ jexec alcatraz ifconfig ${epair_send}b inet6 -ifdisabled
+ jexec alcatraz ifconfig ${epair_link}a inet6 -ifdisabled
+ jexec singsing ifconfig ${epair_link}b inet6 -ifdisabled
+ ifconfig ${epair_send}a inet6 -ifdisabled
+
+ jexec alcatraz pfctl -e
+ pft_set_rules alcatraz \
+ "set reassemble yes" \
+ "pass" \
+ "pass in route-to (${epair_link}a 2001:db8:43::3) inet6 proto icmp6 from any to 2001:db8:43::3 keep state"
+
+ # Forwarding test
+ atf_check -s exit:0 -o ignore \
+ ping -6 -c 1 2001:db8:43::3
+
+ atf_check -s exit:0 -o ignore \
+ ping -6 -c 1 -s 4500 2001:db8:43::3
+
+ atf_check -s exit:0 -o ignore\
+ ping -6 -c 1 -b 70000 -s 65000 2001:db8:43::3
+
+ # Now test this without fragmentation
+ pft_set_rules alcatraz \
+ "set reassemble no" \
+ "pass" \
+ "pass in route-to (${epair_link}a 2001:db8:43::3) inet6 proto icmp6 from any to 2001:db8:43::3 keep state"
+
+ atf_check -s exit:0 -o ignore \
+ ping -6 -c 1 2001:db8:43::3
+
+ atf_check -s exit:0 -o ignore \
+ ping -6 -c 1 -s 4500 2001:db8:43::3
+
+ atf_check -s exit:0 -o ignore\
+ ping -6 -c 1 -b 70000 -s 65000 2001:db8:43::3
+}
+
atf_test_case "mtu_diff" "cleanup"
mtu_diff_head()
{
@@ -544,6 +613,7 @@
{
atf_add_test_case "too_many_fragments"
atf_add_test_case "v6"
+ atf_add_test_case "v6_route_to"
atf_add_test_case "mtu_diff"
atf_add_test_case "overreplace"
atf_add_test_case "overindex"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 12, 7:28 AM (18 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16607855
Default Alt Text
D47684.diff (6 KB)
Attached To
Mode
D47684: pf: handle IPv6 fragmentation for route-to
Attached
Detach File
Event Timeline
Log In to Comment