Skip to content

Commit 902d6a4

Browse files
Subash Abhinov Kasiviswanathanummakynes
authored andcommitted
netfilter: nf_defrag: Skip defrag if NOTRACK is set
conntrack defrag is needed only if some module like CONNTRACK or NAT explicitly requests it. For plain forwarding scenarios, defrag is not needed and can be skipped if NOTRACK is set in a rule. Since conntrack defrag is currently higher priority than raw table, setting NOTRACK is not sufficient. We need to move raw to a higher priority for iptables only. This is achieved by introducing a module parameter "raw_before_defrag" which allows to change the priority of raw table to place it before defrag. By default, the parameter is disabled and the priority of raw table is NF_IP_PRI_RAW to support legacy behavior. If the module parameter is enabled, then the priority of the raw table is set to NF_IP_PRI_RAW_BEFORE_DEFRAG. Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 5ed001b commit 902d6a4

6 files changed

Lines changed: 30 additions & 3 deletions

File tree

include/uapi/linux/netfilter_ipv4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
enum nf_ip_hook_priorities {
5959
NF_IP_PRI_FIRST = INT_MIN,
60+
NF_IP_PRI_RAW_BEFORE_DEFRAG = -450,
6061
NF_IP_PRI_CONNTRACK_DEFRAG = -400,
6162
NF_IP_PRI_RAW = -300,
6263
NF_IP_PRI_SELINUX_FIRST = -225,

include/uapi/linux/netfilter_ipv6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262

6363
enum nf_ip6_hook_priorities {
6464
NF_IP6_PRI_FIRST = INT_MIN,
65+
NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450,
6566
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
6667
NF_IP6_PRI_RAW = -300,
6768
NF_IP6_PRI_SELINUX_FIRST = -225,

net/ipv4/netfilter/iptable_raw.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
55
*/
6+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
67
#include <linux/module.h>
78
#include <linux/netfilter_ipv4/ip_tables.h>
89
#include <linux/slab.h>
@@ -12,7 +13,11 @@
1213

1314
static int __net_init iptable_raw_table_init(struct net *net);
1415

15-
static const struct xt_table packet_raw = {
16+
static bool raw_before_defrag __read_mostly;
17+
MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag");
18+
module_param(raw_before_defrag, bool, 0000);
19+
20+
static struct xt_table packet_raw = {
1621
.name = "raw",
1722
.valid_hooks = RAW_VALID_HOOKS,
1823
.me = THIS_MODULE,
@@ -64,6 +69,12 @@ static int __init iptable_raw_init(void)
6469
{
6570
int ret;
6671

72+
if (raw_before_defrag) {
73+
packet_raw.priority = NF_IP_PRI_RAW_BEFORE_DEFRAG;
74+
75+
pr_info("Enabling raw table before defrag\n");
76+
}
77+
6778
rawtable_ops = xt_hook_ops_alloc(&packet_raw, iptable_raw_hook);
6879
if (IS_ERR(rawtable_ops))
6980
return PTR_ERR(rawtable_ops);

net/ipv4/netfilter/nf_defrag_ipv4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
8080
#endif
8181
#endif
8282
/* Gather fragments. */
83-
if (ip_is_fragment(ip_hdr(skb))) {
83+
if (skb->_nfct != IP_CT_UNTRACKED && ip_is_fragment(ip_hdr(skb))) {
8484
enum ip_defrag_users user =
8585
nf_ct_defrag_user(state->hook, skb);
8686

net/ipv6/netfilter/ip6table_raw.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
55
*/
6+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
67
#include <linux/module.h>
78
#include <linux/netfilter_ipv6/ip6_tables.h>
89
#include <linux/slab.h>
@@ -11,7 +12,11 @@
1112

1213
static int __net_init ip6table_raw_table_init(struct net *net);
1314

14-
static const struct xt_table packet_raw = {
15+
static bool raw_before_defrag __read_mostly;
16+
MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag");
17+
module_param(raw_before_defrag, bool, 0000);
18+
19+
static struct xt_table packet_raw = {
1520
.name = "raw",
1621
.valid_hooks = RAW_VALID_HOOKS,
1722
.me = THIS_MODULE,
@@ -63,6 +68,12 @@ static int __init ip6table_raw_init(void)
6368
{
6469
int ret;
6570

71+
if (raw_before_defrag) {
72+
packet_raw.priority = NF_IP6_PRI_RAW_BEFORE_DEFRAG;
73+
74+
pr_info("Enabling raw table before defrag\n");
75+
}
76+
6677
/* Register hooks */
6778
rawtable_ops = xt_hook_ops_alloc(&packet_raw, ip6table_raw_hook);
6879
if (IS_ERR(rawtable_ops))

net/ipv6/netfilter/nf_defrag_ipv6_hooks.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ static unsigned int ipv6_defrag(void *priv,
6565
return NF_ACCEPT;
6666
#endif
6767

68+
if (skb->_nfct == IP_CT_UNTRACKED)
69+
return NF_ACCEPT;
70+
6871
err = nf_ct_frag6_gather(state->net, skb,
6972
nf_ct6_defrag_user(state->hook, skb));
7073
/* queued */

0 commit comments

Comments
 (0)