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 | |
| 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')
| -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]; | 
