Don't reassemble ipv6 fragments, instead treat the first fragment as a regular
packet (subject to filtering rules), and pass subsequent fragments in the same group unconditionally.
This commit is contained in:
parent
1253c8ab5f
commit
b16498773e
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: npf_handler.c,v 1.36 2017/01/29 00:15:54 christos Exp $ */
|
||||
/* $NetBSD: npf_handler.c,v 1.37 2017/02/19 20:27:22 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.36 2017/01/29 00:15:54 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.37 2017/02/19 20:27:22 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -129,7 +129,7 @@ npf_packet_handler(npf_t *npf, struct mbuf **mp, ifnet_t *ifp, int di)
|
||||
npf_conn_t *con;
|
||||
npf_rule_t *rl;
|
||||
npf_rproc_t *rp;
|
||||
int error, decision;
|
||||
int error, decision, flags;
|
||||
uint32_t ntag;
|
||||
npf_match_info_t mi;
|
||||
|
||||
@ -155,9 +155,17 @@ npf_packet_handler(npf_t *npf, struct mbuf **mp, ifnet_t *ifp, int di)
|
||||
rp = NULL;
|
||||
|
||||
/* Cache everything. Determine whether it is an IP fragment. */
|
||||
if (__predict_false(npf_cache_all(&npc) & NPC_IPFRAG)) {
|
||||
flags = npf_cache_all(&npc);
|
||||
if (__predict_false(flags & NPC_IPFRAG)) {
|
||||
/*
|
||||
* Pass to IPv4 or IPv6 reassembly mechanism.
|
||||
* We pass IPv6 fragments unconditionally
|
||||
* The first IPv6 fragment is not marked as such
|
||||
* and passes through the filter
|
||||
*/
|
||||
if (flags & NPC_IP6)
|
||||
return 0;
|
||||
/*
|
||||
* Pass to IPv4 reassembly mechanism.
|
||||
*/
|
||||
error = npf_reassembly(npf, &npc, mp);
|
||||
if (error) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: npf_inet.c,v 1.36 2016/12/26 23:05:06 christos Exp $ */
|
||||
/* $NetBSD: npf_inet.c,v 1.37 2017/02/19 20:27:22 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.36 2016/12/26 23:05:06 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.37 2017/02/19 20:27:22 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
@ -355,6 +355,7 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *nbuf)
|
||||
case (IPV6_VERSION >> 4): {
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_ext *ip6e;
|
||||
struct ip6_frag *ip6f;
|
||||
size_t off, hlen;
|
||||
|
||||
ip6 = nbuf_ensure_contig(nbuf, sizeof(struct ip6_hdr));
|
||||
@ -387,8 +388,21 @@ npf_cache_ip(npf_cache_t *npc, nbuf_t *nbuf)
|
||||
hlen = (ip6e->ip6e_len + 1) << 3;
|
||||
break;
|
||||
case IPPROTO_FRAGMENT:
|
||||
ip6f = nbuf_ensure_contig(nbuf, sizeof(*ip6f));
|
||||
if (ip6f == NULL)
|
||||
return 0;
|
||||
/*
|
||||
* We treat the first fragment as a regular
|
||||
* packet and then we pass the rest of the
|
||||
* fragments unconditionally. This way if
|
||||
* the first packet passes the rest will
|
||||
* be able to reassembled, if not they will
|
||||
* be ignored. We can do better later.
|
||||
*/
|
||||
if (ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK) != 0)
|
||||
flags |= NPC_IPFRAG;
|
||||
|
||||
hlen = sizeof(struct ip6_frag);
|
||||
flags |= NPC_IPFRAG;
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
hlen = (ip6e->ip6e_len + 2) << 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user