Blame view
net/netfilter/nfnetlink_log.c
24.1 KB
0597f2680 [NETFILTER]: Add ... |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * This is a module which is used for logging packets to userspace via * nfetlink. * * (C) 2005 by Harald Welte <laforge@netfilter.org> * * 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 [NETFILTER]: Add ... |
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
*/ #include <linux/module.h> #include <linux/skbuff.h> #include <linux/init.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/netdevice.h> #include <linux/netfilter.h> #include <linux/netlink.h> #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 include cleanup: ... |
31 |
#include <linux/slab.h> |
0597f2680 [NETFILTER]: Add ... |
32 |
#include <net/sock.h> |
f01ffbd6e [NETFILTER]: nf_l... |
33 |
#include <net/netfilter/nf_log.h> |
d9e150071 netfilter: nfnetl... |
34 |
#include <net/netfilter/nfnetlink_log.h> |
0597f2680 [NETFILTER]: Add ... |
35 |
|
60063497a atomic: use <linu... |
36 |
#include <linux/atomic.h> |
0597f2680 [NETFILTER]: Add ... |
37 |
|
fbcd923c3 [NETFILTER]: add ... |
38 39 40 |
#ifdef CONFIG_BRIDGE_NETFILTER #include "../bridge/br_private.h" #endif |
c2db29243 [NETFILTER]: ULOG... |
41 |
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE |
2c6764b74 netfilter: nfnetl... |
42 |
#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ |
0597f2680 [NETFILTER]: Add ... |
43 |
#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ |
6b6ec99a0 [NETFILTER]: nfne... |
44 |
#define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ |
0597f2680 [NETFILTER]: Add ... |
45 46 47 |
#define PRINTR(x, args...) do { if (net_ratelimit()) \ printk(x, ## args); } while (0); |
0597f2680 [NETFILTER]: Add ... |
48 49 50 51 52 53 54 |
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 [NETFILTER]: Add ... |
55 56 57 58 59 60 61 62 |
struct timer_list timer; int peer_pid; /* PID of the peer process */ /* 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 [NETFILTER] nfnet... |
63 |
u_int32_t seq; /* instance-local sequential counter */ |
0597f2680 [NETFILTER]: Add ... |
64 |
u_int16_t group_num; /* number of this queue */ |
0af5f6c1e [NETFILTER] nfnet... |
65 |
u_int16_t flags; |
601e68e10 [NETFILTER]: Fix ... |
66 |
u_int8_t copy_mode; |
bed1be208 netfilter: nfnetl... |
67 |
struct rcu_head rcu; |
0597f2680 [NETFILTER]: Add ... |
68 |
}; |
bed1be208 netfilter: nfnetl... |
69 |
static DEFINE_SPINLOCK(instances_lock); |
0af5f6c1e [NETFILTER] nfnet... |
70 |
static atomic_t global_seq; |
0597f2680 [NETFILTER]: Add ... |
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#define INSTANCE_BUCKETS 16 static struct hlist_head instance_table[INSTANCE_BUCKETS]; static unsigned int hash_init; static inline u_int8_t instance_hashfn(u_int16_t group_num) { return ((group_num & 0xff) % INSTANCE_BUCKETS); } static struct nfulnl_instance * __instance_lookup(u_int16_t group_num) { struct hlist_head *head; struct hlist_node *pos; struct nfulnl_instance *inst; |
0597f2680 [NETFILTER]: Add ... |
87 |
head = &instance_table[instance_hashfn(group_num)]; |
bed1be208 netfilter: nfnetl... |
88 |
hlist_for_each_entry_rcu(inst, pos, head, hlist) { |
0597f2680 [NETFILTER]: Add ... |
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
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 * instance_lookup_get(u_int16_t group_num) { struct nfulnl_instance *inst; |
bed1be208 netfilter: nfnetl... |
105 |
rcu_read_lock_bh(); |
0597f2680 [NETFILTER]: Add ... |
106 |
inst = __instance_lookup(group_num); |
f5c5440d4 netfilter: nfnetl... |
107 108 |
if (inst && !atomic_inc_not_zero(&inst->use)) inst = NULL; |
bed1be208 netfilter: nfnetl... |
109 |
rcu_read_unlock_bh(); |
0597f2680 [NETFILTER]: Add ... |
110 111 112 |
return inst; } |
bed1be208 netfilter: nfnetl... |
113 114 115 116 117 |
static void nfulnl_instance_free_rcu(struct rcu_head *head) { kfree(container_of(head, struct nfulnl_instance, rcu)); module_put(THIS_MODULE); } |
0597f2680 [NETFILTER]: Add ... |
118 119 120 |
static void instance_put(struct nfulnl_instance *inst) { |
bed1be208 netfilter: nfnetl... |
121 122 |
if (inst && atomic_dec_and_test(&inst->use)) call_rcu_bh(&inst->rcu, nfulnl_instance_free_rcu); |
0597f2680 [NETFILTER]: Add ... |
123 124 125 126 127 128 129 130 |
} static void nfulnl_timer(unsigned long data); static struct nfulnl_instance * instance_create(u_int16_t group_num, int pid) { struct nfulnl_instance *inst; |
baab2ce7d [NETFILTER]: nfne... |
131 |
int err; |
0597f2680 [NETFILTER]: Add ... |
132 |
|
bed1be208 netfilter: nfnetl... |
133 |
spin_lock_bh(&instances_lock); |
0597f2680 [NETFILTER]: Add ... |
134 |
if (__instance_lookup(group_num)) { |
baab2ce7d [NETFILTER]: nfne... |
135 |
err = -EEXIST; |
0597f2680 [NETFILTER]: Add ... |
136 137 |
goto out_unlock; } |
10dfdc69e [NETFILTER] nfnet... |
138 |
inst = kzalloc(sizeof(*inst), GFP_ATOMIC); |
baab2ce7d [NETFILTER]: nfne... |
139 140 |
if (!inst) { err = -ENOMEM; |
0597f2680 [NETFILTER]: Add ... |
141 |
goto out_unlock; |
baab2ce7d [NETFILTER]: nfne... |
142 |
} |
0597f2680 [NETFILTER]: Add ... |
143 |
|
aace57e05 [NETFILTER]: nfne... |
144 145 |
if (!try_module_get(THIS_MODULE)) { kfree(inst); |
baab2ce7d [NETFILTER]: nfne... |
146 |
err = -EAGAIN; |
aace57e05 [NETFILTER]: nfne... |
147 148 |
goto out_unlock; } |
0597f2680 [NETFILTER]: Add ... |
149 |
INIT_HLIST_NODE(&inst->hlist); |
181a46a56 [NETFILTER]: Use ... |
150 |
spin_lock_init(&inst->lock); |
0597f2680 [NETFILTER]: Add ... |
151 152 |
/* needs to be two, since we _put() after creation */ atomic_set(&inst->use, 2); |
e6f689db5 [NETFILTER]: Use ... |
153 |
setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); |
0597f2680 [NETFILTER]: Add ... |
154 155 156 157 158 159 160 161 |
inst->peer_pid = pid; 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 [NETFILTER]: nfne... |
162 |
inst->copy_range = NFULNL_COPY_RANGE_MAX; |
0597f2680 [NETFILTER]: Add ... |
163 |
|
f5c5440d4 netfilter: nfnetl... |
164 |
hlist_add_head_rcu(&inst->hlist, |
0597f2680 [NETFILTER]: Add ... |
165 |
&instance_table[instance_hashfn(group_num)]); |
bed1be208 netfilter: nfnetl... |
166 |
spin_unlock_bh(&instances_lock); |
0597f2680 [NETFILTER]: Add ... |
167 168 |
return inst; |
0597f2680 [NETFILTER]: Add ... |
169 |
out_unlock: |
bed1be208 netfilter: nfnetl... |
170 |
spin_unlock_bh(&instances_lock); |
baab2ce7d [NETFILTER]: nfne... |
171 |
return ERR_PTR(err); |
0597f2680 [NETFILTER]: Add ... |
172 |
} |
e35670614 [NETFILTER]: nfne... |
173 |
static void __nfulnl_flush(struct nfulnl_instance *inst); |
0597f2680 [NETFILTER]: Add ... |
174 |
|
f5c5440d4 netfilter: nfnetl... |
175 |
/* called with BH disabled */ |
0597f2680 [NETFILTER]: Add ... |
176 |
static void |
9afdb00c8 [NETFILTER]: nfne... |
177 |
__instance_destroy(struct nfulnl_instance *inst) |
0597f2680 [NETFILTER]: Add ... |
178 179 |
{ /* first pull it out of the global list */ |
f5c5440d4 netfilter: nfnetl... |
180 |
hlist_del_rcu(&inst->hlist); |
0597f2680 [NETFILTER]: Add ... |
181 |
|
0597f2680 [NETFILTER]: Add ... |
182 |
/* then flush all pending packets from skb */ |
f5c5440d4 netfilter: nfnetl... |
183 184 185 186 |
spin_lock(&inst->lock); /* lockless readers wont be able to use us */ inst->copy_mode = NFULNL_COPY_DISABLED; |
e35670614 [NETFILTER]: nfne... |
187 188 |
if (inst->skb) __nfulnl_flush(inst); |
f5c5440d4 netfilter: nfnetl... |
189 |
spin_unlock(&inst->lock); |
0597f2680 [NETFILTER]: Add ... |
190 191 192 |
/* and finally put the refcount */ instance_put(inst); |
0597f2680 [NETFILTER]: Add ... |
193 194 195 |
} static inline void |
0597f2680 [NETFILTER]: Add ... |
196 197 |
instance_destroy(struct nfulnl_instance *inst) { |
bed1be208 netfilter: nfnetl... |
198 |
spin_lock_bh(&instances_lock); |
9afdb00c8 [NETFILTER]: nfne... |
199 |
__instance_destroy(inst); |
bed1be208 netfilter: nfnetl... |
200 |
spin_unlock_bh(&instances_lock); |
0597f2680 [NETFILTER]: Add ... |
201 202 203 204 205 206 207 208 209 |
} 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 [NETFILTER]: Fix ... |
210 |
|
0597f2680 [NETFILTER]: Add ... |
211 212 213 214 215 216 |
switch (mode) { case NFULNL_COPY_NONE: case NFULNL_COPY_META: inst->copy_mode = mode; inst->copy_range = 0; break; |
601e68e10 [NETFILTER]: Fix ... |
217 |
|
0597f2680 [NETFILTER]: Add ... |
218 219 |
case NFULNL_COPY_PACKET: inst->copy_mode = mode; |
6b6ec99a0 [NETFILTER]: nfne... |
220 221 |
inst->copy_range = min_t(unsigned int, range, NFULNL_COPY_RANGE_MAX); |
0597f2680 [NETFILTER]: Add ... |
222 |
break; |
601e68e10 [NETFILTER]: Fix ... |
223 |
|
0597f2680 [NETFILTER]: Add ... |
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 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 |
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 [NETFILTER] nfnet... |
272 273 274 275 |
static int nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags) { spin_lock_bh(&inst->lock); |
ee433530d [NETFILTER]: nfne... |
276 |
inst->flags = flags; |
0af5f6c1e [NETFILTER] nfnet... |
277 278 279 280 |
spin_unlock_bh(&inst->lock); return 0; } |
c6a8f6483 [NETFILTER]: nfne... |
281 282 |
static struct sk_buff * nfulnl_alloc_skb(unsigned int inst_size, unsigned int pkt_size) |
0597f2680 [NETFILTER]: Add ... |
283 284 |
{ struct sk_buff *skb; |
ad2ad0f96 [NETFILTER]: Fix ... |
285 |
unsigned int n; |
0597f2680 [NETFILTER]: Add ... |
286 |
|
0597f2680 [NETFILTER]: Add ... |
287 288 |
/* alloc skb which should be big enough for a whole multipart * message. WARNING: has to be <= 128k due to slab restrictions */ |
ad2ad0f96 [NETFILTER]: Fix ... |
289 290 |
n = max(inst_size, pkt_size); skb = alloc_skb(n, GFP_ATOMIC); |
0597f2680 [NETFILTER]: Add ... |
291 |
if (!skb) { |
ad2ad0f96 [NETFILTER]: Fix ... |
292 293 294 |
if (n > pkt_size) { /* try to allocate only as much as we need for current * packet */ |
0597f2680 [NETFILTER]: Add ... |
295 |
|
ad2ad0f96 [NETFILTER]: Fix ... |
296 297 |
skb = alloc_skb(pkt_size, GFP_ATOMIC); if (!skb) |
0a9ee8134 netfilter: Remove... |
298 299 300 |
pr_err("nfnetlink_log: can't even alloc %u bytes ", pkt_size); |
ad2ad0f96 [NETFILTER]: Fix ... |
301 |
} |
0597f2680 [NETFILTER]: Add ... |
302 303 304 305 306 307 308 309 |
} return skb; } static int __nfulnl_send(struct nfulnl_instance *inst) { |
29c5d4afb [NETFILTER]: nfne... |
310 |
int status = -1; |
0597f2680 [NETFILTER]: Add ... |
311 |
|
0597f2680 [NETFILTER]: Add ... |
312 |
if (inst->qlen > 1) |
29c5d4afb [NETFILTER]: nfne... |
313 314 315 |
NLMSG_PUT(inst->skb, 0, 0, NLMSG_DONE, sizeof(struct nfgenmsg)); |
0597f2680 [NETFILTER]: Add ... |
316 |
|
cd8c20b65 netfilter: nfnetl... |
317 318 |
status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_pid, MSG_DONTWAIT); |
0597f2680 [NETFILTER]: Add ... |
319 320 321 |
inst->qlen = 0; inst->skb = NULL; |
0597f2680 [NETFILTER]: Add ... |
322 |
|
29c5d4afb [NETFILTER]: nfne... |
323 |
nlmsg_failure: |
0597f2680 [NETFILTER]: Add ... |
324 325 |
return status; } |
e35670614 [NETFILTER]: nfne... |
326 327 328 329 330 331 332 333 334 |
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 [NETFILTER]: nfne... |
335 336 |
static void nfulnl_timer(unsigned long data) |
0597f2680 [NETFILTER]: Add ... |
337 |
{ |
601e68e10 [NETFILTER]: Fix ... |
338 |
struct nfulnl_instance *inst = (struct nfulnl_instance *)data; |
0597f2680 [NETFILTER]: Add ... |
339 |
|
0597f2680 [NETFILTER]: Add ... |
340 |
spin_lock_bh(&inst->lock); |
370e6a878 [NETFILTER]: nfne... |
341 342 |
if (inst->skb) __nfulnl_send(inst); |
0597f2680 [NETFILTER]: Add ... |
343 |
spin_unlock_bh(&inst->lock); |
05f7b7b36 [NETFILTER]: nfne... |
344 |
instance_put(inst); |
0597f2680 [NETFILTER]: Add ... |
345 |
} |
0af5f6c1e [NETFILTER] nfnet... |
346 347 |
/* This is an inline function, we don't really care about a long * list of arguments */ |
601e68e10 [NETFILTER]: Fix ... |
348 |
static inline int |
0597f2680 [NETFILTER]: Add ... |
349 |
__build_packet_message(struct nfulnl_instance *inst, |
601e68e10 [NETFILTER]: Fix ... |
350 |
const struct sk_buff *skb, |
0597f2680 [NETFILTER]: Add ... |
351 |
unsigned int data_len, |
76108cea0 netfilter: Use un... |
352 |
u_int8_t pf, |
0597f2680 [NETFILTER]: Add ... |
353 354 355 |
unsigned int hooknum, const struct net_device *indev, const struct net_device *outdev, |
d7a5c3244 [NETFILTER]: nfne... |
356 |
const char *prefix, unsigned int plen) |
0597f2680 [NETFILTER]: Add ... |
357 |
{ |
0597f2680 [NETFILTER]: Add ... |
358 359 360 |
struct nfulnl_msg_packet_hdr pmsg; struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; |
27a884dc3 [SK_BUFF]: Conver... |
361 |
sk_buff_data_t old_tail = inst->skb->tail; |
0597f2680 [NETFILTER]: Add ... |
362 |
|
601e68e10 [NETFILTER]: Fix ... |
363 |
nlh = NLMSG_PUT(inst->skb, 0, 0, |
0597f2680 [NETFILTER]: Add ... |
364 365 366 367 368 369 |
NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, sizeof(struct nfgenmsg)); nfmsg = NLMSG_DATA(nlh); nfmsg->nfgen_family = pf; nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(inst->group_num); |
febf0a431 [NETFILTER] bug: ... |
370 |
pmsg.hw_protocol = skb->protocol; |
0597f2680 [NETFILTER]: Add ... |
371 |
pmsg.hook = hooknum; |
df6fb868d [NETFILTER]: nfne... |
372 |
NLA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); |
0597f2680 [NETFILTER]: Add ... |
373 |
|
d7a5c3244 [NETFILTER]: nfne... |
374 |
if (prefix) |
df6fb868d [NETFILTER]: nfne... |
375 |
NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix); |
0597f2680 [NETFILTER]: Add ... |
376 377 |
if (indev) { |
fbcd923c3 [NETFILTER]: add ... |
378 |
#ifndef CONFIG_BRIDGE_NETFILTER |
0dfedd287 [NETFILTER]: nfne... |
379 380 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, htonl(indev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
381 382 383 384 385 |
#else if (pf == PF_BRIDGE) { /* Case 1: outdev is physical input device, we need to * look for bridge group (when called from * netfilter_bridge) */ |
0dfedd287 [NETFILTER]: nfne... |
386 387 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, htonl(indev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
388 |
/* this is the bridge group "brX" */ |
f350a0a87 bridge: use rx_ha... |
389 |
/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ |
0dfedd287 [NETFILTER]: nfne... |
390 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, |
f350a0a87 bridge: use rx_ha... |
391 |
htonl(br_port_get_rcu(indev)->br->dev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
392 393 394 |
} else { /* Case 2: indev is bridge group, we need to look for * physical device (when called from ipv4) */ |
0dfedd287 [NETFILTER]: nfne... |
395 396 397 398 399 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, htonl(indev->ifindex)); if (skb->nf_bridge && skb->nf_bridge->physindev) NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, htonl(skb->nf_bridge->physindev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
400 401 |
} #endif |
0597f2680 [NETFILTER]: Add ... |
402 403 404 |
} if (outdev) { |
fbcd923c3 [NETFILTER]: add ... |
405 |
#ifndef CONFIG_BRIDGE_NETFILTER |
0dfedd287 [NETFILTER]: nfne... |
406 407 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, htonl(outdev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
408 409 410 411 412 |
#else if (pf == PF_BRIDGE) { /* Case 1: outdev is physical output device, we need to * look for bridge group (when called from * netfilter_bridge) */ |
0dfedd287 [NETFILTER]: nfne... |
413 414 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, htonl(outdev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
415 |
/* this is the bridge group "brX" */ |
f350a0a87 bridge: use rx_ha... |
416 |
/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ |
0dfedd287 [NETFILTER]: nfne... |
417 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, |
f350a0a87 bridge: use rx_ha... |
418 |
htonl(br_port_get_rcu(outdev)->br->dev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
419 420 421 |
} else { /* Case 2: indev is a bridge group, we need to look * for physical device (when called from ipv4) */ |
0dfedd287 [NETFILTER]: nfne... |
422 423 424 425 426 |
NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, htonl(outdev->ifindex)); if (skb->nf_bridge && skb->nf_bridge->physoutdev) NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, htonl(skb->nf_bridge->physoutdev->ifindex)); |
fbcd923c3 [NETFILTER]: add ... |
427 428 |
} #endif |
0597f2680 [NETFILTER]: Add ... |
429 |
} |
0dfedd287 [NETFILTER]: nfne... |
430 431 |
if (skb->mark) NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); |
0597f2680 [NETFILTER]: Add ... |
432 |
|
2c38de4c1 netfilter: fix lo... |
433 434 |
if (indev && skb->dev && skb->mac_header != skb->network_header) { |
0597f2680 [NETFILTER]: Add ... |
435 |
struct nfulnl_msg_packet_hw phw; |
b95cce357 [NET]: Wrap hard_... |
436 437 438 |
int len = dev_parse_header(skb, phw.hw_addr); if (len > 0) { phw.hw_addrlen = htons(len); |
df6fb868d [NETFILTER]: nfne... |
439 |
NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); |
b95cce357 [NET]: Wrap hard_... |
440 |
} |
0597f2680 [NETFILTER]: Add ... |
441 |
} |
72961ecf8 netfilter: nfnetl... |
442 443 444 445 446 447 448 |
if (indev && skb_mac_header_was_set(skb)) { NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)); NLA_PUT_BE16(inst->skb, NFULA_HWLEN, htons(skb->dev->hard_header_len)); NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, skb_mac_header(skb)); } |
b7aa0bf70 [NET]: convert ne... |
449 |
if (skb->tstamp.tv64) { |
0597f2680 [NETFILTER]: Add ... |
450 |
struct nfulnl_msg_packet_timestamp ts; |
b7aa0bf70 [NET]: convert ne... |
451 452 453 |
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 [NETFILTER]: Add ... |
454 |
|
df6fb868d [NETFILTER]: nfne... |
455 |
NLA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts); |
0597f2680 [NETFILTER]: Add ... |
456 457 458 459 460 461 |
} /* UID */ if (skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) { |
d76b0d9b2 CRED: Use creds i... |
462 463 464 |
struct file *file = skb->sk->sk_socket->file; __be32 uid = htonl(file->f_cred->fsuid); __be32 gid = htonl(file->f_cred->fsgid); |
df6fb868d [NETFILTER]: nfne... |
465 |
/* need to unlock here since NLA_PUT may goto */ |
0597f2680 [NETFILTER]: Add ... |
466 |
read_unlock_bh(&skb->sk->sk_callback_lock); |
0dfedd287 [NETFILTER]: nfne... |
467 |
NLA_PUT_BE32(inst->skb, NFULA_UID, uid); |
76aa1ce13 [NETFILTER]: nfne... |
468 |
NLA_PUT_BE32(inst->skb, NFULA_GID, gid); |
0597f2680 [NETFILTER]: Add ... |
469 470 471 |
} else read_unlock_bh(&skb->sk->sk_callback_lock); } |
0af5f6c1e [NETFILTER] nfnet... |
472 |
/* local sequence number */ |
0dfedd287 [NETFILTER]: nfne... |
473 474 |
if (inst->flags & NFULNL_CFG_F_SEQ) NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++)); |
0af5f6c1e [NETFILTER] nfnet... |
475 |
/* global sequence number */ |
0dfedd287 [NETFILTER]: nfne... |
476 477 478 |
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL, htonl(atomic_inc_return(&global_seq))); |
0af5f6c1e [NETFILTER] nfnet... |
479 |
|
0597f2680 [NETFILTER]: Add ... |
480 |
if (data_len) { |
df6fb868d [NETFILTER]: nfne... |
481 482 |
struct nlattr *nla; int size = nla_attr_size(data_len); |
0597f2680 [NETFILTER]: Add ... |
483 |
|
df6fb868d [NETFILTER]: nfne... |
484 |
if (skb_tailroom(inst->skb) < nla_total_size(data_len)) { |
0597f2680 [NETFILTER]: Add ... |
485 486 487 488 |
printk(KERN_WARNING "nfnetlink_log: no tailroom! "); goto nlmsg_failure; } |
df6fb868d [NETFILTER]: nfne... |
489 490 491 |
nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len)); nla->nla_type = NFULA_PAYLOAD; nla->nla_len = size; |
0597f2680 [NETFILTER]: Add ... |
492 |
|
df6fb868d [NETFILTER]: nfne... |
493 |
if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) |
0597f2680 [NETFILTER]: Add ... |
494 495 |
BUG(); } |
601e68e10 [NETFILTER]: Fix ... |
496 |
|
0597f2680 [NETFILTER]: Add ... |
497 498 499 500 |
nlh->nlmsg_len = inst->skb->tail - old_tail; return 0; nlmsg_failure: |
df6fb868d [NETFILTER]: nfne... |
501 |
nla_put_failure: |
0597f2680 [NETFILTER]: Add ... |
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
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 netfilter: xt_NFL... |
521 |
void |
76108cea0 netfilter: Use un... |
522 |
nfulnl_log_packet(u_int8_t pf, |
0597f2680 [NETFILTER]: Add ... |
523 524 525 526 527 528 529 530 531 532 533 |
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 [NETFILTER]: nfne... |
534 |
unsigned int plen; |
0597f2680 [NETFILTER]: Add ... |
535 |
|
601e68e10 [NETFILTER]: Fix ... |
536 |
if (li_user && li_user->type == NF_LOG_TYPE_ULOG) |
0597f2680 [NETFILTER]: Add ... |
537 538 539 540 541 542 |
li = li_user; else li = &default_loginfo; inst = instance_lookup_get(li->u.ulog.group); if (!inst) |
0597f2680 [NETFILTER]: Add ... |
543 |
return; |
0597f2680 [NETFILTER]: Add ... |
544 |
|
d7a5c3244 [NETFILTER]: nfne... |
545 546 |
plen = 0; if (prefix) |
881dbfe8a [NETFILTER]: nfne... |
547 |
plen = strlen(prefix) + 1; |
d7a5c3244 [NETFILTER]: nfne... |
548 |
|
0597f2680 [NETFILTER]: Add ... |
549 550 551 |
/* 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... */ |
7000d38d6 [NETFILTER]: nfne... |
552 |
size = NLMSG_SPACE(sizeof(struct nfgenmsg)) |
df6fb868d [NETFILTER]: nfne... |
553 554 555 |
+ 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 [NETFILTER]: add ... |
556 |
#ifdef CONFIG_BRIDGE_NETFILTER |
df6fb868d [NETFILTER]: nfne... |
557 558 |
+ nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ |
fbcd923c3 [NETFILTER]: add ... |
559 |
#endif |
df6fb868d [NETFILTER]: nfne... |
560 561 |
+ nla_total_size(sizeof(u_int32_t)) /* mark */ + nla_total_size(sizeof(u_int32_t)) /* uid */ |
76aa1ce13 [NETFILTER]: nfne... |
562 |
+ nla_total_size(sizeof(u_int32_t)) /* gid */ |
df6fb868d [NETFILTER]: nfne... |
563 564 565 |
+ nla_total_size(plen) /* prefix */ + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)); |
0597f2680 [NETFILTER]: Add ... |
566 |
|
eeff9beec netfilter: nfnetl... |
567 568 569 570 571 |
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 [NETFILTER]: Add ... |
572 |
spin_lock_bh(&inst->lock); |
0af5f6c1e [NETFILTER] nfnet... |
573 |
if (inst->flags & NFULNL_CFG_F_SEQ) |
df6fb868d [NETFILTER]: nfne... |
574 |
size += nla_total_size(sizeof(u_int32_t)); |
0af5f6c1e [NETFILTER] nfnet... |
575 |
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) |
df6fb868d [NETFILTER]: nfne... |
576 |
size += nla_total_size(sizeof(u_int32_t)); |
0af5f6c1e [NETFILTER] nfnet... |
577 |
|
0597f2680 [NETFILTER]: Add ... |
578 579 |
qthreshold = inst->qthreshold; /* per-rule qthreshold overrides per-instance */ |
5ca431f9a netfilter: nfnetl... |
580 581 582 |
if (li->u.ulog.qthreshold) if (qthreshold > li->u.ulog.qthreshold) qthreshold = li->u.ulog.qthreshold; |
601e68e10 [NETFILTER]: Fix ... |
583 |
|
0597f2680 [NETFILTER]: Add ... |
584 585 586 587 588 |
switch (inst->copy_mode) { case NFULNL_COPY_META: case NFULNL_COPY_NONE: data_len = 0; break; |
601e68e10 [NETFILTER]: Fix ... |
589 |
|
0597f2680 [NETFILTER]: Add ... |
590 |
case NFULNL_COPY_PACKET: |
601e68e10 [NETFILTER]: Fix ... |
591 |
if (inst->copy_range == 0 |
0597f2680 [NETFILTER]: Add ... |
592 593 594 595 |
|| inst->copy_range > skb->len) data_len = skb->len; else data_len = inst->copy_range; |
601e68e10 [NETFILTER]: Fix ... |
596 |
|
df6fb868d [NETFILTER]: nfne... |
597 |
size += nla_total_size(data_len); |
0597f2680 [NETFILTER]: Add ... |
598 |
break; |
601e68e10 [NETFILTER]: Fix ... |
599 |
|
f5c5440d4 netfilter: nfnetl... |
600 |
case NFULNL_COPY_DISABLED: |
0597f2680 [NETFILTER]: Add ... |
601 |
default: |
55b5a91e1 [NETFILTER]: nfne... |
602 |
goto unlock_and_release; |
0597f2680 [NETFILTER]: Add ... |
603 |
} |
d63b043d9 [NETFILTER]: nfne... |
604 605 |
if (inst->skb && size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) { |
0597f2680 [NETFILTER]: Add ... |
606 607 |
/* either the queue len is too high or we don't have * enough room in the skb left. flush to userspace. */ |
e35670614 [NETFILTER]: nfne... |
608 |
__nfulnl_flush(inst); |
55b5a91e1 [NETFILTER]: nfne... |
609 |
} |
0597f2680 [NETFILTER]: Add ... |
610 |
|
55b5a91e1 [NETFILTER]: nfne... |
611 612 613 |
if (!inst->skb) { inst->skb = nfulnl_alloc_skb(inst->nlbufsiz, size); if (!inst->skb) |
0597f2680 [NETFILTER]: Add ... |
614 |
goto alloc_failure; |
0597f2680 [NETFILTER]: Add ... |
615 |
} |
0597f2680 [NETFILTER]: Add ... |
616 617 618 |
inst->qlen++; __build_packet_message(inst, skb, data_len, pf, |
8248779b1 netfilter: nfnetl... |
619 |
hooknum, in, out, prefix, plen); |
0597f2680 [NETFILTER]: Add ... |
620 |
|
d63b043d9 [NETFILTER]: nfne... |
621 622 |
if (inst->qlen >= qthreshold) __nfulnl_flush(inst); |
0597f2680 [NETFILTER]: Add ... |
623 624 |
/* timer_pending always called within inst->lock, so there * is no chance of a race here */ |
d63b043d9 [NETFILTER]: nfne... |
625 |
else if (!timer_pending(&inst->timer)) { |
0597f2680 [NETFILTER]: Add ... |
626 627 628 629 |
instance_get(inst); inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100); add_timer(&inst->timer); } |
0597f2680 [NETFILTER]: Add ... |
630 |
|
ed32abeaf [NETFILTER]: nfne... |
631 632 633 |
unlock_and_release: spin_unlock_bh(&inst->lock); instance_put(inst); |
0597f2680 [NETFILTER]: Add ... |
634 635 636 |
return; alloc_failure: |
0597f2680 [NETFILTER]: Add ... |
637 |
/* FIXME: statistics */ |
ed32abeaf [NETFILTER]: nfne... |
638 |
goto unlock_and_release; |
0597f2680 [NETFILTER]: Add ... |
639 |
} |
5f7340eff netfilter: xt_NFL... |
640 |
EXPORT_SYMBOL_GPL(nfulnl_log_packet); |
0597f2680 [NETFILTER]: Add ... |
641 642 643 644 645 646 |
static int nfulnl_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr) { struct netlink_notify *n = ptr; |
dee5817e8 netfilter: remove... |
647 |
if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) { |
0597f2680 [NETFILTER]: Add ... |
648 649 650 |
int i; /* destroy all instances for this pid */ |
bed1be208 netfilter: nfnetl... |
651 |
spin_lock_bh(&instances_lock); |
0597f2680 [NETFILTER]: Add ... |
652 653 654 655 656 657 |
for (i = 0; i < INSTANCE_BUCKETS; i++) { struct hlist_node *tmp, *t2; struct nfulnl_instance *inst; struct hlist_head *head = &instance_table[i]; hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) { |
09ad9bc75 net: use net_eq t... |
658 |
if ((net_eq(n->net, &init_net)) && |
b4b510290 [NET]: Support mu... |
659 |
(n->pid == inst->peer_pid)) |
0597f2680 [NETFILTER]: Add ... |
660 661 662 |
__instance_destroy(inst); } } |
bed1be208 netfilter: nfnetl... |
663 |
spin_unlock_bh(&instances_lock); |
0597f2680 [NETFILTER]: Add ... |
664 665 666 667 668 669 670 671 672 673 |
} 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 netfilter: nfnetl... |
674 675 |
const struct nlmsghdr *nlh, const struct nlattr * const nfqa[]) |
0597f2680 [NETFILTER]: Add ... |
676 677 678 |
{ return -ENOTSUPP; } |
ca735b3aa netfilter: use a ... |
679 |
static struct nf_logger nfulnl_logger __read_mostly = { |
0597f2680 [NETFILTER]: Add ... |
680 681 682 683 |
.name = "nfnetlink_log", .logfn = &nfulnl_log_packet, .me = THIS_MODULE, }; |
fd8281ada [NETFILTER]: nfne... |
684 685 686 687 688 689 690 |
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 [NETFILTER]: Add ... |
691 692 693 694 |
}; static int nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, |
399383246 netfilter: nfnetl... |
695 696 |
const struct nlmsghdr *nlh, const struct nlattr * const nfula[]) |
0597f2680 [NETFILTER]: Add ... |
697 698 699 700 |
{ struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t group_num = ntohs(nfmsg->res_id); struct nfulnl_instance *inst; |
b7047a1c8 [NETFILTER]: nfne... |
701 |
struct nfulnl_msg_config_cmd *cmd = NULL; |
0597f2680 [NETFILTER]: Add ... |
702 |
int ret = 0; |
b7047a1c8 [NETFILTER]: nfne... |
703 704 705 706 707 708 709 |
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: |
ca735b3aa netfilter: use a ... |
710 |
return nf_log_bind_pf(pf, &nfulnl_logger); |
b7047a1c8 [NETFILTER]: nfne... |
711 |
case NFULNL_CFG_CMD_PF_UNBIND: |
ca735b3aa netfilter: use a ... |
712 |
nf_log_unbind_pf(pf); |
b7047a1c8 [NETFILTER]: nfne... |
713 714 715 |
return 0; } } |
0597f2680 [NETFILTER]: Add ... |
716 |
inst = instance_lookup_get(group_num); |
c0506365a [NETFILTER]: nfne... |
717 718 719 720 |
if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { ret = -EPERM; goto out_put; } |
b7047a1c8 [NETFILTER]: nfne... |
721 |
if (cmd != NULL) { |
0597f2680 [NETFILTER]: Add ... |
722 723 724 725 726 727 728 729 730 |
switch (cmd->command) { case NFULNL_CFG_CMD_BIND: if (inst) { ret = -EBUSY; goto out_put; } inst = instance_create(group_num, NETLINK_CB(skb).pid); |
baab2ce7d [NETFILTER]: nfne... |
731 732 |
if (IS_ERR(inst)) { ret = PTR_ERR(inst); |
f414c16c0 [NETFILTER]: nfne... |
733 |
goto out; |
0597f2680 [NETFILTER]: Add ... |
734 735 736 737 738 |
} break; case NFULNL_CFG_CMD_UNBIND: if (!inst) { ret = -ENODEV; |
f414c16c0 [NETFILTER]: nfne... |
739 |
goto out; |
0597f2680 [NETFILTER]: Add ... |
740 |
} |
0597f2680 [NETFILTER]: Add ... |
741 |
instance_destroy(inst); |
a49c65037 netfilter: nfnetl... |
742 |
goto out_put; |
0597f2680 [NETFILTER]: Add ... |
743 |
default: |
cd21f0ac4 [NETFILTER]: nfne... |
744 |
ret = -ENOTSUPP; |
0597f2680 [NETFILTER]: Add ... |
745 746 |
break; } |
0597f2680 [NETFILTER]: Add ... |
747 |
} |
df6fb868d [NETFILTER]: nfne... |
748 |
if (nfula[NFULA_CFG_MODE]) { |
0597f2680 [NETFILTER]: Add ... |
749 |
struct nfulnl_msg_config_mode *params; |
df6fb868d [NETFILTER]: nfne... |
750 |
params = nla_data(nfula[NFULA_CFG_MODE]); |
0597f2680 [NETFILTER]: Add ... |
751 |
|
c0506365a [NETFILTER]: nfne... |
752 753 754 755 |
if (!inst) { ret = -ENODEV; goto out; } |
0597f2680 [NETFILTER]: Add ... |
756 |
nfulnl_set_mode(inst, params->copy_mode, |
d1208b999 [NETFILTER] bug: ... |
757 |
ntohl(params->copy_range)); |
0597f2680 [NETFILTER]: Add ... |
758 |
} |
df6fb868d [NETFILTER]: nfne... |
759 |
if (nfula[NFULA_CFG_TIMEOUT]) { |
0dfedd287 [NETFILTER]: nfne... |
760 |
__be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]); |
0597f2680 [NETFILTER]: Add ... |
761 |
|
c0506365a [NETFILTER]: nfne... |
762 763 764 765 |
if (!inst) { ret = -ENODEV; goto out; } |
0597f2680 [NETFILTER]: Add ... |
766 767 |
nfulnl_set_timeout(inst, ntohl(timeout)); } |
df6fb868d [NETFILTER]: nfne... |
768 |
if (nfula[NFULA_CFG_NLBUFSIZ]) { |
0dfedd287 [NETFILTER]: nfne... |
769 |
__be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]); |
0597f2680 [NETFILTER]: Add ... |
770 |
|
c0506365a [NETFILTER]: nfne... |
771 772 773 774 |
if (!inst) { ret = -ENODEV; goto out; } |
0597f2680 [NETFILTER]: Add ... |
775 776 |
nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz)); } |
df6fb868d [NETFILTER]: nfne... |
777 |
if (nfula[NFULA_CFG_QTHRESH]) { |
0dfedd287 [NETFILTER]: nfne... |
778 |
__be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]); |
0597f2680 [NETFILTER]: Add ... |
779 |
|
c0506365a [NETFILTER]: nfne... |
780 781 782 783 |
if (!inst) { ret = -ENODEV; goto out; } |
0597f2680 [NETFILTER]: Add ... |
784 785 |
nfulnl_set_qthresh(inst, ntohl(qthresh)); } |
df6fb868d [NETFILTER]: nfne... |
786 |
if (nfula[NFULA_CFG_FLAGS]) { |
0dfedd287 [NETFILTER]: nfne... |
787 |
__be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]); |
c0506365a [NETFILTER]: nfne... |
788 789 790 791 792 |
if (!inst) { ret = -ENODEV; goto out; } |
ee433530d [NETFILTER]: nfne... |
793 |
nfulnl_set_flags(inst, ntohs(flags)); |
0af5f6c1e [NETFILTER] nfnet... |
794 |
} |
0597f2680 [NETFILTER]: Add ... |
795 796 |
out_put: instance_put(inst); |
dd16704eb [NETFILTER]: nfne... |
797 |
out: |
0597f2680 [NETFILTER]: Add ... |
798 799 |
return ret; } |
7c8d4cb41 [NETFILTER]: nfne... |
800 |
static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { |
0597f2680 [NETFILTER]: Add ... |
801 |
[NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, |
37d2e7a20 [NETFILTER] nfnet... |
802 |
.attr_count = NFULA_MAX, }, |
0597f2680 [NETFILTER]: Add ... |
803 |
[NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, |
fd8281ada [NETFILTER]: nfne... |
804 805 |
.attr_count = NFULA_CFG_MAX, .policy = nfula_cfg_policy }, |
0597f2680 [NETFILTER]: Add ... |
806 |
}; |
7c8d4cb41 [NETFILTER]: nfne... |
807 |
static const struct nfnetlink_subsystem nfulnl_subsys = { |
0597f2680 [NETFILTER]: Add ... |
808 809 810 |
.name = "log", .subsys_id = NFNL_SUBSYS_ULOG, .cb_count = NFULNL_MSG_MAX, |
0597f2680 [NETFILTER]: Add ... |
811 812 813 814 815 816 817 |
.cb = nfulnl_cb, }; #ifdef CONFIG_PROC_FS struct iter_state { unsigned int bucket; }; |
f76cdcee5 [NETFILTER]: nfne... |
818 |
static struct hlist_node *get_first(struct iter_state *st) |
0597f2680 [NETFILTER]: Add ... |
819 |
{ |
0597f2680 [NETFILTER]: Add ... |
820 821 822 823 824 |
if (!st) return NULL; for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) { if (!hlist_empty(&instance_table[st->bucket])) |
0e60ebe04 netfilter: add __... |
825 |
return rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket])); |
0597f2680 [NETFILTER]: Add ... |
826 827 828 |
} return NULL; } |
f76cdcee5 [NETFILTER]: nfne... |
829 |
static struct hlist_node *get_next(struct iter_state *st, struct hlist_node *h) |
0597f2680 [NETFILTER]: Add ... |
830 |
{ |
0e60ebe04 netfilter: add __... |
831 |
h = rcu_dereference_bh(hlist_next_rcu(h)); |
0597f2680 [NETFILTER]: Add ... |
832 833 834 |
while (!h) { if (++st->bucket >= INSTANCE_BUCKETS) return NULL; |
0e60ebe04 netfilter: add __... |
835 |
h = rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket])); |
0597f2680 [NETFILTER]: Add ... |
836 837 838 |
} return h; } |
f76cdcee5 [NETFILTER]: nfne... |
839 |
static struct hlist_node *get_idx(struct iter_state *st, loff_t pos) |
0597f2680 [NETFILTER]: Add ... |
840 841 |
{ struct hlist_node *head; |
f76cdcee5 [NETFILTER]: nfne... |
842 |
head = get_first(st); |
0597f2680 [NETFILTER]: Add ... |
843 844 |
if (head) |
f76cdcee5 [NETFILTER]: nfne... |
845 |
while (pos && (head = get_next(st, head))) |
0597f2680 [NETFILTER]: Add ... |
846 847 848 849 850 |
pos--; return pos ? NULL : head; } static void *seq_start(struct seq_file *seq, loff_t *pos) |
bed1be208 netfilter: nfnetl... |
851 |
__acquires(rcu_bh) |
0597f2680 [NETFILTER]: Add ... |
852 |
{ |
bed1be208 netfilter: nfnetl... |
853 |
rcu_read_lock_bh(); |
f76cdcee5 [NETFILTER]: nfne... |
854 |
return get_idx(seq->private, *pos); |
0597f2680 [NETFILTER]: Add ... |
855 856 857 858 859 |
} static void *seq_next(struct seq_file *s, void *v, loff_t *pos) { (*pos)++; |
f76cdcee5 [NETFILTER]: nfne... |
860 |
return get_next(s->private, v); |
0597f2680 [NETFILTER]: Add ... |
861 862 863 |
} static void seq_stop(struct seq_file *s, void *v) |
bed1be208 netfilter: nfnetl... |
864 |
__releases(rcu_bh) |
0597f2680 [NETFILTER]: Add ... |
865 |
{ |
bed1be208 netfilter: nfnetl... |
866 |
rcu_read_unlock_bh(); |
0597f2680 [NETFILTER]: Add ... |
867 868 869 870 871 |
} static int seq_show(struct seq_file *s, void *v) { const struct nfulnl_instance *inst = v; |
601e68e10 [NETFILTER]: Fix ... |
872 873 |
return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d ", |
0597f2680 [NETFILTER]: Add ... |
874 |
inst->group_num, |
601e68e10 [NETFILTER]: Fix ... |
875 |
inst->peer_pid, inst->qlen, |
0597f2680 [NETFILTER]: Add ... |
876 877 878 |
inst->copy_mode, inst->copy_range, inst->flushtimeout, atomic_read(&inst->use)); } |
56b3d975b [NET]: Make all i... |
879 |
static const struct seq_operations nful_seq_ops = { |
0597f2680 [NETFILTER]: Add ... |
880 881 882 883 884 885 886 887 |
.start = seq_start, .next = seq_next, .stop = seq_stop, .show = seq_show, }; static int nful_open(struct inode *inode, struct file *file) { |
e2da59133 [NETFILTER]: Make... |
888 889 |
return seq_open_private(file, &nful_seq_ops, sizeof(struct iter_state)); |
0597f2680 [NETFILTER]: Add ... |
890 |
} |
da7071d7e [PATCH] mark stru... |
891 |
static const struct file_operations nful_file_ops = { |
0597f2680 [NETFILTER]: Add ... |
892 893 894 895 896 897 898 899 |
.owner = THIS_MODULE, .open = nful_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release_private, }; #endif /* PROC_FS */ |
32292a7ff [NETFILTER]: Fix ... |
900 |
static int __init nfnetlink_log_init(void) |
0597f2680 [NETFILTER]: Add ... |
901 902 |
{ int i, status = -ENOMEM; |
601e68e10 [NETFILTER]: Fix ... |
903 |
|
0597f2680 [NETFILTER]: Add ... |
904 905 |
for (i = 0; i < INSTANCE_BUCKETS; i++) INIT_HLIST_HEAD(&instance_table[i]); |
601e68e10 [NETFILTER]: Fix ... |
906 |
|
0597f2680 [NETFILTER]: Add ... |
907 908 909 910 911 912 913 914 915 916 917 918 |
/* 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) { printk(KERN_ERR "log: failed to create netlink socket "); goto cleanup_netlink_notifier; } |
ca735b3aa netfilter: use a ... |
919 920 921 922 923 924 |
status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger); if (status < 0) { printk(KERN_ERR "log: failed to register logger "); goto cleanup_subsys; } |
0597f2680 [NETFILTER]: Add ... |
925 |
#ifdef CONFIG_PROC_FS |
8eeee8b15 [NETFILTER]: Repl... |
926 927 |
if (!proc_create("nfnetlink_log", 0440, proc_net_netfilter, &nful_file_ops)) |
ca735b3aa netfilter: use a ... |
928 |
goto cleanup_logger; |
0597f2680 [NETFILTER]: Add ... |
929 |
#endif |
0597f2680 [NETFILTER]: Add ... |
930 |
return status; |
0597f2680 [NETFILTER]: Add ... |
931 |
#ifdef CONFIG_PROC_FS |
ca735b3aa netfilter: use a ... |
932 933 934 |
cleanup_logger: nf_log_unregister(&nfulnl_logger); #endif |
0597f2680 [NETFILTER]: Add ... |
935 |
cleanup_subsys: |
0597f2680 [NETFILTER]: Add ... |
936 937 938 939 940 |
nfnetlink_subsys_unregister(&nfulnl_subsys); cleanup_netlink_notifier: netlink_unregister_notifier(&nfulnl_rtnl_notifier); return status; } |
65b4b4e81 [NETFILTER]: Rena... |
941 |
static void __exit nfnetlink_log_fini(void) |
0597f2680 [NETFILTER]: Add ... |
942 |
{ |
e92ad99c7 [NETFILTER]: nf_l... |
943 |
nf_log_unregister(&nfulnl_logger); |
32292a7ff [NETFILTER]: Fix ... |
944 945 946 947 948 |
#ifdef CONFIG_PROC_FS remove_proc_entry("nfnetlink_log", proc_net_netfilter); #endif nfnetlink_subsys_unregister(&nfulnl_subsys); netlink_unregister_notifier(&nfulnl_rtnl_notifier); |
0597f2680 [NETFILTER]: Add ... |
949 950 951 952 953 |
} MODULE_DESCRIPTION("netfilter userspace logging"); MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_LICENSE("GPL"); |
f682faefb [NETFILTER]: fix ... |
954 |
MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG); |
0597f2680 [NETFILTER]: Add ... |
955 |
|
65b4b4e81 [NETFILTER]: Rena... |
956 957 |
module_init(nfnetlink_log_init); module_exit(nfnetlink_log_fini); |