Skip to content

Commit 827318f

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: conntrack: remove helper hook again
place them into the confirm one. Old: hook (300): ipv4/6_help() first call helper, then seqadj. hook (INT_MAX): confirm Now: hook (INT_MAX): confirm, first call helper, then seqadj, then confirm Not having the extra call is noticeable in bechmarks. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 10870dd commit 827318f

File tree

1 file changed

+36
-106
lines changed

1 file changed

+36
-106
lines changed

net/netfilter/nf_conntrack_proto.c

Lines changed: 36 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -364,55 +364,55 @@ void nf_ct_l4proto_pernet_unregister(struct net *net,
364364
}
365365
EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);
366366

367-
static unsigned int ipv4_helper(void *priv,
368-
struct sk_buff *skb,
369-
const struct nf_hook_state *state)
367+
static unsigned int nf_confirm(struct sk_buff *skb,
368+
unsigned int protoff,
369+
struct nf_conn *ct,
370+
enum ip_conntrack_info ctinfo)
370371
{
371-
struct nf_conn *ct;
372-
enum ip_conntrack_info ctinfo;
373372
const struct nf_conn_help *help;
374-
const struct nf_conntrack_helper *helper;
375-
376-
/* This is where we call the helper: as the packet goes out. */
377-
ct = nf_ct_get(skb, &ctinfo);
378-
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
379-
return NF_ACCEPT;
380373

381374
help = nfct_help(ct);
382-
if (!help)
383-
return NF_ACCEPT;
375+
if (help) {
376+
const struct nf_conntrack_helper *helper;
377+
int ret;
378+
379+
/* rcu_read_lock()ed by nf_hook_thresh */
380+
helper = rcu_dereference(help->helper);
381+
if (helper) {
382+
ret = helper->help(skb,
383+
protoff,
384+
ct, ctinfo);
385+
if (ret != NF_ACCEPT)
386+
return ret;
387+
}
388+
}
384389

385-
/* rcu_read_lock()ed by nf_hook_thresh */
386-
helper = rcu_dereference(help->helper);
387-
if (!helper)
388-
return NF_ACCEPT;
390+
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
391+
!nf_is_loopback_packet(skb)) {
392+
if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) {
393+
NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
394+
return NF_DROP;
395+
}
396+
}
389397

390-
return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
391-
ct, ctinfo);
398+
/* We've seen it coming out the other side: confirm it */
399+
return nf_conntrack_confirm(skb);
392400
}
393401

394402
static unsigned int ipv4_confirm(void *priv,
395403
struct sk_buff *skb,
396404
const struct nf_hook_state *state)
397405
{
398-
struct nf_conn *ct;
399406
enum ip_conntrack_info ctinfo;
407+
struct nf_conn *ct;
400408

401409
ct = nf_ct_get(skb, &ctinfo);
402410
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
403-
goto out;
411+
return nf_conntrack_confirm(skb);
404412

405-
/* adjust seqs for loopback traffic only in outgoing direction */
406-
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
407-
!nf_is_loopback_packet(skb)) {
408-
if (!nf_ct_seq_adjust(skb, ct, ctinfo, ip_hdrlen(skb))) {
409-
NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
410-
return NF_DROP;
411-
}
412-
}
413-
out:
414-
/* We've seen it coming out the other side: confirm it */
415-
return nf_conntrack_confirm(skb);
413+
return nf_confirm(skb,
414+
skb_network_offset(skb) + ip_hdrlen(skb),
415+
ct, ctinfo);
416416
}
417417

418418
static unsigned int ipv4_conntrack_in(void *priv,
@@ -460,24 +460,12 @@ static const struct nf_hook_ops ipv4_conntrack_ops[] = {
460460
.hooknum = NF_INET_LOCAL_OUT,
461461
.priority = NF_IP_PRI_CONNTRACK,
462462
},
463-
{
464-
.hook = ipv4_helper,
465-
.pf = NFPROTO_IPV4,
466-
.hooknum = NF_INET_POST_ROUTING,
467-
.priority = NF_IP_PRI_CONNTRACK_HELPER,
468-
},
469463
{
470464
.hook = ipv4_confirm,
471465
.pf = NFPROTO_IPV4,
472466
.hooknum = NF_INET_POST_ROUTING,
473467
.priority = NF_IP_PRI_CONNTRACK_CONFIRM,
474468
},
475-
{
476-
.hook = ipv4_helper,
477-
.pf = NFPROTO_IPV4,
478-
.hooknum = NF_INET_LOCAL_IN,
479-
.priority = NF_IP_PRI_CONNTRACK_HELPER,
480-
},
481469
{
482470
.hook = ipv4_confirm,
483471
.pf = NFPROTO_IPV4,
@@ -623,31 +611,21 @@ static unsigned int ipv6_confirm(void *priv,
623611
struct nf_conn *ct;
624612
enum ip_conntrack_info ctinfo;
625613
unsigned char pnum = ipv6_hdr(skb)->nexthdr;
626-
int protoff;
627614
__be16 frag_off;
615+
int protoff;
628616

629617
ct = nf_ct_get(skb, &ctinfo);
630618
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
631-
goto out;
619+
return nf_conntrack_confirm(skb);
632620

633621
protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
634622
&frag_off);
635623
if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
636624
pr_debug("proto header not found\n");
637-
goto out;
625+
return nf_conntrack_confirm(skb);
638626
}
639627

640-
/* adjust seqs for loopback traffic only in outgoing direction */
641-
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
642-
!nf_is_loopback_packet(skb)) {
643-
if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) {
644-
NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
645-
return NF_DROP;
646-
}
647-
}
648-
out:
649-
/* We've seen it coming out the other side: confirm it */
650-
return nf_conntrack_confirm(skb);
628+
return nf_confirm(skb, protoff, ct, ctinfo);
651629
}
652630

653631
static unsigned int ipv6_conntrack_in(void *priv,
@@ -664,42 +642,6 @@ static unsigned int ipv6_conntrack_local(void *priv,
664642
return nf_conntrack_in(skb, state);
665643
}
666644

667-
static unsigned int ipv6_helper(void *priv,
668-
struct sk_buff *skb,
669-
const struct nf_hook_state *state)
670-
{
671-
struct nf_conn *ct;
672-
const struct nf_conn_help *help;
673-
const struct nf_conntrack_helper *helper;
674-
enum ip_conntrack_info ctinfo;
675-
__be16 frag_off;
676-
int protoff;
677-
u8 nexthdr;
678-
679-
/* This is where we call the helper: as the packet goes out. */
680-
ct = nf_ct_get(skb, &ctinfo);
681-
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
682-
return NF_ACCEPT;
683-
684-
help = nfct_help(ct);
685-
if (!help)
686-
return NF_ACCEPT;
687-
/* rcu_read_lock()ed by nf_hook_thresh */
688-
helper = rcu_dereference(help->helper);
689-
if (!helper)
690-
return NF_ACCEPT;
691-
692-
nexthdr = ipv6_hdr(skb)->nexthdr;
693-
protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
694-
&frag_off);
695-
if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
696-
pr_debug("proto header not found\n");
697-
return NF_ACCEPT;
698-
}
699-
700-
return helper->help(skb, protoff, ct, ctinfo);
701-
}
702-
703645
static const struct nf_hook_ops ipv6_conntrack_ops[] = {
704646
{
705647
.hook = ipv6_conntrack_in,
@@ -713,24 +655,12 @@ static const struct nf_hook_ops ipv6_conntrack_ops[] = {
713655
.hooknum = NF_INET_LOCAL_OUT,
714656
.priority = NF_IP6_PRI_CONNTRACK,
715657
},
716-
{
717-
.hook = ipv6_helper,
718-
.pf = NFPROTO_IPV6,
719-
.hooknum = NF_INET_POST_ROUTING,
720-
.priority = NF_IP6_PRI_CONNTRACK_HELPER,
721-
},
722658
{
723659
.hook = ipv6_confirm,
724660
.pf = NFPROTO_IPV6,
725661
.hooknum = NF_INET_POST_ROUTING,
726662
.priority = NF_IP6_PRI_LAST,
727663
},
728-
{
729-
.hook = ipv6_helper,
730-
.pf = NFPROTO_IPV6,
731-
.hooknum = NF_INET_LOCAL_IN,
732-
.priority = NF_IP6_PRI_CONNTRACK_HELPER,
733-
},
734664
{
735665
.hook = ipv6_confirm,
736666
.pf = NFPROTO_IPV6,

0 commit comments

Comments
 (0)