Commit eaae44d248b151e7257ba551ae589cf343c3fdf6

Authored by David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

Showing 12 changed files Side-by-side Diff

include/linux/list_nulls.h
... ... @@ -56,6 +56,18 @@
56 56 return is_a_nulls(h->first);
57 57 }
58 58  
  59 +static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
  60 + struct hlist_nulls_head *h)
  61 +{
  62 + struct hlist_nulls_node *first = h->first;
  63 +
  64 + n->next = first;
  65 + n->pprev = &h->first;
  66 + h->first = n;
  67 + if (!is_a_nulls(first))
  68 + first->pprev = &n->next;
  69 +}
  70 +
59 71 static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
60 72 {
61 73 struct hlist_nulls_node *next = n->next;
... ... @@ -63,6 +75,12 @@
63 75 *pprev = next;
64 76 if (!is_a_nulls(next))
65 77 next->pprev = pprev;
  78 +}
  79 +
  80 +static inline void hlist_nulls_del(struct hlist_nulls_node *n)
  81 +{
  82 + __hlist_nulls_del(n);
  83 + n->pprev = LIST_POISON2;
66 84 }
67 85  
68 86 /**
include/net/netfilter/nf_conntrack.h
... ... @@ -201,6 +201,8 @@
201 201 __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
202 202  
203 203 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
  204 +extern void nf_ct_delete_from_lists(struct nf_conn *ct);
  205 +extern void nf_ct_insert_dying_list(struct nf_conn *ct);
204 206  
205 207 extern void nf_conntrack_flush_report(struct net *net, u32 pid, int report);
206 208  
include/net/netfilter/nf_conntrack_ecache.h
... ... @@ -6,61 +6,54 @@
6 6 #define _NF_CONNTRACK_ECACHE_H
7 7 #include <net/netfilter/nf_conntrack.h>
8 8  
9   -#include <linux/interrupt.h>
10 9 #include <net/net_namespace.h>
11 10 #include <net/netfilter/nf_conntrack_expect.h>
  11 +#include <linux/netfilter/nf_conntrack_common.h>
  12 +#include <linux/netfilter/nf_conntrack_tuple_common.h>
  13 +#include <net/netfilter/nf_conntrack_extend.h>
12 14  
13   -/* Connection tracking event bits */
  15 +/* Connection tracking event types */
14 16 enum ip_conntrack_events
15 17 {
16   - /* New conntrack */
17   - IPCT_NEW_BIT = 0,
18   - IPCT_NEW = (1 << IPCT_NEW_BIT),
  18 + IPCT_NEW = 0, /* new conntrack */
  19 + IPCT_RELATED = 1, /* related conntrack */
  20 + IPCT_DESTROY = 2, /* destroyed conntrack */
  21 + IPCT_STATUS = 3, /* status has changed */
  22 + IPCT_PROTOINFO = 4, /* protocol information has changed */
  23 + IPCT_HELPER = 5, /* new helper has been set */
  24 + IPCT_MARK = 6, /* new mark has been set */
  25 + IPCT_NATSEQADJ = 7, /* NAT is doing sequence adjustment */
  26 + IPCT_SECMARK = 8, /* new security mark has been set */
  27 +};
19 28  
20   - /* Expected connection */
21   - IPCT_RELATED_BIT = 1,
22   - IPCT_RELATED = (1 << IPCT_RELATED_BIT),
  29 +enum ip_conntrack_expect_events {
  30 + IPEXP_NEW = 0, /* new expectation */
  31 +};
23 32  
24   - /* Destroyed conntrack */
25   - IPCT_DESTROY_BIT = 2,
26   - IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
  33 +struct nf_conntrack_ecache {
  34 + unsigned long cache; /* bitops want long */
  35 + unsigned long missed; /* missed events */
  36 + u32 pid; /* netlink pid of destroyer */
  37 +};
27 38  
28   - /* Status has changed */
29   - IPCT_STATUS_BIT = 3,
30   - IPCT_STATUS = (1 << IPCT_STATUS_BIT),
  39 +static inline struct nf_conntrack_ecache *
  40 +nf_ct_ecache_find(const struct nf_conn *ct)
  41 +{
  42 + return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE);
  43 +}
31 44  
32   - /* Update of protocol info */
33   - IPCT_PROTOINFO_BIT = 4,
34   - IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
  45 +static inline struct nf_conntrack_ecache *
  46 +nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp)
  47 +{
  48 + struct net *net = nf_ct_net(ct);
35 49  
36   - /* New helper for conntrack */
37   - IPCT_HELPER_BIT = 5,
38   - IPCT_HELPER = (1 << IPCT_HELPER_BIT),
  50 + if (!net->ct.sysctl_events)
  51 + return NULL;
39 52  
40   - /* Mark is set */
41   - IPCT_MARK_BIT = 6,
42   - IPCT_MARK = (1 << IPCT_MARK_BIT),
43   -
44   - /* NAT sequence adjustment */
45   - IPCT_NATSEQADJ_BIT = 7,
46   - IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT),
47   -
48   - /* Secmark is set */
49   - IPCT_SECMARK_BIT = 8,
50   - IPCT_SECMARK = (1 << IPCT_SECMARK_BIT),
  53 + return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
51 54 };
52 55  
53   -enum ip_conntrack_expect_events {
54   - IPEXP_NEW_BIT = 0,
55   - IPEXP_NEW = (1 << IPEXP_NEW_BIT),
56   -};
57   -
58 56 #ifdef CONFIG_NF_CONNTRACK_EVENTS
59   -struct nf_conntrack_ecache {
60   - struct nf_conn *ct;
61   - unsigned int events;
62   -};
63   -
64 57 /* This structure is passed to event handler */
65 58 struct nf_ct_event {
66 59 struct nf_conn *ct;
67 60  
68 61  
69 62  
70 63  
71 64  
72 65  
73 66  
74 67  
75 68  
76 69  
77 70  
... ... @@ -76,53 +69,88 @@
76 69 extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
77 70 extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
78 71  
79   -extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
80   -extern void __nf_ct_event_cache_init(struct nf_conn *ct);
81   -extern void nf_ct_event_cache_flush(struct net *net);
  72 +extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
82 73  
83 74 static inline void
84 75 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
85 76 {
86   - struct net *net = nf_ct_net(ct);
87   - struct nf_conntrack_ecache *ecache;
  77 + struct nf_conntrack_ecache *e;
88 78  
89   - local_bh_disable();
90   - ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
91   - if (ct != ecache->ct)
92   - __nf_ct_event_cache_init(ct);
93   - ecache->events |= event;
94   - local_bh_enable();
  79 + if (nf_conntrack_event_cb == NULL)
  80 + return;
  81 +
  82 + e = nf_ct_ecache_find(ct);
  83 + if (e == NULL)
  84 + return;
  85 +
  86 + set_bit(event, &e->cache);
95 87 }
96 88  
97   -static inline void
98   -nf_conntrack_event_report(enum ip_conntrack_events event,
99   - struct nf_conn *ct,
100   - u32 pid,
101   - int report)
  89 +static inline int
  90 +nf_conntrack_eventmask_report(unsigned int eventmask,
  91 + struct nf_conn *ct,
  92 + u32 pid,
  93 + int report)
102 94 {
  95 + int ret = 0;
  96 + struct net *net = nf_ct_net(ct);
103 97 struct nf_ct_event_notifier *notify;
  98 + struct nf_conntrack_ecache *e;
104 99  
105 100 rcu_read_lock();
106 101 notify = rcu_dereference(nf_conntrack_event_cb);
107 102 if (notify == NULL)
108 103 goto out_unlock;
109 104  
  105 + if (!net->ct.sysctl_events)
  106 + goto out_unlock;
  107 +
  108 + e = nf_ct_ecache_find(ct);
  109 + if (e == NULL)
  110 + goto out_unlock;
  111 +
110 112 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
111 113 struct nf_ct_event item = {
112 114 .ct = ct,
113   - .pid = pid,
  115 + .pid = e->pid ? e->pid : pid,
114 116 .report = report
115 117 };
116   - notify->fcn(event, &item);
  118 + /* This is a resent of a destroy event? If so, skip missed */
  119 + unsigned long missed = e->pid ? 0 : e->missed;
  120 +
  121 + ret = notify->fcn(eventmask | missed, &item);
  122 + if (unlikely(ret < 0 || missed)) {
  123 + spin_lock_bh(&ct->lock);
  124 + if (ret < 0) {
  125 + /* This is a destroy event that has been
  126 + * triggered by a process, we store the PID
  127 + * to include it in the retransmission. */
  128 + if (eventmask & (1 << IPCT_DESTROY) &&
  129 + e->pid == 0 && pid != 0)
  130 + e->pid = pid;
  131 + else
  132 + e->missed |= eventmask;
  133 + } else
  134 + e->missed &= ~missed;
  135 + spin_unlock_bh(&ct->lock);
  136 + }
117 137 }
118 138 out_unlock:
119 139 rcu_read_unlock();
  140 + return ret;
120 141 }
121 142  
122   -static inline void
  143 +static inline int
  144 +nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
  145 + u32 pid, int report)
  146 +{
  147 + return nf_conntrack_eventmask_report(1 << event, ct, pid, report);
  148 +}
  149 +
  150 +static inline int
123 151 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
124 152 {
125   - nf_conntrack_event_report(event, ct, 0, 0);
  153 + return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
126 154 }
127 155  
128 156 struct nf_exp_event {
... ... @@ -145,6 +173,7 @@
145 173 u32 pid,
146 174 int report)
147 175 {
  176 + struct net *net = nf_ct_exp_net(exp);
148 177 struct nf_exp_event_notifier *notify;
149 178  
150 179 rcu_read_lock();
151 180  
... ... @@ -152,13 +181,16 @@
152 181 if (notify == NULL)
153 182 goto out_unlock;
154 183  
  184 + if (!net->ct.sysctl_events)
  185 + goto out_unlock;
  186 +
155 187 {
156 188 struct nf_exp_event item = {
157 189 .exp = exp,
158 190 .pid = pid,
159 191 .report = report
160 192 };
161   - notify->fcn(event, &item);
  193 + notify->fcn(1 << event, &item);
162 194 }
163 195 out_unlock:
164 196 rcu_read_unlock();
... ... @@ -178,12 +210,16 @@
178 210  
179 211 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
180 212 struct nf_conn *ct) {}
181   -static inline void nf_conntrack_event(enum ip_conntrack_events event,
182   - struct nf_conn *ct) {}
183   -static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
184   - struct nf_conn *ct,
185   - u32 pid,
186   - int report) {}
  213 +static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
  214 + struct nf_conn *ct,
  215 + u32 pid,
  216 + int report) { return 0; }
  217 +static inline int nf_conntrack_event(enum ip_conntrack_events event,
  218 + struct nf_conn *ct) { return 0; }
  219 +static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
  220 + struct nf_conn *ct,
  221 + u32 pid,
  222 + int report) { return 0; }
187 223 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
188 224 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
189 225 struct nf_conntrack_expect *exp) {}
... ... @@ -191,7 +227,6 @@
191 227 struct nf_conntrack_expect *exp,
192 228 u32 pid,
193 229 int report) {}
194   -static inline void nf_ct_event_cache_flush(struct net *net) {}
195 230  
196 231 static inline int nf_conntrack_ecache_init(struct net *net)
197 232 {
include/net/netfilter/nf_conntrack_extend.h
... ... @@ -8,12 +8,14 @@
8 8 NF_CT_EXT_HELPER,
9 9 NF_CT_EXT_NAT,
10 10 NF_CT_EXT_ACCT,
  11 + NF_CT_EXT_ECACHE,
11 12 NF_CT_EXT_NUM,
12 13 };
13 14  
14 15 #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
15 16 #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
16 17 #define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter
  18 +#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache
17 19  
18 20 /* Extensions: optional stuff which isn't permanently in struct. */
19 21 struct nf_ct_ext {
include/net/netfilter/nf_conntrack_helper.h
... ... @@ -50,6 +50,8 @@
50 50  
51 51 extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags);
52 52  
  53 +extern void nf_ct_helper_destroy(struct nf_conn *ct);
  54 +
53 55 static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
54 56 {
55 57 return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
include/net/netns/conntrack.h
... ... @@ -14,16 +14,17 @@
14 14 struct hlist_nulls_head *hash;
15 15 struct hlist_head *expect_hash;
16 16 struct hlist_nulls_head unconfirmed;
  17 + struct hlist_nulls_head dying;
17 18 struct ip_conntrack_stat *stat;
18   -#ifdef CONFIG_NF_CONNTRACK_EVENTS
19   - struct nf_conntrack_ecache *ecache;
20   -#endif
  19 + int sysctl_events;
  20 + unsigned int sysctl_events_retry_timeout;
21 21 int sysctl_acct;
22 22 int sysctl_checksum;
23 23 unsigned int sysctl_log_invalid; /* Log invalid packets */
24 24 #ifdef CONFIG_SYSCTL
25 25 struct ctl_table_header *sysctl_header;
26 26 struct ctl_table_header *acct_sysctl_header;
  27 + struct ctl_table_header *event_sysctl_header;
27 28 #endif
28 29 int hash_vmalloc;
29 30 int expect_vmalloc;
net/netfilter/nf_conntrack_core.c
... ... @@ -39,6 +39,7 @@
39 39 #include <net/netfilter/nf_conntrack_core.h>
40 40 #include <net/netfilter/nf_conntrack_extend.h>
41 41 #include <net/netfilter/nf_conntrack_acct.h>
  42 +#include <net/netfilter/nf_conntrack_ecache.h>
42 43 #include <net/netfilter/nf_nat.h>
43 44 #include <net/netfilter/nf_nat_core.h>
44 45  
... ... @@ -182,10 +183,6 @@
182 183 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
183 184 NF_CT_ASSERT(!timer_pending(&ct->timeout));
184 185  
185   - if (!test_bit(IPS_DYING_BIT, &ct->status))
186   - nf_conntrack_event(IPCT_DESTROY, ct);
187   - set_bit(IPS_DYING_BIT, &ct->status);
188   -
189 186 /* To make sure we don't get any weird locking issues here:
190 187 * destroy_conntrack() MUST NOT be called with a write lock
191 188 * to nf_conntrack_lock!!! -HW */
192 189  
193 190  
194 191  
195 192  
196 193  
... ... @@ -219,30 +216,73 @@
219 216 nf_conntrack_free(ct);
220 217 }
221 218  
222   -static void death_by_timeout(unsigned long ul_conntrack)
  219 +void nf_ct_delete_from_lists(struct nf_conn *ct)
223 220 {
224   - struct nf_conn *ct = (void *)ul_conntrack;
225 221 struct net *net = nf_ct_net(ct);
226   - struct nf_conn_help *help = nfct_help(ct);
227   - struct nf_conntrack_helper *helper;
228 222  
229   - if (help) {
230   - rcu_read_lock();
231   - helper = rcu_dereference(help->helper);
232   - if (helper && helper->destroy)
233   - helper->destroy(ct);
234   - rcu_read_unlock();
235   - }
236   -
  223 + nf_ct_helper_destroy(ct);
237 224 spin_lock_bh(&nf_conntrack_lock);
238 225 /* Inside lock so preempt is disabled on module removal path.
239 226 * Otherwise we can get spurious warnings. */
240 227 NF_CT_STAT_INC(net, delete_list);
241 228 clean_from_lists(ct);
242 229 spin_unlock_bh(&nf_conntrack_lock);
  230 +}
  231 +EXPORT_SYMBOL_GPL(nf_ct_delete_from_lists);
  232 +
  233 +static void death_by_event(unsigned long ul_conntrack)
  234 +{
  235 + struct nf_conn *ct = (void *)ul_conntrack;
  236 + struct net *net = nf_ct_net(ct);
  237 +
  238 + if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {
  239 + /* bad luck, let's retry again */
  240 + ct->timeout.expires = jiffies +
  241 + (random32() % net->ct.sysctl_events_retry_timeout);
  242 + add_timer(&ct->timeout);
  243 + return;
  244 + }
  245 + /* we've got the event delivered, now it's dying */
  246 + set_bit(IPS_DYING_BIT, &ct->status);
  247 + spin_lock(&nf_conntrack_lock);
  248 + hlist_nulls_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
  249 + spin_unlock(&nf_conntrack_lock);
243 250 nf_ct_put(ct);
244 251 }
245 252  
  253 +void nf_ct_insert_dying_list(struct nf_conn *ct)
  254 +{
  255 + struct net *net = nf_ct_net(ct);
  256 +
  257 + /* add this conntrack to the dying list */
  258 + spin_lock_bh(&nf_conntrack_lock);
  259 + hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
  260 + &net->ct.dying);
  261 + spin_unlock_bh(&nf_conntrack_lock);
  262 + /* set a new timer to retry event delivery */
  263 + setup_timer(&ct->timeout, death_by_event, (unsigned long)ct);
  264 + ct->timeout.expires = jiffies +
  265 + (random32() % net->ct.sysctl_events_retry_timeout);
  266 + add_timer(&ct->timeout);
  267 +}
  268 +EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list);
  269 +
  270 +static void death_by_timeout(unsigned long ul_conntrack)
  271 +{
  272 + struct nf_conn *ct = (void *)ul_conntrack;
  273 +
  274 + if (!test_bit(IPS_DYING_BIT, &ct->status) &&
  275 + unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) {
  276 + /* destroy event was not delivered */
  277 + nf_ct_delete_from_lists(ct);
  278 + nf_ct_insert_dying_list(ct);
  279 + return;
  280 + }
  281 + set_bit(IPS_DYING_BIT, &ct->status);
  282 + nf_ct_delete_from_lists(ct);
  283 + nf_ct_put(ct);
  284 +}
  285 +
246 286 /*
247 287 * Warning :
248 288 * - Caller must take a reference on returned object
... ... @@ -577,6 +617,7 @@
577 617 }
578 618  
579 619 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
  620 + nf_ct_ecache_ext_add(ct, GFP_ATOMIC);
580 621  
581 622 spin_lock_bh(&nf_conntrack_lock);
582 623 exp = nf_ct_find_expectation(net, tuple);
... ... @@ -807,8 +848,6 @@
807 848 NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
808 849 NF_CT_ASSERT(skb);
809 850  
810   - spin_lock_bh(&nf_conntrack_lock);
811   -
812 851 /* Only update if this is not a fixed timeout */
813 852 if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
814 853 goto acct;
... ... @@ -822,11 +861,8 @@
822 861 /* Only update the timeout if the new timeout is at least
823 862 HZ jiffies from the old timeout. Need del_timer for race
824 863 avoidance (may already be dying). */
825   - if (newtime - ct->timeout.expires >= HZ
826   - && del_timer(&ct->timeout)) {
827   - ct->timeout.expires = newtime;
828   - add_timer(&ct->timeout);
829   - }
  864 + if (newtime - ct->timeout.expires >= HZ)
  865 + mod_timer_pending(&ct->timeout, newtime);
830 866 }
831 867  
832 868 acct:
833 869  
834 870  
... ... @@ -835,13 +871,13 @@
835 871  
836 872 acct = nf_conn_acct_find(ct);
837 873 if (acct) {
  874 + spin_lock_bh(&ct->lock);
838 875 acct[CTINFO2DIR(ctinfo)].packets++;
839 876 acct[CTINFO2DIR(ctinfo)].bytes +=
840 877 skb->len - skb_network_offset(skb);
  878 + spin_unlock_bh(&ct->lock);
841 879 }
842 880 }
843   -
844   - spin_unlock_bh(&nf_conntrack_lock);
845 881 }
846 882 EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
847 883  
848 884  
849 885  
850 886  
... ... @@ -853,14 +889,14 @@
853 889 if (do_acct) {
854 890 struct nf_conn_counter *acct;
855 891  
856   - spin_lock_bh(&nf_conntrack_lock);
857 892 acct = nf_conn_acct_find(ct);
858 893 if (acct) {
  894 + spin_lock_bh(&ct->lock);
859 895 acct[CTINFO2DIR(ctinfo)].packets++;
860 896 acct[CTINFO2DIR(ctinfo)].bytes +=
861 897 skb->len - skb_network_offset(skb);
  898 + spin_unlock_bh(&ct->lock);
862 899 }
863   - spin_unlock_bh(&nf_conntrack_lock);
864 900 }
865 901  
866 902 if (del_timer(&ct->timeout)) {
... ... @@ -994,11 +1030,13 @@
994 1030 {
995 1031 struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
996 1032  
997   - /* get_next_corpse sets the dying bit for us */
998   - nf_conntrack_event_report(IPCT_DESTROY,
999   - i,
1000   - fr->pid,
1001   - fr->report);
  1033 + /* If we fail to deliver the event, death_by_timeout() will retry */
  1034 + if (nf_conntrack_event_report(IPCT_DESTROY, i,
  1035 + fr->pid, fr->report) < 0)
  1036 + return 1;
  1037 +
  1038 + /* Avoid the delivery of the destroy event in death_by_timeout(). */
  1039 + set_bit(IPS_DYING_BIT, &i->status);
1002 1040 return 1;
1003 1041 }
1004 1042  
... ... @@ -1027,6 +1065,21 @@
1027 1065 }
1028 1066 EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
1029 1067  
  1068 +static void nf_ct_release_dying_list(void)
  1069 +{
  1070 + struct nf_conntrack_tuple_hash *h;
  1071 + struct nf_conn *ct;
  1072 + struct hlist_nulls_node *n;
  1073 +
  1074 + spin_lock_bh(&nf_conntrack_lock);
  1075 + hlist_nulls_for_each_entry(h, n, &init_net.ct.dying, hnnode) {
  1076 + ct = nf_ct_tuplehash_to_ctrack(h);
  1077 + /* never fails to remove them, no listeners at this point */
  1078 + nf_ct_kill(ct);
  1079 + }
  1080 + spin_unlock_bh(&nf_conntrack_lock);
  1081 +}
  1082 +
1030 1083 static void nf_conntrack_cleanup_init_net(void)
1031 1084 {
1032 1085 nf_conntrack_helper_fini();
1033 1086  
... ... @@ -1036,10 +1089,9 @@
1036 1089  
1037 1090 static void nf_conntrack_cleanup_net(struct net *net)
1038 1091 {
1039   - nf_ct_event_cache_flush(net);
1040   - nf_conntrack_ecache_fini(net);
1041 1092 i_see_dead_people:
1042 1093 nf_ct_iterate_cleanup(net, kill_all, NULL);
  1094 + nf_ct_release_dying_list();
1043 1095 if (atomic_read(&net->ct.count) != 0) {
1044 1096 schedule();
1045 1097 goto i_see_dead_people;
... ... @@ -1050,6 +1102,7 @@
1050 1102  
1051 1103 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1052 1104 nf_conntrack_htable_size);
  1105 + nf_conntrack_ecache_fini(net);
1053 1106 nf_conntrack_acct_fini(net);
1054 1107 nf_conntrack_expect_fini(net);
1055 1108 free_percpu(net->ct.stat);
1056 1109  
... ... @@ -1220,14 +1273,12 @@
1220 1273  
1221 1274 atomic_set(&net->ct.count, 0);
1222 1275 INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, 0);
  1276 + INIT_HLIST_NULLS_HEAD(&net->ct.dying, 0);
1223 1277 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1224 1278 if (!net->ct.stat) {
1225 1279 ret = -ENOMEM;
1226 1280 goto err_stat;
1227 1281 }
1228   - ret = nf_conntrack_ecache_init(net);
1229   - if (ret < 0)
1230   - goto err_ecache;
1231 1282 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1232 1283 &net->ct.hash_vmalloc, 1);
1233 1284 if (!net->ct.hash) {
... ... @@ -1241,6 +1292,9 @@
1241 1292 ret = nf_conntrack_acct_init(net);
1242 1293 if (ret < 0)
1243 1294 goto err_acct;
  1295 + ret = nf_conntrack_ecache_init(net);
  1296 + if (ret < 0)
  1297 + goto err_ecache;
1244 1298  
1245 1299 /* Set up fake conntrack:
1246 1300 - to never be deleted, not in any hashes */
1247 1301  
... ... @@ -1253,14 +1307,14 @@
1253 1307  
1254 1308 return 0;
1255 1309  
  1310 +err_ecache:
  1311 + nf_conntrack_acct_fini(net);
1256 1312 err_acct:
1257 1313 nf_conntrack_expect_fini(net);
1258 1314 err_expect:
1259 1315 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1260 1316 nf_conntrack_htable_size);
1261 1317 err_hash:
1262   - nf_conntrack_ecache_fini(net);
1263   -err_ecache:
1264 1318 free_percpu(net->ct.stat);
1265 1319 err_stat:
1266 1320 return ret;
net/netfilter/nf_conntrack_ecache.c
... ... @@ -21,6 +21,7 @@
21 21  
22 22 #include <net/netfilter/nf_conntrack.h>
23 23 #include <net/netfilter/nf_conntrack_core.h>
  24 +#include <net/netfilter/nf_conntrack_extend.h>
24 25  
25 26 static DEFINE_MUTEX(nf_ct_ecache_mutex);
26 27  
27 28  
28 29  
29 30  
30 31  
31 32  
32 33  
33 34  
34 35  
35 36  
... ... @@ -32,94 +33,51 @@
32 33  
33 34 /* deliver cached events and clear cache entry - must be called with locally
34 35 * disabled softirqs */
35   -static inline void
36   -__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
  36 +void nf_ct_deliver_cached_events(struct nf_conn *ct)
37 37 {
  38 + unsigned long events;
38 39 struct nf_ct_event_notifier *notify;
  40 + struct nf_conntrack_ecache *e;
39 41  
40 42 rcu_read_lock();
41 43 notify = rcu_dereference(nf_conntrack_event_cb);
42 44 if (notify == NULL)
43 45 goto out_unlock;
44 46  
45   - if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
46   - && ecache->events) {
  47 + e = nf_ct_ecache_find(ct);
  48 + if (e == NULL)
  49 + goto out_unlock;
  50 +
  51 + events = xchg(&e->cache, 0);
  52 +
  53 + if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct) && events) {
47 54 struct nf_ct_event item = {
48   - .ct = ecache->ct,
  55 + .ct = ct,
49 56 .pid = 0,
50 57 .report = 0
51 58 };
  59 + int ret;
  60 + /* We make a copy of the missed event cache without taking
  61 + * the lock, thus we may send missed events twice. However,
  62 + * this does not harm and it happens very rarely. */
  63 + unsigned long missed = e->missed;
52 64  
53   - notify->fcn(ecache->events, &item);
  65 + ret = notify->fcn(events | missed, &item);
  66 + if (unlikely(ret < 0 || missed)) {
  67 + spin_lock_bh(&ct->lock);
  68 + if (ret < 0)
  69 + e->missed |= events;
  70 + else
  71 + e->missed &= ~missed;
  72 + spin_unlock_bh(&ct->lock);
  73 + }
54 74 }
55 75  
56   - ecache->events = 0;
57   - nf_ct_put(ecache->ct);
58   - ecache->ct = NULL;
59   -
60 76 out_unlock:
61 77 rcu_read_unlock();
62 78 }
63   -
64   -/* Deliver all cached events for a particular conntrack. This is called
65   - * by code prior to async packet handling for freeing the skb */
66   -void nf_ct_deliver_cached_events(const struct nf_conn *ct)
67   -{
68   - struct net *net = nf_ct_net(ct);
69   - struct nf_conntrack_ecache *ecache;
70   -
71   - local_bh_disable();
72   - ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
73   - if (ecache->ct == ct)
74   - __nf_ct_deliver_cached_events(ecache);
75   - local_bh_enable();
76   -}
77 79 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
78 80  
79   -/* Deliver cached events for old pending events, if current conntrack != old */
80   -void __nf_ct_event_cache_init(struct nf_conn *ct)
81   -{
82   - struct net *net = nf_ct_net(ct);
83   - struct nf_conntrack_ecache *ecache;
84   -
85   - /* take care of delivering potentially old events */
86   - ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
87   - BUG_ON(ecache->ct == ct);
88   - if (ecache->ct)
89   - __nf_ct_deliver_cached_events(ecache);
90   - /* initialize for this conntrack/packet */
91   - ecache->ct = ct;
92   - nf_conntrack_get(&ct->ct_general);
93   -}
94   -EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
95   -
96   -/* flush the event cache - touches other CPU's data and must not be called
97   - * while packets are still passing through the code */
98   -void nf_ct_event_cache_flush(struct net *net)
99   -{
100   - struct nf_conntrack_ecache *ecache;
101   - int cpu;
102   -
103   - for_each_possible_cpu(cpu) {
104   - ecache = per_cpu_ptr(net->ct.ecache, cpu);
105   - if (ecache->ct)
106   - nf_ct_put(ecache->ct);
107   - }
108   -}
109   -
110   -int nf_conntrack_ecache_init(struct net *net)
111   -{
112   - net->ct.ecache = alloc_percpu(struct nf_conntrack_ecache);
113   - if (!net->ct.ecache)
114   - return -ENOMEM;
115   - return 0;
116   -}
117   -
118   -void nf_conntrack_ecache_fini(struct net *net)
119   -{
120   - free_percpu(net->ct.ecache);
121   -}
122   -
123 81 int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
124 82 {
125 83 int ret = 0;
... ... @@ -185,4 +143,119 @@
185 143 mutex_unlock(&nf_ct_ecache_mutex);
186 144 }
187 145 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
  146 +
  147 +#define NF_CT_EVENTS_DEFAULT 1
  148 +static int nf_ct_events __read_mostly = NF_CT_EVENTS_DEFAULT;
  149 +static int nf_ct_events_retry_timeout __read_mostly = 15*HZ;
  150 +
  151 +#ifdef CONFIG_SYSCTL
  152 +static struct ctl_table event_sysctl_table[] = {
  153 + {
  154 + .ctl_name = CTL_UNNUMBERED,
  155 + .procname = "nf_conntrack_events",
  156 + .data = &init_net.ct.sysctl_events,
  157 + .maxlen = sizeof(unsigned int),
  158 + .mode = 0644,
  159 + .proc_handler = proc_dointvec,
  160 + },
  161 + {
  162 + .ctl_name = CTL_UNNUMBERED,
  163 + .procname = "nf_conntrack_events_retry_timeout",
  164 + .data = &init_net.ct.sysctl_events_retry_timeout,
  165 + .maxlen = sizeof(unsigned int),
  166 + .mode = 0644,
  167 + .proc_handler = proc_dointvec_jiffies,
  168 + },
  169 + {}
  170 +};
  171 +#endif /* CONFIG_SYSCTL */
  172 +
  173 +static struct nf_ct_ext_type event_extend __read_mostly = {
  174 + .len = sizeof(struct nf_conntrack_ecache),
  175 + .align = __alignof__(struct nf_conntrack_ecache),
  176 + .id = NF_CT_EXT_ECACHE,
  177 +};
  178 +
  179 +#ifdef CONFIG_SYSCTL
  180 +static int nf_conntrack_event_init_sysctl(struct net *net)
  181 +{
  182 + struct ctl_table *table;
  183 +
  184 + table = kmemdup(event_sysctl_table, sizeof(event_sysctl_table),
  185 + GFP_KERNEL);
  186 + if (!table)
  187 + goto out;
  188 +
  189 + table[0].data = &net->ct.sysctl_events;
  190 + table[1].data = &net->ct.sysctl_events_retry_timeout;
  191 +
  192 + net->ct.event_sysctl_header =
  193 + register_net_sysctl_table(net,
  194 + nf_net_netfilter_sysctl_path, table);
  195 + if (!net->ct.event_sysctl_header) {
  196 + printk(KERN_ERR "nf_ct_event: can't register to sysctl.\n");
  197 + goto out_register;
  198 + }
  199 + return 0;
  200 +
  201 +out_register:
  202 + kfree(table);
  203 +out:
  204 + return -ENOMEM;
  205 +}
  206 +
  207 +static void nf_conntrack_event_fini_sysctl(struct net *net)
  208 +{
  209 + struct ctl_table *table;
  210 +
  211 + table = net->ct.event_sysctl_header->ctl_table_arg;
  212 + unregister_net_sysctl_table(net->ct.event_sysctl_header);
  213 + kfree(table);
  214 +}
  215 +#else
  216 +static int nf_conntrack_event_init_sysctl(struct net *net)
  217 +{
  218 + return 0;
  219 +}
  220 +
  221 +static void nf_conntrack_event_fini_sysctl(struct net *net)
  222 +{
  223 +}
  224 +#endif /* CONFIG_SYSCTL */
  225 +
  226 +int nf_conntrack_ecache_init(struct net *net)
  227 +{
  228 + int ret;
  229 +
  230 + net->ct.sysctl_events = nf_ct_events;
  231 + net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout;
  232 +
  233 + if (net_eq(net, &init_net)) {
  234 + ret = nf_ct_extend_register(&event_extend);
  235 + if (ret < 0) {
  236 + printk(KERN_ERR "nf_ct_event: Unable to register "
  237 + "event extension.\n");
  238 + goto out_extend_register;
  239 + }
  240 + }
  241 +
  242 + ret = nf_conntrack_event_init_sysctl(net);
  243 + if (ret < 0)
  244 + goto out_sysctl;
  245 +
  246 + return 0;
  247 +
  248 +out_sysctl:
  249 + if (net_eq(net, &init_net))
  250 + nf_ct_extend_unregister(&event_extend);
  251 +out_extend_register:
  252 + return ret;
  253 +}
  254 +
  255 +void nf_conntrack_ecache_fini(struct net *net)
  256 +{
  257 + nf_conntrack_event_fini_sysctl(net);
  258 + if (net_eq(net, &init_net))
  259 + nf_ct_extend_unregister(&event_extend);
  260 +}
net/netfilter/nf_conntrack_helper.c
... ... @@ -136,6 +136,20 @@
136 136 return 0;
137 137 }
138 138  
  139 +void nf_ct_helper_destroy(struct nf_conn *ct)
  140 +{
  141 + struct nf_conn_help *help = nfct_help(ct);
  142 + struct nf_conntrack_helper *helper;
  143 +
  144 + if (help) {
  145 + rcu_read_lock();
  146 + helper = rcu_dereference(help->helper);
  147 + if (helper && helper->destroy)
  148 + helper->destroy(ct);
  149 + rcu_read_unlock();
  150 + }
  151 +}
  152 +
139 153 int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
140 154 {
141 155 unsigned int h = helper_hash(&me->tuple);
net/netfilter/nf_conntrack_netlink.c
... ... @@ -463,15 +463,16 @@
463 463 struct sk_buff *skb;
464 464 unsigned int type;
465 465 unsigned int flags = 0, group;
  466 + int err;
466 467  
467 468 /* ignore our fake conntrack entry */
468 469 if (ct == &nf_conntrack_untracked)
469 470 return 0;
470 471  
471   - if (events & IPCT_DESTROY) {
  472 + if (events & (1 << IPCT_DESTROY)) {
472 473 type = IPCTNL_MSG_CT_DELETE;
473 474 group = NFNLGRP_CONNTRACK_DESTROY;
474   - } else if (events & (IPCT_NEW | IPCT_RELATED)) {
  475 + } else if (events & ((1 << IPCT_NEW) | (1 << IPCT_RELATED))) {
475 476 type = IPCTNL_MSG_CT_NEW;
476 477 flags = NLM_F_CREATE|NLM_F_EXCL;
477 478 group = NFNLGRP_CONNTRACK_NEW;
... ... @@ -519,7 +520,7 @@
519 520 if (ctnetlink_dump_status(skb, ct) < 0)
520 521 goto nla_put_failure;
521 522  
522   - if (events & IPCT_DESTROY) {
  523 + if (events & (1 << IPCT_DESTROY)) {
523 524 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
524 525 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
525 526 goto nla_put_failure;
526 527  
527 528  
528 529  
529 530  
530 531  
531 532  
... ... @@ -527,38 +528,41 @@
527 528 if (ctnetlink_dump_timeout(skb, ct) < 0)
528 529 goto nla_put_failure;
529 530  
530   - if (events & IPCT_PROTOINFO
  531 + if (events & (1 << IPCT_PROTOINFO)
531 532 && ctnetlink_dump_protoinfo(skb, ct) < 0)
532 533 goto nla_put_failure;
533 534  
534   - if ((events & IPCT_HELPER || nfct_help(ct))
  535 + if ((events & (1 << IPCT_HELPER) || nfct_help(ct))
535 536 && ctnetlink_dump_helpinfo(skb, ct) < 0)
536 537 goto nla_put_failure;
537 538  
538 539 #ifdef CONFIG_NF_CONNTRACK_SECMARK
539   - if ((events & IPCT_SECMARK || ct->secmark)
  540 + if ((events & (1 << IPCT_SECMARK) || ct->secmark)
540 541 && ctnetlink_dump_secmark(skb, ct) < 0)
541 542 goto nla_put_failure;
542 543 #endif
543 544  
544   - if (events & IPCT_RELATED &&
  545 + if (events & (1 << IPCT_RELATED) &&
545 546 ctnetlink_dump_master(skb, ct) < 0)
546 547 goto nla_put_failure;
547 548  
548   - if (events & IPCT_NATSEQADJ &&
  549 + if (events & (1 << IPCT_NATSEQADJ) &&
549 550 ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
550 551 goto nla_put_failure;
551 552 }
552 553  
553 554 #ifdef CONFIG_NF_CONNTRACK_MARK
554   - if ((events & IPCT_MARK || ct->mark)
  555 + if ((events & (1 << IPCT_MARK) || ct->mark)
555 556 && ctnetlink_dump_mark(skb, ct) < 0)
556 557 goto nla_put_failure;
557 558 #endif
558 559 rcu_read_unlock();
559 560  
560 561 nlmsg_end(skb, nlh);
561   - nfnetlink_send(skb, item->pid, group, item->report, GFP_ATOMIC);
  562 + err = nfnetlink_send(skb, item->pid, group, item->report, GFP_ATOMIC);
  563 + if (err == -ENOBUFS || err == -EAGAIN)
  564 + return -ENOBUFS;
  565 +
562 566 return 0;
563 567  
564 568 nla_put_failure:
... ... @@ -798,10 +802,15 @@
798 802 }
799 803 }
800 804  
801   - nf_conntrack_event_report(IPCT_DESTROY,
802   - ct,
803   - NETLINK_CB(skb).pid,
804   - nlmsg_report(nlh));
  805 + if (nf_conntrack_event_report(IPCT_DESTROY, ct,
  806 + NETLINK_CB(skb).pid,
  807 + nlmsg_report(nlh)) < 0) {
  808 + nf_ct_delete_from_lists(ct);
  809 + /* we failed to report the event, try later */
  810 + nf_ct_insert_dying_list(ct);
  811 + nf_ct_put(ct);
  812 + return 0;
  813 + }
805 814  
806 815 /* death_by_timeout would report the event again */
807 816 set_bit(IPS_DYING_BIT, &ct->status);
... ... @@ -1253,6 +1262,7 @@
1253 1262 }
1254 1263  
1255 1264 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
  1265 + nf_ct_ecache_ext_add(ct, GFP_ATOMIC);
1256 1266  
1257 1267 #if defined(CONFIG_NF_CONNTRACK_MARK)
1258 1268 if (cda[CTA_MARK])
... ... @@ -1340,13 +1350,13 @@
1340 1350 else
1341 1351 events = IPCT_NEW;
1342 1352  
1343   - nf_conntrack_event_report(IPCT_STATUS |
1344   - IPCT_HELPER |
1345   - IPCT_PROTOINFO |
1346   - IPCT_NATSEQADJ |
1347   - IPCT_MARK | events,
1348   - ct, NETLINK_CB(skb).pid,
1349   - nlmsg_report(nlh));
  1353 + nf_conntrack_eventmask_report((1 << IPCT_STATUS) |
  1354 + (1 << IPCT_HELPER) |
  1355 + (1 << IPCT_PROTOINFO) |
  1356 + (1 << IPCT_NATSEQADJ) |
  1357 + (1 << IPCT_MARK) | events,
  1358 + ct, NETLINK_CB(skb).pid,
  1359 + nlmsg_report(nlh));
1350 1360 nf_ct_put(ct);
1351 1361 } else
1352 1362 spin_unlock_bh(&nf_conntrack_lock);
... ... @@ -1365,13 +1375,13 @@
1365 1375 if (err == 0) {
1366 1376 nf_conntrack_get(&ct->ct_general);
1367 1377 spin_unlock_bh(&nf_conntrack_lock);
1368   - nf_conntrack_event_report(IPCT_STATUS |
1369   - IPCT_HELPER |
1370   - IPCT_PROTOINFO |
1371   - IPCT_NATSEQADJ |
1372   - IPCT_MARK,
1373   - ct, NETLINK_CB(skb).pid,
1374   - nlmsg_report(nlh));
  1378 + nf_conntrack_eventmask_report((1 << IPCT_STATUS) |
  1379 + (1 << IPCT_HELPER) |
  1380 + (1 << IPCT_PROTOINFO) |
  1381 + (1 << IPCT_NATSEQADJ) |
  1382 + (1 << IPCT_MARK),
  1383 + ct, NETLINK_CB(skb).pid,
  1384 + nlmsg_report(nlh));
1375 1385 nf_ct_put(ct);
1376 1386 } else
1377 1387 spin_unlock_bh(&nf_conntrack_lock);
... ... @@ -1515,7 +1525,7 @@
1515 1525 unsigned int type;
1516 1526 int flags = 0;
1517 1527  
1518   - if (events & IPEXP_NEW) {
  1528 + if (events & (1 << IPEXP_NEW)) {
1519 1529 type = IPCTNL_MSG_EXP_NEW;
1520 1530 flags = NLM_F_CREATE|NLM_F_EXCL;
1521 1531 } else
net/netfilter/nf_log.c
... ... @@ -248,14 +248,14 @@
248 248 rcu_assign_pointer(nf_loggers[tindex], logger);
249 249 mutex_unlock(&nf_log_mutex);
250 250 } else {
251   - rcu_read_lock();
252   - logger = rcu_dereference(nf_loggers[tindex]);
  251 + mutex_lock(&nf_log_mutex);
  252 + logger = nf_loggers[tindex];
253 253 if (!logger)
254 254 table->data = "NONE";
255 255 else
256 256 table->data = logger->name;
257 257 r = proc_dostring(table, write, filp, buffer, lenp, ppos);
258   - rcu_read_unlock();
  258 + mutex_unlock(&nf_log_mutex);
259 259 }
260 260  
261 261 return r;
net/netfilter/x_tables.c
... ... @@ -364,14 +364,14 @@
364 364 * ebt_among is exempt from centralized matchsize checking
365 365 * because it uses a dynamic-size data set.
366 366 */
367   - printk("%s_tables: %s match: invalid size %Zu != %u\n",
  367 + pr_err("%s_tables: %s match: invalid size %Zu != %u\n",
368 368 xt_prefix[par->family], par->match->name,
369 369 XT_ALIGN(par->match->matchsize), size);
370 370 return -EINVAL;
371 371 }
372 372 if (par->match->table != NULL &&
373 373 strcmp(par->match->table, par->table) != 0) {
374   - printk("%s_tables: %s match: only valid in %s table, not %s\n",
  374 + pr_err("%s_tables: %s match: only valid in %s table, not %s\n",
375 375 xt_prefix[par->family], par->match->name,
376 376 par->match->table, par->table);
377 377 return -EINVAL;
... ... @@ -379,7 +379,7 @@
379 379 if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
380 380 char used[64], allow[64];
381 381  
382   - printk("%s_tables: %s match: used from hooks %s, but only "
  382 + pr_err("%s_tables: %s match: used from hooks %s, but only "
383 383 "valid from %s\n",
384 384 xt_prefix[par->family], par->match->name,
385 385 textify_hooks(used, sizeof(used), par->hook_mask),
... ... @@ -387,7 +387,7 @@
387 387 return -EINVAL;
388 388 }
389 389 if (par->match->proto && (par->match->proto != proto || inv_proto)) {
390   - printk("%s_tables: %s match: only valid for protocol %u\n",
  390 + pr_err("%s_tables: %s match: only valid for protocol %u\n",
391 391 xt_prefix[par->family], par->match->name,
392 392 par->match->proto);
393 393 return -EINVAL;
394 394  
... ... @@ -514,14 +514,14 @@
514 514 unsigned int size, u_int8_t proto, bool inv_proto)
515 515 {
516 516 if (XT_ALIGN(par->target->targetsize) != size) {
517   - printk("%s_tables: %s target: invalid size %Zu != %u\n",
  517 + pr_err("%s_tables: %s target: invalid size %Zu != %u\n",
518 518 xt_prefix[par->family], par->target->name,
519 519 XT_ALIGN(par->target->targetsize), size);
520 520 return -EINVAL;
521 521 }
522 522 if (par->target->table != NULL &&
523 523 strcmp(par->target->table, par->table) != 0) {
524   - printk("%s_tables: %s target: only valid in %s table, not %s\n",
  524 + pr_err("%s_tables: %s target: only valid in %s table, not %s\n",
525 525 xt_prefix[par->family], par->target->name,
526 526 par->target->table, par->table);
527 527 return -EINVAL;
... ... @@ -529,7 +529,7 @@
529 529 if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
530 530 char used[64], allow[64];
531 531  
532   - printk("%s_tables: %s target: used from hooks %s, but only "
  532 + pr_err("%s_tables: %s target: used from hooks %s, but only "
533 533 "usable from %s\n",
534 534 xt_prefix[par->family], par->target->name,
535 535 textify_hooks(used, sizeof(used), par->hook_mask),
... ... @@ -537,7 +537,7 @@
537 537 return -EINVAL;
538 538 }
539 539 if (par->target->proto && (par->target->proto != proto || inv_proto)) {
540   - printk("%s_tables: %s target: only valid for protocol %u\n",
  540 + pr_err("%s_tables: %s target: only valid for protocol %u\n",
541 541 xt_prefix[par->family], par->target->name,
542 542 par->target->proto);
543 543 return -EINVAL;