History

netfilter: ctnetlink: allow to set expectfn for expectations

This patch allows you to set expectfn which is specifically used by the NAT side of most of the existing conntrack helpers. I have added a symbol map that uses a string as key to look up for the function that is attached to the expectation object. This is the best solution I came out with to solve this issue.

Pablo Neira Ayuso committed 14 years ago

Commit 544d5c71 parent 076a0ca7 files · +115 −1Browse files

Unified · Split

7 files
  1. include/linux/netfilter/nfnetlink_conntrack.h +1 −0
  2. include/net/netfilter/nf_conntrack_helper.h +13 −0
  3. net/ipv4/netfilter/nf_nat_core.c +8 −0
  4. net/ipv4/netfilter/nf_nat_h323.c +14 −0
  5. net/ipv4/netfilter/nf_nat_sip.c +7 −0
  6. net/netfilter/nf_conntrack_helper.c +54 −0
  7. net/netfilter/nf_conntrack_netlink.c +18 −1
include/linux/netfilter/nfnetlink_conntrack.h+1−0
@@ -175,6 +175,7 @@ enum ctattr_expect { · 174 unmodified lines
175175 CTA_EXPECT_FLAGS,
176176 CTA_EXPECT_CLASS,
177177 CTA_EXPECT_NAT,
178+ CTA_EXPECT_FN,
178179 __CTA_EXPECT_MAX
179180 };
180181 #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
include/net/netfilter/nf_conntrack_helper.h+13−0
@@ -69,4 +69,17 @@ extern int nf_conntrack_broadcast_help(struct sk_buff *skb, · 68 unmodified lines
6969 enum ip_conntrack_info ctinfo,
7070 unsigned int timeout);
7171
72+struct nf_ct_helper_expectfn {
73+ struct list_head head;
74+ const char *name;
75+ void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp);
76+};
77+
78+void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
79+void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
80+struct nf_ct_helper_expectfn *
81+nf_ct_helper_expectfn_find_by_name(const char *name);
82+struct nf_ct_helper_expectfn *
83+nf_ct_helper_expectfn_find_by_symbol(const void *symbol);
84+
7285 #endif /*_NF_CONNTRACK_HELPER_H*/
net/ipv4/netfilter/nf_nat_core.c+8−0
@@ -686,6 +686,11 @@ static struct pernet_operations nf_nat_net_ops = { · 685 unmodified lines
686686 .exit = nf_nat_net_exit,
687687 };
688688
689+static struct nf_ct_helper_expectfn follow_master_nat = {
690+ .name = "nat-follow-master",
691+ .expectfn = nf_nat_follow_master,
692+};
693+
689694 static int __init nf_nat_init(void)
690695 {
691696 size_t i;
@@ -717,6 +722,8 @@ static int __init nf_nat_init(void) · 25 unmodified lines
717722
718723 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
719724
725+ nf_ct_helper_expectfn_register(&follow_master_nat);
726+
720727 BUG_ON(nf_nat_seq_adjust_hook != NULL);
721728 RCU_INIT_POINTER(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
722729 BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
@@ -736,6 +743,7 @@ static void __exit nf_nat_cleanup(void) · 13 unmodified lines
736743 unregister_pernet_subsys(&nf_nat_net_ops);
737744 nf_ct_l3proto_put(l3proto);
738745 nf_ct_extend_unregister(&nat_extend);
746+ nf_ct_helper_expectfn_unregister(&follow_master_nat);
739747 RCU_INIT_POINTER(nf_nat_seq_adjust_hook, NULL);
740748 RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL);
741749 RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
net/ipv4/netfilter/nf_nat_h323.c+14−0
@@ -568,6 +568,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, · 567 unmodified lines
568568 return 0;
569569 }
570570
571+static struct nf_ct_helper_expectfn q931_nat = {
572+ .name = "Q.931",
573+ .expectfn = ip_nat_q931_expect,
574+};
575+
576+static struct nf_ct_helper_expectfn callforwarding_nat = {
577+ .name = "callforwarding",
578+ .expectfn = ip_nat_callforwarding_expect,
579+};
580+
571581 /****************************************************************************/
572582 static int __init init(void)
573583 {
@@ -590,6 +600,8 @@ static int __init init(void) · 16 unmodified lines
590600 RCU_INIT_POINTER(nat_h245_hook, nat_h245);
591601 RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding);
592602 RCU_INIT_POINTER(nat_q931_hook, nat_q931);
603+ nf_ct_helper_expectfn_register(&q931_nat);
604+ nf_ct_helper_expectfn_register(&callforwarding_nat);
593605 return 0;
594606 }
595607
@@ -605,6 +617,8 @@ static void __exit fini(void) · 9 unmodified lines
605617 RCU_INIT_POINTER(nat_h245_hook, NULL);
606618 RCU_INIT_POINTER(nat_callforwarding_hook, NULL);
607619 RCU_INIT_POINTER(nat_q931_hook, NULL);
620+ nf_ct_helper_expectfn_unregister(&q931_nat);
621+ nf_ct_helper_expectfn_unregister(&callforwarding_nat);
608622 synchronize_rcu();
609623 }
610624
net/ipv4/netfilter/nf_nat_sip.c+7−0
@@ -526,6 +526,11 @@ err1: · 525 unmodified lines
526526 return NF_DROP;
527527 }
528528
529+static struct nf_ct_helper_expectfn sip_nat = {
530+ .name = "sip",
531+ .expectfn = ip_nat_sip_expected,
532+};
533+
529534 static void __exit nf_nat_sip_fini(void)
530535 {
531536 RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
@@ -535,6 +540,7 @@ static void __exit nf_nat_sip_fini(void) · 3 unmodified lines
535540 RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
536541 RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
537542 RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
543+ nf_ct_helper_expectfn_unregister(&sip_nat);
538544 synchronize_rcu();
539545 }
540546
@@ -554,6 +560,7 @@ static int __init nf_nat_sip_init(void) · 13 unmodified lines
554560 RCU_INIT_POINTER(nf_nat_sdp_port_hook, ip_nat_sdp_port);
555561 RCU_INIT_POINTER(nf_nat_sdp_session_hook, ip_nat_sdp_session);
556562 RCU_INIT_POINTER(nf_nat_sdp_media_hook, ip_nat_sdp_media);
563+ nf_ct_helper_expectfn_register(&sip_nat);
557564 return 0;
558565 }
559566
net/netfilter/nf_conntrack_helper.c+54−0
@@ -181,6 +181,60 @@ void nf_ct_helper_destroy(struct nf_conn *ct) · 180 unmodified lines
181181 }
182182 }
183183
184+static LIST_HEAD(nf_ct_helper_expectfn_list);
185+
186+void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n)
187+{
188+ spin_lock_bh(&nf_conntrack_lock);
189+ list_add_rcu(&n->head, &nf_ct_helper_expectfn_list);
190+ spin_unlock_bh(&nf_conntrack_lock);
191+}
192+EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register);
193+
194+void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
195+{
196+ spin_lock_bh(&nf_conntrack_lock);
197+ list_del_rcu(&n->head);
198+ spin_unlock_bh(&nf_conntrack_lock);
199+}
200+EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
201+
202+struct nf_ct_helper_expectfn *
203+nf_ct_helper_expectfn_find_by_name(const char *name)
204+{
205+ struct nf_ct_helper_expectfn *cur;
206+ bool found = false;
207+
208+ rcu_read_lock();
209+ list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) {
210+ if (!strcmp(cur->name, name)) {
211+ found = true;
212+ break;
213+ }
214+ }
215+ rcu_read_unlock();
216+ return found ? cur : NULL;
217+}
218+EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_name);
219+
220+struct nf_ct_helper_expectfn *
221+nf_ct_helper_expectfn_find_by_symbol(const void *symbol)
222+{
223+ struct nf_ct_helper_expectfn *cur;
224+ bool found = false;
225+
226+ rcu_read_lock();
227+ list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) {
228+ if (cur->expectfn == symbol) {
229+ found = true;
230+ break;
231+ }
232+ }
233+ rcu_read_unlock();
234+ return found ? cur : NULL;
235+}
236+EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol);
237+
184238 int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
185239 {
186240 unsigned int h = helper_hash(&me->tuple);
net/netfilter/nf_conntrack_netlink.c+18−1
@@ -1679,6 +1679,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, · 1678 unmodified lines
16791679 struct nlattr *nest_parms;
16801680 struct nf_conntrack_tuple nat_tuple = {};
16811681 #endif
1682+ struct nf_ct_helper_expectfn *expfn;
1683+
16821684 if (timeout < 0)
16831685 timeout = 0;
16841686
@@ -1722,6 +1724,9 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, · 37 unmodified lines
17221724 if (helper)
17231725 NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name);
17241726 }
1727+ expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn);
1728+ if (expfn != NULL)
1729+ NLA_PUT_STRING(skb, CTA_EXPECT_FN, expfn->name);
17251730
17261731 return 0;
17271732
@@ -1881,6 +1886,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { · 153 unmodified lines
18811886 [CTA_EXPECT_FLAGS] = { .type = NLA_U32 },
18821887 [CTA_EXPECT_CLASS] = { .type = NLA_U32 },
18831888 [CTA_EXPECT_NAT] = { .type = NLA_NESTED },
1889+ [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING },
18841890 };
18851891
18861892 static int
@@ -2182,9 +2188,20 @@ ctnetlink_create_expect(struct net *net, u16 zone, · 295 unmodified lines
21822188 } else
21832189 exp->flags = 0;
21842190 }
2191+ if (cda[CTA_EXPECT_FN]) {
2192+ const char *name = nla_data(cda[CTA_EXPECT_FN]);
2193+ struct nf_ct_helper_expectfn *expfn;
2194+
2195+ expfn = nf_ct_helper_expectfn_find_by_name(name);
2196+ if (expfn == NULL) {
2197+ err = -EINVAL;
2198+ goto err_out;
2199+ }
2200+ exp->expectfn = expfn->expectfn;
2201+ } else
2202+ exp->expectfn = NULL;
21852203
21862204 exp->class = class;
2187− exp->expectfn = NULL;
21882205 exp->master = ct;
21892206 exp->helper = helper;
21902207 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t