Blame view

net/netfilter/nfnetlink_log.c 26.9 KB
0597f2680   Harald Welte   [NETFILTER]: Add ...
1
2
3
4
5
  /*
   * This is a module which is used for logging packets to userspace via
   * nfetlink.
   *
   * (C) 2005 by Harald Welte <laforge@netfilter.org>
f229f6ce4   Patrick McHardy   netfilter: add my...
6
   * (C) 2006-2012 Patrick McHardy <kaber@trash.net>
0597f2680   Harald Welte   [NETFILTER]: Add ...
7
8
9
10
11
12
13
   *
   * Based on the old ipv4-only ipt_ULOG.c:
   * (C) 2000-2004 by Harald Welte <laforge@netfilter.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
0597f2680   Harald Welte   [NETFILTER]: Add ...
14
15
16
   */
  #include <linux/module.h>
  #include <linux/skbuff.h>
e035edd16   Pablo Neira Ayuso   netfilter: nfnetl...
17
  #include <linux/if_arp.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
18
19
20
21
22
  #include <linux/init.h>
  #include <linux/ip.h>
  #include <linux/ipv6.h>
  #include <linux/netdevice.h>
  #include <linux/netfilter.h>
573ce260b   Hong zhi guo   net-next: replace...
23
  #include <net/netlink.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
24
25
26
27
28
29
30
31
32
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_log.h>
  #include <linux/spinlock.h>
  #include <linux/sysctl.h>
  #include <linux/proc_fs.h>
  #include <linux/security.h>
  #include <linux/list.h>
  #include <linux/jhash.h>
  #include <linux/random.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
33
  #include <linux/slab.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
34
  #include <net/sock.h>
f01ffbd6e   Patrick McHardy   [NETFILTER]: nf_l...
35
  #include <net/netfilter/nf_log.h>
9368a53c4   Gao feng   netfilter: nfnetl...
36
  #include <net/netns/generic.h>
d9e150071   Patrick McHardy   netfilter: nfnetl...
37
  #include <net/netfilter/nfnetlink_log.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
38

60063497a   Arun Sharma   atomic: use <linu...
39
  #include <linux/atomic.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
40

fbcd923c3   Harald Welte   [NETFILTER]: add ...
41
42
43
  #ifdef CONFIG_BRIDGE_NETFILTER
  #include "../bridge/br_private.h"
  #endif
c2db29243   Holger Eitzenberger   [NETFILTER]: ULOG...
44
  #define NFULNL_NLBUFSIZ_DEFAULT	NLMSG_GOODSIZE
2c6764b74   Eric Leblond   netfilter: nfnetl...
45
  #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
0597f2680   Harald Welte   [NETFILTER]: Add ...
46
  #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
6b6ec99a0   Michal Miroslaw   [NETFILTER]: nfne...
47
  #define NFULNL_COPY_RANGE_MAX	0xFFFF	/* max packet size is limited by 16-bit struct nfattr nfa_len field */
0597f2680   Harald Welte   [NETFILTER]: Add ...
48
49
50
  
  #define PRINTR(x, args...)	do { if (net_ratelimit()) \
  				     printk(x, ## args); } while (0);
0597f2680   Harald Welte   [NETFILTER]: Add ...
51
52
53
54
55
56
57
  struct nfulnl_instance {
  	struct hlist_node hlist;	/* global list of instances */
  	spinlock_t lock;
  	atomic_t use;			/* use count */
  
  	unsigned int qlen;		/* number of nlmsgs in skb */
  	struct sk_buff *skb;		/* pre-allocatd skb */
0597f2680   Harald Welte   [NETFILTER]: Add ...
58
  	struct timer_list timer;
9368a53c4   Gao feng   netfilter: nfnetl...
59
  	struct net *net;
9eea9515c   Eric W. Biederman   userns: nfnetlink...
60
  	struct user_namespace *peer_user_ns;	/* User namespace of the peer process */
15e473046   Eric W. Biederman   netlink: Rename p...
61
  	int peer_portid;			/* PORTID of the peer process */
0597f2680   Harald Welte   [NETFILTER]: Add ...
62
63
64
65
66
67
  
  	/* configurable parameters */
  	unsigned int flushtimeout;	/* timeout until queue flush */
  	unsigned int nlbufsiz;		/* netlink buffer allocation size */
  	unsigned int qthreshold;	/* threshold of the queue */
  	u_int32_t copy_range;
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
68
  	u_int32_t seq;			/* instance-local sequential counter */
0597f2680   Harald Welte   [NETFILTER]: Add ...
69
  	u_int16_t group_num;		/* number of this queue */
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
70
  	u_int16_t flags;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
71
  	u_int8_t copy_mode;
bed1be208   Eric Dumazet   netfilter: nfnetl...
72
  	struct rcu_head rcu;
0597f2680   Harald Welte   [NETFILTER]: Add ...
73
  };
0597f2680   Harald Welte   [NETFILTER]: Add ...
74
  #define INSTANCE_BUCKETS	16
0597f2680   Harald Welte   [NETFILTER]: Add ...
75
  static unsigned int hash_init;
9368a53c4   Gao feng   netfilter: nfnetl...
76
77
78
79
80
81
82
83
84
85
86
87
  static int nfnl_log_net_id __read_mostly;
  
  struct nfnl_log_net {
  	spinlock_t instances_lock;
  	struct hlist_head instance_table[INSTANCE_BUCKETS];
  	atomic_t global_seq;
  };
  
  static struct nfnl_log_net *nfnl_log_pernet(struct net *net)
  {
  	return net_generic(net, nfnl_log_net_id);
  }
0597f2680   Harald Welte   [NETFILTER]: Add ...
88
89
90
91
92
93
  static inline u_int8_t instance_hashfn(u_int16_t group_num)
  {
  	return ((group_num & 0xff) % INSTANCE_BUCKETS);
  }
  
  static struct nfulnl_instance *
9368a53c4   Gao feng   netfilter: nfnetl...
94
  __instance_lookup(struct nfnl_log_net *log, u_int16_t group_num)
0597f2680   Harald Welte   [NETFILTER]: Add ...
95
96
  {
  	struct hlist_head *head;
0597f2680   Harald Welte   [NETFILTER]: Add ...
97
  	struct nfulnl_instance *inst;
9368a53c4   Gao feng   netfilter: nfnetl...
98
  	head = &log->instance_table[instance_hashfn(group_num)];
b67bfe0d4   Sasha Levin   hlist: drop the n...
99
  	hlist_for_each_entry_rcu(inst, head, hlist) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
100
101
102
103
104
105
106
107
108
109
110
111
112
  		if (inst->group_num == group_num)
  			return inst;
  	}
  	return NULL;
  }
  
  static inline void
  instance_get(struct nfulnl_instance *inst)
  {
  	atomic_inc(&inst->use);
  }
  
  static struct nfulnl_instance *
9368a53c4   Gao feng   netfilter: nfnetl...
113
  instance_lookup_get(struct nfnl_log_net *log, u_int16_t group_num)
0597f2680   Harald Welte   [NETFILTER]: Add ...
114
115
  {
  	struct nfulnl_instance *inst;
bed1be208   Eric Dumazet   netfilter: nfnetl...
116
  	rcu_read_lock_bh();
9368a53c4   Gao feng   netfilter: nfnetl...
117
  	inst = __instance_lookup(log, group_num);
f5c5440d4   Eric Dumazet   netfilter: nfnetl...
118
119
  	if (inst && !atomic_inc_not_zero(&inst->use))
  		inst = NULL;
bed1be208   Eric Dumazet   netfilter: nfnetl...
120
  	rcu_read_unlock_bh();
0597f2680   Harald Welte   [NETFILTER]: Add ...
121
122
123
  
  	return inst;
  }
bed1be208   Eric Dumazet   netfilter: nfnetl...
124
125
  static void nfulnl_instance_free_rcu(struct rcu_head *head)
  {
9368a53c4   Gao feng   netfilter: nfnetl...
126
127
128
129
130
  	struct nfulnl_instance *inst =
  		container_of(head, struct nfulnl_instance, rcu);
  
  	put_net(inst->net);
  	kfree(inst);
bed1be208   Eric Dumazet   netfilter: nfnetl...
131
132
  	module_put(THIS_MODULE);
  }
0597f2680   Harald Welte   [NETFILTER]: Add ...
133
134
135
  static void
  instance_put(struct nfulnl_instance *inst)
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
136
137
  	if (inst && atomic_dec_and_test(&inst->use))
  		call_rcu_bh(&inst->rcu, nfulnl_instance_free_rcu);
0597f2680   Harald Welte   [NETFILTER]: Add ...
138
139
140
141
142
  }
  
  static void nfulnl_timer(unsigned long data);
  
  static struct nfulnl_instance *
9368a53c4   Gao feng   netfilter: nfnetl...
143
144
  instance_create(struct net *net, u_int16_t group_num,
  		int portid, struct user_namespace *user_ns)
0597f2680   Harald Welte   [NETFILTER]: Add ...
145
146
  {
  	struct nfulnl_instance *inst;
9368a53c4   Gao feng   netfilter: nfnetl...
147
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
148
  	int err;
0597f2680   Harald Welte   [NETFILTER]: Add ...
149

9368a53c4   Gao feng   netfilter: nfnetl...
150
151
  	spin_lock_bh(&log->instances_lock);
  	if (__instance_lookup(log, group_num)) {
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
152
  		err = -EEXIST;
0597f2680   Harald Welte   [NETFILTER]: Add ...
153
154
  		goto out_unlock;
  	}
10dfdc69e   Harald Welte   [NETFILTER] nfnet...
155
  	inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
156
157
  	if (!inst) {
  		err = -ENOMEM;
0597f2680   Harald Welte   [NETFILTER]: Add ...
158
  		goto out_unlock;
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
159
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
160

aace57e05   Michal Miroslaw   [NETFILTER]: nfne...
161
162
  	if (!try_module_get(THIS_MODULE)) {
  		kfree(inst);
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
163
  		err = -EAGAIN;
aace57e05   Michal Miroslaw   [NETFILTER]: nfne...
164
165
  		goto out_unlock;
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
166
  	INIT_HLIST_NODE(&inst->hlist);
181a46a56   YOSHIFUJI Hideaki   [NETFILTER]: Use ...
167
  	spin_lock_init(&inst->lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
168
169
  	/* needs to be two, since we _put() after creation */
  	atomic_set(&inst->use, 2);
e6f689db5   Patrick McHardy   [NETFILTER]: Use ...
170
  	setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
171

9368a53c4   Gao feng   netfilter: nfnetl...
172
  	inst->net = get_net(net);
9eea9515c   Eric W. Biederman   userns: nfnetlink...
173
  	inst->peer_user_ns = user_ns;
15e473046   Eric W. Biederman   netlink: Rename p...
174
  	inst->peer_portid = portid;
0597f2680   Harald Welte   [NETFILTER]: Add ...
175
176
177
178
179
180
  	inst->group_num = group_num;
  
  	inst->qthreshold 	= NFULNL_QTHRESH_DEFAULT;
  	inst->flushtimeout 	= NFULNL_TIMEOUT_DEFAULT;
  	inst->nlbufsiz 		= NFULNL_NLBUFSIZ_DEFAULT;
  	inst->copy_mode 	= NFULNL_COPY_PACKET;
6b6ec99a0   Michal Miroslaw   [NETFILTER]: nfne...
181
  	inst->copy_range 	= NFULNL_COPY_RANGE_MAX;
0597f2680   Harald Welte   [NETFILTER]: Add ...
182

f5c5440d4   Eric Dumazet   netfilter: nfnetl...
183
  	hlist_add_head_rcu(&inst->hlist,
9368a53c4   Gao feng   netfilter: nfnetl...
184
  		       &log->instance_table[instance_hashfn(group_num)]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
185

9368a53c4   Gao feng   netfilter: nfnetl...
186
  	spin_unlock_bh(&log->instances_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
187
188
  
  	return inst;
0597f2680   Harald Welte   [NETFILTER]: Add ...
189
  out_unlock:
9368a53c4   Gao feng   netfilter: nfnetl...
190
  	spin_unlock_bh(&log->instances_lock);
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
191
  	return ERR_PTR(err);
0597f2680   Harald Welte   [NETFILTER]: Add ...
192
  }
e35670614   Michal Miroslaw   [NETFILTER]: nfne...
193
  static void __nfulnl_flush(struct nfulnl_instance *inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
194

f5c5440d4   Eric Dumazet   netfilter: nfnetl...
195
  /* called with BH disabled */
0597f2680   Harald Welte   [NETFILTER]: Add ...
196
  static void
9afdb00c8   Patrick McHardy   [NETFILTER]: nfne...
197
  __instance_destroy(struct nfulnl_instance *inst)
0597f2680   Harald Welte   [NETFILTER]: Add ...
198
199
  {
  	/* first pull it out of the global list */
f5c5440d4   Eric Dumazet   netfilter: nfnetl...
200
  	hlist_del_rcu(&inst->hlist);
0597f2680   Harald Welte   [NETFILTER]: Add ...
201

0597f2680   Harald Welte   [NETFILTER]: Add ...
202
  	/* then flush all pending packets from skb */
f5c5440d4   Eric Dumazet   netfilter: nfnetl...
203
204
205
206
  	spin_lock(&inst->lock);
  
  	/* lockless readers wont be able to use us */
  	inst->copy_mode = NFULNL_COPY_DISABLED;
e35670614   Michal Miroslaw   [NETFILTER]: nfne...
207
208
  	if (inst->skb)
  		__nfulnl_flush(inst);
f5c5440d4   Eric Dumazet   netfilter: nfnetl...
209
  	spin_unlock(&inst->lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
210
211
212
  
  	/* and finally put the refcount */
  	instance_put(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
213
214
215
  }
  
  static inline void
9368a53c4   Gao feng   netfilter: nfnetl...
216
217
  instance_destroy(struct nfnl_log_net *log,
  		 struct nfulnl_instance *inst)
0597f2680   Harald Welte   [NETFILTER]: Add ...
218
  {
9368a53c4   Gao feng   netfilter: nfnetl...
219
  	spin_lock_bh(&log->instances_lock);
9afdb00c8   Patrick McHardy   [NETFILTER]: nfne...
220
  	__instance_destroy(inst);
9368a53c4   Gao feng   netfilter: nfnetl...
221
  	spin_unlock_bh(&log->instances_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
222
223
224
225
226
227
228
229
230
  }
  
  static int
  nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode,
  		  unsigned int range)
  {
  	int status = 0;
  
  	spin_lock_bh(&inst->lock);
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
231

0597f2680   Harald Welte   [NETFILTER]: Add ...
232
233
234
235
236
237
  	switch (mode) {
  	case NFULNL_COPY_NONE:
  	case NFULNL_COPY_META:
  		inst->copy_mode = mode;
  		inst->copy_range = 0;
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
238

0597f2680   Harald Welte   [NETFILTER]: Add ...
239
240
  	case NFULNL_COPY_PACKET:
  		inst->copy_mode = mode;
6b6ec99a0   Michal Miroslaw   [NETFILTER]: nfne...
241
242
  		inst->copy_range = min_t(unsigned int,
  					 range, NFULNL_COPY_RANGE_MAX);
0597f2680   Harald Welte   [NETFILTER]: Add ...
243
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
244

0597f2680   Harald Welte   [NETFILTER]: Add ...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  	default:
  		status = -EINVAL;
  		break;
  	}
  
  	spin_unlock_bh(&inst->lock);
  
  	return status;
  }
  
  static int
  nfulnl_set_nlbufsiz(struct nfulnl_instance *inst, u_int32_t nlbufsiz)
  {
  	int status;
  
  	spin_lock_bh(&inst->lock);
  	if (nlbufsiz < NFULNL_NLBUFSIZ_DEFAULT)
  		status = -ERANGE;
  	else if (nlbufsiz > 131072)
  		status = -ERANGE;
  	else {
  		inst->nlbufsiz = nlbufsiz;
  		status = 0;
  	}
  	spin_unlock_bh(&inst->lock);
  
  	return status;
  }
  
  static int
  nfulnl_set_timeout(struct nfulnl_instance *inst, u_int32_t timeout)
  {
  	spin_lock_bh(&inst->lock);
  	inst->flushtimeout = timeout;
  	spin_unlock_bh(&inst->lock);
  
  	return 0;
  }
  
  static int
  nfulnl_set_qthresh(struct nfulnl_instance *inst, u_int32_t qthresh)
  {
  	spin_lock_bh(&inst->lock);
  	inst->qthreshold = qthresh;
  	spin_unlock_bh(&inst->lock);
  
  	return 0;
  }
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
293
294
295
296
  static int
  nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags)
  {
  	spin_lock_bh(&inst->lock);
ee433530d   Patrick McHardy   [NETFILTER]: nfne...
297
  	inst->flags = flags;
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
298
299
300
301
  	spin_unlock_bh(&inst->lock);
  
  	return 0;
  }
c6a8f6483   Michal Miroslaw   [NETFILTER]: nfne...
302
  static struct sk_buff *
3ab1f683b   Patrick McHardy   nfnetlink: add su...
303
  nfulnl_alloc_skb(u32 peer_portid, unsigned int inst_size, unsigned int pkt_size)
0597f2680   Harald Welte   [NETFILTER]: Add ...
304
305
  {
  	struct sk_buff *skb;
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
306
  	unsigned int n;
0597f2680   Harald Welte   [NETFILTER]: Add ...
307

0597f2680   Harald Welte   [NETFILTER]: Add ...
308
309
  	/* alloc skb which should be big enough for a whole multipart
  	 * message.  WARNING: has to be <= 128k due to slab restrictions */
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
310
  	n = max(inst_size, pkt_size);
3ab1f683b   Patrick McHardy   nfnetlink: add su...
311
  	skb = nfnetlink_alloc_skb(&init_net, n, peer_portid, GFP_ATOMIC);
0597f2680   Harald Welte   [NETFILTER]: Add ...
312
  	if (!skb) {
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
313
314
315
  		if (n > pkt_size) {
  			/* try to allocate only as much as we need for current
  			 * packet */
0597f2680   Harald Welte   [NETFILTER]: Add ...
316

3ab1f683b   Patrick McHardy   nfnetlink: add su...
317
318
  			skb = nfnetlink_alloc_skb(&init_net, pkt_size,
  						  peer_portid, GFP_ATOMIC);
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
319
  			if (!skb)
0a9ee8134   Joe Perches   netfilter: Remove...
320
321
322
  				pr_err("nfnetlink_log: can't even alloc %u bytes
  ",
  				       pkt_size);
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
323
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
324
325
326
327
328
329
330
331
  	}
  
  	return skb;
  }
  
  static int
  __nfulnl_send(struct nfulnl_instance *inst)
  {
29c5d4afb   Eric Leblond   [NETFILTER]: nfne...
332
  	int status = -1;
0597f2680   Harald Welte   [NETFILTER]: Add ...
333

d550d0958   David S. Miller   netfilter: nfnetl...
334
335
336
337
338
339
340
341
  	if (inst->qlen > 1) {
  		struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
  						 NLMSG_DONE,
  						 sizeof(struct nfgenmsg),
  						 0);
  		if (!nlh)
  			goto out;
  	}
9368a53c4   Gao feng   netfilter: nfnetl...
342
  	status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
cd8c20b65   Alexey Dobriyan   netfilter: nfnetl...
343
  				   MSG_DONTWAIT);
0597f2680   Harald Welte   [NETFILTER]: Add ...
344
345
346
  
  	inst->qlen = 0;
  	inst->skb = NULL;
d550d0958   David S. Miller   netfilter: nfnetl...
347
  out:
0597f2680   Harald Welte   [NETFILTER]: Add ...
348
349
  	return status;
  }
e35670614   Michal Miroslaw   [NETFILTER]: nfne...
350
351
352
353
354
355
356
357
358
  static void
  __nfulnl_flush(struct nfulnl_instance *inst)
  {
  	/* timer holds a reference */
  	if (del_timer(&inst->timer))
  		instance_put(inst);
  	if (inst->skb)
  		__nfulnl_send(inst);
  }
c6a8f6483   Michal Miroslaw   [NETFILTER]: nfne...
359
360
  static void
  nfulnl_timer(unsigned long data)
0597f2680   Harald Welte   [NETFILTER]: Add ...
361
  {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
362
  	struct nfulnl_instance *inst = (struct nfulnl_instance *)data;
0597f2680   Harald Welte   [NETFILTER]: Add ...
363

0597f2680   Harald Welte   [NETFILTER]: Add ...
364
  	spin_lock_bh(&inst->lock);
370e6a878   Michal Miroslaw   [NETFILTER]: nfne...
365
366
  	if (inst->skb)
  		__nfulnl_send(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
367
  	spin_unlock_bh(&inst->lock);
05f7b7b36   Michal Miroslaw   [NETFILTER]: nfne...
368
  	instance_put(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
369
  }
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
370
371
  /* This is an inline function, we don't really care about a long
   * list of arguments */
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
372
  static inline int
9368a53c4   Gao feng   netfilter: nfnetl...
373
374
  __build_packet_message(struct nfnl_log_net *log,
  			struct nfulnl_instance *inst,
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
375
  			const struct sk_buff *skb,
0597f2680   Harald Welte   [NETFILTER]: Add ...
376
  			unsigned int data_len,
76108cea0   Jan Engelhardt   netfilter: Use un...
377
  			u_int8_t pf,
0597f2680   Harald Welte   [NETFILTER]: Add ...
378
379
380
  			unsigned int hooknum,
  			const struct net_device *indev,
  			const struct net_device *outdev,
d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
381
  			const char *prefix, unsigned int plen)
0597f2680   Harald Welte   [NETFILTER]: Add ...
382
  {
0597f2680   Harald Welte   [NETFILTER]: Add ...
383
384
385
  	struct nfulnl_msg_packet_hdr pmsg;
  	struct nlmsghdr *nlh;
  	struct nfgenmsg *nfmsg;
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
386
  	sk_buff_data_t old_tail = inst->skb->tail;
0626af313   Eric Dumazet   netfilter: take c...
387
  	struct sock *sk;
0c36b48b3   Bob Hockney   netfilter: nfnetl...
388
  	const unsigned char *hwhdrp;
0597f2680   Harald Welte   [NETFILTER]: Add ...
389

d550d0958   David S. Miller   netfilter: nfnetl...
390
  	nlh = nlmsg_put(inst->skb, 0, 0,
0597f2680   Harald Welte   [NETFILTER]: Add ...
391
  			NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
d550d0958   David S. Miller   netfilter: nfnetl...
392
393
394
395
  			sizeof(struct nfgenmsg), 0);
  	if (!nlh)
  		return -1;
  	nfmsg = nlmsg_data(nlh);
0597f2680   Harald Welte   [NETFILTER]: Add ...
396
397
398
  	nfmsg->nfgen_family = pf;
  	nfmsg->version = NFNETLINK_V0;
  	nfmsg->res_id = htons(inst->group_num);
febf0a431   Al Viro   [NETFILTER] bug: ...
399
  	pmsg.hw_protocol	= skb->protocol;
0597f2680   Harald Welte   [NETFILTER]: Add ...
400
  	pmsg.hook		= hooknum;
1db20a529   David S. Miller   nfnetlink_log: St...
401
402
  	if (nla_put(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg))
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
403

1db20a529   David S. Miller   nfnetlink_log: St...
404
405
406
  	if (prefix &&
  	    nla_put(inst->skb, NFULA_PREFIX, plen, prefix))
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
407
408
  
  	if (indev) {
fbcd923c3   Harald Welte   [NETFILTER]: add ...
409
  #ifndef CONFIG_BRIDGE_NETFILTER
1db20a529   David S. Miller   nfnetlink_log: St...
410
411
412
  		if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
  				 htonl(indev->ifindex)))
  			goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
413
414
415
416
417
  #else
  		if (pf == PF_BRIDGE) {
  			/* Case 1: outdev is physical input device, we need to
  			 * look for bridge group (when called from
  			 * netfilter_bridge) */
1db20a529   David S. Miller   nfnetlink_log: St...
418
419
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
  					 htonl(indev->ifindex)) ||
fbcd923c3   Harald Welte   [NETFILTER]: add ...
420
  			/* this is the bridge group "brX" */
f350a0a87   Jiri Pirko   bridge: use rx_ha...
421
  			/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
1db20a529   David S. Miller   nfnetlink_log: St...
422
423
424
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
  					 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
425
426
427
  		} else {
  			/* Case 2: indev is bridge group, we need to look for
  			 * physical device (when called from ipv4) */
1db20a529   David S. Miller   nfnetlink_log: St...
428
429
430
431
432
433
434
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
  					 htonl(indev->ifindex)))
  				goto nla_put_failure;
  			if (skb->nf_bridge && skb->nf_bridge->physindev &&
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
  					 htonl(skb->nf_bridge->physindev->ifindex)))
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
435
436
  		}
  #endif
0597f2680   Harald Welte   [NETFILTER]: Add ...
437
438
439
  	}
  
  	if (outdev) {
fbcd923c3   Harald Welte   [NETFILTER]: add ...
440
  #ifndef CONFIG_BRIDGE_NETFILTER
1db20a529   David S. Miller   nfnetlink_log: St...
441
442
443
  		if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
  				 htonl(outdev->ifindex)))
  			goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
444
445
446
447
448
  #else
  		if (pf == PF_BRIDGE) {
  			/* Case 1: outdev is physical output device, we need to
  			 * look for bridge group (when called from
  			 * netfilter_bridge) */
1db20a529   David S. Miller   nfnetlink_log: St...
449
450
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
  					 htonl(outdev->ifindex)) ||
fbcd923c3   Harald Welte   [NETFILTER]: add ...
451
  			/* this is the bridge group "brX" */
f350a0a87   Jiri Pirko   bridge: use rx_ha...
452
  			/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
1db20a529   David S. Miller   nfnetlink_log: St...
453
454
455
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
  					 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
456
457
458
  		} else {
  			/* Case 2: indev is a bridge group, we need to look
  			 * for physical device (when called from ipv4) */
1db20a529   David S. Miller   nfnetlink_log: St...
459
460
461
462
463
464
465
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
  					 htonl(outdev->ifindex)))
  				goto nla_put_failure;
  			if (skb->nf_bridge && skb->nf_bridge->physoutdev &&
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
  					 htonl(skb->nf_bridge->physoutdev->ifindex)))
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
466
467
  		}
  #endif
0597f2680   Harald Welte   [NETFILTER]: Add ...
468
  	}
1db20a529   David S. Miller   nfnetlink_log: St...
469
470
471
  	if (skb->mark &&
  	    nla_put_be32(inst->skb, NFULA_MARK, htonl(skb->mark)))
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
472

2c38de4c1   Nicolas Cavallari   netfilter: fix lo...
473
474
  	if (indev && skb->dev &&
  	    skb->mac_header != skb->network_header) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
475
  		struct nfulnl_msg_packet_hw phw;
b95cce357   Stephen Hemminger   [NET]: Wrap hard_...
476
477
478
  		int len = dev_parse_header(skb, phw.hw_addr);
  		if (len > 0) {
  			phw.hw_addrlen = htons(len);
1db20a529   David S. Miller   nfnetlink_log: St...
479
480
  			if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
  				goto nla_put_failure;
b95cce357   Stephen Hemminger   [NET]: Wrap hard_...
481
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
482
  	}
72961ecf8   Eric Leblond   netfilter: nfnetl...
483
  	if (indev && skb_mac_header_was_set(skb)) {
2dba62c30   Patrick McHardy   netfilter: nfnetl...
484
  		if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
1db20a529   David S. Miller   nfnetlink_log: St...
485
  		    nla_put_be16(inst->skb, NFULA_HWLEN,
0c36b48b3   Bob Hockney   netfilter: nfnetl...
486
487
488
489
490
491
492
493
494
495
496
  				 htons(skb->dev->hard_header_len)))
  			goto nla_put_failure;
  
  		hwhdrp = skb_mac_header(skb);
  
  		if (skb->dev->type == ARPHRD_SIT)
  			hwhdrp -= ETH_HLEN;
  
  		if (hwhdrp >= skb->head &&
  		    nla_put(inst->skb, NFULA_HWHEADER,
  			    skb->dev->hard_header_len, hwhdrp))
1db20a529   David S. Miller   nfnetlink_log: St...
497
  			goto nla_put_failure;
72961ecf8   Eric Leblond   netfilter: nfnetl...
498
  	}
b7aa0bf70   Eric Dumazet   [NET]: convert ne...
499
  	if (skb->tstamp.tv64) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
500
  		struct nfulnl_msg_packet_timestamp ts;
b7aa0bf70   Eric Dumazet   [NET]: convert ne...
501
502
503
  		struct timeval tv = ktime_to_timeval(skb->tstamp);
  		ts.sec = cpu_to_be64(tv.tv_sec);
  		ts.usec = cpu_to_be64(tv.tv_usec);
0597f2680   Harald Welte   [NETFILTER]: Add ...
504

1db20a529   David S. Miller   nfnetlink_log: St...
505
506
  		if (nla_put(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts))
  			goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
507
508
509
  	}
  
  	/* UID */
0626af313   Eric Dumazet   netfilter: take c...
510
511
512
513
514
  	sk = skb->sk;
  	if (sk && sk->sk_state != TCP_TIME_WAIT) {
  		read_lock_bh(&sk->sk_callback_lock);
  		if (sk->sk_socket && sk->sk_socket->file) {
  			struct file *file = sk->sk_socket->file;
437589a74   Linus Torvalds   Merge branch 'for...
515
516
517
518
  			const struct cred *cred = file->f_cred;
  			struct user_namespace *user_ns = inst->peer_user_ns;
  			__be32 uid = htonl(from_kuid_munged(user_ns, cred->fsuid));
  			__be32 gid = htonl(from_kgid_munged(user_ns, cred->fsgid));
0626af313   Eric Dumazet   netfilter: take c...
519
  			read_unlock_bh(&sk->sk_callback_lock);
1db20a529   David S. Miller   nfnetlink_log: St...
520
521
522
  			if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
  			    nla_put_be32(inst->skb, NFULA_GID, gid))
  				goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
523
  		} else
0626af313   Eric Dumazet   netfilter: take c...
524
  			read_unlock_bh(&sk->sk_callback_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
525
  	}
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
526
  	/* local sequence number */
1db20a529   David S. Miller   nfnetlink_log: St...
527
528
529
  	if ((inst->flags & NFULNL_CFG_F_SEQ) &&
  	    nla_put_be32(inst->skb, NFULA_SEQ, htonl(inst->seq++)))
  		goto nla_put_failure;
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
530

0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
531
  	/* global sequence number */
1db20a529   David S. Miller   nfnetlink_log: St...
532
533
  	if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) &&
  	    nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL,
9368a53c4   Gao feng   netfilter: nfnetl...
534
  			 htonl(atomic_inc_return(&log->global_seq))))
1db20a529   David S. Miller   nfnetlink_log: St...
535
  		goto nla_put_failure;
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
536

0597f2680   Harald Welte   [NETFILTER]: Add ...
537
  	if (data_len) {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
538
539
  		struct nlattr *nla;
  		int size = nla_attr_size(data_len);
0597f2680   Harald Welte   [NETFILTER]: Add ...
540

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
541
  		if (skb_tailroom(inst->skb) < nla_total_size(data_len)) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
542
543
  			printk(KERN_WARNING "nfnetlink_log: no tailroom!
  ");
d550d0958   David S. Miller   netfilter: nfnetl...
544
  			return -1;
0597f2680   Harald Welte   [NETFILTER]: Add ...
545
  		}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
546
547
548
  		nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len));
  		nla->nla_type = NFULA_PAYLOAD;
  		nla->nla_len = size;
0597f2680   Harald Welte   [NETFILTER]: Add ...
549

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
550
  		if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
0597f2680   Harald Welte   [NETFILTER]: Add ...
551
552
  			BUG();
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
553

0597f2680   Harald Welte   [NETFILTER]: Add ...
554
555
  	nlh->nlmsg_len = inst->skb->tail - old_tail;
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
556
  nla_put_failure:
0597f2680   Harald Welte   [NETFILTER]: Add ...
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  	PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg
  ");
  	return -1;
  }
  
  #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
  
  static struct nf_loginfo default_loginfo = {
  	.type =		NF_LOG_TYPE_ULOG,
  	.u = {
  		.ulog = {
  			.copy_len	= 0xffff,
  			.group		= 0,
  			.qthreshold	= 1,
  		},
  	},
  };
  
  /* log handler for internal netfilter logging api */
5f7340eff   Eric Leblond   netfilter: xt_NFL...
576
  void
8cdb46da0   Hans Schillstrom   netfilter: log: n...
577
578
  nfulnl_log_packet(struct net *net,
  		  u_int8_t pf,
0597f2680   Harald Welte   [NETFILTER]: Add ...
579
580
581
582
583
584
585
586
587
588
589
  		  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)
  {
  	unsigned int size, data_len;
  	struct nfulnl_instance *inst;
  	const struct nf_loginfo *li;
  	unsigned int qthreshold;
d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
590
  	unsigned int plen;
9368a53c4   Gao feng   netfilter: nfnetl...
591
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
592

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
593
  	if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
0597f2680   Harald Welte   [NETFILTER]: Add ...
594
595
596
  		li = li_user;
  	else
  		li = &default_loginfo;
9368a53c4   Gao feng   netfilter: nfnetl...
597
  	inst = instance_lookup_get(log, li->u.ulog.group);
0597f2680   Harald Welte   [NETFILTER]: Add ...
598
  	if (!inst)
0597f2680   Harald Welte   [NETFILTER]: Add ...
599
  		return;
0597f2680   Harald Welte   [NETFILTER]: Add ...
600

d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
601
602
  	plen = 0;
  	if (prefix)
881dbfe8a   Patrick McHardy   [NETFILTER]: nfne...
603
  		plen = strlen(prefix) + 1;
d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
604

0597f2680   Harald Welte   [NETFILTER]: Add ...
605
606
607
  	/* FIXME: do we want to make the size calculation conditional based on
  	 * what is actually present?  way more branches and checks, but more
  	 * memory efficient... */
573ce260b   Hong zhi guo   net-next: replace...
608
  	size =    nlmsg_total_size(sizeof(struct nfgenmsg))
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
609
610
611
  		+ nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
fbcd923c3   Harald Welte   [NETFILTER]: add ...
612
  #ifdef CONFIG_BRIDGE_NETFILTER
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
613
614
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
fbcd923c3   Harald Welte   [NETFILTER]: add ...
615
  #endif
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
616
617
  		+ nla_total_size(sizeof(u_int32_t))	/* mark */
  		+ nla_total_size(sizeof(u_int32_t))	/* uid */
76aa1ce13   Patrick McHardy   [NETFILTER]: nfne...
618
  		+ nla_total_size(sizeof(u_int32_t))	/* gid */
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
619
620
621
  		+ nla_total_size(plen)			/* prefix */
  		+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
  		+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
0597f2680   Harald Welte   [NETFILTER]: Add ...
622

eeff9beec   Pablo Neira Ayuso   netfilter: nfnetl...
623
624
625
626
627
  	if (in && skb_mac_header_was_set(skb)) {
  		size +=   nla_total_size(skb->dev->hard_header_len)
  			+ nla_total_size(sizeof(u_int16_t))	/* hwtype */
  			+ nla_total_size(sizeof(u_int16_t));	/* hwlen */
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
628
  	spin_lock_bh(&inst->lock);
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
629
  	if (inst->flags & NFULNL_CFG_F_SEQ)
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
630
  		size += nla_total_size(sizeof(u_int32_t));
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
631
  	if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
632
  		size += nla_total_size(sizeof(u_int32_t));
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
633

0597f2680   Harald Welte   [NETFILTER]: Add ...
634
635
  	qthreshold = inst->qthreshold;
  	/* per-rule qthreshold overrides per-instance */
5ca431f9a   Eric Leblond   netfilter: nfnetl...
636
637
638
  	if (li->u.ulog.qthreshold)
  		if (qthreshold > li->u.ulog.qthreshold)
  			qthreshold = li->u.ulog.qthreshold;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
639

0597f2680   Harald Welte   [NETFILTER]: Add ...
640
641
642
643
644
  	switch (inst->copy_mode) {
  	case NFULNL_COPY_META:
  	case NFULNL_COPY_NONE:
  		data_len = 0;
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
645

0597f2680   Harald Welte   [NETFILTER]: Add ...
646
  	case NFULNL_COPY_PACKET:
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
647
  		if (inst->copy_range == 0
0597f2680   Harald Welte   [NETFILTER]: Add ...
648
649
650
651
  		    || inst->copy_range > skb->len)
  			data_len = skb->len;
  		else
  			data_len = inst->copy_range;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
652

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
653
  		size += nla_total_size(data_len);
0597f2680   Harald Welte   [NETFILTER]: Add ...
654
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
655

f5c5440d4   Eric Dumazet   netfilter: nfnetl...
656
  	case NFULNL_COPY_DISABLED:
0597f2680   Harald Welte   [NETFILTER]: Add ...
657
  	default:
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
658
  		goto unlock_and_release;
0597f2680   Harald Welte   [NETFILTER]: Add ...
659
  	}
d63b043d9   Michal Miroslaw   [NETFILTER]: nfne...
660
661
  	if (inst->skb &&
  	    size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
662
663
  		/* either the queue len is too high or we don't have
  		 * enough room in the skb left. flush to userspace. */
e35670614   Michal Miroslaw   [NETFILTER]: nfne...
664
  		__nfulnl_flush(inst);
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
665
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
666

55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
667
  	if (!inst->skb) {
3ab1f683b   Patrick McHardy   nfnetlink: add su...
668
669
  		inst->skb = nfulnl_alloc_skb(inst->peer_portid, inst->nlbufsiz,
  					     size);
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
670
  		if (!inst->skb)
0597f2680   Harald Welte   [NETFILTER]: Add ...
671
  			goto alloc_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
672
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
673
  	inst->qlen++;
9368a53c4   Gao feng   netfilter: nfnetl...
674
  	__build_packet_message(log, inst, skb, data_len, pf,
8248779b1   Florian Westphal   netfilter: nfnetl...
675
  				hooknum, in, out, prefix, plen);
0597f2680   Harald Welte   [NETFILTER]: Add ...
676

d63b043d9   Michal Miroslaw   [NETFILTER]: nfne...
677
678
  	if (inst->qlen >= qthreshold)
  		__nfulnl_flush(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
679
680
  	/* timer_pending always called within inst->lock, so there
  	 * is no chance of a race here */
d63b043d9   Michal Miroslaw   [NETFILTER]: nfne...
681
  	else if (!timer_pending(&inst->timer)) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
682
683
684
685
  		instance_get(inst);
  		inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
  		add_timer(&inst->timer);
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
686

ed32abeaf   Michal Miroslaw   [NETFILTER]: nfne...
687
688
689
  unlock_and_release:
  	spin_unlock_bh(&inst->lock);
  	instance_put(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
690
691
692
  	return;
  
  alloc_failure:
0597f2680   Harald Welte   [NETFILTER]: Add ...
693
  	/* FIXME: statistics */
ed32abeaf   Michal Miroslaw   [NETFILTER]: nfne...
694
  	goto unlock_and_release;
0597f2680   Harald Welte   [NETFILTER]: Add ...
695
  }
5f7340eff   Eric Leblond   netfilter: xt_NFL...
696
  EXPORT_SYMBOL_GPL(nfulnl_log_packet);
0597f2680   Harald Welte   [NETFILTER]: Add ...
697
698
699
700
701
702
  
  static int
  nfulnl_rcv_nl_event(struct notifier_block *this,
  		   unsigned long event, void *ptr)
  {
  	struct netlink_notify *n = ptr;
9368a53c4   Gao feng   netfilter: nfnetl...
703
  	struct nfnl_log_net *log = nfnl_log_pernet(n->net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
704

dee5817e8   Patrick McHardy   netfilter: remove...
705
  	if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
706
  		int i;
15e473046   Eric W. Biederman   netlink: Rename p...
707
  		/* destroy all instances for this portid */
9368a53c4   Gao feng   netfilter: nfnetl...
708
  		spin_lock_bh(&log->instances_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
709
  		for  (i = 0; i < INSTANCE_BUCKETS; i++) {
b67bfe0d4   Sasha Levin   hlist: drop the n...
710
  			struct hlist_node *t2;
0597f2680   Harald Welte   [NETFILTER]: Add ...
711
  			struct nfulnl_instance *inst;
9368a53c4   Gao feng   netfilter: nfnetl...
712
  			struct hlist_head *head = &log->instance_table[i];
0597f2680   Harald Welte   [NETFILTER]: Add ...
713

b67bfe0d4   Sasha Levin   hlist: drop the n...
714
  			hlist_for_each_entry_safe(inst, t2, head, hlist) {
9368a53c4   Gao feng   netfilter: nfnetl...
715
  				if (n->portid == inst->peer_portid)
0597f2680   Harald Welte   [NETFILTER]: Add ...
716
717
718
  					__instance_destroy(inst);
  			}
  		}
9368a53c4   Gao feng   netfilter: nfnetl...
719
  		spin_unlock_bh(&log->instances_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
720
721
722
723
724
725
726
727
728
729
  	}
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block nfulnl_rtnl_notifier = {
  	.notifier_call	= nfulnl_rcv_nl_event,
  };
  
  static int
  nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
399383246   Patrick McHardy   netfilter: nfnetl...
730
731
  		   const struct nlmsghdr *nlh,
  		   const struct nlattr * const nfqa[])
0597f2680   Harald Welte   [NETFILTER]: Add ...
732
733
734
  {
  	return -ENOTSUPP;
  }
ca735b3aa   Eric Leblond   netfilter: use a ...
735
  static struct nf_logger nfulnl_logger __read_mostly = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
736
737
738
739
  	.name	= "nfnetlink_log",
  	.logfn	= &nfulnl_log_packet,
  	.me	= THIS_MODULE,
  };
fd8281ada   Patrick McHardy   [NETFILTER]: nfne...
740
741
742
743
744
745
746
  static const struct nla_policy nfula_cfg_policy[NFULA_CFG_MAX+1] = {
  	[NFULA_CFG_CMD]		= { .len = sizeof(struct nfulnl_msg_config_cmd) },
  	[NFULA_CFG_MODE]	= { .len = sizeof(struct nfulnl_msg_config_mode) },
  	[NFULA_CFG_TIMEOUT]	= { .type = NLA_U32 },
  	[NFULA_CFG_QTHRESH]	= { .type = NLA_U32 },
  	[NFULA_CFG_NLBUFSIZ]	= { .type = NLA_U32 },
  	[NFULA_CFG_FLAGS]	= { .type = NLA_U16 },
0597f2680   Harald Welte   [NETFILTER]: Add ...
747
748
749
750
  };
  
  static int
  nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
399383246   Patrick McHardy   netfilter: nfnetl...
751
752
  		   const struct nlmsghdr *nlh,
  		   const struct nlattr * const nfula[])
0597f2680   Harald Welte   [NETFILTER]: Add ...
753
  {
d550d0958   David S. Miller   netfilter: nfnetl...
754
  	struct nfgenmsg *nfmsg = nlmsg_data(nlh);
0597f2680   Harald Welte   [NETFILTER]: Add ...
755
756
  	u_int16_t group_num = ntohs(nfmsg->res_id);
  	struct nfulnl_instance *inst;
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
757
  	struct nfulnl_msg_config_cmd *cmd = NULL;
30e0c6a6b   Gao feng   netfilter: nf_log...
758
  	struct net *net = sock_net(ctnl);
9368a53c4   Gao feng   netfilter: nfnetl...
759
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
760
  	int ret = 0;
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
761
762
763
764
765
766
767
  	if (nfula[NFULA_CFG_CMD]) {
  		u_int8_t pf = nfmsg->nfgen_family;
  		cmd = nla_data(nfula[NFULA_CFG_CMD]);
  
  		/* Commands without queue context */
  		switch (cmd->command) {
  		case NFULNL_CFG_CMD_PF_BIND:
30e0c6a6b   Gao feng   netfilter: nf_log...
768
  			return nf_log_bind_pf(net, pf, &nfulnl_logger);
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
769
  		case NFULNL_CFG_CMD_PF_UNBIND:
30e0c6a6b   Gao feng   netfilter: nf_log...
770
  			nf_log_unbind_pf(net, pf);
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
771
772
773
  			return 0;
  		}
  	}
9368a53c4   Gao feng   netfilter: nfnetl...
774
  	inst = instance_lookup_get(log, group_num);
15e473046   Eric W. Biederman   netlink: Rename p...
775
  	if (inst && inst->peer_portid != NETLINK_CB(skb).portid) {
c0506365a   Patrick McHardy   [NETFILTER]: nfne...
776
777
778
  		ret = -EPERM;
  		goto out_put;
  	}
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
779
  	if (cmd != NULL) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
780
781
782
783
784
785
  		switch (cmd->command) {
  		case NFULNL_CFG_CMD_BIND:
  			if (inst) {
  				ret = -EBUSY;
  				goto out_put;
  			}
9368a53c4   Gao feng   netfilter: nfnetl...
786
  			inst = instance_create(net, group_num,
15e473046   Eric W. Biederman   netlink: Rename p...
787
  					       NETLINK_CB(skb).portid,
e32123e59   Patrick McHardy   netlink: rename s...
788
  					       sk_user_ns(NETLINK_CB(skb).sk));
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
789
790
  			if (IS_ERR(inst)) {
  				ret = PTR_ERR(inst);
f414c16c0   Michal Miroslaw   [NETFILTER]: nfne...
791
  				goto out;
0597f2680   Harald Welte   [NETFILTER]: Add ...
792
793
794
795
796
  			}
  			break;
  		case NFULNL_CFG_CMD_UNBIND:
  			if (!inst) {
  				ret = -ENODEV;
f414c16c0   Michal Miroslaw   [NETFILTER]: nfne...
797
  				goto out;
0597f2680   Harald Welte   [NETFILTER]: Add ...
798
  			}
9368a53c4   Gao feng   netfilter: nfnetl...
799
  			instance_destroy(log, inst);
a49c65037   Alexey Dobriyan   netfilter: nfnetl...
800
  			goto out_put;
0597f2680   Harald Welte   [NETFILTER]: Add ...
801
  		default:
cd21f0ac4   Patrick McHardy   [NETFILTER]: nfne...
802
  			ret = -ENOTSUPP;
0597f2680   Harald Welte   [NETFILTER]: Add ...
803
804
  			break;
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
805
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
806
  	if (nfula[NFULA_CFG_MODE]) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
807
  		struct nfulnl_msg_config_mode *params;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
808
  		params = nla_data(nfula[NFULA_CFG_MODE]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
809

c0506365a   Patrick McHardy   [NETFILTER]: nfne...
810
811
812
813
  		if (!inst) {
  			ret = -ENODEV;
  			goto out;
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
814
  		nfulnl_set_mode(inst, params->copy_mode,
d1208b999   Al Viro   [NETFILTER] bug: ...
815
  				ntohl(params->copy_range));
0597f2680   Harald Welte   [NETFILTER]: Add ...
816
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
817
  	if (nfula[NFULA_CFG_TIMEOUT]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
818
  		__be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
819

c0506365a   Patrick McHardy   [NETFILTER]: nfne...
820
821
822
823
  		if (!inst) {
  			ret = -ENODEV;
  			goto out;
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
824
825
  		nfulnl_set_timeout(inst, ntohl(timeout));
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
826
  	if (nfula[NFULA_CFG_NLBUFSIZ]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
827
  		__be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
828

c0506365a   Patrick McHardy   [NETFILTER]: nfne...
829
830
831
832
  		if (!inst) {
  			ret = -ENODEV;
  			goto out;
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
833
834
  		nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz));
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
835
  	if (nfula[NFULA_CFG_QTHRESH]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
836
  		__be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
837

c0506365a   Patrick McHardy   [NETFILTER]: nfne...
838
839
840
841
  		if (!inst) {
  			ret = -ENODEV;
  			goto out;
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
842
843
  		nfulnl_set_qthresh(inst, ntohl(qthresh));
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
844
  	if (nfula[NFULA_CFG_FLAGS]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
845
  		__be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]);
c0506365a   Patrick McHardy   [NETFILTER]: nfne...
846
847
848
849
850
  
  		if (!inst) {
  			ret = -ENODEV;
  			goto out;
  		}
ee433530d   Patrick McHardy   [NETFILTER]: nfne...
851
  		nfulnl_set_flags(inst, ntohs(flags));
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
852
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
853
854
  out_put:
  	instance_put(inst);
dd16704eb   Michal Miroslaw   [NETFILTER]: nfne...
855
  out:
0597f2680   Harald Welte   [NETFILTER]: Add ...
856
857
  	return ret;
  }
7c8d4cb41   Patrick McHardy   [NETFILTER]: nfne...
858
  static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
859
  	[NFULNL_MSG_PACKET]	= { .call = nfulnl_recv_unsupp,
37d2e7a20   Harald Welte   [NETFILTER] nfnet...
860
  				    .attr_count = NFULA_MAX, },
0597f2680   Harald Welte   [NETFILTER]: Add ...
861
  	[NFULNL_MSG_CONFIG]	= { .call = nfulnl_recv_config,
fd8281ada   Patrick McHardy   [NETFILTER]: nfne...
862
863
  				    .attr_count = NFULA_CFG_MAX,
  				    .policy = nfula_cfg_policy },
0597f2680   Harald Welte   [NETFILTER]: Add ...
864
  };
7c8d4cb41   Patrick McHardy   [NETFILTER]: nfne...
865
  static const struct nfnetlink_subsystem nfulnl_subsys = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
866
867
868
  	.name		= "log",
  	.subsys_id	= NFNL_SUBSYS_ULOG,
  	.cb_count	= NFULNL_MSG_MAX,
0597f2680   Harald Welte   [NETFILTER]: Add ...
869
870
871
872
873
  	.cb		= nfulnl_cb,
  };
  
  #ifdef CONFIG_PROC_FS
  struct iter_state {
9368a53c4   Gao feng   netfilter: nfnetl...
874
  	struct seq_net_private p;
0597f2680   Harald Welte   [NETFILTER]: Add ...
875
876
  	unsigned int bucket;
  };
9368a53c4   Gao feng   netfilter: nfnetl...
877
  static struct hlist_node *get_first(struct net *net, struct iter_state *st)
0597f2680   Harald Welte   [NETFILTER]: Add ...
878
  {
9368a53c4   Gao feng   netfilter: nfnetl...
879
  	struct nfnl_log_net *log;
0597f2680   Harald Welte   [NETFILTER]: Add ...
880
881
  	if (!st)
  		return NULL;
9368a53c4   Gao feng   netfilter: nfnetl...
882
  	log = nfnl_log_pernet(net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
883
  	for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
9368a53c4   Gao feng   netfilter: nfnetl...
884
885
886
887
  		struct hlist_head *head = &log->instance_table[st->bucket];
  
  		if (!hlist_empty(head))
  			return rcu_dereference_bh(hlist_first_rcu(head));
0597f2680   Harald Welte   [NETFILTER]: Add ...
888
889
890
  	}
  	return NULL;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
891
892
  static struct hlist_node *get_next(struct net *net, struct iter_state *st,
  				   struct hlist_node *h)
0597f2680   Harald Welte   [NETFILTER]: Add ...
893
  {
0e60ebe04   Eric Dumazet   netfilter: add __...
894
  	h = rcu_dereference_bh(hlist_next_rcu(h));
0597f2680   Harald Welte   [NETFILTER]: Add ...
895
  	while (!h) {
9368a53c4   Gao feng   netfilter: nfnetl...
896
897
  		struct nfnl_log_net *log;
  		struct hlist_head *head;
0597f2680   Harald Welte   [NETFILTER]: Add ...
898
899
  		if (++st->bucket >= INSTANCE_BUCKETS)
  			return NULL;
9368a53c4   Gao feng   netfilter: nfnetl...
900
901
902
  		log = nfnl_log_pernet(net);
  		head = &log->instance_table[st->bucket];
  		h = rcu_dereference_bh(hlist_first_rcu(head));
0597f2680   Harald Welte   [NETFILTER]: Add ...
903
904
905
  	}
  	return h;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
906
907
  static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
  				  loff_t pos)
0597f2680   Harald Welte   [NETFILTER]: Add ...
908
909
  {
  	struct hlist_node *head;
9368a53c4   Gao feng   netfilter: nfnetl...
910
  	head = get_first(net, st);
0597f2680   Harald Welte   [NETFILTER]: Add ...
911
912
  
  	if (head)
9368a53c4   Gao feng   netfilter: nfnetl...
913
  		while (pos && (head = get_next(net, st, head)))
0597f2680   Harald Welte   [NETFILTER]: Add ...
914
915
916
  			pos--;
  	return pos ? NULL : head;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
917
  static void *seq_start(struct seq_file *s, loff_t *pos)
bed1be208   Eric Dumazet   netfilter: nfnetl...
918
  	__acquires(rcu_bh)
0597f2680   Harald Welte   [NETFILTER]: Add ...
919
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
920
  	rcu_read_lock_bh();
9368a53c4   Gao feng   netfilter: nfnetl...
921
  	return get_idx(seq_file_net(s), s->private, *pos);
0597f2680   Harald Welte   [NETFILTER]: Add ...
922
923
924
925
926
  }
  
  static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
  {
  	(*pos)++;
9368a53c4   Gao feng   netfilter: nfnetl...
927
  	return get_next(seq_file_net(s), s->private, v);
0597f2680   Harald Welte   [NETFILTER]: Add ...
928
929
930
  }
  
  static void seq_stop(struct seq_file *s, void *v)
bed1be208   Eric Dumazet   netfilter: nfnetl...
931
  	__releases(rcu_bh)
0597f2680   Harald Welte   [NETFILTER]: Add ...
932
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
933
  	rcu_read_unlock_bh();
0597f2680   Harald Welte   [NETFILTER]: Add ...
934
935
936
937
938
  }
  
  static int seq_show(struct seq_file *s, void *v)
  {
  	const struct nfulnl_instance *inst = v;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
939
940
  	return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d
  ",
0597f2680   Harald Welte   [NETFILTER]: Add ...
941
  			  inst->group_num,
15e473046   Eric W. Biederman   netlink: Rename p...
942
  			  inst->peer_portid, inst->qlen,
0597f2680   Harald Welte   [NETFILTER]: Add ...
943
944
945
  			  inst->copy_mode, inst->copy_range,
  			  inst->flushtimeout, atomic_read(&inst->use));
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
946
  static const struct seq_operations nful_seq_ops = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
947
948
949
950
951
952
953
954
  	.start	= seq_start,
  	.next	= seq_next,
  	.stop	= seq_stop,
  	.show	= seq_show,
  };
  
  static int nful_open(struct inode *inode, struct file *file)
  {
9368a53c4   Gao feng   netfilter: nfnetl...
955
956
  	return seq_open_net(inode, file, &nful_seq_ops,
  			    sizeof(struct iter_state));
0597f2680   Harald Welte   [NETFILTER]: Add ...
957
  }
da7071d7e   Arjan van de Ven   [PATCH] mark stru...
958
  static const struct file_operations nful_file_ops = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
959
960
961
962
  	.owner	 = THIS_MODULE,
  	.open	 = nful_open,
  	.read	 = seq_read,
  	.llseek	 = seq_lseek,
9368a53c4   Gao feng   netfilter: nfnetl...
963
  	.release = seq_release_net,
0597f2680   Harald Welte   [NETFILTER]: Add ...
964
965
966
  };
  
  #endif /* PROC_FS */
9368a53c4   Gao feng   netfilter: nfnetl...
967
  static int __net_init nfnl_log_net_init(struct net *net)
0597f2680   Harald Welte   [NETFILTER]: Add ...
968
  {
9368a53c4   Gao feng   netfilter: nfnetl...
969
970
  	unsigned int i;
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
971

0597f2680   Harald Welte   [NETFILTER]: Add ...
972
  	for (i = 0; i < INSTANCE_BUCKETS; i++)
9368a53c4   Gao feng   netfilter: nfnetl...
973
974
975
976
977
978
979
980
981
982
983
984
985
  		INIT_HLIST_HEAD(&log->instance_table[i]);
  	spin_lock_init(&log->instances_lock);
  
  #ifdef CONFIG_PROC_FS
  	if (!proc_create("nfnetlink_log", 0440,
  			 net->nf.proc_netfilter, &nful_file_ops))
  		return -ENOMEM;
  #endif
  	return 0;
  }
  
  static void __net_exit nfnl_log_net_exit(struct net *net)
  {
e778f56e2   Pablo Neira Ayuso   netfilter: nf_{lo...
986
  #ifdef CONFIG_PROC_FS
9368a53c4   Gao feng   netfilter: nfnetl...
987
  	remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
e778f56e2   Pablo Neira Ayuso   netfilter: nf_{lo...
988
  #endif
9368a53c4   Gao feng   netfilter: nfnetl...
989
990
991
992
993
994
995
996
997
998
999
1000
  }
  
  static struct pernet_operations nfnl_log_net_ops = {
  	.init	= nfnl_log_net_init,
  	.exit	= nfnl_log_net_exit,
  	.id	= &nfnl_log_net_id,
  	.size	= sizeof(struct nfnl_log_net),
  };
  
  static int __init nfnetlink_log_init(void)
  {
  	int status = -ENOMEM;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1001

0597f2680   Harald Welte   [NETFILTER]: Add ...
1002
1003
1004
1005
1006
1007
1008
1009
  	/* it's not really all that important to have a random value, so
  	 * we can do this from the init function, even if there hasn't
  	 * been that much entropy yet */
  	get_random_bytes(&hash_init, sizeof(hash_init));
  
  	netlink_register_notifier(&nfulnl_rtnl_notifier);
  	status = nfnetlink_subsys_register(&nfulnl_subsys);
  	if (status < 0) {
9368a53c4   Gao feng   netfilter: nfnetl...
1010
1011
  		pr_err("log: failed to create netlink socket
  ");
0597f2680   Harald Welte   [NETFILTER]: Add ...
1012
1013
  		goto cleanup_netlink_notifier;
  	}
ca735b3aa   Eric Leblond   netfilter: use a ...
1014
1015
  	status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
  	if (status < 0) {
9368a53c4   Gao feng   netfilter: nfnetl...
1016
1017
  		pr_err("log: failed to register logger
  ");
ca735b3aa   Eric Leblond   netfilter: use a ...
1018
1019
  		goto cleanup_subsys;
  	}
9368a53c4   Gao feng   netfilter: nfnetl...
1020
1021
1022
1023
  	status = register_pernet_subsys(&nfnl_log_net_ops);
  	if (status < 0) {
  		pr_err("log: failed to register pernet ops
  ");
ca735b3aa   Eric Leblond   netfilter: use a ...
1024
  		goto cleanup_logger;
6fc09f10f   Julia Lawall   netfilter: nfnetl...
1025
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
1026
  	return status;
ca735b3aa   Eric Leblond   netfilter: use a ...
1027
1028
  cleanup_logger:
  	nf_log_unregister(&nfulnl_logger);
0597f2680   Harald Welte   [NETFILTER]: Add ...
1029
  cleanup_subsys:
0597f2680   Harald Welte   [NETFILTER]: Add ...
1030
1031
1032
1033
1034
  	nfnetlink_subsys_unregister(&nfulnl_subsys);
  cleanup_netlink_notifier:
  	netlink_unregister_notifier(&nfulnl_rtnl_notifier);
  	return status;
  }
65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
1035
  static void __exit nfnetlink_log_fini(void)
0597f2680   Harald Welte   [NETFILTER]: Add ...
1036
  {
9368a53c4   Gao feng   netfilter: nfnetl...
1037
  	unregister_pernet_subsys(&nfnl_log_net_ops);
e92ad99c7   Patrick McHardy   [NETFILTER]: nf_l...
1038
  	nf_log_unregister(&nfulnl_logger);
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
1039
1040
  	nfnetlink_subsys_unregister(&nfulnl_subsys);
  	netlink_unregister_notifier(&nfulnl_rtnl_notifier);
0597f2680   Harald Welte   [NETFILTER]: Add ...
1041
1042
1043
1044
1045
  }
  
  MODULE_DESCRIPTION("netfilter userspace logging");
  MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  MODULE_LICENSE("GPL");
f682faefb   Harald Welte   [NETFILTER]: fix ...
1046
  MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
0597f2680   Harald Welte   [NETFILTER]: Add ...
1047

65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
1048
1049
  module_init(nfnetlink_log_init);
  module_exit(nfnetlink_log_fini);