Blame view

net/netfilter/nfnetlink_log.c 28.2 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
   */
beacd3e8e   Marcelo Leitner   netfilter: nfnetl...
15
16
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0597f2680   Harald Welte   [NETFILTER]: Add ...
17
18
  #include <linux/module.h>
  #include <linux/skbuff.h>
e035edd16   Pablo Neira Ayuso   netfilter: nfnetl...
19
  #include <linux/if_arp.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
20
21
22
23
24
  #include <linux/init.h>
  #include <linux/ip.h>
  #include <linux/ipv6.h>
  #include <linux/netdevice.h>
  #include <linux/netfilter.h>
c737b7c45   Florian Westphal   netfilter: bridge...
25
  #include <linux/netfilter_bridge.h>
573ce260b   Hong zhi guo   net-next: replace...
26
  #include <net/netlink.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
27
28
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_log.h>
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
29
  #include <linux/netfilter/nf_conntrack_common.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
30
31
32
33
34
  #include <linux/spinlock.h>
  #include <linux/sysctl.h>
  #include <linux/proc_fs.h>
  #include <linux/security.h>
  #include <linux/list.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
35
  #include <linux/slab.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
36
  #include <net/sock.h>
f01ffbd6e   Patrick McHardy   [NETFILTER]: nf_l...
37
  #include <net/netfilter/nf_log.h>
9368a53c4   Gao feng   netfilter: nfnetl...
38
  #include <net/netns/generic.h>
d9e150071   Patrick McHardy   netfilter: nfnetl...
39
  #include <net/netfilter/nfnetlink_log.h>
0597f2680   Harald Welte   [NETFILTER]: Add ...
40

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

1109a90c0   Pablo Neira Ayuso   netfilter: use IS...
43
  #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
fbcd923c3   Harald Welte   [NETFILTER]: add ...
44
45
  #include "../bridge/br_private.h"
  #endif
c2db29243   Holger Eitzenberger   [NETFILTER]: ULOG...
46
  #define NFULNL_NLBUFSIZ_DEFAULT	NLMSG_GOODSIZE
2c6764b74   Eric Leblond   netfilter: nfnetl...
47
  #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
0597f2680   Harald Welte   [NETFILTER]: Add ...
48
  #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
c1e7dc91e   Florian Westphal   netfilter: nfnetl...
49
50
  /* max packet size is limited by 16-bit struct nfattr nfa_len field */
  #define NFULNL_COPY_RANGE_MAX	(0xFFFF - NLA_HDRLEN)
0597f2680   Harald Welte   [NETFILTER]: Add ...
51
52
53
  
  #define PRINTR(x, args...)	do { if (net_ratelimit()) \
  				     printk(x, ## args); } while (0);
0597f2680   Harald Welte   [NETFILTER]: Add ...
54
55
56
57
58
59
60
  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 ...
61
  	struct timer_list timer;
9368a53c4   Gao feng   netfilter: nfnetl...
62
  	struct net *net;
9eea9515c   Eric W. Biederman   userns: nfnetlink...
63
  	struct user_namespace *peer_user_ns;	/* User namespace of the peer process */
cc6bc4486   Richard Weinberger   netfilter: Fix po...
64
  	u32 peer_portid;		/* PORTID of the peer process */
0597f2680   Harald Welte   [NETFILTER]: Add ...
65
66
67
68
69
70
  
  	/* 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...
71
  	u_int32_t seq;			/* instance-local sequential counter */
0597f2680   Harald Welte   [NETFILTER]: Add ...
72
  	u_int16_t group_num;		/* number of this queue */
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
73
  	u_int16_t flags;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
74
  	u_int8_t copy_mode;
bed1be208   Eric Dumazet   netfilter: nfnetl...
75
  	struct rcu_head rcu;
0597f2680   Harald Welte   [NETFILTER]: Add ...
76
  };
0597f2680   Harald Welte   [NETFILTER]: Add ...
77
  #define INSTANCE_BUCKETS	16
0597f2680   Harald Welte   [NETFILTER]: Add ...
78

9368a53c4   Gao feng   netfilter: nfnetl...
79
80
81
82
83
84
85
86
87
88
89
90
  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 ...
91
92
93
94
95
96
  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...
97
  __instance_lookup(struct nfnl_log_net *log, u_int16_t group_num)
0597f2680   Harald Welte   [NETFILTER]: Add ...
98
99
  {
  	struct hlist_head *head;
0597f2680   Harald Welte   [NETFILTER]: Add ...
100
  	struct nfulnl_instance *inst;
9368a53c4   Gao feng   netfilter: nfnetl...
101
  	head = &log->instance_table[instance_hashfn(group_num)];
b67bfe0d4   Sasha Levin   hlist: drop the n...
102
  	hlist_for_each_entry_rcu(inst, head, hlist) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
103
104
105
106
107
108
109
110
111
112
113
114
115
  		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...
116
  instance_lookup_get(struct nfnl_log_net *log, u_int16_t group_num)
0597f2680   Harald Welte   [NETFILTER]: Add ...
117
118
  {
  	struct nfulnl_instance *inst;
bed1be208   Eric Dumazet   netfilter: nfnetl...
119
  	rcu_read_lock_bh();
9368a53c4   Gao feng   netfilter: nfnetl...
120
  	inst = __instance_lookup(log, group_num);
f5c5440d4   Eric Dumazet   netfilter: nfnetl...
121
122
  	if (inst && !atomic_inc_not_zero(&inst->use))
  		inst = NULL;
bed1be208   Eric Dumazet   netfilter: nfnetl...
123
  	rcu_read_unlock_bh();
0597f2680   Harald Welte   [NETFILTER]: Add ...
124
125
126
  
  	return inst;
  }
bed1be208   Eric Dumazet   netfilter: nfnetl...
127
128
  static void nfulnl_instance_free_rcu(struct rcu_head *head)
  {
9368a53c4   Gao feng   netfilter: nfnetl...
129
130
131
132
133
  	struct nfulnl_instance *inst =
  		container_of(head, struct nfulnl_instance, rcu);
  
  	put_net(inst->net);
  	kfree(inst);
bed1be208   Eric Dumazet   netfilter: nfnetl...
134
135
  	module_put(THIS_MODULE);
  }
0597f2680   Harald Welte   [NETFILTER]: Add ...
136
137
138
  static void
  instance_put(struct nfulnl_instance *inst)
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
139
140
  	if (inst && atomic_dec_and_test(&inst->use))
  		call_rcu_bh(&inst->rcu, nfulnl_instance_free_rcu);
0597f2680   Harald Welte   [NETFILTER]: Add ...
141
142
143
144
145
  }
  
  static void nfulnl_timer(unsigned long data);
  
  static struct nfulnl_instance *
9368a53c4   Gao feng   netfilter: nfnetl...
146
  instance_create(struct net *net, u_int16_t group_num,
cc6bc4486   Richard Weinberger   netfilter: Fix po...
147
  		u32 portid, struct user_namespace *user_ns)
0597f2680   Harald Welte   [NETFILTER]: Add ...
148
149
  {
  	struct nfulnl_instance *inst;
9368a53c4   Gao feng   netfilter: nfnetl...
150
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
151
  	int err;
0597f2680   Harald Welte   [NETFILTER]: Add ...
152

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

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

9368a53c4   Gao feng   netfilter: nfnetl...
175
  	inst->net = get_net(net);
9eea9515c   Eric W. Biederman   userns: nfnetlink...
176
  	inst->peer_user_ns = user_ns;
15e473046   Eric W. Biederman   netlink: Rename p...
177
  	inst->peer_portid = portid;
0597f2680   Harald Welte   [NETFILTER]: Add ...
178
179
180
181
182
183
  	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...
184
  	inst->copy_range 	= NFULNL_COPY_RANGE_MAX;
0597f2680   Harald Welte   [NETFILTER]: Add ...
185

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

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

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

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

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

0597f2680   Harald Welte   [NETFILTER]: Add ...
242
243
  	case NFULNL_COPY_PACKET:
  		inst->copy_mode = mode;
c1e7dc91e   Florian Westphal   netfilter: nfnetl...
244
245
  		if (range == 0)
  			range = NFULNL_COPY_RANGE_MAX;
6b6ec99a0   Michal Miroslaw   [NETFILTER]: nfne...
246
247
  		inst->copy_range = min_t(unsigned int,
  					 range, NFULNL_COPY_RANGE_MAX);
0597f2680   Harald Welte   [NETFILTER]: Add ...
248
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
249

0597f2680   Harald Welte   [NETFILTER]: Add ...
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
  	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;
  }
23509fcd4   Rosen, Rami   netfilter: nfnetl...
278
  static void
0597f2680   Harald Welte   [NETFILTER]: Add ...
279
280
281
282
283
  nfulnl_set_timeout(struct nfulnl_instance *inst, u_int32_t timeout)
  {
  	spin_lock_bh(&inst->lock);
  	inst->flushtimeout = timeout;
  	spin_unlock_bh(&inst->lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
284
  }
23509fcd4   Rosen, Rami   netfilter: nfnetl...
285
  static void
0597f2680   Harald Welte   [NETFILTER]: Add ...
286
287
288
289
290
  nfulnl_set_qthresh(struct nfulnl_instance *inst, u_int32_t qthresh)
  {
  	spin_lock_bh(&inst->lock);
  	inst->qthreshold = qthresh;
  	spin_unlock_bh(&inst->lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
291
  }
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
292
293
294
295
  static int
  nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags)
  {
  	spin_lock_bh(&inst->lock);
ee433530d   Patrick McHardy   [NETFILTER]: nfne...
296
  	inst->flags = flags;
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
297
298
299
300
  	spin_unlock_bh(&inst->lock);
  
  	return 0;
  }
c6a8f6483   Michal Miroslaw   [NETFILTER]: nfne...
301
  static struct sk_buff *
afff14f60   Gao feng   netfilter: nfnetl...
302
303
  nfulnl_alloc_skb(struct net *net, 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);
905f0a739   Florian Westphal   nfnetlink: remove...
311
  	skb = alloc_skb(n, 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

905f0a739   Florian Westphal   nfnetlink: remove...
317
  			skb = alloc_skb(pkt_size, GFP_ATOMIC);
ad2ad0f96   Patrick McHardy   [NETFILTER]: Fix ...
318
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
319
320
321
322
  	}
  
  	return skb;
  }
b51d3fa36   Houcheng Lin   netfilter: nf_log...
323
  static void
0597f2680   Harald Welte   [NETFILTER]: Add ...
324
325
  __nfulnl_send(struct nfulnl_instance *inst)
  {
d550d0958   David S. Miller   netfilter: nfnetl...
326
327
328
329
330
  	if (inst->qlen > 1) {
  		struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
  						 NLMSG_DONE,
  						 sizeof(struct nfgenmsg),
  						 0);
b51d3fa36   Houcheng Lin   netfilter: nf_log...
331
332
333
334
  		if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d
  ",
  			      inst->skb->len, skb_tailroom(inst->skb))) {
  			kfree_skb(inst->skb);
d550d0958   David S. Miller   netfilter: nfnetl...
335
  			goto out;
b51d3fa36   Houcheng Lin   netfilter: nf_log...
336
  		}
d550d0958   David S. Miller   netfilter: nfnetl...
337
  	}
b51d3fa36   Houcheng Lin   netfilter: nf_log...
338
339
340
  	nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
  			  MSG_DONTWAIT);
  out:
0597f2680   Harald Welte   [NETFILTER]: Add ...
341
342
  	inst->qlen = 0;
  	inst->skb = NULL;
0597f2680   Harald Welte   [NETFILTER]: Add ...
343
  }
e35670614   Michal Miroslaw   [NETFILTER]: nfne...
344
345
346
347
348
349
350
351
352
  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...
353
354
  static void
  nfulnl_timer(unsigned long data)
0597f2680   Harald Welte   [NETFILTER]: Add ...
355
  {
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
356
  	struct nfulnl_instance *inst = (struct nfulnl_instance *)data;
0597f2680   Harald Welte   [NETFILTER]: Add ...
357

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

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

1db20a529   David S. Miller   nfnetlink_log: St...
401
402
403
  	if (prefix &&
  	    nla_put(inst->skb, NFULA_PREFIX, plen, prefix))
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
404
405
  
  	if (indev) {
1109a90c0   Pablo Neira Ayuso   netfilter: use IS...
406
  #if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
1db20a529   David S. Miller   nfnetlink_log: St...
407
408
409
  		if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
  				 htonl(indev->ifindex)))
  			goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
410
411
412
413
414
  #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...
415
416
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
  					 htonl(indev->ifindex)) ||
fbcd923c3   Harald Welte   [NETFILTER]: add ...
417
  			/* this is the bridge group "brX" */
e2361cb90   Aaron Conole   netfilter: Remove...
418
419
420
  			/* rcu_read_lock()ed by nf_hook_thresh or
  			 * nf_log_packet.
  			 */
1db20a529   David S. Miller   nfnetlink_log: St...
421
422
423
  			    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 ...
424
  		} else {
c737b7c45   Florian Westphal   netfilter: bridge...
425
  			struct net_device *physindev;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
426
427
  			/* 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
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
  					 htonl(indev->ifindex)))
  				goto nla_put_failure;
c737b7c45   Florian Westphal   netfilter: bridge...
431
432
433
  
  			physindev = nf_bridge_get_physindev(skb);
  			if (physindev &&
1db20a529   David S. Miller   nfnetlink_log: St...
434
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
c737b7c45   Florian Westphal   netfilter: bridge...
435
  					 htonl(physindev->ifindex)))
1db20a529   David S. Miller   nfnetlink_log: St...
436
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
437
438
  		}
  #endif
0597f2680   Harald Welte   [NETFILTER]: Add ...
439
440
441
  	}
  
  	if (outdev) {
1109a90c0   Pablo Neira Ayuso   netfilter: use IS...
442
  #if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
1db20a529   David S. Miller   nfnetlink_log: St...
443
444
445
  		if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
  				 htonl(outdev->ifindex)))
  			goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
446
447
448
449
450
  #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...
451
452
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
  					 htonl(outdev->ifindex)) ||
fbcd923c3   Harald Welte   [NETFILTER]: add ...
453
  			/* this is the bridge group "brX" */
e2361cb90   Aaron Conole   netfilter: Remove...
454
455
456
  			/* rcu_read_lock()ed by nf_hook_thresh or
  			 * nf_log_packet.
  			 */
1db20a529   David S. Miller   nfnetlink_log: St...
457
458
459
  			    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 ...
460
  		} else {
c737b7c45   Florian Westphal   netfilter: bridge...
461
  			struct net_device *physoutdev;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
462
463
  			/* 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...
464
465
466
  			if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
  					 htonl(outdev->ifindex)))
  				goto nla_put_failure;
c737b7c45   Florian Westphal   netfilter: bridge...
467
468
469
  
  			physoutdev = nf_bridge_get_physoutdev(skb);
  			if (physoutdev &&
1db20a529   David S. Miller   nfnetlink_log: St...
470
  			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
c737b7c45   Florian Westphal   netfilter: bridge...
471
  					 htonl(physoutdev->ifindex)))
1db20a529   David S. Miller   nfnetlink_log: St...
472
  				goto nla_put_failure;
fbcd923c3   Harald Welte   [NETFILTER]: add ...
473
474
  		}
  #endif
0597f2680   Harald Welte   [NETFILTER]: Add ...
475
  	}
1db20a529   David S. Miller   nfnetlink_log: St...
476
477
478
  	if (skb->mark &&
  	    nla_put_be32(inst->skb, NFULA_MARK, htonl(skb->mark)))
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
479

2c38de4c1   Nicolas Cavallari   netfilter: fix lo...
480
481
  	if (indev && skb->dev &&
  	    skb->mac_header != skb->network_header) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
482
  		struct nfulnl_msg_packet_hw phw;
e4d091d7b   Dan Carpenter   netfilter: nfnetl...
483
484
485
486
  		int len;
  
  		memset(&phw, 0, sizeof(phw));
  		len = dev_parse_header(skb, phw.hw_addr);
b95cce357   Stephen Hemminger   [NET]: Wrap hard_...
487
488
  		if (len > 0) {
  			phw.hw_addrlen = htons(len);
1db20a529   David S. Miller   nfnetlink_log: St...
489
490
  			if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
  				goto nla_put_failure;
b95cce357   Stephen Hemminger   [NET]: Wrap hard_...
491
  		}
0597f2680   Harald Welte   [NETFILTER]: Add ...
492
  	}
72961ecf8   Eric Leblond   netfilter: nfnetl...
493
  	if (indev && skb_mac_header_was_set(skb)) {
2dba62c30   Patrick McHardy   netfilter: nfnetl...
494
  		if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
1db20a529   David S. Miller   nfnetlink_log: St...
495
  		    nla_put_be16(inst->skb, NFULA_HWLEN,
0c36b48b3   Bob Hockney   netfilter: nfnetl...
496
497
498
499
500
501
502
503
504
505
506
  				 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...
507
  			goto nla_put_failure;
72961ecf8   Eric Leblond   netfilter: nfnetl...
508
  	}
b7aa0bf70   Eric Dumazet   [NET]: convert ne...
509
  	if (skb->tstamp.tv64) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
510
  		struct nfulnl_msg_packet_timestamp ts;
f6389ecbc   Arnd Bergmann   nfnetlink: use y2...
511
512
513
  		struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
  		ts.sec = cpu_to_be64(kts.tv_sec);
  		ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
0597f2680   Harald Welte   [NETFILTER]: Add ...
514

1db20a529   David S. Miller   nfnetlink_log: St...
515
516
  		if (nla_put(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts))
  			goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
517
518
519
  	}
  
  	/* UID */
0626af313   Eric Dumazet   netfilter: take c...
520
  	sk = skb->sk;
a8399231f   Eric Dumazet   netfilter: use sk...
521
  	if (sk && sk_fullsock(sk)) {
0626af313   Eric Dumazet   netfilter: take c...
522
523
524
  		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...
525
526
527
528
  			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...
529
  			read_unlock_bh(&sk->sk_callback_lock);
1db20a529   David S. Miller   nfnetlink_log: St...
530
531
532
  			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 ...
533
  		} else
0626af313   Eric Dumazet   netfilter: take c...
534
  			read_unlock_bh(&sk->sk_callback_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
535
  	}
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
536
  	/* local sequence number */
1db20a529   David S. Miller   nfnetlink_log: St...
537
538
539
  	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...
540

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

a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
547
548
549
  	if (ct && nfnl_ct->build(inst->skb, ct, ctinfo,
  				 NFULA_CT, NFULA_CT_INFO) < 0)
  		goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
550
  	if (data_len) {
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
551
552
  		struct nlattr *nla;
  		int size = nla_attr_size(data_len);
0597f2680   Harald Welte   [NETFILTER]: Add ...
553

822516154   Pablo Neira Ayuso   netfilter: nfnetl...
554
555
  		if (skb_tailroom(inst->skb) < nla_total_size(data_len))
  			goto nla_put_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
556

df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
557
558
559
  		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 ...
560

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

0597f2680   Harald Welte   [NETFILTER]: Add ...
565
566
  	nlh->nlmsg_len = inst->skb->tail - old_tail;
  	return 0;
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
567
  nla_put_failure:
0597f2680   Harald Welte   [NETFILTER]: Add ...
568
569
570
571
  	PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg
  ");
  	return -1;
  }
0597f2680   Harald Welte   [NETFILTER]: Add ...
572
573
574
575
576
577
578
579
580
581
582
583
  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...
584
  void
8cdb46da0   Hans Schillstrom   netfilter: log: n...
585
586
  nfulnl_log_packet(struct net *net,
  		  u_int8_t pf,
0597f2680   Harald Welte   [NETFILTER]: Add ...
587
588
589
590
591
592
593
  		  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)
  {
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
594
595
  	size_t size;
  	unsigned int data_len;
0597f2680   Harald Welte   [NETFILTER]: Add ...
596
597
598
  	struct nfulnl_instance *inst;
  	const struct nf_loginfo *li;
  	unsigned int qthreshold;
d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
599
  	unsigned int plen;
9368a53c4   Gao feng   netfilter: nfnetl...
600
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
601
602
603
  	const struct nfnl_ct_hook *nfnl_ct = NULL;
  	struct nf_conn *ct = NULL;
  	enum ip_conntrack_info uninitialized_var(ctinfo);
0597f2680   Harald Welte   [NETFILTER]: Add ...
604

601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
605
  	if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
0597f2680   Harald Welte   [NETFILTER]: Add ...
606
607
608
  		li = li_user;
  	else
  		li = &default_loginfo;
9368a53c4   Gao feng   netfilter: nfnetl...
609
  	inst = instance_lookup_get(log, li->u.ulog.group);
0597f2680   Harald Welte   [NETFILTER]: Add ...
610
  	if (!inst)
0597f2680   Harald Welte   [NETFILTER]: Add ...
611
  		return;
0597f2680   Harald Welte   [NETFILTER]: Add ...
612

d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
613
614
  	plen = 0;
  	if (prefix)
881dbfe8a   Patrick McHardy   [NETFILTER]: nfne...
615
  		plen = strlen(prefix) + 1;
d7a5c3244   Patrick McHardy   [NETFILTER]: nfne...
616

0597f2680   Harald Welte   [NETFILTER]: Add ...
617
618
619
  	/* 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...
620
  	size =    nlmsg_total_size(sizeof(struct nfgenmsg))
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
621
622
623
  		+ 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 */
1109a90c0   Pablo Neira Ayuso   netfilter: use IS...
624
  #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
625
626
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
  		+ nla_total_size(sizeof(u_int32_t))	/* ifindex */
fbcd923c3   Harald Welte   [NETFILTER]: add ...
627
  #endif
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
628
629
  		+ nla_total_size(sizeof(u_int32_t))	/* mark */
  		+ nla_total_size(sizeof(u_int32_t))	/* uid */
76aa1ce13   Patrick McHardy   [NETFILTER]: nfne...
630
  		+ nla_total_size(sizeof(u_int32_t))	/* gid */
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
631
632
  		+ nla_total_size(plen)			/* prefix */
  		+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
9dfa1dfe4   Florian Westphal   netfilter: nf_log...
633
634
  		+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
  		+ nla_total_size(sizeof(struct nfgenmsg));	/* NLMSG_DONE */
0597f2680   Harald Welte   [NETFILTER]: Add ...
635

eeff9beec   Pablo Neira Ayuso   netfilter: nfnetl...
636
637
638
639
640
  	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 ...
641
  	spin_lock_bh(&inst->lock);
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
642
  	if (inst->flags & NFULNL_CFG_F_SEQ)
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
643
  		size += nla_total_size(sizeof(u_int32_t));
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
644
  	if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
645
  		size += nla_total_size(sizeof(u_int32_t));
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
646
647
648
649
650
651
652
653
  	if (inst->flags & NFULNL_CFG_F_CONNTRACK) {
  		nfnl_ct = rcu_dereference(nfnl_ct_hook);
  		if (nfnl_ct != NULL) {
  			ct = nfnl_ct->get_ct(skb, &ctinfo);
  			if (ct != NULL)
  				size += nfnl_ct->build_size(ct);
  		}
  	}
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
654

0597f2680   Harald Welte   [NETFILTER]: Add ...
655
656
  	qthreshold = inst->qthreshold;
  	/* per-rule qthreshold overrides per-instance */
5ca431f9a   Eric Leblond   netfilter: nfnetl...
657
658
659
  	if (li->u.ulog.qthreshold)
  		if (qthreshold > li->u.ulog.qthreshold)
  			qthreshold = li->u.ulog.qthreshold;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
660

0597f2680   Harald Welte   [NETFILTER]: Add ...
661
662
663
664
665
  	switch (inst->copy_mode) {
  	case NFULNL_COPY_META:
  	case NFULNL_COPY_NONE:
  		data_len = 0;
  		break;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
666

0597f2680   Harald Welte   [NETFILTER]: Add ...
667
  	case NFULNL_COPY_PACKET:
7643507fe   Vishwanath Pai   netfilter: xt_NFL...
668
669
670
671
672
673
  		data_len = inst->copy_range;
  		if ((li->u.ulog.flags & NF_LOG_F_COPY_LEN) &&
  		    (li->u.ulog.copy_len < data_len))
  			data_len = li->u.ulog.copy_len;
  
  		if (data_len > skb->len)
0597f2680   Harald Welte   [NETFILTER]: Add ...
674
  			data_len = skb->len;
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
675

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

f5c5440d4   Eric Dumazet   netfilter: nfnetl...
679
  	case NFULNL_COPY_DISABLED:
0597f2680   Harald Welte   [NETFILTER]: Add ...
680
  	default:
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
681
  		goto unlock_and_release;
0597f2680   Harald Welte   [NETFILTER]: Add ...
682
  	}
9dfa1dfe4   Florian Westphal   netfilter: nf_log...
683
  	if (inst->skb && size > skb_tailroom(inst->skb)) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
684
685
  		/* 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...
686
  		__nfulnl_flush(inst);
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
687
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
688

55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
689
  	if (!inst->skb) {
afff14f60   Gao feng   netfilter: nfnetl...
690
691
  		inst->skb = nfulnl_alloc_skb(net, inst->peer_portid,
  					     inst->nlbufsiz, size);
55b5a91e1   Michal Miroslaw   [NETFILTER]: nfne...
692
  		if (!inst->skb)
0597f2680   Harald Welte   [NETFILTER]: Add ...
693
  			goto alloc_failure;
0597f2680   Harald Welte   [NETFILTER]: Add ...
694
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
695
  	inst->qlen++;
9368a53c4   Gao feng   netfilter: nfnetl...
696
  	__build_packet_message(log, inst, skb, data_len, pf,
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
697
698
  				hooknum, in, out, prefix, plen,
  				nfnl_ct, ct, ctinfo);
0597f2680   Harald Welte   [NETFILTER]: Add ...
699

d63b043d9   Michal Miroslaw   [NETFILTER]: nfne...
700
701
  	if (inst->qlen >= qthreshold)
  		__nfulnl_flush(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
702
703
  	/* timer_pending always called within inst->lock, so there
  	 * is no chance of a race here */
d63b043d9   Michal Miroslaw   [NETFILTER]: nfne...
704
  	else if (!timer_pending(&inst->timer)) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
705
706
707
708
  		instance_get(inst);
  		inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
  		add_timer(&inst->timer);
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
709

ed32abeaf   Michal Miroslaw   [NETFILTER]: nfne...
710
711
712
  unlock_and_release:
  	spin_unlock_bh(&inst->lock);
  	instance_put(inst);
0597f2680   Harald Welte   [NETFILTER]: Add ...
713
714
715
  	return;
  
  alloc_failure:
0597f2680   Harald Welte   [NETFILTER]: Add ...
716
  	/* FIXME: statistics */
ed32abeaf   Michal Miroslaw   [NETFILTER]: nfne...
717
  	goto unlock_and_release;
0597f2680   Harald Welte   [NETFILTER]: Add ...
718
  }
5f7340eff   Eric Leblond   netfilter: xt_NFL...
719
  EXPORT_SYMBOL_GPL(nfulnl_log_packet);
0597f2680   Harald Welte   [NETFILTER]: Add ...
720
721
722
723
724
725
  
  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...
726
  	struct nfnl_log_net *log = nfnl_log_pernet(n->net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
727

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

b67bfe0d4   Sasha Levin   hlist: drop the n...
737
  			hlist_for_each_entry_safe(inst, t2, head, hlist) {
9368a53c4   Gao feng   netfilter: nfnetl...
738
  				if (n->portid == inst->peer_portid)
0597f2680   Harald Welte   [NETFILTER]: Add ...
739
740
741
  					__instance_destroy(inst);
  			}
  		}
9368a53c4   Gao feng   netfilter: nfnetl...
742
  		spin_unlock_bh(&log->instances_lock);
0597f2680   Harald Welte   [NETFILTER]: Add ...
743
744
745
746
747
748
749
  	}
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block nfulnl_rtnl_notifier = {
  	.notifier_call	= nfulnl_rcv_nl_event,
  };
7b8002a15   Pablo Neira Ayuso   netfilter: nfnetl...
750
751
752
  static int nfulnl_recv_unsupp(struct net *net, struct sock *ctnl,
  			      struct sk_buff *skb, const struct nlmsghdr *nlh,
  			      const struct nlattr * const nfqa[])
0597f2680   Harald Welte   [NETFILTER]: Add ...
753
754
755
  {
  	return -ENOTSUPP;
  }
ca735b3aa   Eric Leblond   netfilter: use a ...
756
  static struct nf_logger nfulnl_logger __read_mostly = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
757
  	.name	= "nfnetlink_log",
5962815a6   Pablo Neira Ayuso   netfilter: nf_log...
758
  	.type	= NF_LOG_TYPE_ULOG,
0597f2680   Harald Welte   [NETFILTER]: Add ...
759
760
761
  	.logfn	= &nfulnl_log_packet,
  	.me	= THIS_MODULE,
  };
fd8281ada   Patrick McHardy   [NETFILTER]: nfne...
762
763
764
765
766
767
768
  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 ...
769
  };
7b8002a15   Pablo Neira Ayuso   netfilter: nfnetl...
770
771
772
  static int nfulnl_recv_config(struct net *net, struct sock *ctnl,
  			      struct sk_buff *skb, const struct nlmsghdr *nlh,
  			      const struct nlattr * const nfula[])
0597f2680   Harald Welte   [NETFILTER]: Add ...
773
  {
d550d0958   David S. Miller   netfilter: nfnetl...
774
  	struct nfgenmsg *nfmsg = nlmsg_data(nlh);
0597f2680   Harald Welte   [NETFILTER]: Add ...
775
776
  	u_int16_t group_num = ntohs(nfmsg->res_id);
  	struct nfulnl_instance *inst;
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
777
  	struct nfulnl_msg_config_cmd *cmd = NULL;
9368a53c4   Gao feng   netfilter: nfnetl...
778
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
779
  	int ret = 0;
c872a2d9e   Arnd Bergmann   netfilter: nfnetl...
780
  	u16 flags = 0;
0597f2680   Harald Welte   [NETFILTER]: Add ...
781

b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
782
783
784
785
786
787
788
  	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...
789
  			return nf_log_bind_pf(net, pf, &nfulnl_logger);
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
790
  		case NFULNL_CFG_CMD_PF_UNBIND:
30e0c6a6b   Gao feng   netfilter: nf_log...
791
  			nf_log_unbind_pf(net, pf);
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
792
793
794
  			return 0;
  		}
  	}
9368a53c4   Gao feng   netfilter: nfnetl...
795
  	inst = instance_lookup_get(log, group_num);
15e473046   Eric W. Biederman   netlink: Rename p...
796
  	if (inst && inst->peer_portid != NETLINK_CB(skb).portid) {
c0506365a   Patrick McHardy   [NETFILTER]: nfne...
797
798
799
  		ret = -EPERM;
  		goto out_put;
  	}
8cbc87082   Pablo Neira   netfilter: nfnetl...
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  	/* Check if we support these flags in first place, dependencies should
  	 * be there too not to break atomicity.
  	 */
  	if (nfula[NFULA_CFG_FLAGS]) {
  		flags = ntohs(nla_get_be16(nfula[NFULA_CFG_FLAGS]));
  
  		if ((flags & NFULNL_CFG_F_CONNTRACK) &&
  		    !rcu_access_pointer(nfnl_ct_hook)) {
  #ifdef CONFIG_MODULES
  			nfnl_unlock(NFNL_SUBSYS_ULOG);
  			request_module("ip_conntrack_netlink");
  			nfnl_lock(NFNL_SUBSYS_ULOG);
  			if (rcu_access_pointer(nfnl_ct_hook)) {
  				ret = -EAGAIN;
  				goto out_put;
  			}
  #endif
  			ret = -EOPNOTSUPP;
  			goto out_put;
  		}
  	}
b7047a1c8   Patrick McHardy   [NETFILTER]: nfne...
821
  	if (cmd != NULL) {
0597f2680   Harald Welte   [NETFILTER]: Add ...
822
823
824
825
826
827
  		switch (cmd->command) {
  		case NFULNL_CFG_CMD_BIND:
  			if (inst) {
  				ret = -EBUSY;
  				goto out_put;
  			}
9368a53c4   Gao feng   netfilter: nfnetl...
828
  			inst = instance_create(net, group_num,
15e473046   Eric W. Biederman   netlink: Rename p...
829
  					       NETLINK_CB(skb).portid,
e32123e59   Patrick McHardy   netlink: rename s...
830
  					       sk_user_ns(NETLINK_CB(skb).sk));
baab2ce7d   Patrick McHardy   [NETFILTER]: nfne...
831
832
  			if (IS_ERR(inst)) {
  				ret = PTR_ERR(inst);
f414c16c0   Michal Miroslaw   [NETFILTER]: nfne...
833
  				goto out;
0597f2680   Harald Welte   [NETFILTER]: Add ...
834
835
836
837
838
  			}
  			break;
  		case NFULNL_CFG_CMD_UNBIND:
  			if (!inst) {
  				ret = -ENODEV;
f414c16c0   Michal Miroslaw   [NETFILTER]: nfne...
839
  				goto out;
0597f2680   Harald Welte   [NETFILTER]: Add ...
840
  			}
9368a53c4   Gao feng   netfilter: nfnetl...
841
  			instance_destroy(log, inst);
a49c65037   Alexey Dobriyan   netfilter: nfnetl...
842
  			goto out_put;
0597f2680   Harald Welte   [NETFILTER]: Add ...
843
  		default:
cd21f0ac4   Patrick McHardy   [NETFILTER]: nfne...
844
  			ret = -ENOTSUPP;
eb075954e   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
845
  			goto out_put;
0597f2680   Harald Welte   [NETFILTER]: Add ...
846
  		}
336a3b3ee   Pablo Neira Ayuso   netfilter: nfnetl...
847
848
849
  	} else if (!inst) {
  		ret = -ENODEV;
  		goto out;
0597f2680   Harald Welte   [NETFILTER]: Add ...
850
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
851
  	if (nfula[NFULA_CFG_MODE]) {
336a3b3ee   Pablo Neira Ayuso   netfilter: nfnetl...
852
853
  		struct nfulnl_msg_config_mode *params =
  			nla_data(nfula[NFULA_CFG_MODE]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
854
855
  
  		nfulnl_set_mode(inst, params->copy_mode,
d1208b999   Al Viro   [NETFILTER] bug: ...
856
  				ntohl(params->copy_range));
0597f2680   Harald Welte   [NETFILTER]: Add ...
857
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
858
  	if (nfula[NFULA_CFG_TIMEOUT]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
859
  		__be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
860
861
862
  
  		nfulnl_set_timeout(inst, ntohl(timeout));
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
863
  	if (nfula[NFULA_CFG_NLBUFSIZ]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
864
  		__be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
865
866
867
  
  		nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz));
  	}
df6fb868d   Patrick McHardy   [NETFILTER]: nfne...
868
  	if (nfula[NFULA_CFG_QTHRESH]) {
0dfedd287   Patrick McHardy   [NETFILTER]: nfne...
869
  		__be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]);
0597f2680   Harald Welte   [NETFILTER]: Add ...
870
871
872
  
  		nfulnl_set_qthresh(inst, ntohl(qthresh));
  	}
8cbc87082   Pablo Neira   netfilter: nfnetl...
873
  	if (nfula[NFULA_CFG_FLAGS])
a29a9a585   Ken-ichirou MATSUZAWA   netfilter: nfnetl...
874
  		nfulnl_set_flags(inst, flags);
0af5f6c1e   Harald Welte   [NETFILTER] nfnet...
875

0597f2680   Harald Welte   [NETFILTER]: Add ...
876
877
  out_put:
  	instance_put(inst);
dd16704eb   Michal Miroslaw   [NETFILTER]: nfne...
878
  out:
0597f2680   Harald Welte   [NETFILTER]: Add ...
879
880
  	return ret;
  }
7c8d4cb41   Patrick McHardy   [NETFILTER]: nfne...
881
  static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
882
  	[NFULNL_MSG_PACKET]	= { .call = nfulnl_recv_unsupp,
37d2e7a20   Harald Welte   [NETFILTER] nfnet...
883
  				    .attr_count = NFULA_MAX, },
0597f2680   Harald Welte   [NETFILTER]: Add ...
884
  	[NFULNL_MSG_CONFIG]	= { .call = nfulnl_recv_config,
fd8281ada   Patrick McHardy   [NETFILTER]: nfne...
885
886
  				    .attr_count = NFULA_CFG_MAX,
  				    .policy = nfula_cfg_policy },
0597f2680   Harald Welte   [NETFILTER]: Add ...
887
  };
7c8d4cb41   Patrick McHardy   [NETFILTER]: nfne...
888
  static const struct nfnetlink_subsystem nfulnl_subsys = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
889
890
891
  	.name		= "log",
  	.subsys_id	= NFNL_SUBSYS_ULOG,
  	.cb_count	= NFULNL_MSG_MAX,
0597f2680   Harald Welte   [NETFILTER]: Add ...
892
893
894
895
896
  	.cb		= nfulnl_cb,
  };
  
  #ifdef CONFIG_PROC_FS
  struct iter_state {
9368a53c4   Gao feng   netfilter: nfnetl...
897
  	struct seq_net_private p;
0597f2680   Harald Welte   [NETFILTER]: Add ...
898
899
  	unsigned int bucket;
  };
9368a53c4   Gao feng   netfilter: nfnetl...
900
  static struct hlist_node *get_first(struct net *net, struct iter_state *st)
0597f2680   Harald Welte   [NETFILTER]: Add ...
901
  {
9368a53c4   Gao feng   netfilter: nfnetl...
902
  	struct nfnl_log_net *log;
0597f2680   Harald Welte   [NETFILTER]: Add ...
903
904
  	if (!st)
  		return NULL;
9368a53c4   Gao feng   netfilter: nfnetl...
905
  	log = nfnl_log_pernet(net);
0597f2680   Harald Welte   [NETFILTER]: Add ...
906
  	for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
9368a53c4   Gao feng   netfilter: nfnetl...
907
908
909
910
  		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 ...
911
912
913
  	}
  	return NULL;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
914
915
  static struct hlist_node *get_next(struct net *net, struct iter_state *st,
  				   struct hlist_node *h)
0597f2680   Harald Welte   [NETFILTER]: Add ...
916
  {
0e60ebe04   Eric Dumazet   netfilter: add __...
917
  	h = rcu_dereference_bh(hlist_next_rcu(h));
0597f2680   Harald Welte   [NETFILTER]: Add ...
918
  	while (!h) {
9368a53c4   Gao feng   netfilter: nfnetl...
919
920
  		struct nfnl_log_net *log;
  		struct hlist_head *head;
0597f2680   Harald Welte   [NETFILTER]: Add ...
921
922
  		if (++st->bucket >= INSTANCE_BUCKETS)
  			return NULL;
9368a53c4   Gao feng   netfilter: nfnetl...
923
924
925
  		log = nfnl_log_pernet(net);
  		head = &log->instance_table[st->bucket];
  		h = rcu_dereference_bh(hlist_first_rcu(head));
0597f2680   Harald Welte   [NETFILTER]: Add ...
926
927
928
  	}
  	return h;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
929
930
  static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
  				  loff_t pos)
0597f2680   Harald Welte   [NETFILTER]: Add ...
931
932
  {
  	struct hlist_node *head;
9368a53c4   Gao feng   netfilter: nfnetl...
933
  	head = get_first(net, st);
0597f2680   Harald Welte   [NETFILTER]: Add ...
934
935
  
  	if (head)
9368a53c4   Gao feng   netfilter: nfnetl...
936
  		while (pos && (head = get_next(net, st, head)))
0597f2680   Harald Welte   [NETFILTER]: Add ...
937
938
939
  			pos--;
  	return pos ? NULL : head;
  }
9368a53c4   Gao feng   netfilter: nfnetl...
940
  static void *seq_start(struct seq_file *s, loff_t *pos)
bed1be208   Eric Dumazet   netfilter: nfnetl...
941
  	__acquires(rcu_bh)
0597f2680   Harald Welte   [NETFILTER]: Add ...
942
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
943
  	rcu_read_lock_bh();
9368a53c4   Gao feng   netfilter: nfnetl...
944
  	return get_idx(seq_file_net(s), s->private, *pos);
0597f2680   Harald Welte   [NETFILTER]: Add ...
945
946
947
948
949
  }
  
  static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
  {
  	(*pos)++;
9368a53c4   Gao feng   netfilter: nfnetl...
950
  	return get_next(seq_file_net(s), s->private, v);
0597f2680   Harald Welte   [NETFILTER]: Add ...
951
952
953
  }
  
  static void seq_stop(struct seq_file *s, void *v)
bed1be208   Eric Dumazet   netfilter: nfnetl...
954
  	__releases(rcu_bh)
0597f2680   Harald Welte   [NETFILTER]: Add ...
955
  {
bed1be208   Eric Dumazet   netfilter: nfnetl...
956
  	rcu_read_unlock_bh();
0597f2680   Harald Welte   [NETFILTER]: Add ...
957
958
959
960
961
  }
  
  static int seq_show(struct seq_file *s, void *v)
  {
  	const struct nfulnl_instance *inst = v;
20a1d1652   Richard Weinberger   netfilter: Fix fo...
962
963
  	seq_printf(s, "%5u %6u %5u %1u %5u %6u %2u
  ",
1ca9e4177   Joe Perches   netfilter: Remove...
964
965
966
967
968
969
  		   inst->group_num,
  		   inst->peer_portid, inst->qlen,
  		   inst->copy_mode, inst->copy_range,
  		   inst->flushtimeout, atomic_read(&inst->use));
  
  	return 0;
0597f2680   Harald Welte   [NETFILTER]: Add ...
970
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
971
  static const struct seq_operations nful_seq_ops = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
972
973
974
975
976
977
978
979
  	.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...
980
981
  	return seq_open_net(inode, file, &nful_seq_ops,
  			    sizeof(struct iter_state));
0597f2680   Harald Welte   [NETFILTER]: Add ...
982
  }
da7071d7e   Arjan van de Ven   [PATCH] mark stru...
983
  static const struct file_operations nful_file_ops = {
0597f2680   Harald Welte   [NETFILTER]: Add ...
984
985
986
987
  	.owner	 = THIS_MODULE,
  	.open	 = nful_open,
  	.read	 = seq_read,
  	.llseek	 = seq_lseek,
9368a53c4   Gao feng   netfilter: nfnetl...
988
  	.release = seq_release_net,
0597f2680   Harald Welte   [NETFILTER]: Add ...
989
990
991
  };
  
  #endif /* PROC_FS */
9368a53c4   Gao feng   netfilter: nfnetl...
992
  static int __net_init nfnl_log_net_init(struct net *net)
0597f2680   Harald Welte   [NETFILTER]: Add ...
993
  {
9368a53c4   Gao feng   netfilter: nfnetl...
994
995
  	unsigned int i;
  	struct nfnl_log_net *log = nfnl_log_pernet(net);
f13f2aeed   Philip Whineray   netfilter: Set /p...
996
997
998
999
1000
  #ifdef CONFIG_PROC_FS
  	struct proc_dir_entry *proc;
  	kuid_t root_uid;
  	kgid_t root_gid;
  #endif
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1001

0597f2680   Harald Welte   [NETFILTER]: Add ...
1002
  	for (i = 0; i < INSTANCE_BUCKETS; i++)
9368a53c4   Gao feng   netfilter: nfnetl...
1003
1004
1005
1006
  		INIT_HLIST_HEAD(&log->instance_table[i]);
  	spin_lock_init(&log->instances_lock);
  
  #ifdef CONFIG_PROC_FS
f13f2aeed   Philip Whineray   netfilter: Set /p...
1007
1008
1009
  	proc = proc_create("nfnetlink_log", 0440,
  			   net->nf.proc_netfilter, &nful_file_ops);
  	if (!proc)
9368a53c4   Gao feng   netfilter: nfnetl...
1010
  		return -ENOMEM;
f13f2aeed   Philip Whineray   netfilter: Set /p...
1011
1012
1013
1014
1015
  
  	root_uid = make_kuid(net->user_ns, 0);
  	root_gid = make_kgid(net->user_ns, 0);
  	if (uid_valid(root_uid) && gid_valid(root_gid))
  		proc_set_user(proc, root_uid, root_gid);
9368a53c4   Gao feng   netfilter: nfnetl...
1016
1017
1018
1019
1020
1021
  #endif
  	return 0;
  }
  
  static void __net_exit nfnl_log_net_exit(struct net *net)
  {
e778f56e2   Pablo Neira Ayuso   netfilter: nf_{lo...
1022
  #ifdef CONFIG_PROC_FS
9368a53c4   Gao feng   netfilter: nfnetl...
1023
  	remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
e778f56e2   Pablo Neira Ayuso   netfilter: nf_{lo...
1024
  #endif
45c2aff64   Gao feng   netfilter: nfnetl...
1025
  	nf_log_unset(net, &nfulnl_logger);
9368a53c4   Gao feng   netfilter: nfnetl...
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
  }
  
  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)
  {
3bfe04980   Francesco Ruggeri   netfilter: nfnetl...
1037
1038
1039
1040
1041
1042
1043
1044
  	int status;
  
  	status = register_pernet_subsys(&nfnl_log_net_ops);
  	if (status < 0) {
  		pr_err("failed to register pernet ops
  ");
  		goto out;
  	}
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
1045

0597f2680   Harald Welte   [NETFILTER]: Add ...
1046
1047
1048
  	netlink_register_notifier(&nfulnl_rtnl_notifier);
  	status = nfnetlink_subsys_register(&nfulnl_subsys);
  	if (status < 0) {
beacd3e8e   Marcelo Leitner   netfilter: nfnetl...
1049
1050
  		pr_err("failed to create netlink socket
  ");
0597f2680   Harald Welte   [NETFILTER]: Add ...
1051
1052
  		goto cleanup_netlink_notifier;
  	}
ca735b3aa   Eric Leblond   netfilter: use a ...
1053
1054
  	status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
  	if (status < 0) {
beacd3e8e   Marcelo Leitner   netfilter: nfnetl...
1055
1056
  		pr_err("failed to register logger
  ");
ca735b3aa   Eric Leblond   netfilter: use a ...
1057
1058
  		goto cleanup_subsys;
  	}
0597f2680   Harald Welte   [NETFILTER]: Add ...
1059
  	return status;
0597f2680   Harald Welte   [NETFILTER]: Add ...
1060
  cleanup_subsys:
0597f2680   Harald Welte   [NETFILTER]: Add ...
1061
1062
1063
  	nfnetlink_subsys_unregister(&nfulnl_subsys);
  cleanup_netlink_notifier:
  	netlink_unregister_notifier(&nfulnl_rtnl_notifier);
3bfe04980   Francesco Ruggeri   netfilter: nfnetl...
1064
1065
  	unregister_pernet_subsys(&nfnl_log_net_ops);
  out:
0597f2680   Harald Welte   [NETFILTER]: Add ...
1066
1067
  	return status;
  }
65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
1068
  static void __exit nfnetlink_log_fini(void)
0597f2680   Harald Welte   [NETFILTER]: Add ...
1069
  {
e92ad99c7   Patrick McHardy   [NETFILTER]: nf_l...
1070
  	nf_log_unregister(&nfulnl_logger);
32292a7ff   Patrick McHardy   [NETFILTER]: Fix ...
1071
1072
  	nfnetlink_subsys_unregister(&nfulnl_subsys);
  	netlink_unregister_notifier(&nfulnl_rtnl_notifier);
3bfe04980   Francesco Ruggeri   netfilter: nfnetl...
1073
  	unregister_pernet_subsys(&nfnl_log_net_ops);
0597f2680   Harald Welte   [NETFILTER]: Add ...
1074
1075
1076
1077
1078
  }
  
  MODULE_DESCRIPTION("netfilter userspace logging");
  MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  MODULE_LICENSE("GPL");
f682faefb   Harald Welte   [NETFILTER]: fix ...
1079
  MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
fab4085f4   Pablo Neira Ayuso   netfilter: log: n...
1080
1081
1082
  MODULE_ALIAS_NF_LOGGER(AF_INET, 1);
  MODULE_ALIAS_NF_LOGGER(AF_INET6, 1);
  MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1);
2497b8462   Liping Zhang   netfilter: nfnetl...
1083
  MODULE_ALIAS_NF_LOGGER(3, 1); /* NFPROTO_ARP */
0597f2680   Harald Welte   [NETFILTER]: Add ...
1084

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