Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
authorDavid S. Miller <davem@davemloft.net>
Fri, 28 Nov 2008 10:19:15 +0000 (02:19 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 28 Nov 2008 10:19:15 +0000 (02:19 -0800)
Conflicts:

net/netfilter/nf_conntrack_netlink.c

40 files changed:
include/linux/netfilter_bridge/ebtables.h
include/linux/netfilter_ipv4/ipt_policy.h
include/linux/netfilter_ipv6/ip6t_policy.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netfilter/nf_conntrack_expect.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_conntrack_l4proto.h
include/net/netfilter/nfnetlink_log.h [new file with mode: 0644]
include/net/netns/x_tables.h
net/bridge/br_netfilter.c
net/bridge/netfilter/ebtable_broute.c
net/bridge/netfilter/ebtable_filter.c
net/bridge/netfilter/ebtable_nat.c
net/bridge/netfilter/ebtables.c
net/ipv4/netfilter.c
net/ipv4/netfilter/arptable_filter.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6table_filter.c
net/netfilter/nf_conntrack_amanda.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_netbios_ns.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_sane.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_conntrack_tftp.c
net/netfilter/nfnetlink_log.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_recent.c

index d45e29cd1cfb9dc35d3953edcccfaa408bf39f0f..e40ddb94b1af8b4bf39b9989b1f51136e7d7f56d 100644 (file)
@@ -300,7 +300,8 @@ struct ebt_table
 
 #define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
                     ~(__alignof__(struct ebt_replace)-1))
-extern int ebt_register_table(struct ebt_table *table);
+extern struct ebt_table *ebt_register_table(struct net *net,
+                                           struct ebt_table *table);
 extern void ebt_unregister_table(struct ebt_table *table);
 extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
index b9478a255301b6db9b730ff53f9c17434e133cf1..1037fb2cd2061f44d7bdde6e8cacf5e891b05569 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _IPT_POLICY_H
 #define _IPT_POLICY_H
 
+#include <linux/netfilter/xt_policy.h>
+
 #define IPT_POLICY_MAX_ELEM            XT_POLICY_MAX_ELEM
 
 /* ipt_policy_flags */
index 6bab3163d2fb6700b11c326a309d1079f7b73c5f..b1c449d7ec89626bfa8b88a3e0fc03aed46df0d6 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _IP6T_POLICY_H
 #define _IP6T_POLICY_H
 
+#include <linux/netfilter/xt_policy.h>
+
 #define IP6T_POLICY_MAX_ELEM           XT_POLICY_MAX_ELEM
 
 /* ip6t_policy_flags */
index b76a8685b5b5ae96073d1c54a3e03878141d6d55..2e0c53641cbe2f7edcabd209db372b394d7bc6c0 100644 (file)
@@ -199,7 +199,7 @@ __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
 
-extern void nf_conntrack_flush(struct net *net);
+extern void nf_conntrack_flush(struct net *net, u32 pid, int report);
 
 extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
                              unsigned int nhoff, u_int16_t l3num,
@@ -298,5 +298,8 @@ do {                                                        \
        local_bh_enable();                              \
 } while (0)
 
+#define MODULE_ALIAS_NFCT_HELPER(helper) \
+        MODULE_ALIAS("nfct-helper-" helper)
+
 #endif /* __KERNEL__ */
 #endif /* _NF_CONNTRACK_H */
index 1285ff26a0145fc408dd8ca6b4035bca69d91f28..0ff0dc69ca4a53b9b3827122e715f1a15c1fa0cc 100644 (file)
@@ -17,6 +17,13 @@ struct nf_conntrack_ecache {
        unsigned int events;
 };
 
+/* This structure is passed to event handler */
+struct nf_ct_event {
+       struct nf_conn *ct;
+       u32 pid;
+       int report;
+};
+
 extern struct atomic_notifier_head nf_conntrack_chain;
 extern int nf_conntrack_register_notifier(struct notifier_block *nb);
 extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
@@ -39,22 +46,56 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
        local_bh_enable();
 }
 
-static inline void nf_conntrack_event(enum ip_conntrack_events event,
-                                     struct nf_conn *ct)
+static inline void
+nf_conntrack_event_report(enum ip_conntrack_events event,
+                         struct nf_conn *ct,
+                         u32 pid,
+                         int report)
 {
+       struct nf_ct_event item = {
+               .ct     = ct,
+               .pid    = pid,
+               .report = report
+       };
        if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
-               atomic_notifier_call_chain(&nf_conntrack_chain, event, ct);
+               atomic_notifier_call_chain(&nf_conntrack_chain, event, &item);
 }
 
+static inline void
+nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
+{
+       nf_conntrack_event_report(event, ct, 0, 0);
+}
+
+struct nf_exp_event {
+       struct nf_conntrack_expect *exp;
+       u32 pid;
+       int report;
+};
+
 extern struct atomic_notifier_head nf_ct_expect_chain;
 extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
 extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);
 
+static inline void
+nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
+                         struct nf_conntrack_expect *exp,
+                         u32 pid,
+                         int report)
+{
+       struct nf_exp_event item = {
+               .exp    = exp,
+               .pid    = pid,
+               .report = report
+       };
+       atomic_notifier_call_chain(&nf_ct_expect_chain, event, &item);
+}
+
 static inline void
 nf_ct_expect_event(enum ip_conntrack_expect_events event,
                   struct nf_conntrack_expect *exp)
 {
-       atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
+       nf_ct_expect_event_report(event, exp, 0, 0);
 }
 
 extern int nf_conntrack_ecache_init(struct net *net);
@@ -66,9 +107,17 @@ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
                                            struct nf_conn *ct) {}
 static inline void nf_conntrack_event(enum ip_conntrack_events event,
                                      struct nf_conn *ct) {}
+static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
+                                            struct nf_conn *ct,
+                                            u32 pid,
+                                            int report) {}
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
                                      struct nf_conntrack_expect *exp) {}
+static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
+                                            struct nf_conntrack_expect *exp,
+                                            u32 pid,
+                                            int report) {}
 static inline void nf_ct_event_cache_flush(struct net *net) {}
 
 static inline int nf_conntrack_ecache_init(struct net *net)
index 37a7fc1164b00588ff390305d335e51f49b93c0f..ab17a159ac66192bdc4e6a445f3f1325653c571e 100644 (file)
@@ -100,6 +100,8 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
                       u_int8_t, const __be16 *, const __be16 *);
 void nf_ct_expect_put(struct nf_conntrack_expect *exp);
 int nf_ct_expect_related(struct nf_conntrack_expect *expect);
+int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, 
+                               u32 pid, int report);
 
 #endif /*_NF_CONNTRACK_EXPECT_H*/
 
index f8060ab5a0839d39373249d778db5b8e1fbe6830..66d65a7caa394164776c8559d3c5bd41c55bc8d8 100644 (file)
@@ -38,9 +38,6 @@ struct nf_conntrack_helper
        unsigned int expect_class_max;
 };
 
-extern struct nf_conntrack_helper *
-__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple);
-
 extern struct nf_conntrack_helper *
 __nf_conntrack_helper_find_byname(const char *name);
 
@@ -49,6 +46,8 @@ extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
 
 extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
 
+extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags);
+
 static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
 {
        return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
index 7f2f43c77284a7f6eb485fecac6f5ed7277420da..debdaf75cecf7563def7f6d8421a91e71bb08ca7 100644 (file)
@@ -129,7 +129,7 @@ extern const struct nla_policy nf_ct_port_nla_policy[];
         && net_ratelimit())
 #endif
 #else
-#define LOG_INVALID(net, proto) 0
+static inline int LOG_INVALID(struct net *net, int proto) { return 0; }
 #endif /* CONFIG_SYSCTL */
 
 #endif /*_NF_CONNTRACK_PROTOCOL_H*/
diff --git a/include/net/netfilter/nfnetlink_log.h b/include/net/netfilter/nfnetlink_log.h
new file mode 100644 (file)
index 0000000..b0569ff
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _KER_NFNETLINK_LOG_H
+#define _KER_NFNETLINK_LOG_H
+
+void
+nfulnl_log_packet(u_int8_t pf,
+                 unsigned int hooknum,
+                 const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const struct nf_loginfo *li_user,
+                 const char *prefix);
+
+#endif /* _KER_NFNETLINK_LOG_H */
+
index b8093971ccb476e5288037a8c653cb06a8addf49..9554a644a8f85150c80792f666557cdde6ec4642 100644 (file)
@@ -4,7 +4,12 @@
 #include <linux/list.h>
 #include <linux/netfilter.h>
 
+struct ebt_table;
+
 struct netns_xt {
        struct list_head tables[NFPROTO_NUMPROTO];
+       struct ebt_table *broute_table;
+       struct ebt_table *frame_filter;
+       struct ebt_table *frame_nat;
 };
 #endif
index 274194b78247ba24e1390107e212004b5b3cc88e..a65e43a17fbb2c3ab6334be3ab60f8ffd0e19ced 100644 (file)
@@ -369,7 +369,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
                        if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
                                goto free_skb;
 
-                       if (!ip_route_output_key(&init_net, &rt, &fl)) {
+                       if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
                                /* - Bridged-and-DNAT'ed traffic doesn't
                                 *   require ip_forwarding. */
                                if (((struct dst_entry *)rt)->dev == dev) {
index 246626bb0c879db5f62786b53c992d48e939f188..8604dfc1fc3be0f2c36f6b84b3bceecb930cdfba 100644 (file)
@@ -56,29 +56,47 @@ static int ebt_broute(struct sk_buff *skb)
        int ret;
 
        ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL,
-          &broute_table);
+                          dev_net(skb->dev)->xt.broute_table);
        if (ret == NF_DROP)
                return 1; /* route it */
        return 0; /* bridge it */
 }
 
+static int __net_init broute_net_init(struct net *net)
+{
+       net->xt.broute_table = ebt_register_table(net, &broute_table);
+       if (IS_ERR(net->xt.broute_table))
+               return PTR_ERR(net->xt.broute_table);
+       return 0;
+}
+
+static void __net_exit broute_net_exit(struct net *net)
+{
+       ebt_unregister_table(net->xt.broute_table);
+}
+
+static struct pernet_operations broute_net_ops = {
+       .init = broute_net_init,
+       .exit = broute_net_exit,
+};
+
 static int __init ebtable_broute_init(void)
 {
        int ret;
 
-       ret = ebt_register_table(&broute_table);
+       ret = register_pernet_subsys(&broute_net_ops);
        if (ret < 0)
                return ret;
        /* see br_input.c */
        rcu_assign_pointer(br_should_route_hook, ebt_broute);
-       return ret;
+       return 0;
 }
 
 static void __exit ebtable_broute_fini(void)
 {
        rcu_assign_pointer(br_should_route_hook, NULL);
        synchronize_net();
-       ebt_unregister_table(&broute_table);
+       unregister_pernet_subsys(&broute_net_ops);
 }
 
 module_init(ebtable_broute_init);
index 1a58af51a2e24a374d2d558e65e8206a5c96f329..2b2e8040a9c68c4b55fd1b30850fa9703ba4f7ca 100644 (file)
@@ -61,29 +61,36 @@ static struct ebt_table frame_filter =
 };
 
 static unsigned int
-ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
+ebt_in_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, int (*okfn)(struct sk_buff *))
 {
-       return ebt_do_table(hook, skb, in, out, &frame_filter);
+       return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_filter);
+}
+
+static unsigned int
+ebt_out_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, int (*okfn)(struct sk_buff *))
+{
+       return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_filter);
 }
 
 static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
        {
-               .hook           = ebt_hook,
+               .hook           = ebt_in_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_LOCAL_IN,
                .priority       = NF_BR_PRI_FILTER_BRIDGED,
        },
        {
-               .hook           = ebt_hook,
+               .hook           = ebt_in_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_FORWARD,
                .priority       = NF_BR_PRI_FILTER_BRIDGED,
        },
        {
-               .hook           = ebt_hook,
+               .hook           = ebt_out_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_LOCAL_OUT,
@@ -91,23 +98,41 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
        },
 };
 
+static int __net_init frame_filter_net_init(struct net *net)
+{
+       net->xt.frame_filter = ebt_register_table(net, &frame_filter);
+       if (IS_ERR(net->xt.frame_filter))
+               return PTR_ERR(net->xt.frame_filter);
+       return 0;
+}
+
+static void __net_exit frame_filter_net_exit(struct net *net)
+{
+       ebt_unregister_table(net->xt.frame_filter);
+}
+
+static struct pernet_operations frame_filter_net_ops = {
+       .init = frame_filter_net_init,
+       .exit = frame_filter_net_exit,
+};
+
 static int __init ebtable_filter_init(void)
 {
        int ret;
 
-       ret = ebt_register_table(&frame_filter);
+       ret = register_pernet_subsys(&frame_filter_net_ops);
        if (ret < 0)
                return ret;
        ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
        if (ret < 0)
-               ebt_unregister_table(&frame_filter);
+               unregister_pernet_subsys(&frame_filter_net_ops);
        return ret;
 }
 
 static void __exit ebtable_filter_fini(void)
 {
        nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
-       ebt_unregister_table(&frame_filter);
+       unregister_pernet_subsys(&frame_filter_net_ops);
 }
 
 module_init(ebtable_filter_init);
index f60c1e78e57537541e9e1d2ddbd186ff4e681df5..3fe1ae87e35f912cdb0e255cadff4deb579d121f 100644 (file)
@@ -61,36 +61,36 @@ static struct ebt_table frame_nat =
 };
 
 static unsigned int
-ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in
+ebt_nat_in(unsigned int hook, struct sk_buff *skb, const struct net_device *in
    , const struct net_device *out, int (*okfn)(struct sk_buff *))
 {
-       return ebt_do_table(hook, skb, in, out, &frame_nat);
+       return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_nat);
 }
 
 static unsigned int
-ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in
+ebt_nat_out(unsigned int hook, struct sk_buff *skb, const struct net_device *in
    , const struct net_device *out, int (*okfn)(struct sk_buff *))
 {
-       return ebt_do_table(hook, skb, in, out, &frame_nat);
+       return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_nat);
 }
 
 static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
        {
-               .hook           = ebt_nat_dst,
+               .hook           = ebt_nat_out,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_LOCAL_OUT,
                .priority       = NF_BR_PRI_NAT_DST_OTHER,
        },
        {
-               .hook           = ebt_nat_src,
+               .hook           = ebt_nat_out,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_POST_ROUTING,
                .priority       = NF_BR_PRI_NAT_SRC,
        },
        {
-               .hook           = ebt_nat_dst,
+               .hook           = ebt_nat_in,
                .owner          = THIS_MODULE,
                .pf             = PF_BRIDGE,
                .hooknum        = NF_BR_PRE_ROUTING,
@@ -98,23 +98,41 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
        },
 };
 
+static int __net_init frame_nat_net_init(struct net *net)
+{
+       net->xt.frame_nat = ebt_register_table(net, &frame_nat);
+       if (IS_ERR(net->xt.frame_nat))
+               return PTR_ERR(net->xt.frame_nat);
+       return 0;
+}
+
+static void __net_exit frame_nat_net_exit(struct net *net)
+{
+       ebt_unregister_table(net->xt.frame_nat);
+}
+
+static struct pernet_operations frame_nat_net_ops = {
+       .init = frame_nat_net_init,
+       .exit = frame_nat_net_exit,
+};
+
 static int __init ebtable_nat_init(void)
 {
        int ret;
 
-       ret = ebt_register_table(&frame_nat);
+       ret = register_pernet_subsys(&frame_nat_net_ops);
        if (ret < 0)
                return ret;
        ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
        if (ret < 0)
-               ebt_unregister_table(&frame_nat);
+               unregister_pernet_subsys(&frame_nat_net_ops);
        return ret;
 }
 
 static void __exit ebtable_nat_fini(void)
 {
        nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
-       ebt_unregister_table(&frame_nat);
+       unregister_pernet_subsys(&frame_nat_net_ops);
 }
 
 module_init(ebtable_nat_init);
index 0fa208e86405ceab189042dd36e03fd3e6b893fd..fa108c46e8510d1cf447cd4501576d2fd9cf4934 100644 (file)
@@ -55,7 +55,6 @@
 
 
 static DEFINE_MUTEX(ebt_mutex);
-static LIST_HEAD(ebt_tables);
 
 static struct xt_target ebt_standard_target = {
        .name       = "standard",
@@ -315,9 +314,11 @@ find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
 }
 
 static inline struct ebt_table *
-find_table_lock(const char *name, int *error, struct mutex *mutex)
+find_table_lock(struct net *net, const char *name, int *error,
+               struct mutex *mutex)
 {
-       return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
+       return find_inlist_lock(&net->xt.tables[NFPROTO_BRIDGE], name,
+                               "ebtable_", error, mutex);
 }
 
 static inline int
@@ -944,7 +945,7 @@ static void get_counters(struct ebt_counter *oldcounters,
 }
 
 /* replace the table */
-static int do_replace(void __user *user, unsigned int len)
+static int do_replace(struct net *net, void __user *user, unsigned int len)
 {
        int ret, i, countersize;
        struct ebt_table_info *newinfo;
@@ -1016,7 +1017,7 @@ static int do_replace(void __user *user, unsigned int len)
        if (ret != 0)
                goto free_counterstmp;
 
-       t = find_table_lock(tmp.name, &ret, &ebt_mutex);
+       t = find_table_lock(net, tmp.name, &ret, &ebt_mutex);
        if (!t) {
                ret = -ENOENT;
                goto free_iterate;
@@ -1097,7 +1098,7 @@ free_newinfo:
        return ret;
 }
 
-int ebt_register_table(struct ebt_table *table)
+struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table)
 {
        struct ebt_table_info *newinfo;
        struct ebt_table *t;
@@ -1109,14 +1110,21 @@ int ebt_register_table(struct ebt_table *table)
            repl->entries_size == 0 ||
            repl->counters || table->private) {
                BUGPRINT("Bad table data for ebt_register_table!!!\n");
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
+       }
+
+       /* Don't add one table to multiple lists. */
+       table = kmemdup(table, sizeof(struct ebt_table), GFP_KERNEL);
+       if (!table) {
+               ret = -ENOMEM;
+               goto out;
        }
 
        countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids;
        newinfo = vmalloc(sizeof(*newinfo) + countersize);
        ret = -ENOMEM;
        if (!newinfo)
-               return -ENOMEM;
+               goto free_table;
 
        p = vmalloc(repl->entries_size);
        if (!p)
@@ -1148,7 +1156,7 @@ int ebt_register_table(struct ebt_table *table)
 
        if (table->check && table->check(newinfo, table->valid_hooks)) {
                BUGPRINT("The table doesn't like its own initial data, lol\n");
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
        }
 
        table->private = newinfo;
@@ -1157,7 +1165,7 @@ int ebt_register_table(struct ebt_table *table)
        if (ret != 0)
                goto free_chainstack;
 
-       list_for_each_entry(t, &ebt_tables, list) {
+       list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
                if (strcmp(t->name, table->name) == 0) {
                        ret = -EEXIST;
                        BUGPRINT("Table name already exists\n");
@@ -1170,9 +1178,9 @@ int ebt_register_table(struct ebt_table *table)
                ret = -ENOENT;
                goto free_unlock;
        }
-       list_add(&table->list, &ebt_tables);
+       list_add(&table->list, &net->xt.tables[NFPROTO_BRIDGE]);
        mutex_unlock(&ebt_mutex);
-       return 0;
+       return table;
 free_unlock:
        mutex_unlock(&ebt_mutex);
 free_chainstack:
@@ -1184,7 +1192,10 @@ free_chainstack:
        vfree(newinfo->entries);
 free_newinfo:
        vfree(newinfo);
-       return ret;
+free_table:
+       kfree(table);
+out:
+       return ERR_PTR(ret);
 }
 
 void ebt_unregister_table(struct ebt_table *table)
@@ -1198,6 +1209,10 @@ void ebt_unregister_table(struct ebt_table *table)
        mutex_lock(&ebt_mutex);
        list_del(&table->list);
        mutex_unlock(&ebt_mutex);
+       EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
+                         ebt_cleanup_entry, NULL);
+       if (table->private->nentries)
+               module_put(table->me);
        vfree(table->private->entries);
        if (table->private->chainstack) {
                for_each_possible_cpu(i)
@@ -1205,10 +1220,11 @@ void ebt_unregister_table(struct ebt_table *table)
                vfree(table->private->chainstack);
        }
        vfree(table->private);
+       kfree(table);
 }
 
 /* userspace just supplied us with counters */
-static int update_counters(void __user *user, unsigned int len)
+static int update_counters(struct net *net, void __user *user, unsigned int len)
 {
        int i, ret;
        struct ebt_counter *tmp;
@@ -1228,7 +1244,7 @@ static int update_counters(void __user *user, unsigned int len)
                return -ENOMEM;
        }
 
-       t = find_table_lock(hlp.name, &ret, &ebt_mutex);
+       t = find_table_lock(net, hlp.name, &ret, &ebt_mutex);
        if (!t)
                goto free_tmp;
 
@@ -1386,10 +1402,10 @@ static int do_ebt_set_ctl(struct sock *sk,
 
        switch(cmd) {
        case EBT_SO_SET_ENTRIES:
-               ret = do_replace(user, len);
+               ret = do_replace(sock_net(sk), user, len);
                break;
        case EBT_SO_SET_COUNTERS:
-               ret = update_counters(user, len);
+               ret = update_counters(sock_net(sk), user, len);
                break;
        default:
                ret = -EINVAL;
@@ -1406,7 +1422,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        if (copy_from_user(&tmp, user, sizeof(tmp)))
                return -EFAULT;
 
-       t = find_table_lock(tmp.name, &ret, &ebt_mutex);
+       t = find_table_lock(sock_net(sk), tmp.name, &ret, &ebt_mutex);
        if (!t)
                return ret;
 
index c99eecf89da56feea8244f56ca0533ddf0dd2279..fdf6811c31a246df891495fdc76b46c00e5f783b 100644 (file)
@@ -125,6 +125,7 @@ struct ip_rt_info {
        __be32 daddr;
        __be32 saddr;
        u_int8_t tos;
+       u_int32_t mark;
 };
 
 static void nf_ip_saveroute(const struct sk_buff *skb,
@@ -138,6 +139,7 @@ static void nf_ip_saveroute(const struct sk_buff *skb,
                rt_info->tos = iph->tos;
                rt_info->daddr = iph->daddr;
                rt_info->saddr = iph->saddr;
+               rt_info->mark = skb->mark;
        }
 }
 
@@ -150,6 +152,7 @@ static int nf_ip_reroute(struct sk_buff *skb,
                const struct iphdr *iph = ip_hdr(skb);
 
                if (!(iph->tos == rt_info->tos
+                     && skb->mark == rt_info->mark
                      && iph->daddr == rt_info->daddr
                      && iph->saddr == rt_info->saddr))
                        return ip_route_me_harder(skb, RTN_UNSPEC);
index bee3d117661a54127666209e3005f9b2f7be7ebc..e091187e864fe95ac03437bc73cd0713f2d93a01 100644 (file)
@@ -75,16 +75,6 @@ static unsigned int arpt_out_hook(unsigned int hook,
                             dev_net(out)->ipv4.arptable_filter);
 }
 
-static unsigned int arpt_forward_hook(unsigned int hook,
-                                     struct sk_buff *skb,
-                                     const struct net_device *in,
-                                     const struct net_device *out,
-                                     int (*okfn)(struct sk_buff *))
-{
-       return arpt_do_table(skb, hook, in, out,
-                            dev_net(in)->ipv4.arptable_filter);
-}
-
 static struct nf_hook_ops arpt_ops[] __read_mostly = {
        {
                .hook           = arpt_in_hook,
@@ -101,7 +91,7 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
                .priority       = NF_IP_PRI_FILTER,
        },
        {
-               .hook           = arpt_forward_hook,
+               .hook           = arpt_in_hook,
                .owner          = THIS_MODULE,
                .pf             = NFPROTO_ARP,
                .hooknum        = NF_ARP_FORWARD,
index 88762f02779d001270a9186c1f1569aed7fe6068..3b216be3bc9fbcf940d00dff5c8d428ec229fe59 100644 (file)
@@ -23,24 +23,25 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("Xtables: address type match for IPv4");
 
-static inline bool match_type(const struct net_device *dev, __be32 addr,
-                             u_int16_t mask)
+static inline bool match_type(struct net *net, const struct net_device *dev,
+                             __be32 addr, u_int16_t mask)
 {
-       return !!(mask & (1 << inet_dev_addr_type(&init_net, dev, addr)));
+       return !!(mask & (1 << inet_dev_addr_type(net, dev, addr)));
 }
 
 static bool
 addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
 {
+       struct net *net = dev_net(par->in ? par->in : par->out);
        const struct ipt_addrtype_info *info = par->matchinfo;
        const struct iphdr *iph = ip_hdr(skb);
        bool ret = true;
 
        if (info->source)
-               ret &= match_type(NULL, iph->saddr, info->source) ^
+               ret &= match_type(net, NULL, iph->saddr, info->source) ^
                       info->invert_source;
        if (info->dest)
-               ret &= match_type(NULL, iph->daddr, info->dest) ^
+               ret &= match_type(net, NULL, iph->daddr, info->dest) ^
                       info->invert_dest;
 
        return ret;
@@ -49,6 +50,7 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
 static bool
 addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
 {
+       struct net *net = dev_net(par->in ? par->in : par->out);
        const struct ipt_addrtype_info_v1 *info = par->matchinfo;
        const struct iphdr *iph = ip_hdr(skb);
        const struct net_device *dev = NULL;
@@ -60,10 +62,10 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
                dev = par->out;
 
        if (info->source)
-               ret &= match_type(dev, iph->saddr, info->source) ^
+               ret &= match_type(net, dev, iph->saddr, info->source) ^
                       (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
        if (ret && info->dest)
-               ret &= match_type(dev, iph->daddr, info->dest) ^
+               ret &= match_type(net, dev, iph->daddr, info->dest) ^
                       !!(info->flags & IPT_ADDRTYPE_INVERT_DEST);
        return ret;
 }
index a4f1c3479e23eac1cad79e4eb6f39b8e7df03872..cf95469ab9f108cc9440701e913f1f7044c467e6 100644 (file)
@@ -86,24 +86,6 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par)
        return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
 }
 
-/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
-static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
-{
-       static int warned = 0;
-       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
-       struct rtable *rt;
-
-       if (ip_route_output_key(net, &rt, &fl) != 0)
-               return;
-
-       if (rt->rt_src != srcip && !warned) {
-               printk("NAT: no longer support implicit source local NAT\n");
-               printk("NAT: packet src %pI4 -> dst %pI4\n", &srcip, &dstip);
-               warned = 1;
-       }
-       ip_rt_put(rt);
-}
-
 static unsigned int
 ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
 {
@@ -119,11 +101,6 @@ ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
        /* Connection must be valid and new. */
        NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
-       if (par->hooknum == NF_INET_LOCAL_OUT &&
-           mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
-               warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr,
-                                    mr->range[0].min_ip);
-
        return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
 }
 
index 627e21db65df77318c27aec152af4e1a0aec227c..834cea69fb53b1a081be1de8368f1b9cec8921dd 100644 (file)
@@ -56,6 +56,7 @@ EXPORT_SYMBOL(ip6_route_me_harder);
 struct ip6_rt_info {
        struct in6_addr daddr;
        struct in6_addr saddr;
+       u_int32_t mark;
 };
 
 static void nf_ip6_saveroute(const struct sk_buff *skb,
@@ -68,6 +69,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb,
 
                rt_info->daddr = iph->daddr;
                rt_info->saddr = iph->saddr;
+               rt_info->mark = skb->mark;
        }
 }
 
@@ -79,7 +81,8 @@ static int nf_ip6_reroute(struct sk_buff *skb,
        if (entry->hook == NF_INET_LOCAL_OUT) {
                struct ipv6hdr *iph = ipv6_hdr(skb);
                if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
-                   !ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
+                   !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) ||
+                   skb->mark != rt_info->mark)
                        return ip6_route_me_harder(skb);
        }
        return 0;
index b110a8a85a1480855fb6bdea238c82dccd29cc7a..40d2e36d8fac292b8fdf8663717d3eaf505108c5 100644 (file)
@@ -61,7 +61,7 @@ static struct xt_table packet_filter = {
 
 /* The work comes in here from netfilter.c. */
 static unsigned int
-ip6t_local_in_hook(unsigned int hook,
+ip6t_in_hook(unsigned int hook,
                   struct sk_buff *skb,
                   const struct net_device *in,
                   const struct net_device *out,
@@ -71,17 +71,6 @@ ip6t_local_in_hook(unsigned int hook,
                             dev_net(in)->ipv6.ip6table_filter);
 }
 
-static unsigned int
-ip6t_forward_hook(unsigned int hook,
-                 struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 int (*okfn)(struct sk_buff *))
-{
-       return ip6t_do_table(skb, hook, in, out,
-                            dev_net(in)->ipv6.ip6table_filter);
-}
-
 static unsigned int
 ip6t_local_out_hook(unsigned int hook,
                   struct sk_buff *skb,
@@ -105,14 +94,14 @@ ip6t_local_out_hook(unsigned int hook,
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        {
-               .hook           = ip6t_local_in_hook,
+               .hook           = ip6t_in_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
                .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP6_PRI_FILTER,
        },
        {
-               .hook           = ip6t_forward_hook,
+               .hook           = ip6t_in_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
                .hooknum        = NF_INET_FORWARD,
index 38aedeeaf4e1cb71100c726d42a9f21b3618ef74..4f8fcf498545f302105535bfebaf34b9755908fe 100644 (file)
@@ -30,6 +30,7 @@ MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
 MODULE_DESCRIPTION("Amanda connection tracking module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ip_conntrack_amanda");
+MODULE_ALIAS_NFCT_HELPER("amanda");
 
 module_param(master_timeout, uint, 0600);
 MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
index 233fdd2d7d2186b03fd6bac169d4090dbab562a3..7e83f74cd5de3dea8f3ba32a2feea84f12cbe359 100644 (file)
 #include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_conntrack_acct.h>
 #include <net/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat_core.h>
 
 #define NF_CONNTRACK_VERSION   "0.5.0"
 
-unsigned int
-(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
-                                 enum nf_nat_manip_type manip,
-                                 struct nlattr *attr) __read_mostly;
+int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+                                     enum nf_nat_manip_type manip,
+                                     struct nlattr *attr) __read_mostly;
 EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
 
 DEFINE_SPINLOCK(nf_conntrack_lock);
@@ -181,7 +181,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
        NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
        NF_CT_ASSERT(!timer_pending(&ct->timeout));
 
-       nf_conntrack_event(IPCT_DESTROY, ct);
+       if (!test_bit(IPS_DYING_BIT, &ct->status))
+               nf_conntrack_event(IPCT_DESTROY, ct);
        set_bit(IPS_DYING_BIT, &ct->status);
 
        /* To make sure we don't get any weird locking issues here:
@@ -586,14 +587,7 @@ init_conntrack(struct net *net,
                nf_conntrack_get(&ct->master->ct_general);
                NF_CT_STAT_INC(net, expect_new);
        } else {
-               struct nf_conntrack_helper *helper;
-
-               helper = __nf_ct_helper_find(&repl_tuple);
-               if (helper) {
-                       help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
-                       if (help)
-                               rcu_assign_pointer(help->helper, helper);
-               }
+               __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
                NF_CT_STAT_INC(net, new);
        }
 
@@ -770,7 +764,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
                              const struct nf_conntrack_tuple *newreply)
 {
        struct nf_conn_help *help = nfct_help(ct);
-       struct nf_conntrack_helper *helper;
 
        /* Should be unconfirmed, so not in hash table yet */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
@@ -783,23 +776,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
                return;
 
        rcu_read_lock();
-       helper = __nf_ct_helper_find(newreply);
-       if (helper == NULL) {
-               if (help)
-                       rcu_assign_pointer(help->helper, NULL);
-               goto out;
-       }
-
-       if (help == NULL) {
-               help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
-               if (help == NULL)
-                       goto out;
-       } else {
-               memset(&help->help, 0, sizeof(help->help));
-       }
-
-       rcu_assign_pointer(help->helper, helper);
-out:
+       __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
        rcu_read_unlock();
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -994,8 +971,20 @@ void nf_ct_iterate_cleanup(struct net *net,
 }
 EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
 
+struct __nf_ct_flush_report {
+       u32 pid;
+       int report;
+};
+
 static int kill_all(struct nf_conn *i, void *data)
 {
+       struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
+
+       /* get_next_corpse sets the dying bit for us */
+       nf_conntrack_event_report(IPCT_DESTROY,
+                                 i,
+                                 fr->pid,
+                                 fr->report);
        return 1;
 }
 
@@ -1009,9 +998,13 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
 }
 EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
 
-void nf_conntrack_flush(struct net *net)
+void nf_conntrack_flush(struct net *net, u32 pid, int report)
 {
-       nf_ct_iterate_cleanup(net, kill_all, NULL);
+       struct __nf_ct_flush_report fr = {
+               .pid    = pid,
+               .report = report,
+       };
+       nf_ct_iterate_cleanup(net, kill_all, &fr);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_flush);
 
@@ -1027,7 +1020,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
        nf_ct_event_cache_flush(net);
        nf_conntrack_ecache_fini(net);
  i_see_dead_people:
-       nf_conntrack_flush(net);
+       nf_conntrack_flush(net, 0, 0);
        if (atomic_read(&net->ct.count) != 0) {
                schedule();
                goto i_see_dead_people;
index a5f5e2e65d13770bf62a419e94962986f8c21a56..dee4190209ccc2420709bcbcab29527270625730 100644 (file)
@@ -35,9 +35,17 @@ static inline void
 __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
 {
        if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
-           && ecache->events)
-               atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
-                                   ecache->ct);
+           && ecache->events) {
+               struct nf_ct_event item = {
+                       .ct     = ecache->ct,
+                       .pid    = 0,
+                       .report = 0
+               };
+
+               atomic_notifier_call_chain(&nf_conntrack_chain,
+                                          ecache->events,
+                                          &item);
+       }
 
        ecache->events = 0;
        nf_ct_put(ecache->ct);
index 37a703bc3b8ee0556fedbeccb6a89a72ce39750c..3a8a34a6d37c807bd995eb0a43f3498ddf567662 100644 (file)
@@ -362,7 +362,7 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
        return 1;
 }
 
-int nf_ct_expect_related(struct nf_conntrack_expect *expect)
+static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
 {
        const struct nf_conntrack_expect_policy *p;
        struct nf_conntrack_expect *i;
@@ -371,11 +371,8 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
        struct net *net = nf_ct_exp_net(expect);
        struct hlist_node *n;
        unsigned int h;
-       int ret;
-
-       NF_CT_ASSERT(master_help);
+       int ret = 0;
 
-       spin_lock_bh(&nf_conntrack_lock);
        if (!master_help->helper) {
                ret = -ESHUTDOWN;
                goto out;
@@ -409,18 +406,50 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
                        printk(KERN_WARNING
                               "nf_conntrack: expectation table full\n");
                ret = -EMFILE;
-               goto out;
        }
+out:
+       return ret;
+}
+
+int nf_ct_expect_related(struct nf_conntrack_expect *expect)
+{
+       int ret;
+
+       spin_lock_bh(&nf_conntrack_lock);
+       ret = __nf_ct_expect_check(expect);
+       if (ret < 0)
+               goto out;
 
        nf_ct_expect_insert(expect);
+       atomic_inc(&expect->use);
+       spin_unlock_bh(&nf_conntrack_lock);
        nf_ct_expect_event(IPEXP_NEW, expect);
-       ret = 0;
+       nf_ct_expect_put(expect);
+       return ret;
 out:
        spin_unlock_bh(&nf_conntrack_lock);
        return ret;
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_related);
 
+int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, 
+                               u32 pid, int report)
+{
+       int ret;
+
+       spin_lock_bh(&nf_conntrack_lock);
+       ret = __nf_ct_expect_check(expect);
+       if (ret < 0)
+               goto out;
+       nf_ct_expect_insert(expect);
+out:
+       spin_unlock_bh(&nf_conntrack_lock);
+       if (ret == 0)
+               nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
+
 #ifdef CONFIG_PROC_FS
 struct ct_expect_iter_state {
        struct seq_net_private p;
index 629500901bd4d1eb5f2e05a03939ef06c24f2d62..00fecc385f9b55e9aa6edb2452a7c6025f043618 100644 (file)
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
 MODULE_DESCRIPTION("ftp connection tracking helper");
 MODULE_ALIAS("ip_conntrack_ftp");
+MODULE_ALIAS_NFCT_HELPER("ftp");
 
 /* This is slow, but it's simple. --RR */
 static char *ftp_buffer;
@@ -357,7 +358,7 @@ static int help(struct sk_buff *skb,
        int ret;
        u32 seq;
        int dir = CTINFO2DIR(ctinfo);
-       unsigned int matchlen, matchoff;
+       unsigned int uninitialized_var(matchlen), uninitialized_var(matchoff);
        struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
        struct nf_conntrack_expect *exp;
        union nf_inet_addr *daddr;
@@ -427,10 +428,8 @@ static int help(struct sk_buff *skb,
                   connection tracking, not packet filtering.
                   However, it is necessary for accurate tracking in
                   this case. */
-               if (net_ratelimit())
-                       printk("conntrack_ftp: partial %s %u+%u\n",
-                              search[dir][i].pattern,
-                              ntohl(th->seq), datalen);
+               pr_debug("conntrack_ftp: partial %s %u+%u\n",
+                        search[dir][i].pattern,  ntohl(th->seq), datalen);
                ret = NF_DROP;
                goto out;
        } else if (found == 0) { /* No match */
index 99bc803d1dd14ae9e30dc83f53e1f5ae147c2ce2..687bd633c3d7020c277ba0f25b6e3033fd5053c7 100644 (file)
@@ -1827,3 +1827,4 @@ MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
 MODULE_DESCRIPTION("H.323 connection tracking helper");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ip_conntrack_h323");
+MODULE_ALIAS_NFCT_HELPER("h323");
index c39b6a9941331c8fe6c6fe2a80130f04bd1b1129..a51bdac9f3a0682a442d833d44a82c813cd19eff 100644 (file)
@@ -45,7 +45,7 @@ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
                (__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
 }
 
-struct nf_conntrack_helper *
+static struct nf_conntrack_helper *
 __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
 {
        struct nf_conntrack_helper *helper;
@@ -63,7 +63,6 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
        }
        return NULL;
 }
-EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
 
 struct nf_conntrack_helper *
 __nf_conntrack_helper_find_byname(const char *name)
@@ -95,6 +94,35 @@ struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
 
+int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags)
+{
+       int ret = 0;
+       struct nf_conntrack_helper *helper;
+       struct nf_conn_help *help = nfct_help(ct);
+
+       helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+       if (helper == NULL) {
+               if (help)
+                       rcu_assign_pointer(help->helper, NULL);
+               goto out;
+       }
+
+       if (help == NULL) {
+               help = nf_ct_helper_ext_add(ct, flags);
+               if (help == NULL) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+       } else {
+               memset(&help->help, 0, sizeof(help->help));
+       }
+
+       rcu_assign_pointer(help->helper, helper);
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
+
 static inline int unhelp(struct nf_conntrack_tuple_hash *i,
                         const struct nf_conntrack_helper *me)
 {
index 4d681a04447e4792d5371984975042c0612df345..409c8be58e7c3fe097ceacc47c37ffb8092a155a 100644 (file)
@@ -41,6 +41,7 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ip_conntrack_irc");
+MODULE_ALIAS_NFCT_HELPER("irc");
 
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of IRC servers");
index 08404e6755fb15064ab086d3229a34cc9139ce3d..5af4273b4668c3bf53b0ea1dc1937ed973831610 100644 (file)
@@ -37,6 +37,7 @@ MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ip_conntrack_netbios_ns");
+MODULE_ALIAS_NFCT_HELPER("netbios_ns");
 
 static unsigned int timeout __read_mostly = 3;
 module_param(timeout, uint, 0400);
index 5f4a6516b3b6b6f935e677f774c22de1c038dccb..00e8c27130ff6ad6fa345b860948ddb8dca2bf4e 100644 (file)
@@ -105,16 +105,14 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
 
-       l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+       l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
        ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
-       nf_ct_l3proto_put(l3proto);
 
        if (unlikely(ret < 0))
                return ret;
 
-       l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+       l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
        ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
-       nf_ct_l4proto_put(l4proto);
 
        return ret;
 }
@@ -151,11 +149,9 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
        struct nlattr *nest_proto;
        int ret;
 
-       l4proto = nf_ct_l4proto_find_get(nf_ct_l3num(ct), nf_ct_protonum(ct));
-       if (!l4proto->to_nlattr) {
-               nf_ct_l4proto_put(l4proto);
+       l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
+       if (!l4proto->to_nlattr)
                return 0;
-       }
 
        nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED);
        if (!nest_proto)
@@ -163,14 +159,11 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
 
        ret = l4proto->to_nlattr(skb, nest_proto, ct);
 
-       nf_ct_l4proto_put(l4proto);
-
        nla_nest_end(skb, nest_proto);
 
        return ret;
 
 nla_put_failure:
-       nf_ct_l4proto_put(l4proto);
        return -1;
 }
 
@@ -184,7 +177,6 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
        if (!help)
                return 0;
 
-       rcu_read_lock();
        helper = rcu_dereference(help->helper);
        if (!helper)
                goto out;
@@ -199,11 +191,9 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
 
        nla_nest_end(skb, nest_helper);
 out:
-       rcu_read_unlock();
        return 0;
 
 nla_put_failure:
-       rcu_read_unlock();
        return -1;
 }
 
@@ -420,7 +410,8 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nlattr *nest_parms;
-       struct nf_conn *ct = (struct nf_conn *)ptr;
+       struct nf_ct_event *item = (struct nf_ct_event *)ptr;
+       struct nf_conn *ct = item->ct;
        struct sk_buff *skb;
        unsigned int type;
        sk_buff_data_t b;
@@ -453,7 +444,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        b = skb->tail;
 
        type |= NFNL_SUBSYS_CTNETLINK << 8;
-       nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+       nlh   = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
        nfmsg = NLMSG_DATA(nlh);
 
        nlh->nlmsg_flags    = flags;
@@ -461,6 +452,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        nfmsg->version  = NFNETLINK_V0;
        nfmsg->res_id   = 0;
 
+       rcu_read_lock();
        nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
@@ -517,13 +509,15 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
            && ctnetlink_dump_mark(skb, ct) < 0)
                goto nla_put_failure;
 #endif
+       rcu_read_unlock();
 
        nlh->nlmsg_len = skb->tail - b;
-       nfnetlink_send(skb, 0, group, 0);
+       nfnetlink_send(skb, item->pid, group, item->report);
        return NOTIFY_DONE;
 
-nlmsg_failure:
 nla_put_failure:
+       rcu_read_unlock();
+nlmsg_failure:
        kfree_skb(skb);
        return NOTIFY_DONE;
 }
@@ -729,7 +723,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
        else {
                /* Flush the whole table */
-               nf_conntrack_flush(&init_net);
+               nf_conntrack_flush(&init_net, 
+                                  NETLINK_CB(skb).pid, 
+                                  nlmsg_report(nlh));
                return 0;
        }
 
@@ -750,6 +746,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                }
        }
 
+       nf_conntrack_event_report(IPCT_DESTROY,
+                                 ct,
+                                 NETLINK_CB(skb).pid,
+                                 nlmsg_report(nlh));
+
+       /* death_by_timeout would report the event again */
+       set_bit(IPS_DYING_BIT, &ct->status);
+
        nf_ct_kill(ct);
        nf_ct_put(ct);
 
@@ -795,8 +799,10 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return -ENOMEM;
        }
 
+       rcu_read_lock();
        err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
                                  IPCTNL_MSG_CT_NEW, 1, ct);
+       rcu_read_unlock();
        nf_ct_put(ct);
        if (err <= 0)
                goto free;
@@ -922,8 +928,22 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
        }
 
        helper = __nf_conntrack_helper_find_byname(helpname);
-       if (helper == NULL)
+       if (helper == NULL) {
+#ifdef CONFIG_MODULES
+               spin_unlock_bh(&nf_conntrack_lock);
+
+               if (request_module("nfct-helper-%s", helpname) < 0) {
+                       spin_lock_bh(&nf_conntrack_lock);
+                       return -EOPNOTSUPP;
+               }
+
+               spin_lock_bh(&nf_conntrack_lock);
+               helper = __nf_conntrack_helper_find_byname(helpname);
+               if (helper)
+                       return -EAGAIN;
+#endif
                return -EOPNOTSUPP;
+       }
 
        if (help) {
                if (help->helper == helper)
@@ -1079,15 +1099,38 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
        return 0;
 }
 
+static inline void
+ctnetlink_event_report(struct nf_conn *ct, u32 pid, int report)
+{
+       unsigned int events = 0;
+
+       if (test_bit(IPS_EXPECTED_BIT, &ct->status))
+               events |= IPCT_RELATED;
+       else
+               events |= IPCT_NEW;
+
+       nf_conntrack_event_report(IPCT_STATUS |
+                                 IPCT_HELPER |
+                                 IPCT_REFRESH |
+                                 IPCT_PROTOINFO |
+                                 IPCT_NATSEQADJ |
+                                 IPCT_MARK |
+                                 events,
+                                 ct,
+                                 pid,
+                                 report);
+}
+
 static int
 ctnetlink_create_conntrack(struct nlattr *cda[],
                           struct nf_conntrack_tuple *otuple,
                           struct nf_conntrack_tuple *rtuple,
-                          struct nf_conn *master_ct)
+                          struct nf_conn *master_ct,
+                          u32 pid,
+                          int report)
 {
        struct nf_conn *ct;
        int err = -EINVAL;
-       struct nf_conn_help *help;
        struct nf_conntrack_helper *helper;
 
        ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC);
@@ -1102,16 +1145,55 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
        ct->status |= IPS_CONFIRMED;
 
        rcu_read_lock();
-       helper = __nf_ct_helper_find(rtuple);
-       if (helper) {
-               help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
-               if (help == NULL) {
+       if (cda[CTA_HELP]) {
+               char *helpname;
+               err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
+               if (err < 0) {
+                       rcu_read_unlock();
+                       goto err;
+               }
+
+               helper = __nf_conntrack_helper_find_byname(helpname);
+               if (helper == NULL) {
+                       rcu_read_unlock();
+#ifdef CONFIG_MODULES
+                       if (request_module("nfct-helper-%s", helpname) < 0) {
+                               err = -EOPNOTSUPP;
+                               goto err;
+                       }
+
+                       rcu_read_lock();
+                       helper = __nf_conntrack_helper_find_byname(helpname);
+                       if (helper) {
+                               rcu_read_unlock();
+                               err = -EAGAIN;
+                               goto err;
+                       }
+                       rcu_read_unlock();
+#endif
+                       err = -EOPNOTSUPP;
+                       goto err;
+               } else {
+                       struct nf_conn_help *help;
+
+                       help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+                       if (help == NULL) {
+                               rcu_read_unlock();
+                               err = -ENOMEM;
+                               goto err;
+                       }
+
+                       /* not in hash table yet so not strictly necessary */
+                       rcu_assign_pointer(help->helper, helper);
+               }
+       } else {
+               /* try an implicit helper assignation */
+               err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
+               if (err < 0) {
                        rcu_read_unlock();
-                       err = -ENOMEM;
                        goto err;
                }
-               /* not in hash table yet so not strictly necessary */
-               rcu_assign_pointer(help->helper, helper);
        }
 
        if (cda[CTA_STATUS]) {
@@ -1151,9 +1233,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
                ct->master = master_ct;
        }
 
+       nf_conntrack_get(&ct->ct_general);
        add_timer(&ct->timeout);
        nf_conntrack_hash_insert(ct);
        rcu_read_unlock();
+       ctnetlink_event_report(ct, pid, report);
+       nf_ct_put(ct);
 
        return 0;
 
@@ -1209,7 +1294,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                                goto out_unlock;
                        }
                        master_ct = nf_ct_tuplehash_to_ctrack(master_h);
-                       atomic_inc(&master_ct->ct_general.use);
+                       nf_conntrack_get(&master_ct->ct_general);
                }
 
                err = -ENOENT;
@@ -1217,9 +1302,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                        err = ctnetlink_create_conntrack(cda,
                                                         &otuple,
                                                         &rtuple,
-                                                        master_ct);
+                                                        master_ct,
+                                                        NETLINK_CB(skb).pid,
+                                                        nlmsg_report(nlh));
                spin_unlock_bh(&nf_conntrack_lock);
-
                if (err < 0 && master_ct)
                        nf_ct_put(master_ct);
 
@@ -1231,6 +1317,8 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
         * so there's no need to increase the refcount */
        err = -EEXIST;
        if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
+               struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+
                /* we only allow nat config for new conntracks */
                if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
                        err = -EOPNOTSUPP;
@@ -1241,8 +1329,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                        err = -EOPNOTSUPP;
                        goto out_unlock;
                }
-               err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h),
-                                                cda);
+
+               err = ctnetlink_change_conntrack(ct, cda);
+               if (err == 0) {
+                       nf_conntrack_get(&ct->ct_general);
+                       spin_unlock_bh(&nf_conntrack_lock);
+                       ctnetlink_event_report(ct,
+                                              NETLINK_CB(skb).pid,
+                                              nlmsg_report(nlh));
+                       nf_ct_put(ct);
+               } else
+                       spin_unlock_bh(&nf_conntrack_lock);
+
+               return err;
        }
 
 out_unlock:
@@ -1293,16 +1392,14 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb,
        if (!nest_parms)
                goto nla_put_failure;
 
-       l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+       l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
        ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
-       nf_ct_l3proto_put(l3proto);
 
        if (unlikely(ret < 0))
                goto nla_put_failure;
 
-       l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+       l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
        ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
-       nf_ct_l4proto_put(l4proto);
        if (unlikely(ret < 0))
                goto nla_put_failure;
 
@@ -1379,7 +1476,8 @@ static int ctnetlink_expect_event(struct notifier_block *this,
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
+       struct nf_exp_event *item = (struct nf_exp_event *)ptr;
+       struct nf_conntrack_expect *exp = item->exp;
        struct sk_buff *skb;
        unsigned int type;
        sk_buff_data_t b;
@@ -1401,7 +1499,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
        b = skb->tail;
 
        type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+       nlh   = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
        nfmsg = NLMSG_DATA(nlh);
 
        nlh->nlmsg_flags    = flags;
@@ -1409,15 +1507,18 @@ static int ctnetlink_expect_event(struct notifier_block *this,
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
 
+       rcu_read_lock();
        if (ctnetlink_exp_dump_expect(skb, exp) < 0)
                goto nla_put_failure;
+       rcu_read_unlock();
 
        nlh->nlmsg_len = skb->tail - b;
-       nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
+       nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, item->report);
        return NOTIFY_DONE;
 
-nlmsg_failure:
 nla_put_failure:
+       rcu_read_unlock();
+nlmsg_failure:
        kfree_skb(skb);
        return NOTIFY_DONE;
 }
@@ -1521,9 +1622,11 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        if (!skb2)
                goto out;
 
+       rcu_read_lock();
        err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
                                      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
                                      1, exp);
+       rcu_read_unlock();
        if (err <= 0)
                goto free;
 
@@ -1624,7 +1727,7 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[])
 }
 
 static int
-ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
+ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report)
 {
        struct nf_conntrack_tuple tuple, mask, master_tuple;
        struct nf_conntrack_tuple_hash *h = NULL;
@@ -1653,7 +1756,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
 
        if (!help || !help->helper) {
                /* such conntrack hasn't got any helper, abort */
-               err = -EINVAL;
+               err = -EOPNOTSUPP;
                goto out;
        }
 
@@ -1671,7 +1774,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
        memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
        exp->mask.src.u.all = mask.src.u.all;
 
-       err = nf_ct_expect_related(exp);
+       err = nf_ct_expect_related_report(exp, pid, report);
        nf_ct_expect_put(exp);
 
 out:
@@ -1704,8 +1807,12 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
        if (!exp) {
                spin_unlock_bh(&nf_conntrack_lock);
                err = -ENOENT;
-               if (nlh->nlmsg_flags & NLM_F_CREATE)
-                       err = ctnetlink_create_expect(cda, u3);
+               if (nlh->nlmsg_flags & NLM_F_CREATE) {
+                       err = ctnetlink_create_expect(cda,
+                                                     u3,
+                                                     NETLINK_CB(skb).pid,
+                                                     nlmsg_report(nlh));
+               }
                return err;
        }
 
index 1bc3001d182773e33872081d4b40fc7bf6f4e95d..9e169ef2e85443eaff5c8224ccbeaad1d0f4a202 100644 (file)
@@ -37,6 +37,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
 MODULE_ALIAS("ip_conntrack_pptp");
+MODULE_ALIAS_NFCT_HELPER("pptp");
 
 static DEFINE_SPINLOCK(nf_pptp_lock);
 
index 4ab62ad85dd493e473b68bc2affa5eb63783fbfb..1b279f9d6bf3a81d90205b5dd06cb158fdbf4829 100644 (file)
@@ -341,7 +341,7 @@ static int __init nf_ct_proto_gre_init(void)
        return rv;
 }
 
-static void nf_ct_proto_gre_fini(void)
+static void __exit nf_ct_proto_gre_fini(void)
 {
        nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
        unregister_pernet_gen_subsys(proto_gre_net_id, &proto_gre_net_ops);
index c2bd457bc2f24bcae0b0804a595a6368cdae1091..74e03790119989df87cd1a95e8a80280f1c85764 100644 (file)
@@ -317,7 +317,7 @@ static int sctp_packet(struct nf_conn *ct,
                goto out;
        }
 
-       old_state = new_state = SCTP_CONNTRACK_MAX;
+       old_state = new_state = SCTP_CONNTRACK_NONE;
        write_lock_bh(&sctp_lock);
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
                /* Special cases of Verification tag check (Sec 8.5.1) */
index a94294b2b23ca71f2bfc30e3b88dc7dea962c373..dcfecbb81c4617784178009bc02de37b9a32cb00 100644 (file)
@@ -30,6 +30,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
 MODULE_DESCRIPTION("SANE connection tracking helper");
+MODULE_ALIAS_NFCT_HELPER("sane");
 
 static char *sane_buffer;
 
index 6813f1c8863f245ac84ffc7ad3a1b9e36c8e5cd3..4b572163784b338b1efa430713e1ae73d5da38b2 100644 (file)
@@ -28,6 +28,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
 MODULE_DESCRIPTION("SIP connection tracking helper");
 MODULE_ALIAS("ip_conntrack_sip");
+MODULE_ALIAS_NFCT_HELPER("sip");
 
 #define MAX_PORTS      8
 static unsigned short ports[MAX_PORTS];
index f57f6e7a71ee4e9e6913d7646dddfc8607ebe746..46e646b2e9b922ff1210ff06c835f32538f0d0c7 100644 (file)
@@ -22,6 +22,7 @@ MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
 MODULE_DESCRIPTION("TFTP connection tracking helper");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ip_conntrack_tftp");
+MODULE_ALIAS_NFCT_HELPER("tftp");
 
 #define MAX_PORTS 8
 static unsigned short ports[MAX_PORTS];
index 41e0105d3828c3c9c8dd5d03c3aea4ec4e831658..2770b4e57ea0cbcca63929db8d8f9d49f38a0788 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/random.h>
 #include <net/sock.h>
 #include <net/netfilter/nf_log.h>
+#include <net/netfilter/nfnetlink_log.h>
 
 #include <asm/atomic.h>
 
@@ -533,7 +534,7 @@ static struct nf_loginfo default_loginfo = {
 };
 
 /* log handler for internal netfilter logging api */
-static void
+void
 nfulnl_log_packet(u_int8_t pf,
                  unsigned int hooknum,
                  const struct sk_buff *skb,
@@ -648,6 +649,7 @@ alloc_failure:
        /* FIXME: statistics */
        goto unlock_and_release;
 }
+EXPORT_SYMBOL_GPL(nfulnl_log_packet);
 
 static int
 nfulnl_rcv_nl_event(struct notifier_block *this,
index 50e3a52d3b31006421bd4ad32f6a63d1305c5925..a57c5cf018ec04871d07a4f4c948c78b08ddb443 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_NFLOG.h>
 #include <net/netfilter/nf_log.h>
+#include <net/netfilter/nfnetlink_log.h>
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("Xtables: packet logging to netlink using NFLOG");
@@ -31,8 +32,8 @@ nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
        li.u.ulog.group      = info->group;
        li.u.ulog.qthreshold = info->threshold;
 
-       nf_log_packet(par->family, par->hooknum, skb, par->in,
-                     par->out, &li, "%s", info->prefix);
+       nfulnl_log_packet(par->family, par->hooknum, skb, par->in,
+                         par->out, &li, info->prefix);
        return XT_CONTINUE;
 }
 
index 3c3dd22b1d061e946079261d00670158d9ff4b9e..fe80b614a40033014f48cfe1fad26f3806af85c2 100644 (file)
@@ -72,9 +72,6 @@ struct recent_entry {
 struct recent_table {
        struct list_head        list;
        char                    name[XT_RECENT_NAME_LEN];
-#ifdef CONFIG_PROC_FS
-       struct proc_dir_entry   *proc_old, *proc;
-#endif
        unsigned int            refcnt;
        unsigned int            entries;
        struct list_head        lru_list;
@@ -284,6 +281,9 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_recent_mtinfo *info = par->matchinfo;
        struct recent_table *t;
+#ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *pde;
+#endif
        unsigned i;
        bool ret = false;
 
@@ -318,25 +318,25 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
        for (i = 0; i < ip_list_hash_size; i++)
                INIT_LIST_HEAD(&t->iphash[i]);
 #ifdef CONFIG_PROC_FS
-       t->proc = proc_create_data(t->name, ip_list_perms, recent_proc_dir,
+       pde = proc_create_data(t->name, ip_list_perms, recent_proc_dir,
                  &recent_mt_fops, t);
-       if (t->proc == NULL) {
+       if (pde == NULL) {
                kfree(t);
                goto out;
        }
+       pde->uid = ip_list_uid;
+       pde->gid = ip_list_gid;
 #ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       t->proc_old = proc_create_data(t->name, ip_list_perms, proc_old_dir,
+       pde = proc_create_data(t->name, ip_list_perms, proc_old_dir,
                      &recent_old_fops, t);
-       if (t->proc_old == NULL) {
+       if (pde == NULL) {
                remove_proc_entry(t->name, proc_old_dir);
                kfree(t);
                goto out;
        }
-       t->proc_old->uid   = ip_list_uid;
-       t->proc_old->gid   = ip_list_gid;
+       pde->uid = ip_list_uid;
+       pde->gid = ip_list_gid;
 #endif
-       t->proc->uid       = ip_list_uid;
-       t->proc->gid       = ip_list_gid;
 #endif
        spin_lock_bh(&recent_lock);
        list_add_tail(&t->list, &tables);