* Ebtables NFQUEUE Support
@ 2012-10-19 18:32 Benjamin Beckmeyer
2012-10-24 5:16 ` JieYue Ma
2013-11-11 1:47 ` ravi
0 siblings, 2 replies; 7+ messages in thread
From: Benjamin Beckmeyer @ 2012-10-19 18:32 UTC (permalink / raw)
To: netfilter
Hi all,
I am trying to build an Ebtables NFQUEUE module to also move layer 2
traffic to the NFQUEUE system provided by IPtables. A few years ago a
Pierre Chifflier provided 3 patches to Ebtables that appear to try and
utilize the NFQUEUE xt_tables target within Ebtables to pass the layer 2
data via nfnetlink_queue.
Some background, I am trying to get this working on 2.6.26.5 kernel
version and have applied the patches listed here:
http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37859
http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37862
I have also patched the Ebtables (2.0.8) userspace utility to produce the
shared object ebt_NFQUEUE.so with code also from Pierre, which can be
found here:
https://www.wzdftpd.net/downloads/ebt_NFQUEUE.c
To get the patches to work for the ebt_nfqueue kernel object, due to an
older kernel, I had to modify the target and check function arguments as
the "const struct xt_action_param" does not exist in my kernel version:
static int ebt_nfqueue_tg(const struct sk_buff *skb, const struct
net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
{
const struct ebt_nfqueue_info *info = data;
struct nf_loginfo li;
unsigned int verdict = NF_ACCEPT;
printk(KERN_NOTICE "ebt_NFQUEUE: returning EBT_QUEUE\n");
return EBT_QUEUE; // return -5
}
static struct ebt_target ebt_nfqueue __read_mostly = {
.name = "NFQUEUE",
.target = ebt_nfqueue_tg,
.check = ebt_nfqueue_check,
.me = THIS_MODULE,
};
+++++ VERSUS +++++
static struct xt_target ebt_xt_nfqueue __read_mostly = {
.name = "NFQUEUE",
.revision = 0,
.family = 7, // NFPROTO_BRIDGE
.target = ebt_nfqueue_tg,
.checkentry = ebt_nfqueue_check,
.targetsize = sizeof(struct ebt_nfqueue_info),
.me = THIS_MODULE,
};
Nevertheless, the return value from this target is just the EBT_QUEUE (-5)
to inform the Netfilter system of the queue number. If I use the
ebt_target rather than xt_target the kernel module will build and can be
inserted into ebtables with no errors - the problem is that queuing does
not work. If I use the xt_target rather than the ebt_target then Ebtables
userspace complains that it is not supported from this kernel version
(error in communication.c in userspace and appears to fail on the
"setsockopt" calls).
I have printed out the entire contents of using the xt_target vs
ebt_target and all data going into this call is identical, which boggles
my mind as to why xt_target will trigger the error in the ebtables
userspace program and ebt_target will not.
I think that I MUST use the xt_target within ebtables to properly pass
this data to the NFQUEUE system. This comes from an earlier discussion:
+++
On 04.02.2011 14:40, Pierre Chifflier wrote:
> On 02/04/2011 02:25 PM, Patrick McHardy wrote:
>> On 03.02.2011 15:32, Pierre Chifflier wrote:
>>> This adds support for sending bridge packets to userspace using
>>> the NFQUEUE target with ebtables.
>>
>> I don't think we need a new target for this (and the EBT_QUEUE
>> definition), just using xt_NFQUEUE should work fine.
>
> I thought ebtables did not support sending packet to xtables ? (that's
> on the TODO list for ebtables).
It can use xtables targets and matches if I'm not completely
mistaken.
+++
It appears I can 'use' xtables targets, it will compile correctly, but
ebtables will not actually allow me to insert the rules to jump to the
NFQUEUE target, so I am unable to actually verify if packets would be
queue'd by the system.
When using the ebt_target I can insert my NFQUEUE rules into the nat
PREROUTING table, and the packet counter will actually increment on layer
2 traffic, but the packets do not appear to actually hit any of the
nfnetlink_queue functions (I have added a printk to every function). I
even see that my target has been hit via a printk:
user.notice kernel: ebt_NFQUEUE: returning EBT_QUEUE
But then it appears that is as far as the packet goes.
When queueing a packet from IPtables I see a huge amount of output:
user.notice kernel: BB: File: nfnetlink_queue.c Function:
__enqueue_entry
user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv
user.notice kernel: BB: File: nfnetlink.c Function: nfnl_lock
user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv_msg
user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_get_subsys
user.notice kernel: BB: File: nfnetlink.c Function:
nfnetlink_find_client
user.notice kernel: BB: File: nfnetlink_queue.c Function:
nfqnl_recv_verdict
user.notice kernel: BB: File: nfnetlink_queue.c Function:
instance_lookup
user.notice kernel: BB: File: nfnetlink_queue.c Function:
find_dequeue_entry
user.notice kernel: BB: File: nfnetlink.c Function: nfnl_unlock
user.notice kernel: BB: File: nfnetlink_queue.c Function:
nfqnl_enqueue_packet
user.notice kernel: BB: File: nfnetlink_queue.c Function:
instance_lookup
user.notice kernel: BB: File: nfnetlink_queue.c Function:
nfqnl_build_packet_message
user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_unicast
But from my ebtables -j NFQUEUE there are no calls to the nfnetlink.c or
nfnetlink_queue.c functions. It is almost like the target is hit then the
packet is just mysteriously gone...or hits other functions unrelated to
the queueing system.
In summation, the problem is if using the ebt_target struct in the kernel
module for ebtables, it will be inserted and can be utilized by the
userspace Ebtables - but it doesnt appear to pass the packet to the
IPtables nfqueue correctly. If using the xt_target struct in the kernel
module for ebtables, it will compile, but fails to be utilized by Ebtables
userspace due to a "setsockopt error mentioned above.
Any help or suggestions are greatly appreciated!
Thank you, Benny
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: Ebtables NFQUEUE Support 2012-10-19 18:32 Ebtables NFQUEUE Support Benjamin Beckmeyer @ 2012-10-24 5:16 ` JieYue Ma 2012-10-24 6:38 ` JieYue Ma 2013-11-11 1:47 ` ravi 1 sibling, 1 reply; 7+ messages in thread From: JieYue Ma @ 2012-10-24 5:16 UTC (permalink / raw) To: B.Beckmeyer; +Cc: netfilter Well, I wrote the nfqueue patch for both ebtables and arptables a few months ago, it did work well, so I think it is appropriate to release these patches. Hope it will help you. I am not sure if I understand the problem you raised correctly. I guess it might be the netfilter sus-subsystem currently not supporting queue verdict for bridge very well. As you can see, you need a nf_afinfo structure to be registered before using netfilter queue verdict for this protocol. Unfortunately, during initialization of netfilter, it did register such nf_afinfo for ipv4, ipv6, maybe arp as well.. but not for bridge. So in order to enable queue verdict to work under bridge, you need to register it by yourself, maybe during initialization of ebtables nfqueue target module here is my patch for ebtables: diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h new/include/linux/netfilter_bridge/ebt_nfqueue.h --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1969-12-31 19:00:00.000000000 -0500 +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-05-29 23:59:06.940194206 -0400 @@ -0,0 +1,10 @@ +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H +#define __LINUX_BRIDGE_EBT_NFQUEUE_H +#include <linux/types.h> + +struct xt_NFQ_info { + __u16 queuenum; + int target; +}; + +#endif diff -upNr old/net/bridge/netfilter/ebtables.c new/net/bridge/netfilter/ebtables.c --- old/net/bridge/netfilter/ebtables.c 2012-05-27 08:48:00.095617214 -0400 +++ new/net/bridge/netfilter/ebtables.c 2012-05-27 08:57:27.644193954 -0400 @@ -252,6 +252,17 @@ letsreturn: return NF_DROP; } #endif + /* + * We add NFQUEUE support in ebtables here: + * + * If verdict is NF_QUEUE type, pass it to Netfilter. Netfilter will + * call nf_queue to handle this. + */ + if (verdict > 0 && (verdict & NF_VERDICT_MASK) == NF_QUEUE) { + read_unlock_bh(&table->lock); + return verdict; + } + /* jump to a udc */ cs[sp].n = i + 1; cs[sp].chaininfo = chaininfo; diff -upNr old/net/bridge/netfilter/ebt_nfqueue.c new/net/bridge/netfilter/ebt_nfqueue.c --- old/net/bridge/netfilter/ebt_nfqueue.c 1969-12-31 19:00:00.000000000 -0500 +++ new/net/bridge/netfilter/ebt_nfqueue.c 2012-05-27 08:58:58.511193378 -0400 @@ -0,0 +1,117 @@ +/* + * 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. + * + */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/netfilter.h> +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter_bridge/ebtables.h> +#include <linux/netfilter_bridge/ebt_nfqueue.h> + +MODULE_AUTHOR("alibaba"); +MODULE_DESCRIPTION("ebtables: forwarding to netlink"); +MODULE_LICENSE("GPL"); + +static unsigned int ebt_nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par) { + const struct xt_NFQ_info *info = par->targinfo; + + return NF_QUEUE_NR(info->queuenum); +} + +static bool ebt_nfqueue_tg_check(const struct xt_tgchk_param* par) { + const struct xt_NFQ_info *info = par->targinfo; + + if (BASE_CHAIN && info->target == EBT_RETURN) { + printk(KERN_INFO"ebt_nfqueue: ebt_nfqueue_tg_check failed\n"); + return false; + } + + return true; +} + +void dummy_from_user(void *dst, void *src) { +} + +int dummy_to_user(void __user *dst, void *src) { + return 0; +} + +static struct xt_target nfqueue_tg_reg __read_mostly = { + .name = "nfqueue", + .revision = 0, + .family = NFPROTO_BRIDGE, + .table = "filter", + .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_FORWARD), + .target = ebt_nfqueue_tg, + .checkentry = ebt_nfqueue_tg_check, + .targetsize = XT_ALIGN(sizeof(struct xt_NFQ_info)), + .compat_from_user = dummy_from_user, + .compat_to_user = dummy_to_user, + .me = THIS_MODULE, +}; + + +__sum16 nf_br_checksum(struct sk_buff* skb, unsigned int hook, unsigned int dataoff, u_int8_t protocol) { + return 0; +} + +static __sum16 nf_br_checksum_partial(struct sk_buff* skb, unsigned int hook, + unsigned int dataoff, unsigned int len, + u_int8_t protocol) { + return 0; +} + +static int nf_br_route(struct dst_entry **dst, struct flowi *fl) { + return 0; +} + +static void nf_br_saveroute(const struct sk_buff *skb, struct nf_queue_entry *entry) { + +} + +static int nf_br_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry) { + return 0; +} + +static const struct nf_afinfo nf_br_afinfo = { + .family = NFPROTO_BRIDGE, + .checksum = nf_br_checksum, + .checksum_partial = nf_br_checksum_partial, + .route = nf_br_route, + .saveroute = nf_br_saveroute, + .reroute = nf_br_reroute, + .route_key_size = 0, +}; + + +static int __init nfqueue_tg_init(void) +{ + int ret; + /* + * a tricky hack here, we forge a bridge nf_afinfo struct and register it + * + * We have to do this, coz currently netfilter subsystem doesn't support bridge in nf_queue + */ + ret = nf_register_afinfo(&nf_br_afinfo); + if (ret < 0) { + printk("[ebt_nfqueue] nf_register_afinfo failed, cannot install ebt_nfqueue.ko\n"); + return ret; + } + + return xt_register_target(&nfqueue_tg_reg); +} + +static void __exit nfqueue_tg_exit(void) +{ + nf_unregister_afinfo(&nf_br_afinfo); + xt_unregister_target(&nfqueue_tg_reg); +} + +module_init(nfqueue_tg_init); +module_exit(nfqueue_tg_exit); On Sat, Oct 20, 2012 at 2:32 AM, Benjamin Beckmeyer <B.Beckmeyer@stud.hs-esslingen.de> wrote: > Hi all, > > I am trying to build an Ebtables NFQUEUE module to also move layer 2 > traffic to the NFQUEUE system provided by IPtables. A few years ago a > Pierre Chifflier provided 3 patches to Ebtables that appear to try and > utilize the NFQUEUE xt_tables target within Ebtables to pass the layer 2 > data via nfnetlink_queue. > > Some background, I am trying to get this working on 2.6.26.5 kernel > version and have applied the patches listed here: > > http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37859 > http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37862 > > I have also patched the Ebtables (2.0.8) userspace utility to produce the > shared object ebt_NFQUEUE.so with code also from Pierre, which can be > found here: > > https://www.wzdftpd.net/downloads/ebt_NFQUEUE.c > > To get the patches to work for the ebt_nfqueue kernel object, due to an > older kernel, I had to modify the target and check function arguments as > the "const struct xt_action_param" does not exist in my kernel version: > > static int ebt_nfqueue_tg(const struct sk_buff *skb, const struct > net_device *in, > const struct net_device *out, const void *data, unsigned int datalen) > { > const struct ebt_nfqueue_info *info = data; > struct nf_loginfo li; > unsigned int verdict = NF_ACCEPT; > > printk(KERN_NOTICE "ebt_NFQUEUE: returning EBT_QUEUE\n"); > return EBT_QUEUE; // return -5 > } > > static struct ebt_target ebt_nfqueue __read_mostly = { > .name = "NFQUEUE", > .target = ebt_nfqueue_tg, > .check = ebt_nfqueue_check, > .me = THIS_MODULE, > }; > > +++++ VERSUS +++++ > > static struct xt_target ebt_xt_nfqueue __read_mostly = { > .name = "NFQUEUE", > .revision = 0, > .family = 7, // NFPROTO_BRIDGE > .target = ebt_nfqueue_tg, > .checkentry = ebt_nfqueue_check, > .targetsize = sizeof(struct ebt_nfqueue_info), > .me = THIS_MODULE, > }; > > Nevertheless, the return value from this target is just the EBT_QUEUE (-5) > to inform the Netfilter system of the queue number. If I use the > ebt_target rather than xt_target the kernel module will build and can be > inserted into ebtables with no errors - the problem is that queuing does > not work. If I use the xt_target rather than the ebt_target then Ebtables > userspace complains that it is not supported from this kernel version > (error in communication.c in userspace and appears to fail on the > "setsockopt" calls). > > I have printed out the entire contents of using the xt_target vs > ebt_target and all data going into this call is identical, which boggles > my mind as to why xt_target will trigger the error in the ebtables > userspace program and ebt_target will not. > > I think that I MUST use the xt_target within ebtables to properly pass > this data to the NFQUEUE system. This comes from an earlier discussion: > > +++ > > On 04.02.2011 14:40, Pierre Chifflier wrote: >> On 02/04/2011 02:25 PM, Patrick McHardy wrote: >>> On 03.02.2011 15:32, Pierre Chifflier wrote: >>>> This adds support for sending bridge packets to userspace using >>>> the NFQUEUE target with ebtables. >>> >>> I don't think we need a new target for this (and the EBT_QUEUE >>> definition), just using xt_NFQUEUE should work fine. >> >> I thought ebtables did not support sending packet to xtables ? (that's >> on the TODO list for ebtables). > > It can use xtables targets and matches if I'm not completely > mistaken. > > +++ > > It appears I can 'use' xtables targets, it will compile correctly, but > ebtables will not actually allow me to insert the rules to jump to the > NFQUEUE target, so I am unable to actually verify if packets would be > queue'd by the system. > > When using the ebt_target I can insert my NFQUEUE rules into the nat > PREROUTING table, and the packet counter will actually increment on layer > 2 traffic, but the packets do not appear to actually hit any of the > nfnetlink_queue functions (I have added a printk to every function). I > even see that my target has been hit via a printk: > > user.notice kernel: ebt_NFQUEUE: returning EBT_QUEUE > > But then it appears that is as far as the packet goes. > > When queueing a packet from IPtables I see a huge amount of output: > > user.notice kernel: BB: File: nfnetlink_queue.c Function: > __enqueue_entry > user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv > user.notice kernel: BB: File: nfnetlink.c Function: nfnl_lock > user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv_msg > user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_get_subsys > user.notice kernel: BB: File: nfnetlink.c Function: > nfnetlink_find_client > user.notice kernel: BB: File: nfnetlink_queue.c Function: > nfqnl_recv_verdict > user.notice kernel: BB: File: nfnetlink_queue.c Function: > instance_lookup > user.notice kernel: BB: File: nfnetlink_queue.c Function: > find_dequeue_entry > user.notice kernel: BB: File: nfnetlink.c Function: nfnl_unlock > user.notice kernel: BB: File: nfnetlink_queue.c Function: > nfqnl_enqueue_packet > user.notice kernel: BB: File: nfnetlink_queue.c Function: > instance_lookup > user.notice kernel: BB: File: nfnetlink_queue.c Function: > nfqnl_build_packet_message > user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_unicast > > But from my ebtables -j NFQUEUE there are no calls to the nfnetlink.c or > nfnetlink_queue.c functions. It is almost like the target is hit then the > packet is just mysteriously gone...or hits other functions unrelated to > the queueing system. > > In summation, the problem is if using the ebt_target struct in the kernel > module for ebtables, it will be inserted and can be utilized by the > userspace Ebtables - but it doesnt appear to pass the packet to the > IPtables nfqueue correctly. If using the xt_target struct in the kernel > module for ebtables, it will compile, but fails to be utilized by Ebtables > userspace due to a "setsockopt error mentioned above. > > Any help or suggestions are greatly appreciated! > > Thank you, Benny > > > > > > > > -- > To unsubscribe from this list: send the line "unsubscribe netfilter" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Ebtables NFQUEUE Support 2012-10-24 5:16 ` JieYue Ma @ 2012-10-24 6:38 ` JieYue Ma 2012-10-24 23:39 ` Benjamin Beckmeyer 0 siblings, 1 reply; 7+ messages in thread From: JieYue Ma @ 2012-10-24 6:38 UTC (permalink / raw) To: B.Beckmeyer; +Cc: netfilter I forgot the ebtables command patch, here it is.. diff -upNr old/extensions/ebt_nfqueue.c new/extensions/ebt_nfqueue.c --- old/extensions/ebt_nfqueue.c 1970-01-01 08:00:00.000000000 +0800 +++ new/extensions/ebt_nfqueue.c 2012-10-24 14:35:40.000000000 +0800 @@ -0,0 +1,127 @@ +/* + * Shared library add-on to ebtables for NFQ + * + * (C) 2012 by Ma Jie Yue <jieyue.majy@aliyun-inc.com> + * + * This program is distributed under the terms of GNU GPLv2, 1991 + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <errno.h> + +#include "../include/ebtables_u.h" +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter_bridge/ebt_nfqueue.h> + +#define NFQUEUE_QUEUENUM 0x1 +#define NFQUEUE_QUEUEBALANCE 0x2 + +static int string_to_number(const char *s, unsigned int min, unsigned int max, unsigned int *ret) +{ + long number; + char *end; + errno = 0; + number = strtol(s, &end, 0); + + if (*end == '\0' && end != s) { + if (errno != ERANGE && min <= number && number <= max) { + *ret = number; + return 0; + } + } + return -1; +} + +static void nfqueue_help(void) +{ + printf("NFQUEUE target options\n" + " --queue-num value Send packet to QUEUE number <value>.\n" + " Valid queue numbers are 0-65535\n"); +} + +static void nfqueue_init(struct ebt_entry_target* target) { + struct xt_NFQ_info* info = (struct xt_NFQ_info *)target->data; + + info->queuenum = 0; +} + +static const struct option nfqueue_opts[] = { + { "queue-num", 1, NULL, 'F' }, + { "queue-balance", 1, NULL, 'B' }, + { .name = NULL } +}; + +static void parse_num(const char *s, struct xt_NFQ_info *tinfo) +{ + unsigned int num = 0; + if (string_to_number(s, 0, 65535, &num) < 0) { + ebt_print_error("Invalid queue number %s\n", s); + } + + tinfo->queuenum = num; +} + +static int nfqueue_parse(int c, char **argv, int argc, + const struct ebt_u_entry *entry, unsigned int *flags, + struct ebt_entry_target **target) +{ + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)(*target)->data; + tinfo->queuenum = 0; + + switch (c) { + case 'F': + if (*flags) + ebt_print_error2("NFQUEUE target: " + "Only use --queue-num ONCE!"); + *flags |= NFQUEUE_QUEUENUM; + parse_num(optarg, tinfo); + break; + + case 'B': + ebt_print_error2("NFQUEUE target: " + "--queue-balance not supported (kernel too old?)"); + + default: + break; + } + return 1; +} + +static void nfqueue_print(const struct ebt_u_entry* entry, const struct ebt_entry_target *target) { + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)target->data; + + printf("--queue-num %u ", tinfo->queuenum); +} + +static void nfqueue_check(const struct ebt_u_entry *entry, + const struct ebt_entry_target *target, const char *name, + unsigned int hookmask, unsigned int time) { + +} + +static int nfqueue_compare(const struct ebt_entry_target *t1, const struct ebt_entry_target *t2) { + struct xt_NFQ_info *info1 = (struct xt_NFQ_info *)t1->data; + struct xt_NFQ_info *info2 = (struct xt_NFQ_info *)t2->data; + + return (info1->queuenum == info2->queuenum); +} + +static struct ebt_u_target nfqueue_target = { + .name = "nfqueue", + .init = nfqueue_init, + .size = sizeof(struct xt_NFQ_info), + .help = nfqueue_help, + .parse = nfqueue_parse, + .print = nfqueue_print, + .final_check = nfqueue_check, + .compare = nfqueue_compare, + .extra_ops = nfqueue_opts, +}; + +void _init(void) { + ebt_register_target(&nfqueue_target); +} + diff -upNr old/extensions/Makefile new/extensions/Makefile --- old/extensions/Makefile 2011-12-16 04:02:47.000000000 +0800 +++ new/extensions/Makefile 2012-10-24 14:18:50.000000000 +0800 @@ -1,7 +1,7 @@ #! /usr/bin/make EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \ - pkttype stp among limit ulog nflog + pkttype stp among limit ulog nflog nfqueue EXT_TABLES+=filter nat broute EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h new/include/linux/netfilter_bridge/ebt_nfqueue.h --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1970-01-01 08:00:00.000000000 +0800 +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-10-24 14:17:02.000000000 +0800 @@ -0,0 +1,11 @@ +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H +#define __LINUX_BRIDGE_EBT_NFQUEUE_H + +#include <linux/types.h> + +struct xt_NFQ_info { + __u16 queuenum; + int target; +}; + +#endif On Wed, Oct 24, 2012 at 1:16 PM, JieYue Ma <xiaoma80.dev@gmail.com> wrote: > Well, I wrote the nfqueue patch for both ebtables and arptables a few > months ago, it did work well, so I think it is appropriate to release > these patches. Hope it will help you. > > I am not sure if I understand the problem you raised correctly. I > guess it might be the netfilter sus-subsystem currently not supporting > queue verdict for bridge very well. As you can see, you need a > nf_afinfo structure to be registered before using netfilter queue > verdict for this protocol. Unfortunately, during initialization of > netfilter, it did register such nf_afinfo for ipv4, ipv6, maybe arp as > well.. but not for bridge. So in order to enable queue verdict to work > under bridge, you need to register it by yourself, maybe during > initialization of ebtables nfqueue target module > > here is my patch for ebtables: > > > diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h > new/include/linux/netfilter_bridge/ebt_nfqueue.h > --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1969-12-31 > 19:00:00.000000000 -0500 > +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-05-29 > 23:59:06.940194206 -0400 > @@ -0,0 +1,10 @@ > +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H > +#define __LINUX_BRIDGE_EBT_NFQUEUE_H > +#include <linux/types.h> > + > +struct xt_NFQ_info { > + __u16 queuenum; > + int target; > +}; > + > +#endif > diff -upNr old/net/bridge/netfilter/ebtables.c > new/net/bridge/netfilter/ebtables.c > --- old/net/bridge/netfilter/ebtables.c 2012-05-27 08:48:00.095617214 -0400 > +++ new/net/bridge/netfilter/ebtables.c 2012-05-27 08:57:27.644193954 -0400 > @@ -252,6 +252,17 @@ letsreturn: > return NF_DROP; > } > #endif > + /* > + * We add NFQUEUE support in ebtables here: > + * > + * If verdict is NF_QUEUE type, pass it to Netfilter. Netfilter will > + * call nf_queue to handle this. > + */ > + if (verdict > 0 && (verdict & NF_VERDICT_MASK) == NF_QUEUE) { > + read_unlock_bh(&table->lock); > + return verdict; > + } > + > /* jump to a udc */ > cs[sp].n = i + 1; > cs[sp].chaininfo = chaininfo; > > diff -upNr old/net/bridge/netfilter/ebt_nfqueue.c > new/net/bridge/netfilter/ebt_nfqueue.c > --- old/net/bridge/netfilter/ebt_nfqueue.c 1969-12-31 19:00:00.000000000 -0500 > +++ new/net/bridge/netfilter/ebt_nfqueue.c 2012-05-27 08:58:58.511193378 -0400 > @@ -0,0 +1,117 @@ > +/* > + * 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. > + * > + */ > + > +#include <linux/module.h> > +#include <linux/skbuff.h> > +#include <linux/kernel.h> > +#include <linux/types.h> > +#include <linux/netfilter.h> > +#include <linux/netfilter/x_tables.h> > +#include <linux/netfilter_bridge/ebtables.h> > +#include <linux/netfilter_bridge/ebt_nfqueue.h> > + > +MODULE_AUTHOR("alibaba"); > +MODULE_DESCRIPTION("ebtables: forwarding to netlink"); > +MODULE_LICENSE("GPL"); > + > +static unsigned int ebt_nfqueue_tg(struct sk_buff *skb, const struct > xt_target_param *par) { > + const struct xt_NFQ_info *info = par->targinfo; > + > + return NF_QUEUE_NR(info->queuenum); > +} > + > +static bool ebt_nfqueue_tg_check(const struct xt_tgchk_param* par) { > + const struct xt_NFQ_info *info = par->targinfo; > + > + if (BASE_CHAIN && info->target == EBT_RETURN) { > + printk(KERN_INFO"ebt_nfqueue: ebt_nfqueue_tg_check failed\n"); > + return false; > + } > + > + return true; > +} > + > +void dummy_from_user(void *dst, void *src) { > +} > + > +int dummy_to_user(void __user *dst, void *src) { > + return 0; > +} > + > +static struct xt_target nfqueue_tg_reg __read_mostly = { > + .name = "nfqueue", > + .revision = 0, > + .family = NFPROTO_BRIDGE, > + .table = "filter", > + .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | (1 > << NF_BR_LOCAL_OUT) | (1 << NF_BR_FORWARD), > + .target = ebt_nfqueue_tg, > + .checkentry = ebt_nfqueue_tg_check, > + .targetsize = XT_ALIGN(sizeof(struct xt_NFQ_info)), > + .compat_from_user = dummy_from_user, > + .compat_to_user = dummy_to_user, > + .me = THIS_MODULE, > +}; > + > + > +__sum16 nf_br_checksum(struct sk_buff* skb, unsigned int hook, > unsigned int dataoff, u_int8_t protocol) { > + return 0; > +} > + > +static __sum16 nf_br_checksum_partial(struct sk_buff* skb, unsigned int hook, > + unsigned int dataoff, unsigned int len, > + u_int8_t protocol) { > + return 0; > +} > + > +static int nf_br_route(struct dst_entry **dst, struct flowi *fl) { > + return 0; > +} > + > +static void nf_br_saveroute(const struct sk_buff *skb, struct > nf_queue_entry *entry) { > + > +} > + > +static int nf_br_reroute(struct sk_buff *skb, const struct > nf_queue_entry *entry) { > + return 0; > +} > + > +static const struct nf_afinfo nf_br_afinfo = { > + .family = NFPROTO_BRIDGE, > + .checksum = nf_br_checksum, > + .checksum_partial = nf_br_checksum_partial, > + .route = nf_br_route, > + .saveroute = nf_br_saveroute, > + .reroute = nf_br_reroute, > + .route_key_size = 0, > +}; > + > + > +static int __init nfqueue_tg_init(void) > +{ > + int ret; > + /* > + * a tricky hack here, we forge a bridge nf_afinfo struct and register it > + * > + * We have to do this, coz currently netfilter subsystem doesn't > support bridge in nf_queue > + */ > + ret = nf_register_afinfo(&nf_br_afinfo); > + if (ret < 0) { > + printk("[ebt_nfqueue] nf_register_afinfo failed, cannot > install ebt_nfqueue.ko\n"); > + return ret; > + } > + > + return xt_register_target(&nfqueue_tg_reg); > +} > + > +static void __exit nfqueue_tg_exit(void) > +{ > + nf_unregister_afinfo(&nf_br_afinfo); > + xt_unregister_target(&nfqueue_tg_reg); > +} > + > +module_init(nfqueue_tg_init); > +module_exit(nfqueue_tg_exit); > > > > > On Sat, Oct 20, 2012 at 2:32 AM, Benjamin Beckmeyer > <B.Beckmeyer@stud.hs-esslingen.de> wrote: >> Hi all, >> >> I am trying to build an Ebtables NFQUEUE module to also move layer 2 >> traffic to the NFQUEUE system provided by IPtables. A few years ago a >> Pierre Chifflier provided 3 patches to Ebtables that appear to try and >> utilize the NFQUEUE xt_tables target within Ebtables to pass the layer 2 >> data via nfnetlink_queue. >> >> Some background, I am trying to get this working on 2.6.26.5 kernel >> version and have applied the patches listed here: >> >> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37859 >> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37862 >> >> I have also patched the Ebtables (2.0.8) userspace utility to produce the >> shared object ebt_NFQUEUE.so with code also from Pierre, which can be >> found here: >> >> https://www.wzdftpd.net/downloads/ebt_NFQUEUE.c >> >> To get the patches to work for the ebt_nfqueue kernel object, due to an >> older kernel, I had to modify the target and check function arguments as >> the "const struct xt_action_param" does not exist in my kernel version: >> >> static int ebt_nfqueue_tg(const struct sk_buff *skb, const struct >> net_device *in, >> const struct net_device *out, const void *data, unsigned int datalen) >> { >> const struct ebt_nfqueue_info *info = data; >> struct nf_loginfo li; >> unsigned int verdict = NF_ACCEPT; >> >> printk(KERN_NOTICE "ebt_NFQUEUE: returning EBT_QUEUE\n"); >> return EBT_QUEUE; // return -5 >> } >> >> static struct ebt_target ebt_nfqueue __read_mostly = { >> .name = "NFQUEUE", >> .target = ebt_nfqueue_tg, >> .check = ebt_nfqueue_check, >> .me = THIS_MODULE, >> }; >> >> +++++ VERSUS +++++ >> >> static struct xt_target ebt_xt_nfqueue __read_mostly = { >> .name = "NFQUEUE", >> .revision = 0, >> .family = 7, // NFPROTO_BRIDGE >> .target = ebt_nfqueue_tg, >> .checkentry = ebt_nfqueue_check, >> .targetsize = sizeof(struct ebt_nfqueue_info), >> .me = THIS_MODULE, >> }; >> >> Nevertheless, the return value from this target is just the EBT_QUEUE (-5) >> to inform the Netfilter system of the queue number. If I use the >> ebt_target rather than xt_target the kernel module will build and can be >> inserted into ebtables with no errors - the problem is that queuing does >> not work. If I use the xt_target rather than the ebt_target then Ebtables >> userspace complains that it is not supported from this kernel version >> (error in communication.c in userspace and appears to fail on the >> "setsockopt" calls). >> >> I have printed out the entire contents of using the xt_target vs >> ebt_target and all data going into this call is identical, which boggles >> my mind as to why xt_target will trigger the error in the ebtables >> userspace program and ebt_target will not. >> >> I think that I MUST use the xt_target within ebtables to properly pass >> this data to the NFQUEUE system. This comes from an earlier discussion: >> >> +++ >> >> On 04.02.2011 14:40, Pierre Chifflier wrote: >>> On 02/04/2011 02:25 PM, Patrick McHardy wrote: >>>> On 03.02.2011 15:32, Pierre Chifflier wrote: >>>>> This adds support for sending bridge packets to userspace using >>>>> the NFQUEUE target with ebtables. >>>> >>>> I don't think we need a new target for this (and the EBT_QUEUE >>>> definition), just using xt_NFQUEUE should work fine. >>> >>> I thought ebtables did not support sending packet to xtables ? (that's >>> on the TODO list for ebtables). >> >> It can use xtables targets and matches if I'm not completely >> mistaken. >> >> +++ >> >> It appears I can 'use' xtables targets, it will compile correctly, but >> ebtables will not actually allow me to insert the rules to jump to the >> NFQUEUE target, so I am unable to actually verify if packets would be >> queue'd by the system. >> >> When using the ebt_target I can insert my NFQUEUE rules into the nat >> PREROUTING table, and the packet counter will actually increment on layer >> 2 traffic, but the packets do not appear to actually hit any of the >> nfnetlink_queue functions (I have added a printk to every function). I >> even see that my target has been hit via a printk: >> >> user.notice kernel: ebt_NFQUEUE: returning EBT_QUEUE >> >> But then it appears that is as far as the packet goes. >> >> When queueing a packet from IPtables I see a huge amount of output: >> >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> __enqueue_entry >> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv >> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_lock >> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv_msg >> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_get_subsys >> user.notice kernel: BB: File: nfnetlink.c Function: >> nfnetlink_find_client >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> nfqnl_recv_verdict >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> instance_lookup >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> find_dequeue_entry >> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_unlock >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> nfqnl_enqueue_packet >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> instance_lookup >> user.notice kernel: BB: File: nfnetlink_queue.c Function: >> nfqnl_build_packet_message >> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_unicast >> >> But from my ebtables -j NFQUEUE there are no calls to the nfnetlink.c or >> nfnetlink_queue.c functions. It is almost like the target is hit then the >> packet is just mysteriously gone...or hits other functions unrelated to >> the queueing system. >> >> In summation, the problem is if using the ebt_target struct in the kernel >> module for ebtables, it will be inserted and can be utilized by the >> userspace Ebtables - but it doesnt appear to pass the packet to the >> IPtables nfqueue correctly. If using the xt_target struct in the kernel >> module for ebtables, it will compile, but fails to be utilized by Ebtables >> userspace due to a "setsockopt error mentioned above. >> >> Any help or suggestions are greatly appreciated! >> >> Thank you, Benny >> >> >> >> >> >> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe netfilter" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Ebtables NFQUEUE Support 2012-10-24 6:38 ` JieYue Ma @ 2012-10-24 23:39 ` Benjamin Beckmeyer 2012-10-25 5:54 ` JieYue Ma 0 siblings, 1 reply; 7+ messages in thread From: Benjamin Beckmeyer @ 2012-10-24 23:39 UTC (permalink / raw) To: JieYue Ma; +Cc: b.beckmeyer, netfilter Thank you JieYue Ma! This is excellent. Out of curiousity which kernel version and ebtables version were you working against? Benny > I forgot the ebtables command patch, here it is.. > > diff -upNr old/extensions/ebt_nfqueue.c new/extensions/ebt_nfqueue.c > --- old/extensions/ebt_nfqueue.c 1970-01-01 08:00:00.000000000 +0800 > +++ new/extensions/ebt_nfqueue.c 2012-10-24 14:35:40.000000000 +0800 > @@ -0,0 +1,127 @@ > +/* > + * Shared library add-on to ebtables for NFQ > + * > + * (C) 2012 by Ma Jie Yue <jieyue.majy@aliyun-inc.com> > + * > + * This program is distributed under the terms of GNU GPLv2, 1991 > + */ > + > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > +#include <getopt.h> > +#include <errno.h> > + > +#include "../include/ebtables_u.h" > +#include <linux/netfilter/x_tables.h> > +#include <linux/netfilter_bridge/ebt_nfqueue.h> > + > +#define NFQUEUE_QUEUENUM 0x1 > +#define NFQUEUE_QUEUEBALANCE 0x2 > + > +static int string_to_number(const char *s, unsigned int min, unsigned > int max, unsigned int *ret) > +{ > + long number; > + char *end; > + errno = 0; > + number = strtol(s, &end, 0); > + > + if (*end == '\0' && end != s) { > + if (errno != ERANGE && min <= number && number <= max) { > + *ret = number; > + return 0; > + } > + } > + return -1; > +} > + > +static void nfqueue_help(void) > +{ > + printf("NFQUEUE target options\n" > + " --queue-num value Send packet to QUEUE number > <value>.\n" > + " Valid queue numbers are > 0-65535\n"); > +} > + > +static void nfqueue_init(struct ebt_entry_target* target) { > + struct xt_NFQ_info* info = (struct xt_NFQ_info *)target->data; > + > + info->queuenum = 0; > +} > + > +static const struct option nfqueue_opts[] = { > + { "queue-num", 1, NULL, 'F' }, > + { "queue-balance", 1, NULL, 'B' }, > + { .name = NULL } > +}; > + > +static void parse_num(const char *s, struct xt_NFQ_info *tinfo) > +{ > + unsigned int num = 0; > + if (string_to_number(s, 0, 65535, &num) < 0) { > + ebt_print_error("Invalid queue number %s\n", s); > + } > + > + tinfo->queuenum = num; > +} > + > +static int nfqueue_parse(int c, char **argv, int argc, > + const struct ebt_u_entry *entry, unsigned int *flags, > + struct ebt_entry_target **target) > +{ > + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)(*target)->data; > + tinfo->queuenum = 0; > + > + switch (c) { > + case 'F': > + if (*flags) > + ebt_print_error2("NFQUEUE target: " > + "Only use --queue-num ONCE!"); > + *flags |= NFQUEUE_QUEUENUM; > + parse_num(optarg, tinfo); > + break; > + > + case 'B': > + ebt_print_error2("NFQUEUE target: " > + "--queue-balance not supported (kernel too > old?)"); > + > + default: > + break; > + } > + return 1; > +} > + > +static void nfqueue_print(const struct ebt_u_entry* entry, const > struct ebt_entry_target *target) { > + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)target->data; > + > + printf("--queue-num %u ", tinfo->queuenum); > +} > + > +static void nfqueue_check(const struct ebt_u_entry *entry, > + const struct ebt_entry_target *target, const char *name, > + unsigned int hookmask, unsigned int time) { > + > +} > + > +static int nfqueue_compare(const struct ebt_entry_target *t1, const > struct ebt_entry_target *t2) { > + struct xt_NFQ_info *info1 = (struct xt_NFQ_info *)t1->data; > + struct xt_NFQ_info *info2 = (struct xt_NFQ_info *)t2->data; > + > + return (info1->queuenum == info2->queuenum); > +} > + > +static struct ebt_u_target nfqueue_target = { > + .name = "nfqueue", > + .init = nfqueue_init, > + .size = sizeof(struct xt_NFQ_info), > + .help = nfqueue_help, > + .parse = nfqueue_parse, > + .print = nfqueue_print, > + .final_check = nfqueue_check, > + .compare = nfqueue_compare, > + .extra_ops = nfqueue_opts, > +}; > + > +void _init(void) { > + ebt_register_target(&nfqueue_target); > +} > + > diff -upNr old/extensions/Makefile new/extensions/Makefile > --- old/extensions/Makefile 2011-12-16 04:02:47.000000000 +0800 > +++ new/extensions/Makefile 2012-10-24 14:18:50.000000000 +0800 > @@ -1,7 +1,7 @@ > #! /usr/bin/make > > EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan > mark_m mark \ > - pkttype stp among limit ulog nflog > + pkttype stp among limit ulog nflog nfqueue > EXT_TABLES+=filter nat broute > EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) > EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) > diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h > new/include/linux/netfilter_bridge/ebt_nfqueue.h > --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1970-01-01 > 08:00:00.000000000 +0800 > +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-10-24 > 14:17:02.000000000 +0800 > @@ -0,0 +1,11 @@ > +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H > +#define __LINUX_BRIDGE_EBT_NFQUEUE_H > + > +#include <linux/types.h> > + > +struct xt_NFQ_info { > + __u16 queuenum; > + int target; > +}; > + > +#endif > > > On Wed, Oct 24, 2012 at 1:16 PM, JieYue Ma <xiaoma80.dev@gmail.com> wrote: >> Well, I wrote the nfqueue patch for both ebtables and arptables a few >> months ago, it did work well, so I think it is appropriate to release >> these patches. Hope it will help you. >> >> I am not sure if I understand the problem you raised correctly. I >> guess it might be the netfilter sus-subsystem currently not supporting >> queue verdict for bridge very well. As you can see, you need a >> nf_afinfo structure to be registered before using netfilter queue >> verdict for this protocol. Unfortunately, during initialization of >> netfilter, it did register such nf_afinfo for ipv4, ipv6, maybe arp as >> well.. but not for bridge. So in order to enable queue verdict to work >> under bridge, you need to register it by yourself, maybe during >> initialization of ebtables nfqueue target module >> >> here is my patch for ebtables: >> >> >> diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h >> new/include/linux/netfilter_bridge/ebt_nfqueue.h >> --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1969-12-31 >> 19:00:00.000000000 -0500 >> +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-05-29 >> 23:59:06.940194206 -0400 >> @@ -0,0 +1,10 @@ >> +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H >> +#define __LINUX_BRIDGE_EBT_NFQUEUE_H >> +#include <linux/types.h> >> + >> +struct xt_NFQ_info { >> + __u16 queuenum; >> + int target; >> +}; >> + >> +#endif >> diff -upNr old/net/bridge/netfilter/ebtables.c >> new/net/bridge/netfilter/ebtables.c >> --- old/net/bridge/netfilter/ebtables.c 2012-05-27 08:48:00.095617214 >> -0400 >> +++ new/net/bridge/netfilter/ebtables.c 2012-05-27 08:57:27.644193954 >> -0400 >> @@ -252,6 +252,17 @@ letsreturn: >> return NF_DROP; >> } >> #endif >> + /* >> + * We add NFQUEUE support in ebtables here: >> + * >> + * If verdict is NF_QUEUE type, pass it to Netfilter. Netfilter >> will >> + * call nf_queue to handle this. >> + */ >> + if (verdict > 0 && (verdict & NF_VERDICT_MASK) == NF_QUEUE) { >> + read_unlock_bh(&table->lock); >> + return verdict; >> + } >> + >> /* jump to a udc */ >> cs[sp].n = i + 1; >> cs[sp].chaininfo = chaininfo; >> >> diff -upNr old/net/bridge/netfilter/ebt_nfqueue.c >> new/net/bridge/netfilter/ebt_nfqueue.c >> --- old/net/bridge/netfilter/ebt_nfqueue.c 1969-12-31 >> 19:00:00.000000000 -0500 >> +++ new/net/bridge/netfilter/ebt_nfqueue.c 2012-05-27 >> 08:58:58.511193378 -0400 >> @@ -0,0 +1,117 @@ >> +/* >> + * 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. >> + * >> + */ >> + >> +#include <linux/module.h> >> +#include <linux/skbuff.h> >> +#include <linux/kernel.h> >> +#include <linux/types.h> >> +#include <linux/netfilter.h> >> +#include <linux/netfilter/x_tables.h> >> +#include <linux/netfilter_bridge/ebtables.h> >> +#include <linux/netfilter_bridge/ebt_nfqueue.h> >> + >> +MODULE_AUTHOR("alibaba"); >> +MODULE_DESCRIPTION("ebtables: forwarding to netlink"); >> +MODULE_LICENSE("GPL"); >> + >> +static unsigned int ebt_nfqueue_tg(struct sk_buff *skb, const struct >> xt_target_param *par) { >> + const struct xt_NFQ_info *info = par->targinfo; >> + >> + return NF_QUEUE_NR(info->queuenum); >> +} >> + >> +static bool ebt_nfqueue_tg_check(const struct xt_tgchk_param* par) { >> + const struct xt_NFQ_info *info = par->targinfo; >> + >> + if (BASE_CHAIN && info->target == EBT_RETURN) { >> + printk(KERN_INFO"ebt_nfqueue: ebt_nfqueue_tg_check failed\n"); >> + return false; >> + } >> + >> + return true; >> +} >> + >> +void dummy_from_user(void *dst, void *src) { >> +} >> + >> +int dummy_to_user(void __user *dst, void *src) { >> + return 0; >> +} >> + >> +static struct xt_target nfqueue_tg_reg __read_mostly = { >> + .name = "nfqueue", >> + .revision = 0, >> + .family = NFPROTO_BRIDGE, >> + .table = "filter", >> + .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | (1 >> << NF_BR_LOCAL_OUT) | (1 << NF_BR_FORWARD), >> + .target = ebt_nfqueue_tg, >> + .checkentry = ebt_nfqueue_tg_check, >> + .targetsize = XT_ALIGN(sizeof(struct xt_NFQ_info)), >> + .compat_from_user = dummy_from_user, >> + .compat_to_user = dummy_to_user, >> + .me = THIS_MODULE, >> +}; >> + >> + >> +__sum16 nf_br_checksum(struct sk_buff* skb, unsigned int hook, >> unsigned int dataoff, u_int8_t protocol) { >> + return 0; >> +} >> + >> +static __sum16 nf_br_checksum_partial(struct sk_buff* skb, unsigned int >> hook, >> + unsigned int dataoff, unsigned int len, >> + u_int8_t protocol) { >> + return 0; >> +} >> + >> +static int nf_br_route(struct dst_entry **dst, struct flowi *fl) { >> + return 0; >> +} >> + >> +static void nf_br_saveroute(const struct sk_buff *skb, struct >> nf_queue_entry *entry) { >> + >> +} >> + >> +static int nf_br_reroute(struct sk_buff *skb, const struct >> nf_queue_entry *entry) { >> + return 0; >> +} >> + >> +static const struct nf_afinfo nf_br_afinfo = { >> + .family = NFPROTO_BRIDGE, >> + .checksum = nf_br_checksum, >> + .checksum_partial = nf_br_checksum_partial, >> + .route = nf_br_route, >> + .saveroute = nf_br_saveroute, >> + .reroute = nf_br_reroute, >> + .route_key_size = 0, >> +}; >> + >> + >> +static int __init nfqueue_tg_init(void) >> +{ >> + int ret; >> + /* >> + * a tricky hack here, we forge a bridge nf_afinfo struct and >> register it >> + * >> + * We have to do this, coz currently netfilter subsystem doesn't >> support bridge in nf_queue >> + */ >> + ret = nf_register_afinfo(&nf_br_afinfo); >> + if (ret < 0) { >> + printk("[ebt_nfqueue] nf_register_afinfo failed, cannot >> install ebt_nfqueue.ko\n"); >> + return ret; >> + } >> + >> + return xt_register_target(&nfqueue_tg_reg); >> +} >> + >> +static void __exit nfqueue_tg_exit(void) >> +{ >> + nf_unregister_afinfo(&nf_br_afinfo); >> + xt_unregister_target(&nfqueue_tg_reg); >> +} >> + >> +module_init(nfqueue_tg_init); >> +module_exit(nfqueue_tg_exit); >> >> >> >> >> On Sat, Oct 20, 2012 at 2:32 AM, Benjamin Beckmeyer >> <B.Beckmeyer@stud.hs-esslingen.de> wrote: >>> Hi all, >>> >>> I am trying to build an Ebtables NFQUEUE module to also move layer 2 >>> traffic to the NFQUEUE system provided by IPtables. A few years ago a >>> Pierre Chifflier provided 3 patches to Ebtables that appear to try and >>> utilize the NFQUEUE xt_tables target within Ebtables to pass the layer >>> 2 >>> data via nfnetlink_queue. >>> >>> Some background, I am trying to get this working on 2.6.26.5 kernel >>> version and have applied the patches listed here: >>> >>> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37859 >>> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37862 >>> >>> I have also patched the Ebtables (2.0.8) userspace utility to produce >>> the >>> shared object ebt_NFQUEUE.so with code also from Pierre, which can be >>> found here: >>> >>> https://www.wzdftpd.net/downloads/ebt_NFQUEUE.c >>> >>> To get the patches to work for the ebt_nfqueue kernel object, due to an >>> older kernel, I had to modify the target and check function arguments >>> as >>> the "const struct xt_action_param" does not exist in my kernel version: >>> >>> static int ebt_nfqueue_tg(const struct sk_buff *skb, const struct >>> net_device *in, >>> const struct net_device *out, const >>> void *data, unsigned int datalen) >>> { >>> const struct ebt_nfqueue_info *info = data; >>> struct nf_loginfo li; >>> unsigned int verdict = NF_ACCEPT; >>> >>> printk(KERN_NOTICE "ebt_NFQUEUE: returning EBT_QUEUE\n"); >>> return EBT_QUEUE; // return -5 >>> } >>> >>> static struct ebt_target ebt_nfqueue __read_mostly = { >>> .name = "NFQUEUE", >>> .target = ebt_nfqueue_tg, >>> .check = ebt_nfqueue_check, >>> .me = THIS_MODULE, >>> }; >>> >>> +++++ VERSUS +++++ >>> >>> static struct xt_target ebt_xt_nfqueue __read_mostly = { >>> .name = "NFQUEUE", >>> .revision = 0, >>> .family = 7, // NFPROTO_BRIDGE >>> .target = ebt_nfqueue_tg, >>> .checkentry = ebt_nfqueue_check, >>> .targetsize = sizeof(struct ebt_nfqueue_info), >>> .me = THIS_MODULE, >>> }; >>> >>> Nevertheless, the return value from this target is just the EBT_QUEUE >>> (-5) >>> to inform the Netfilter system of the queue number. If I use the >>> ebt_target rather than xt_target the kernel module will build and can >>> be >>> inserted into ebtables with no errors - the problem is that queuing >>> does >>> not work. If I use the xt_target rather than the ebt_target then >>> Ebtables >>> userspace complains that it is not supported from this kernel version >>> (error in communication.c in userspace and appears to fail on the >>> "setsockopt" calls). >>> >>> I have printed out the entire contents of using the xt_target vs >>> ebt_target and all data going into this call is identical, which >>> boggles >>> my mind as to why xt_target will trigger the error in the ebtables >>> userspace program and ebt_target will not. >>> >>> I think that I MUST use the xt_target within ebtables to properly pass >>> this data to the NFQUEUE system. This comes from an earlier >>> discussion: >>> >>> +++ >>> >>> On 04.02.2011 14:40, Pierre Chifflier wrote: >>>> On 02/04/2011 02:25 PM, Patrick McHardy wrote: >>>>> On 03.02.2011 15:32, Pierre Chifflier wrote: >>>>>> This adds support for sending bridge packets to userspace using >>>>>> the NFQUEUE target with ebtables. >>>>> >>>>> I don't think we need a new target for this (and the EBT_QUEUE >>>>> definition), just using xt_NFQUEUE should work fine. >>>> >>>> I thought ebtables did not support sending packet to xtables ? (that's >>>> on the TODO list for ebtables). >>> >>> It can use xtables targets and matches if I'm not completely >>> mistaken. >>> >>> +++ >>> >>> It appears I can 'use' xtables targets, it will compile correctly, but >>> ebtables will not actually allow me to insert the rules to jump to the >>> NFQUEUE target, so I am unable to actually verify if packets would be >>> queue'd by the system. >>> >>> When using the ebt_target I can insert my NFQUEUE rules into the nat >>> PREROUTING table, and the packet counter will actually increment on >>> layer >>> 2 traffic, but the packets do not appear to actually hit any of the >>> nfnetlink_queue functions (I have added a printk to every function). I >>> even see that my target has been hit via a printk: >>> >>> user.notice kernel: ebt_NFQUEUE: returning EBT_QUEUE >>> >>> But then it appears that is as far as the packet goes. >>> >>> When queueing a packet from IPtables I see a huge amount of output: >>> >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> __enqueue_entry >>> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv >>> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_lock >>> user.notice kernel: BB: File: nfnetlink.c Function: >>> nfnetlink_rcv_msg >>> user.notice kernel: BB: File: nfnetlink.c Function: >>> nfnetlink_get_subsys >>> user.notice kernel: BB: File: nfnetlink.c Function: >>> nfnetlink_find_client >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> nfqnl_recv_verdict >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> instance_lookup >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> find_dequeue_entry >>> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_unlock >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> nfqnl_enqueue_packet >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> instance_lookup >>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>> nfqnl_build_packet_message >>> user.notice kernel: BB: File: nfnetlink.c Function: >>> nfnetlink_unicast >>> >>> But from my ebtables -j NFQUEUE there are no calls to the nfnetlink.c >>> or >>> nfnetlink_queue.c functions. It is almost like the target is hit then >>> the >>> packet is just mysteriously gone...or hits other functions unrelated to >>> the queueing system. >>> >>> In summation, the problem is if using the ebt_target struct in the >>> kernel >>> module for ebtables, it will be inserted and can be utilized by the >>> userspace Ebtables - but it doesnt appear to pass the packet to the >>> IPtables nfqueue correctly. If using the xt_target struct in the >>> kernel >>> module for ebtables, it will compile, but fails to be utilized by >>> Ebtables >>> userspace due to a "setsockopt error mentioned above. >>> >>> Any help or suggestions are greatly appreciated! >>> >>> Thank you, Benny >>> >>> >>> >>> >>> >>> >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe netfilter" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Ebtables NFQUEUE Support 2012-10-24 23:39 ` Benjamin Beckmeyer @ 2012-10-25 5:54 ` JieYue Ma 0 siblings, 0 replies; 7+ messages in thread From: JieYue Ma @ 2012-10-25 5:54 UTC (permalink / raw) To: B.Beckmeyer; +Cc: netfilter kernel is 2.6.32, while ebtables is 2.0.10-4 On Thu, Oct 25, 2012 at 7:39 AM, Benjamin Beckmeyer <B.Beckmeyer@stud.hs-esslingen.de> wrote: > Thank you JieYue Ma! > > This is excellent. Out of curiousity which kernel version and ebtables > version were you working against? > > Benny > >> I forgot the ebtables command patch, here it is.. >> >> diff -upNr old/extensions/ebt_nfqueue.c new/extensions/ebt_nfqueue.c >> --- old/extensions/ebt_nfqueue.c 1970-01-01 08:00:00.000000000 +0800 >> +++ new/extensions/ebt_nfqueue.c 2012-10-24 14:35:40.000000000 +0800 >> @@ -0,0 +1,127 @@ >> +/* >> + * Shared library add-on to ebtables for NFQ >> + * >> + * (C) 2012 by Ma Jie Yue <jieyue.majy@aliyun-inc.com> >> + * >> + * This program is distributed under the terms of GNU GPLv2, 1991 >> + */ >> + >> +#include <stdio.h> >> +#include <string.h> >> +#include <stdlib.h> >> +#include <getopt.h> >> +#include <errno.h> >> + >> +#include "../include/ebtables_u.h" >> +#include <linux/netfilter/x_tables.h> >> +#include <linux/netfilter_bridge/ebt_nfqueue.h> >> + >> +#define NFQUEUE_QUEUENUM 0x1 >> +#define NFQUEUE_QUEUEBALANCE 0x2 >> + >> +static int string_to_number(const char *s, unsigned int min, unsigned >> int max, unsigned int *ret) >> +{ >> + long number; >> + char *end; >> + errno = 0; >> + number = strtol(s, &end, 0); >> + >> + if (*end == '\0' && end != s) { >> + if (errno != ERANGE && min <= number && number <= max) { >> + *ret = number; >> + return 0; >> + } >> + } >> + return -1; >> +} >> + >> +static void nfqueue_help(void) >> +{ >> + printf("NFQUEUE target options\n" >> + " --queue-num value Send packet to QUEUE number >> <value>.\n" >> + " Valid queue numbers are >> 0-65535\n"); >> +} >> + >> +static void nfqueue_init(struct ebt_entry_target* target) { >> + struct xt_NFQ_info* info = (struct xt_NFQ_info *)target->data; >> + >> + info->queuenum = 0; >> +} >> + >> +static const struct option nfqueue_opts[] = { >> + { "queue-num", 1, NULL, 'F' }, >> + { "queue-balance", 1, NULL, 'B' }, >> + { .name = NULL } >> +}; >> + >> +static void parse_num(const char *s, struct xt_NFQ_info *tinfo) >> +{ >> + unsigned int num = 0; >> + if (string_to_number(s, 0, 65535, &num) < 0) { >> + ebt_print_error("Invalid queue number %s\n", s); >> + } >> + >> + tinfo->queuenum = num; >> +} >> + >> +static int nfqueue_parse(int c, char **argv, int argc, >> + const struct ebt_u_entry *entry, unsigned int *flags, >> + struct ebt_entry_target **target) >> +{ >> + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)(*target)->data; >> + tinfo->queuenum = 0; >> + >> + switch (c) { >> + case 'F': >> + if (*flags) >> + ebt_print_error2("NFQUEUE target: " >> + "Only use --queue-num ONCE!"); >> + *flags |= NFQUEUE_QUEUENUM; >> + parse_num(optarg, tinfo); >> + break; >> + >> + case 'B': >> + ebt_print_error2("NFQUEUE target: " >> + "--queue-balance not supported (kernel too >> old?)"); >> + >> + default: >> + break; >> + } >> + return 1; >> +} >> + >> +static void nfqueue_print(const struct ebt_u_entry* entry, const >> struct ebt_entry_target *target) { >> + struct xt_NFQ_info *tinfo = (struct xt_NFQ_info *)target->data; >> + >> + printf("--queue-num %u ", tinfo->queuenum); >> +} >> + >> +static void nfqueue_check(const struct ebt_u_entry *entry, >> + const struct ebt_entry_target *target, const char *name, >> + unsigned int hookmask, unsigned int time) { >> + >> +} >> + >> +static int nfqueue_compare(const struct ebt_entry_target *t1, const >> struct ebt_entry_target *t2) { >> + struct xt_NFQ_info *info1 = (struct xt_NFQ_info *)t1->data; >> + struct xt_NFQ_info *info2 = (struct xt_NFQ_info *)t2->data; >> + >> + return (info1->queuenum == info2->queuenum); >> +} >> + >> +static struct ebt_u_target nfqueue_target = { >> + .name = "nfqueue", >> + .init = nfqueue_init, >> + .size = sizeof(struct xt_NFQ_info), >> + .help = nfqueue_help, >> + .parse = nfqueue_parse, >> + .print = nfqueue_print, >> + .final_check = nfqueue_check, >> + .compare = nfqueue_compare, >> + .extra_ops = nfqueue_opts, >> +}; >> + >> +void _init(void) { >> + ebt_register_target(&nfqueue_target); >> +} >> + >> diff -upNr old/extensions/Makefile new/extensions/Makefile >> --- old/extensions/Makefile 2011-12-16 04:02:47.000000000 +0800 >> +++ new/extensions/Makefile 2012-10-24 14:18:50.000000000 +0800 >> @@ -1,7 +1,7 @@ >> #! /usr/bin/make >> >> EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan >> mark_m mark \ >> - pkttype stp among limit ulog nflog >> + pkttype stp among limit ulog nflog nfqueue >> EXT_TABLES+=filter nat broute >> EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) >> EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) >> diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h >> new/include/linux/netfilter_bridge/ebt_nfqueue.h >> --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1970-01-01 >> 08:00:00.000000000 +0800 >> +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-10-24 >> 14:17:02.000000000 +0800 >> @@ -0,0 +1,11 @@ >> +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H >> +#define __LINUX_BRIDGE_EBT_NFQUEUE_H >> + >> +#include <linux/types.h> >> + >> +struct xt_NFQ_info { >> + __u16 queuenum; >> + int target; >> +}; >> + >> +#endif >> >> >> On Wed, Oct 24, 2012 at 1:16 PM, JieYue Ma <xiaoma80.dev@gmail.com> wrote: >>> Well, I wrote the nfqueue patch for both ebtables and arptables a few >>> months ago, it did work well, so I think it is appropriate to release >>> these patches. Hope it will help you. >>> >>> I am not sure if I understand the problem you raised correctly. I >>> guess it might be the netfilter sus-subsystem currently not supporting >>> queue verdict for bridge very well. As you can see, you need a >>> nf_afinfo structure to be registered before using netfilter queue >>> verdict for this protocol. Unfortunately, during initialization of >>> netfilter, it did register such nf_afinfo for ipv4, ipv6, maybe arp as >>> well.. but not for bridge. So in order to enable queue verdict to work >>> under bridge, you need to register it by yourself, maybe during >>> initialization of ebtables nfqueue target module >>> >>> here is my patch for ebtables: >>> >>> >>> diff -upNr old/include/linux/netfilter_bridge/ebt_nfqueue.h >>> new/include/linux/netfilter_bridge/ebt_nfqueue.h >>> --- old/include/linux/netfilter_bridge/ebt_nfqueue.h 1969-12-31 >>> 19:00:00.000000000 -0500 >>> +++ new/include/linux/netfilter_bridge/ebt_nfqueue.h 2012-05-29 >>> 23:59:06.940194206 -0400 >>> @@ -0,0 +1,10 @@ >>> +#ifndef __LINUX_BRIDGE_EBT_NFQUEUE_H >>> +#define __LINUX_BRIDGE_EBT_NFQUEUE_H >>> +#include <linux/types.h> >>> + >>> +struct xt_NFQ_info { >>> + __u16 queuenum; >>> + int target; >>> +}; >>> + >>> +#endif >>> diff -upNr old/net/bridge/netfilter/ebtables.c >>> new/net/bridge/netfilter/ebtables.c >>> --- old/net/bridge/netfilter/ebtables.c 2012-05-27 08:48:00.095617214 >>> -0400 >>> +++ new/net/bridge/netfilter/ebtables.c 2012-05-27 08:57:27.644193954 >>> -0400 >>> @@ -252,6 +252,17 @@ letsreturn: >>> return NF_DROP; >>> } >>> #endif >>> + /* >>> + * We add NFQUEUE support in ebtables here: >>> + * >>> + * If verdict is NF_QUEUE type, pass it to Netfilter. Netfilter >>> will >>> + * call nf_queue to handle this. >>> + */ >>> + if (verdict > 0 && (verdict & NF_VERDICT_MASK) == NF_QUEUE) { >>> + read_unlock_bh(&table->lock); >>> + return verdict; >>> + } >>> + >>> /* jump to a udc */ >>> cs[sp].n = i + 1; >>> cs[sp].chaininfo = chaininfo; >>> >>> diff -upNr old/net/bridge/netfilter/ebt_nfqueue.c >>> new/net/bridge/netfilter/ebt_nfqueue.c >>> --- old/net/bridge/netfilter/ebt_nfqueue.c 1969-12-31 >>> 19:00:00.000000000 -0500 >>> +++ new/net/bridge/netfilter/ebt_nfqueue.c 2012-05-27 >>> 08:58:58.511193378 -0400 >>> @@ -0,0 +1,117 @@ >>> +/* >>> + * 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. >>> + * >>> + */ >>> + >>> +#include <linux/module.h> >>> +#include <linux/skbuff.h> >>> +#include <linux/kernel.h> >>> +#include <linux/types.h> >>> +#include <linux/netfilter.h> >>> +#include <linux/netfilter/x_tables.h> >>> +#include <linux/netfilter_bridge/ebtables.h> >>> +#include <linux/netfilter_bridge/ebt_nfqueue.h> >>> + >>> +MODULE_AUTHOR("alibaba"); >>> +MODULE_DESCRIPTION("ebtables: forwarding to netlink"); >>> +MODULE_LICENSE("GPL"); >>> + >>> +static unsigned int ebt_nfqueue_tg(struct sk_buff *skb, const struct >>> xt_target_param *par) { >>> + const struct xt_NFQ_info *info = par->targinfo; >>> + >>> + return NF_QUEUE_NR(info->queuenum); >>> +} >>> + >>> +static bool ebt_nfqueue_tg_check(const struct xt_tgchk_param* par) { >>> + const struct xt_NFQ_info *info = par->targinfo; >>> + >>> + if (BASE_CHAIN && info->target == EBT_RETURN) { >>> + printk(KERN_INFO"ebt_nfqueue: ebt_nfqueue_tg_check failed\n"); >>> + return false; >>> + } >>> + >>> + return true; >>> +} >>> + >>> +void dummy_from_user(void *dst, void *src) { >>> +} >>> + >>> +int dummy_to_user(void __user *dst, void *src) { >>> + return 0; >>> +} >>> + >>> +static struct xt_target nfqueue_tg_reg __read_mostly = { >>> + .name = "nfqueue", >>> + .revision = 0, >>> + .family = NFPROTO_BRIDGE, >>> + .table = "filter", >>> + .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_LOCAL_IN) | (1 >>> << NF_BR_LOCAL_OUT) | (1 << NF_BR_FORWARD), >>> + .target = ebt_nfqueue_tg, >>> + .checkentry = ebt_nfqueue_tg_check, >>> + .targetsize = XT_ALIGN(sizeof(struct xt_NFQ_info)), >>> + .compat_from_user = dummy_from_user, >>> + .compat_to_user = dummy_to_user, >>> + .me = THIS_MODULE, >>> +}; >>> + >>> + >>> +__sum16 nf_br_checksum(struct sk_buff* skb, unsigned int hook, >>> unsigned int dataoff, u_int8_t protocol) { >>> + return 0; >>> +} >>> + >>> +static __sum16 nf_br_checksum_partial(struct sk_buff* skb, unsigned int >>> hook, >>> + unsigned int dataoff, unsigned int len, >>> + u_int8_t protocol) { >>> + return 0; >>> +} >>> + >>> +static int nf_br_route(struct dst_entry **dst, struct flowi *fl) { >>> + return 0; >>> +} >>> + >>> +static void nf_br_saveroute(const struct sk_buff *skb, struct >>> nf_queue_entry *entry) { >>> + >>> +} >>> + >>> +static int nf_br_reroute(struct sk_buff *skb, const struct >>> nf_queue_entry *entry) { >>> + return 0; >>> +} >>> + >>> +static const struct nf_afinfo nf_br_afinfo = { >>> + .family = NFPROTO_BRIDGE, >>> + .checksum = nf_br_checksum, >>> + .checksum_partial = nf_br_checksum_partial, >>> + .route = nf_br_route, >>> + .saveroute = nf_br_saveroute, >>> + .reroute = nf_br_reroute, >>> + .route_key_size = 0, >>> +}; >>> + >>> + >>> +static int __init nfqueue_tg_init(void) >>> +{ >>> + int ret; >>> + /* >>> + * a tricky hack here, we forge a bridge nf_afinfo struct and >>> register it >>> + * >>> + * We have to do this, coz currently netfilter subsystem doesn't >>> support bridge in nf_queue >>> + */ >>> + ret = nf_register_afinfo(&nf_br_afinfo); >>> + if (ret < 0) { >>> + printk("[ebt_nfqueue] nf_register_afinfo failed, cannot >>> install ebt_nfqueue.ko\n"); >>> + return ret; >>> + } >>> + >>> + return xt_register_target(&nfqueue_tg_reg); >>> +} >>> + >>> +static void __exit nfqueue_tg_exit(void) >>> +{ >>> + nf_unregister_afinfo(&nf_br_afinfo); >>> + xt_unregister_target(&nfqueue_tg_reg); >>> +} >>> + >>> +module_init(nfqueue_tg_init); >>> +module_exit(nfqueue_tg_exit); >>> >>> >>> >>> >>> On Sat, Oct 20, 2012 at 2:32 AM, Benjamin Beckmeyer >>> <B.Beckmeyer@stud.hs-esslingen.de> wrote: >>>> Hi all, >>>> >>>> I am trying to build an Ebtables NFQUEUE module to also move layer 2 >>>> traffic to the NFQUEUE system provided by IPtables. A few years ago a >>>> Pierre Chifflier provided 3 patches to Ebtables that appear to try and >>>> utilize the NFQUEUE xt_tables target within Ebtables to pass the layer >>>> 2 >>>> data via nfnetlink_queue. >>>> >>>> Some background, I am trying to get this working on 2.6.26.5 kernel >>>> version and have applied the patches listed here: >>>> >>>> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37859 >>>> http://permalink.gmane.org/gmane.comp.security.firewalls.netfilter.devel/37862 >>>> >>>> I have also patched the Ebtables (2.0.8) userspace utility to produce >>>> the >>>> shared object ebt_NFQUEUE.so with code also from Pierre, which can be >>>> found here: >>>> >>>> https://www.wzdftpd.net/downloads/ebt_NFQUEUE.c >>>> >>>> To get the patches to work for the ebt_nfqueue kernel object, due to an >>>> older kernel, I had to modify the target and check function arguments >>>> as >>>> the "const struct xt_action_param" does not exist in my kernel version: >>>> >>>> static int ebt_nfqueue_tg(const struct sk_buff *skb, const struct >>>> net_device *in, >>>> const struct net_device *out, const >>>> void *data, unsigned int datalen) >>>> { >>>> const struct ebt_nfqueue_info *info = data; >>>> struct nf_loginfo li; >>>> unsigned int verdict = NF_ACCEPT; >>>> >>>> printk(KERN_NOTICE "ebt_NFQUEUE: returning EBT_QUEUE\n"); >>>> return EBT_QUEUE; // return -5 >>>> } >>>> >>>> static struct ebt_target ebt_nfqueue __read_mostly = { >>>> .name = "NFQUEUE", >>>> .target = ebt_nfqueue_tg, >>>> .check = ebt_nfqueue_check, >>>> .me = THIS_MODULE, >>>> }; >>>> >>>> +++++ VERSUS +++++ >>>> >>>> static struct xt_target ebt_xt_nfqueue __read_mostly = { >>>> .name = "NFQUEUE", >>>> .revision = 0, >>>> .family = 7, // NFPROTO_BRIDGE >>>> .target = ebt_nfqueue_tg, >>>> .checkentry = ebt_nfqueue_check, >>>> .targetsize = sizeof(struct ebt_nfqueue_info), >>>> .me = THIS_MODULE, >>>> }; >>>> >>>> Nevertheless, the return value from this target is just the EBT_QUEUE >>>> (-5) >>>> to inform the Netfilter system of the queue number. If I use the >>>> ebt_target rather than xt_target the kernel module will build and can >>>> be >>>> inserted into ebtables with no errors - the problem is that queuing >>>> does >>>> not work. If I use the xt_target rather than the ebt_target then >>>> Ebtables >>>> userspace complains that it is not supported from this kernel version >>>> (error in communication.c in userspace and appears to fail on the >>>> "setsockopt" calls). >>>> >>>> I have printed out the entire contents of using the xt_target vs >>>> ebt_target and all data going into this call is identical, which >>>> boggles >>>> my mind as to why xt_target will trigger the error in the ebtables >>>> userspace program and ebt_target will not. >>>> >>>> I think that I MUST use the xt_target within ebtables to properly pass >>>> this data to the NFQUEUE system. This comes from an earlier >>>> discussion: >>>> >>>> +++ >>>> >>>> On 04.02.2011 14:40, Pierre Chifflier wrote: >>>>> On 02/04/2011 02:25 PM, Patrick McHardy wrote: >>>>>> On 03.02.2011 15:32, Pierre Chifflier wrote: >>>>>>> This adds support for sending bridge packets to userspace using >>>>>>> the NFQUEUE target with ebtables. >>>>>> >>>>>> I don't think we need a new target for this (and the EBT_QUEUE >>>>>> definition), just using xt_NFQUEUE should work fine. >>>>> >>>>> I thought ebtables did not support sending packet to xtables ? (that's >>>>> on the TODO list for ebtables). >>>> >>>> It can use xtables targets and matches if I'm not completely >>>> mistaken. >>>> >>>> +++ >>>> >>>> It appears I can 'use' xtables targets, it will compile correctly, but >>>> ebtables will not actually allow me to insert the rules to jump to the >>>> NFQUEUE target, so I am unable to actually verify if packets would be >>>> queue'd by the system. >>>> >>>> When using the ebt_target I can insert my NFQUEUE rules into the nat >>>> PREROUTING table, and the packet counter will actually increment on >>>> layer >>>> 2 traffic, but the packets do not appear to actually hit any of the >>>> nfnetlink_queue functions (I have added a printk to every function). I >>>> even see that my target has been hit via a printk: >>>> >>>> user.notice kernel: ebt_NFQUEUE: returning EBT_QUEUE >>>> >>>> But then it appears that is as far as the packet goes. >>>> >>>> When queueing a packet from IPtables I see a huge amount of output: >>>> >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> __enqueue_entry >>>> user.notice kernel: BB: File: nfnetlink.c Function: nfnetlink_rcv >>>> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_lock >>>> user.notice kernel: BB: File: nfnetlink.c Function: >>>> nfnetlink_rcv_msg >>>> user.notice kernel: BB: File: nfnetlink.c Function: >>>> nfnetlink_get_subsys >>>> user.notice kernel: BB: File: nfnetlink.c Function: >>>> nfnetlink_find_client >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> nfqnl_recv_verdict >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> instance_lookup >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> find_dequeue_entry >>>> user.notice kernel: BB: File: nfnetlink.c Function: nfnl_unlock >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> nfqnl_enqueue_packet >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> instance_lookup >>>> user.notice kernel: BB: File: nfnetlink_queue.c Function: >>>> nfqnl_build_packet_message >>>> user.notice kernel: BB: File: nfnetlink.c Function: >>>> nfnetlink_unicast >>>> >>>> But from my ebtables -j NFQUEUE there are no calls to the nfnetlink.c >>>> or >>>> nfnetlink_queue.c functions. It is almost like the target is hit then >>>> the >>>> packet is just mysteriously gone...or hits other functions unrelated to >>>> the queueing system. >>>> >>>> In summation, the problem is if using the ebt_target struct in the >>>> kernel >>>> module for ebtables, it will be inserted and can be utilized by the >>>> userspace Ebtables - but it doesnt appear to pass the packet to the >>>> IPtables nfqueue correctly. If using the xt_target struct in the >>>> kernel >>>> module for ebtables, it will compile, but fails to be utilized by >>>> Ebtables >>>> userspace due to a "setsockopt error mentioned above. >>>> >>>> Any help or suggestions are greatly appreciated! >>>> >>>> Thank you, Benny >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> -- >>>> To unsubscribe from this list: send the line "unsubscribe netfilter" in >>>> the body of a message to majordomo@vger.kernel.org >>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Ebtables NFQUEUE Support 2012-10-19 18:32 Ebtables NFQUEUE Support Benjamin Beckmeyer 2012-10-24 5:16 ` JieYue Ma @ 2013-11-11 1:47 ` ravi 1 sibling, 0 replies; 7+ messages in thread From: ravi @ 2013-11-11 1:47 UTC (permalink / raw) To: netfilter Benjamin Beckmeyer <B.Beckmeyer <at> stud.hs-esslingen.de> writes: Hi Benjamin, Were you able to get this working. I do not see any of this checked in to the main stream. Can you please send me the actual patches that you applied after your fixes. Thanks & Regards, Ravi ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Ebtables NFQUEUE Support @ 2012-11-09 10:07 T L 0 siblings, 0 replies; 7+ messages in thread From: T L @ 2012-11-09 10:07 UTC (permalink / raw) To: netfilter Great! I would like to try it out and have tried to apply both patches to ebtables-v2.0.10-4, but not succeeded. I can't figure out what to do with ebtables.c, the diff seems not towards the 2.0.10-4 version. Could you provide a new patch to 2.0.10-4 version? /Torgny ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-11-11 1:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-10-19 18:32 Ebtables NFQUEUE Support Benjamin Beckmeyer 2012-10-24 5:16 ` JieYue Ma 2012-10-24 6:38 ` JieYue Ma 2012-10-24 23:39 ` Benjamin Beckmeyer 2012-10-25 5:54 ` JieYue Ma 2013-11-11 1:47 ` ravi -- strict thread matches above, loose matches on Subject: below -- 2012-11-09 10:07 T L
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox