diff options
author | Bart De Schuymer <bdschuym@pandora.be> | 2005-12-14 02:14:08 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-03 16:10:30 -0500 |
commit | d5228a4f49db32d22a39c653281b527ef371129c (patch) | |
tree | 89d2c988c877fd3d25078c40a4bdfdd8df2e553a /net/bridge | |
parent | 318360646941d6f3d4c6e4ee99107392728a4079 (diff) |
[NETFILTER] ebtables: Support nf_log API from ebt_log and ebt_ulog
This makes ebt_log and ebt_ulog use the new nf_log api. This enables
the bridging packet filter to log packets e.g. via nfnetlink_log.
Signed-off-by: Bart De Schuymer <bdschuym@pandora.be>
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/Kconfig | 6 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_log.c | 72 | ||||
-rw-r--r-- | net/bridge/netfilter/ebt_ulog.c | 53 |
3 files changed, 110 insertions, 21 deletions
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index c70b3be23026..b84fc6075fe1 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig | |||
@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG | |||
196 | To compile it as a module, choose M here. If unsure, say N. | 196 | To compile it as a module, choose M here. If unsure, say N. |
197 | 197 | ||
198 | config BRIDGE_EBT_ULOG | 198 | config BRIDGE_EBT_ULOG |
199 | tristate "ebt: ulog support" | 199 | tristate "ebt: ulog support (OBSOLETE)" |
200 | depends on BRIDGE_NF_EBTABLES | 200 | depends on BRIDGE_NF_EBTABLES |
201 | help | 201 | help |
202 | This option enables the old bridge-specific "ebt_ulog" implementation | ||
203 | which has been obsoleted by the new "nfnetlink_log" code (see | ||
204 | CONFIG_NETFILTER_NETLINK_LOG). | ||
205 | |||
202 | This option adds the ulog watcher, that you can use in any rule | 206 | This option adds the ulog watcher, that you can use in any rule |
203 | in any ebtables table. The packet is passed to a userspace | 207 | in any ebtables table. The packet is passed to a userspace |
204 | logging daemon using netlink multicast sockets. This differs | 208 | logging daemon using netlink multicast sockets. This differs |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 662975be3d1d..c436e6c6242b 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Authors: | 4 | * Authors: |
5 | * Bart De Schuymer <bdschuym@pandora.be> | 5 | * Bart De Schuymer <bdschuym@pandora.be> |
6 | * Harald Welte <laforge@netfilter.org> | ||
6 | * | 7 | * |
7 | * April, 2002 | 8 | * April, 2002 |
8 | * | 9 | * |
@@ -10,6 +11,7 @@ | |||
10 | 11 | ||
11 | #include <linux/netfilter_bridge/ebtables.h> | 12 | #include <linux/netfilter_bridge/ebtables.h> |
12 | #include <linux/netfilter_bridge/ebt_log.h> | 13 | #include <linux/netfilter_bridge/ebt_log.h> |
14 | #include <linux/netfilter.h> | ||
13 | #include <linux/module.h> | 15 | #include <linux/module.h> |
14 | #include <linux/ip.h> | 16 | #include <linux/ip.h> |
15 | #include <linux/if_arp.h> | 17 | #include <linux/if_arp.h> |
@@ -55,27 +57,30 @@ static void print_MAC(unsigned char *p) | |||
55 | } | 57 | } |
56 | 58 | ||
57 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] | 59 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] |
58 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | 60 | static void |
59 | const struct net_device *in, const struct net_device *out, | 61 | ebt_log_packet(unsigned int pf, unsigned int hooknum, |
60 | const void *data, unsigned int datalen) | 62 | const struct sk_buff *skb, const struct net_device *in, |
63 | const struct net_device *out, const struct nf_loginfo *loginfo, | ||
64 | const char *prefix) | ||
61 | { | 65 | { |
62 | struct ebt_log_info *info = (struct ebt_log_info *)data; | 66 | unsigned int bitmask; |
63 | char level_string[4] = "< >"; | ||
64 | 67 | ||
65 | level_string[1] = '0' + info->loglevel; | ||
66 | spin_lock_bh(&ebt_log_lock); | 68 | spin_lock_bh(&ebt_log_lock); |
67 | printk(level_string); | 69 | printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level, |
68 | printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", | 70 | prefix, in ? in->name : "", out ? out->name : ""); |
69 | out ? out->name : ""); | ||
70 | 71 | ||
71 | printk("MAC source = "); | ||
72 | print_MAC(eth_hdr(skb)->h_source); | 72 | print_MAC(eth_hdr(skb)->h_source); |
73 | printk("MAC dest = "); | 73 | printk("MAC dest = "); |
74 | print_MAC(eth_hdr(skb)->h_dest); | 74 | print_MAC(eth_hdr(skb)->h_dest); |
75 | 75 | ||
76 | printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); | 76 | printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); |
77 | 77 | ||
78 | if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == | 78 | if (loginfo->type == NF_LOG_TYPE_LOG) |
79 | bitmask = loginfo->u.log.logflags; | ||
80 | else | ||
81 | bitmask = NF_LOG_MASK; | ||
82 | |||
83 | if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == | ||
79 | htons(ETH_P_IP)){ | 84 | htons(ETH_P_IP)){ |
80 | struct iphdr _iph, *ih; | 85 | struct iphdr _iph, *ih; |
81 | 86 | ||
@@ -84,10 +89,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
84 | printk(" INCOMPLETE IP header"); | 89 | printk(" INCOMPLETE IP header"); |
85 | goto out; | 90 | goto out; |
86 | } | 91 | } |
87 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", | 92 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP " |
88 | NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); | 93 | "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr), |
89 | printk(" IP tos=0x%02X, IP proto=%d", ih->tos, | 94 | NIPQUAD(ih->daddr), ih->tos, ih->protocol); |
90 | ih->protocol); | ||
91 | if (ih->protocol == IPPROTO_TCP || | 95 | if (ih->protocol == IPPROTO_TCP || |
92 | ih->protocol == IPPROTO_UDP) { | 96 | ih->protocol == IPPROTO_UDP) { |
93 | struct tcpudphdr _ports, *pptr; | 97 | struct tcpudphdr _ports, *pptr; |
@@ -104,7 +108,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
104 | goto out; | 108 | goto out; |
105 | } | 109 | } |
106 | 110 | ||
107 | if ((info->bitmask & EBT_LOG_ARP) && | 111 | if ((bitmask & EBT_LOG_ARP) && |
108 | ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || | 112 | ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || |
109 | (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { | 113 | (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { |
110 | struct arphdr _arph, *ah; | 114 | struct arphdr _arph, *ah; |
@@ -144,6 +148,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
144 | out: | 148 | out: |
145 | printk("\n"); | 149 | printk("\n"); |
146 | spin_unlock_bh(&ebt_log_lock); | 150 | spin_unlock_bh(&ebt_log_lock); |
151 | |||
152 | } | ||
153 | |||
154 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | ||
155 | const struct net_device *in, const struct net_device *out, | ||
156 | const void *data, unsigned int datalen) | ||
157 | { | ||
158 | struct ebt_log_info *info = (struct ebt_log_info *)data; | ||
159 | struct nf_loginfo li; | ||
160 | |||
161 | li.type = NF_LOG_TYPE_LOG; | ||
162 | li.u.log.level = info->loglevel; | ||
163 | li.u.log.logflags = info->bitmask; | ||
164 | |||
165 | nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix); | ||
147 | } | 166 | } |
148 | 167 | ||
149 | static struct ebt_watcher log = | 168 | static struct ebt_watcher log = |
@@ -154,13 +173,32 @@ static struct ebt_watcher log = | |||
154 | .me = THIS_MODULE, | 173 | .me = THIS_MODULE, |
155 | }; | 174 | }; |
156 | 175 | ||
176 | static struct nf_logger ebt_log_logger = { | ||
177 | .name = "ebt_log", | ||
178 | .logfn = &ebt_log_packet, | ||
179 | .me = THIS_MODULE, | ||
180 | }; | ||
181 | |||
157 | static int __init init(void) | 182 | static int __init init(void) |
158 | { | 183 | { |
159 | return ebt_register_watcher(&log); | 184 | int ret; |
185 | |||
186 | ret = ebt_register_watcher(&log); | ||
187 | if (ret < 0) | ||
188 | return ret; | ||
189 | if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) { | ||
190 | printk(KERN_WARNING "ebt_log: not logging via system console " | ||
191 | "since somebody else already registered for PF_INET\n"); | ||
192 | /* we cannot make module load fail here, since otherwise | ||
193 | * ebtables userspace would abort */ | ||
194 | } | ||
195 | |||
196 | return 0; | ||
160 | } | 197 | } |
161 | 198 | ||
162 | static void __exit fini(void) | 199 | static void __exit fini(void) |
163 | { | 200 | { |
201 | nf_log_unregister_logger(&ebt_log_logger); | ||
164 | ebt_unregister_watcher(&log); | 202 | ebt_unregister_watcher(&log); |
165 | } | 203 | } |
166 | 204 | ||
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index aae26ae2e61f..ce617b3dbbb8 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Authors: | 4 | * Authors: |
5 | * Bart De Schuymer <bdschuym@pandora.be> | 5 | * Bart De Schuymer <bdschuym@pandora.be> |
6 | * Harald Welte <laforge@netfilter.org> | ||
6 | * | 7 | * |
7 | * November, 2004 | 8 | * November, 2004 |
8 | * | 9 | * |
@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
115 | return skb; | 116 | return skb; |
116 | } | 117 | } |
117 | 118 | ||
118 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | 119 | static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, |
119 | const struct net_device *in, const struct net_device *out, | 120 | const struct net_device *in, const struct net_device *out, |
120 | const void *data, unsigned int datalen) | 121 | const struct ebt_ulog_info *uloginfo, const char *prefix) |
121 | { | 122 | { |
122 | ebt_ulog_packet_msg_t *pm; | 123 | ebt_ulog_packet_msg_t *pm; |
123 | size_t size, copy_len; | 124 | size_t size, copy_len; |
124 | struct nlmsghdr *nlh; | 125 | struct nlmsghdr *nlh; |
125 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; | ||
126 | unsigned int group = uloginfo->nlgroup; | 126 | unsigned int group = uloginfo->nlgroup; |
127 | ebt_ulog_buff_t *ub = &ulog_buffers[group]; | 127 | ebt_ulog_buff_t *ub = &ulog_buffers[group]; |
128 | spinlock_t *lock = &ub->lock; | 128 | spinlock_t *lock = &ub->lock; |
@@ -216,6 +216,39 @@ alloc_failure: | |||
216 | goto unlock; | 216 | goto unlock; |
217 | } | 217 | } |
218 | 218 | ||
219 | /* this function is registered with the netfilter core */ | ||
220 | static void ebt_log_packet(unsigned int pf, unsigned int hooknum, | ||
221 | const struct sk_buff *skb, const struct net_device *in, | ||
222 | const struct net_device *out, const struct nf_loginfo *li, | ||
223 | const char *prefix) | ||
224 | { | ||
225 | struct ebt_ulog_info loginfo; | ||
226 | |||
227 | if (!li || li->type != NF_LOG_TYPE_ULOG) { | ||
228 | loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP; | ||
229 | loginfo.cprange = 0; | ||
230 | loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD; | ||
231 | loginfo.prefix[0] = '\0'; | ||
232 | } else { | ||
233 | loginfo.nlgroup = li->u.ulog.group; | ||
234 | loginfo.cprange = li->u.ulog.copy_len; | ||
235 | loginfo.qthreshold = li->u.ulog.qthreshold; | ||
236 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); | ||
237 | } | ||
238 | |||
239 | ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | ||
240 | } | ||
241 | |||
242 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | ||
243 | const struct net_device *in, const struct net_device *out, | ||
244 | const void *data, unsigned int datalen) | ||
245 | { | ||
246 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; | ||
247 | |||
248 | ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); | ||
249 | } | ||
250 | |||
251 | |||
219 | static int ebt_ulog_check(const char *tablename, unsigned int hookmask, | 252 | static int ebt_ulog_check(const char *tablename, unsigned int hookmask, |
220 | const struct ebt_entry *e, void *data, unsigned int datalen) | 253 | const struct ebt_entry *e, void *data, unsigned int datalen) |
221 | { | 254 | { |
@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = { | |||
240 | .me = THIS_MODULE, | 273 | .me = THIS_MODULE, |
241 | }; | 274 | }; |
242 | 275 | ||
276 | static struct nf_logger ebt_ulog_logger = { | ||
277 | .name = EBT_ULOG_WATCHER, | ||
278 | .logfn = &ebt_log_packet, | ||
279 | .me = THIS_MODULE, | ||
280 | }; | ||
281 | |||
243 | static int __init init(void) | 282 | static int __init init(void) |
244 | { | 283 | { |
245 | int i, ret = 0; | 284 | int i, ret = 0; |
@@ -265,6 +304,13 @@ static int __init init(void) | |||
265 | else if ((ret = ebt_register_watcher(&ulog))) | 304 | else if ((ret = ebt_register_watcher(&ulog))) |
266 | sock_release(ebtulognl->sk_socket); | 305 | sock_release(ebtulognl->sk_socket); |
267 | 306 | ||
307 | if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) { | ||
308 | printk(KERN_WARNING "ebt_ulog: not logging via ulog " | ||
309 | "since somebody else already registered for PF_BRIDGE\n"); | ||
310 | /* we cannot make module load fail here, since otherwise | ||
311 | * ebtables userspace would abort */ | ||
312 | } | ||
313 | |||
268 | return ret; | 314 | return ret; |
269 | } | 315 | } |
270 | 316 | ||
@@ -273,6 +319,7 @@ static void __exit fini(void) | |||
273 | ebt_ulog_buff_t *ub; | 319 | ebt_ulog_buff_t *ub; |
274 | int i; | 320 | int i; |
275 | 321 | ||
322 | nf_log_unregister_logger(&ebt_ulog_logger); | ||
276 | ebt_unregister_watcher(&ulog); | 323 | ebt_unregister_watcher(&ulog); |
277 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { | 324 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { |
278 | ub = &ulog_buffers[i]; | 325 | ub = &ulog_buffers[i]; |