aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-21 00:01:43 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-21 00:01:43 -0400
commita8138f42d494bcd41a6f7ff301e12fa8d4f330f1 (patch)
tree3ef25c22129c7f72aa0d6667143227b3a62a7708 /net/bridge
parent6fe82a39e583a50f28f03b294df79c9de9ec0de4 (diff)
parent16ea4c6b9dde2ff44b2bd8bb459daa283cf3a46e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains updates for your net-next tree, they are: 1) Use kvfree() helper function from x_tables, from Eric Dumazet. 2) Remove extra timer from the conntrack ecache extension, use a workqueue instead to redeliver lost events to userspace instead, from Florian Westphal. 3) Removal of the ulog targets for ebtables and iptables. The nflog infrastructure superseded this almost 9 years ago, time to get rid of this code. 4) Replace the list of loggers by an array now that we can only have two possible non-overlapping logger flavours, ie. kernel ring buffer and netlink logging. 5) Move Eric Dumazet's log buffer code to nf_log to reuse it from all of the supported per-family loggers. 6) Consolidate nf_log_packet() as an unified interface for packet logging. After this patch, if the struct nf_loginfo is available, it explicitly selects the logger that is used. 7) Move ip and ip6 logging code from xt_LOG to the corresponding per-family loggers. Thus, x_tables and nf_tables share the same code for packet logging. 8) Add generic ARP packet logger, which is used by nf_tables. The format aims to be consistent with the output of xt_LOG. 9) Add generic bridge packet logger. Again, this is used by nf_tables and it routes the packets to the real family loggers. As a result, we get consistent logging format for the bridge family. The ebt_log logging code has been intentionally left in place not to break backward compatibility since the logging output differs from xt_LOG. 10) Update nft_log to explicitly request the required family logger when needed. 11) Finish nft_log so it supports arp, ip, ip6, bridge and inet families. Allowing selection between netlink and kernel buffer ring logging. 12) Several fixes coming after the netfilter core logging changes spotted by robots. 13) Use IS_ENABLED() macros whenever possible in the netfilter tree, from Duan Jiong. 14) Removal of a couple of unnecessary branch before kfree, from Fabian Frederick. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/netfilter/Kconfig19
-rw-r--r--net/bridge/netfilter/Makefile3
-rw-r--r--net/bridge/netfilter/ebt_log.c47
-rw-r--r--net/bridge/netfilter/ebt_ulog.c393
-rw-r--r--net/bridge/netfilter/nf_log_bridge.c96
5 files changed, 107 insertions, 451 deletions
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 629dc77874a9..4ce0b313f72c 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -14,6 +14,9 @@ config NFT_BRIDGE_META
14 help 14 help
15 Add support for bridge dedicated meta key. 15 Add support for bridge dedicated meta key.
16 16
17config NF_LOG_BRIDGE
18 tristate "Bridge packet logging"
19
17endif # NF_TABLES_BRIDGE 20endif # NF_TABLES_BRIDGE
18 21
19menuconfig BRIDGE_NF_EBTABLES 22menuconfig BRIDGE_NF_EBTABLES
@@ -202,22 +205,6 @@ config BRIDGE_EBT_LOG
202 205
203 To compile it as a module, choose M here. If unsure, say N. 206 To compile it as a module, choose M here. If unsure, say N.
204 207
205config BRIDGE_EBT_ULOG
206 tristate "ebt: ulog support (OBSOLETE)"
207 help
208 This option enables the old bridge-specific "ebt_ulog" implementation
209 which has been obsoleted by the new "nfnetlink_log" code (see
210 CONFIG_NETFILTER_NETLINK_LOG).
211
212 This option adds the ulog watcher, that you can use in any rule
213 in any ebtables table. The packet is passed to a userspace
214 logging daemon using netlink multicast sockets. This differs
215 from the log watcher in the sense that the complete packet is
216 sent to userspace instead of a descriptive text and that
217 netlink multicast sockets are used instead of the syslog.
218
219 To compile it as a module, choose M here. If unsure, say N.
220
221config BRIDGE_EBT_NFLOG 208config BRIDGE_EBT_NFLOG
222 tristate "ebt: nflog support" 209 tristate "ebt: nflog support"
223 help 210 help
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 6f2f3943d66f..1f78ea0d90e4 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -5,6 +5,9 @@
5obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o 5obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o
6obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o 6obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o
7 7
8# packet logging
9obj-$(CONFIG_NF_LOG_BRIDGE) += nf_log_bridge.o
10
8obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o 11obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
9 12
10# tables 13# tables
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 5322a36867a3..17f2e4bc2a29 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -186,6 +186,10 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
186 li.u.log.level = info->loglevel; 186 li.u.log.level = info->loglevel;
187 li.u.log.logflags = info->bitmask; 187 li.u.log.logflags = info->bitmask;
188 188
189 /* Remember that we have to use ebt_log_packet() not to break backward
190 * compatibility. We cannot use the default bridge packet logger via
191 * nf_log_packet() with NFT_LOG_TYPE_LOG here. --Pablo
192 */
189 if (info->bitmask & EBT_LOG_NFLOG) 193 if (info->bitmask & EBT_LOG_NFLOG)
190 nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, 194 nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
191 par->in, par->out, &li, "%s", info->prefix); 195 par->in, par->out, &li, "%s", info->prefix);
@@ -205,54 +209,13 @@ static struct xt_target ebt_log_tg_reg __read_mostly = {
205 .me = THIS_MODULE, 209 .me = THIS_MODULE,
206}; 210};
207 211
208static struct nf_logger ebt_log_logger __read_mostly = {
209 .name = "ebt_log",
210 .logfn = &ebt_log_packet,
211 .me = THIS_MODULE,
212};
213
214static int __net_init ebt_log_net_init(struct net *net)
215{
216 nf_log_set(net, NFPROTO_BRIDGE, &ebt_log_logger);
217 return 0;
218}
219
220static void __net_exit ebt_log_net_fini(struct net *net)
221{
222 nf_log_unset(net, &ebt_log_logger);
223}
224
225static struct pernet_operations ebt_log_net_ops = {
226 .init = ebt_log_net_init,
227 .exit = ebt_log_net_fini,
228};
229
230static int __init ebt_log_init(void) 212static int __init ebt_log_init(void)
231{ 213{
232 int ret; 214 return xt_register_target(&ebt_log_tg_reg);
233
234 ret = register_pernet_subsys(&ebt_log_net_ops);
235 if (ret < 0)
236 goto err_pernet;
237
238 ret = xt_register_target(&ebt_log_tg_reg);
239 if (ret < 0)
240 goto err_target;
241
242 nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
243
244 return ret;
245
246err_target:
247 unregister_pernet_subsys(&ebt_log_net_ops);
248err_pernet:
249 return ret;
250} 215}
251 216
252static void __exit ebt_log_fini(void) 217static void __exit ebt_log_fini(void)
253{ 218{
254 unregister_pernet_subsys(&ebt_log_net_ops);
255 nf_log_unregister(&ebt_log_logger);
256 xt_unregister_target(&ebt_log_tg_reg); 219 xt_unregister_target(&ebt_log_tg_reg);
257} 220}
258 221
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
deleted file mode 100644
index 7c470c371e14..000000000000
--- a/net/bridge/netfilter/ebt_ulog.c
+++ /dev/null
@@ -1,393 +0,0 @@
1/*
2 * netfilter module for userspace bridged Ethernet frames logging daemons
3 *
4 * Authors:
5 * Bart De Schuymer <bdschuym@pandora.be>
6 * Harald Welte <laforge@netfilter.org>
7 *
8 * November, 2004
9 *
10 * Based on ipt_ULOG.c, which is
11 * (C) 2000-2002 by Harald Welte <laforge@netfilter.org>
12 *
13 * This module accepts two parameters:
14 *
15 * nlbufsiz:
16 * The parameter specifies how big the buffer for each netlink multicast
17 * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will
18 * get accumulated in the kernel until they are sent to userspace. It is
19 * NOT possible to allocate more than 128kB, and it is strongly discouraged,
20 * because atomically allocating 128kB inside the network rx softirq is not
21 * reliable. Please also keep in mind that this buffer size is allocated for
22 * each nlgroup you are using, so the total kernel memory usage increases
23 * by that factor.
24 *
25 * flushtimeout:
26 * Specify, after how many hundredths of a second the queue should be
27 * flushed even if it is not full yet.
28 *
29 */
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/spinlock.h>
34#include <linux/socket.h>
35#include <linux/skbuff.h>
36#include <linux/kernel.h>
37#include <linux/timer.h>
38#include <net/netlink.h>
39#include <linux/netdevice.h>
40#include <linux/netfilter/x_tables.h>
41#include <linux/netfilter_bridge/ebtables.h>
42#include <linux/netfilter_bridge/ebt_ulog.h>
43#include <net/netfilter/nf_log.h>
44#include <net/netns/generic.h>
45#include <net/sock.h>
46#include "../br_private.h"
47
48static unsigned int nlbufsiz = NLMSG_GOODSIZE;
49module_param(nlbufsiz, uint, 0600);
50MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
51 "(defaults to 4096)");
52
53static unsigned int flushtimeout = 10;
54module_param(flushtimeout, uint, 0600);
55MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths ofa second) "
56 "(defaults to 10)");
57
58typedef struct {
59 unsigned int qlen; /* number of nlmsgs' in the skb */
60 struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */
61 struct sk_buff *skb; /* the pre-allocated skb */
62 struct timer_list timer; /* the timer function */
63 spinlock_t lock; /* the per-queue lock */
64} ebt_ulog_buff_t;
65
66static int ebt_ulog_net_id __read_mostly;
67struct ebt_ulog_net {
68 unsigned int nlgroup[EBT_ULOG_MAXNLGROUPS];
69 ebt_ulog_buff_t ulog_buffers[EBT_ULOG_MAXNLGROUPS];
70 struct sock *ebtulognl;
71};
72
73static struct ebt_ulog_net *ebt_ulog_pernet(struct net *net)
74{
75 return net_generic(net, ebt_ulog_net_id);
76}
77
78/* send one ulog_buff_t to userspace */
79static void ulog_send(struct ebt_ulog_net *ebt, unsigned int nlgroup)
80{
81 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[nlgroup];
82
83 del_timer(&ub->timer);
84
85 if (!ub->skb)
86 return;
87
88 /* last nlmsg needs NLMSG_DONE */
89 if (ub->qlen > 1)
90 ub->lastnlh->nlmsg_type = NLMSG_DONE;
91
92 NETLINK_CB(ub->skb).dst_group = nlgroup + 1;
93 netlink_broadcast(ebt->ebtulognl, ub->skb, 0, nlgroup + 1, GFP_ATOMIC);
94
95 ub->qlen = 0;
96 ub->skb = NULL;
97}
98
99/* timer function to flush queue in flushtimeout time */
100static void ulog_timer(unsigned long data)
101{
102 struct ebt_ulog_net *ebt = container_of((void *)data,
103 struct ebt_ulog_net,
104 nlgroup[*(unsigned int *)data]);
105
106 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[*(unsigned int *)data];
107 spin_lock_bh(&ub->lock);
108 if (ub->skb)
109 ulog_send(ebt, *(unsigned int *)data);
110 spin_unlock_bh(&ub->lock);
111}
112
113static struct sk_buff *ulog_alloc_skb(unsigned int size)
114{
115 struct sk_buff *skb;
116 unsigned int n;
117
118 n = max(size, nlbufsiz);
119 skb = alloc_skb(n, GFP_ATOMIC | __GFP_NOWARN);
120 if (!skb) {
121 if (n > size) {
122 /* try to allocate only as much as we need for
123 * current packet */
124 skb = alloc_skb(size, GFP_ATOMIC);
125 if (!skb)
126 pr_debug("cannot even allocate buffer of size %ub\n",
127 size);
128 }
129 }
130
131 return skb;
132}
133
134static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
135 const struct sk_buff *skb,
136 const struct net_device *in,
137 const struct net_device *out,
138 const struct ebt_ulog_info *uloginfo,
139 const char *prefix)
140{
141 ebt_ulog_packet_msg_t *pm;
142 size_t size, copy_len;
143 struct nlmsghdr *nlh;
144 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
145 unsigned int group = uloginfo->nlgroup;
146 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group];
147 spinlock_t *lock = &ub->lock;
148 ktime_t kt;
149
150 if ((uloginfo->cprange == 0) ||
151 (uloginfo->cprange > skb->len + ETH_HLEN))
152 copy_len = skb->len + ETH_HLEN;
153 else
154 copy_len = uloginfo->cprange;
155
156 size = nlmsg_total_size(sizeof(*pm) + copy_len);
157 if (size > nlbufsiz) {
158 pr_debug("Size %Zd needed, but nlbufsiz=%d\n", size, nlbufsiz);
159 return;
160 }
161
162 spin_lock_bh(lock);
163
164 if (!ub->skb) {
165 if (!(ub->skb = ulog_alloc_skb(size)))
166 goto unlock;
167 } else if (size > skb_tailroom(ub->skb)) {
168 ulog_send(ebt, group);
169
170 if (!(ub->skb = ulog_alloc_skb(size)))
171 goto unlock;
172 }
173
174 nlh = nlmsg_put(ub->skb, 0, ub->qlen, 0,
175 size - NLMSG_ALIGN(sizeof(*nlh)), 0);
176 if (!nlh) {
177 kfree_skb(ub->skb);
178 ub->skb = NULL;
179 goto unlock;
180 }
181 ub->qlen++;
182
183 pm = nlmsg_data(nlh);
184 memset(pm, 0, sizeof(*pm));
185
186 /* Fill in the ulog data */
187 pm->version = EBT_ULOG_VERSION;
188 kt = ktime_get_real();
189 pm->stamp = ktime_to_timeval(kt);
190 if (ub->qlen == 1)
191 ub->skb->tstamp = kt;
192 pm->data_len = copy_len;
193 pm->mark = skb->mark;
194 pm->hook = hooknr;
195 if (uloginfo->prefix != NULL)
196 strcpy(pm->prefix, uloginfo->prefix);
197
198 if (in) {
199 strcpy(pm->physindev, in->name);
200 /* If in isn't a bridge, then physindev==indev */
201 if (br_port_exists(in))
202 /* rcu_read_lock()ed by nf_hook_slow */
203 strcpy(pm->indev, br_port_get_rcu(in)->br->dev->name);
204 else
205 strcpy(pm->indev, in->name);
206 }
207
208 if (out) {
209 /* If out exists, then out is a bridge port */
210 strcpy(pm->physoutdev, out->name);
211 /* rcu_read_lock()ed by nf_hook_slow */
212 strcpy(pm->outdev, br_port_get_rcu(out)->br->dev->name);
213 }
214
215 if (skb_copy_bits(skb, -ETH_HLEN, pm->data, copy_len) < 0)
216 BUG();
217
218 if (ub->qlen > 1)
219 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
220
221 ub->lastnlh = nlh;
222
223 if (ub->qlen >= uloginfo->qthreshold)
224 ulog_send(ebt, group);
225 else if (!timer_pending(&ub->timer)) {
226 ub->timer.expires = jiffies + flushtimeout * HZ / 100;
227 add_timer(&ub->timer);
228 }
229
230unlock:
231 spin_unlock_bh(lock);
232}
233
234/* this function is registered with the netfilter core */
235static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
236 const struct sk_buff *skb, const struct net_device *in,
237 const struct net_device *out, const struct nf_loginfo *li,
238 const char *prefix)
239{
240 struct ebt_ulog_info loginfo;
241
242 if (!li || li->type != NF_LOG_TYPE_ULOG) {
243 loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
244 loginfo.cprange = 0;
245 loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
246 loginfo.prefix[0] = '\0';
247 } else {
248 loginfo.nlgroup = li->u.ulog.group;
249 loginfo.cprange = li->u.ulog.copy_len;
250 loginfo.qthreshold = li->u.ulog.qthreshold;
251 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
252 }
253
254 ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
255}
256
257static unsigned int
258ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
259{
260 struct net *net = dev_net(par->in ? par->in : par->out);
261
262 ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
263 par->targinfo, NULL);
264 return EBT_CONTINUE;
265}
266
267static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
268{
269 struct ebt_ulog_info *uloginfo = par->targinfo;
270
271 if (!par->net->xt.ebt_ulog_warn_deprecated) {
272 pr_info("ebt_ulog is deprecated and it will be removed soon, "
273 "use ebt_nflog instead\n");
274 par->net->xt.ebt_ulog_warn_deprecated = true;
275 }
276
277 if (uloginfo->nlgroup > 31)
278 return -EINVAL;
279
280 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
281
282 if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
283 uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
284
285 return 0;
286}
287
288static struct xt_target ebt_ulog_tg_reg __read_mostly = {
289 .name = "ulog",
290 .revision = 0,
291 .family = NFPROTO_BRIDGE,
292 .target = ebt_ulog_tg,
293 .checkentry = ebt_ulog_tg_check,
294 .targetsize = sizeof(struct ebt_ulog_info),
295 .me = THIS_MODULE,
296};
297
298static struct nf_logger ebt_ulog_logger __read_mostly = {
299 .name = "ebt_ulog",
300 .logfn = &ebt_log_packet,
301 .me = THIS_MODULE,
302};
303
304static int __net_init ebt_ulog_net_init(struct net *net)
305{
306 int i;
307 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
308
309 struct netlink_kernel_cfg cfg = {
310 .groups = EBT_ULOG_MAXNLGROUPS,
311 };
312
313 /* initialize ulog_buffers */
314 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
315 ebt->nlgroup[i] = i;
316 setup_timer(&ebt->ulog_buffers[i].timer, ulog_timer,
317 (unsigned long)&ebt->nlgroup[i]);
318 spin_lock_init(&ebt->ulog_buffers[i].lock);
319 }
320
321 ebt->ebtulognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg);
322 if (!ebt->ebtulognl)
323 return -ENOMEM;
324
325 nf_log_set(net, NFPROTO_BRIDGE, &ebt_ulog_logger);
326 return 0;
327}
328
329static void __net_exit ebt_ulog_net_fini(struct net *net)
330{
331 int i;
332 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
333
334 nf_log_unset(net, &ebt_ulog_logger);
335 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
336 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[i];
337 del_timer(&ub->timer);
338
339 if (ub->skb) {
340 kfree_skb(ub->skb);
341 ub->skb = NULL;
342 }
343 }
344 netlink_kernel_release(ebt->ebtulognl);
345}
346
347static struct pernet_operations ebt_ulog_net_ops = {
348 .init = ebt_ulog_net_init,
349 .exit = ebt_ulog_net_fini,
350 .id = &ebt_ulog_net_id,
351 .size = sizeof(struct ebt_ulog_net),
352};
353
354static int __init ebt_ulog_init(void)
355{
356 int ret;
357
358 if (nlbufsiz >= 128*1024) {
359 pr_warn("Netlink buffer has to be <= 128kB,"
360 "please try a smaller nlbufsiz parameter.\n");
361 return -EINVAL;
362 }
363
364 ret = register_pernet_subsys(&ebt_ulog_net_ops);
365 if (ret)
366 goto out_pernet;
367
368 ret = xt_register_target(&ebt_ulog_tg_reg);
369 if (ret)
370 goto out_target;
371
372 nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
373
374 return 0;
375
376out_target:
377 unregister_pernet_subsys(&ebt_ulog_net_ops);
378out_pernet:
379 return ret;
380}
381
382static void __exit ebt_ulog_fini(void)
383{
384 nf_log_unregister(&ebt_ulog_logger);
385 xt_unregister_target(&ebt_ulog_tg_reg);
386 unregister_pernet_subsys(&ebt_ulog_net_ops);
387}
388
389module_init(ebt_ulog_init);
390module_exit(ebt_ulog_fini);
391MODULE_LICENSE("GPL");
392MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
393MODULE_DESCRIPTION("Ebtables: Packet logging to netlink using ULOG");
diff --git a/net/bridge/netfilter/nf_log_bridge.c b/net/bridge/netfilter/nf_log_bridge.c
new file mode 100644
index 000000000000..5d9953a90929
--- /dev/null
+++ b/net/bridge/netfilter/nf_log_bridge.c
@@ -0,0 +1,96 @@
1/*
2 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/if_bridge.h>
13#include <linux/ip.h>
14#include <net/route.h>
15
16#include <linux/netfilter.h>
17#include <net/netfilter/nf_log.h>
18
19static void nf_log_bridge_packet(struct net *net, u_int8_t pf,
20 unsigned int hooknum,
21 const struct sk_buff *skb,
22 const struct net_device *in,
23 const struct net_device *out,
24 const struct nf_loginfo *loginfo,
25 const char *prefix)
26{
27 switch (eth_hdr(skb)->h_proto) {
28 case htons(ETH_P_IP):
29 nf_log_packet(net, NFPROTO_IPV4, hooknum, skb, in, out,
30 loginfo, "%s", prefix);
31 break;
32 case htons(ETH_P_IPV6):
33 nf_log_packet(net, NFPROTO_IPV6, hooknum, skb, in, out,
34 loginfo, "%s", prefix);
35 break;
36 case htons(ETH_P_ARP):
37 case htons(ETH_P_RARP):
38 nf_log_packet(net, NFPROTO_ARP, hooknum, skb, in, out,
39 loginfo, "%s", prefix);
40 break;
41 }
42}
43
44static struct nf_logger nf_bridge_logger __read_mostly = {
45 .name = "nf_log_bridge",
46 .type = NF_LOG_TYPE_LOG,
47 .logfn = nf_log_bridge_packet,
48 .me = THIS_MODULE,
49};
50
51static int __net_init nf_log_bridge_net_init(struct net *net)
52{
53 nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
54 return 0;
55}
56
57static void __net_exit nf_log_bridge_net_exit(struct net *net)
58{
59 nf_log_unset(net, &nf_bridge_logger);
60}
61
62static struct pernet_operations nf_log_bridge_net_ops = {
63 .init = nf_log_bridge_net_init,
64 .exit = nf_log_bridge_net_exit,
65};
66
67static int __init nf_log_bridge_init(void)
68{
69 int ret;
70
71 /* Request to load the real packet loggers. */
72 nf_logger_request_module(NFPROTO_IPV4, NF_LOG_TYPE_LOG);
73 nf_logger_request_module(NFPROTO_IPV6, NF_LOG_TYPE_LOG);
74 nf_logger_request_module(NFPROTO_ARP, NF_LOG_TYPE_LOG);
75
76 ret = register_pernet_subsys(&nf_log_bridge_net_ops);
77 if (ret < 0)
78 return ret;
79
80 nf_log_register(NFPROTO_BRIDGE, &nf_bridge_logger);
81 return 0;
82}
83
84static void __exit nf_log_bridge_exit(void)
85{
86 unregister_pernet_subsys(&nf_log_bridge_net_ops);
87 nf_log_unregister(&nf_bridge_logger);
88}
89
90module_init(nf_log_bridge_init);
91module_exit(nf_log_bridge_exit);
92
93MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
94MODULE_DESCRIPTION("Netfilter bridge packet logging");
95MODULE_LICENSE("GPL");
96MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 0);