tags 559022 - moreinfo thanks Hello Igor!
Thanks for the additional information. Yes, it seems the xtables extension (the new iptables api) is still broken. Because the configuration tests for xtables are also broken, iproute falls back on building the old non-working iptables module for tc instead of the xtables module. Could you please test the attached patch? cd /tmp git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git wget http://fatal.se/tmp/iproute-xtables-1.4.5-rev2.diff cd iproute2 patch -p1 < ../iproute-xtables-1.4.5-rev2.diff make ./tc/tc .... On Wed, Dec 02, 2009 at 10:51:19AM +0300, Igor Bogomazov wrote: > My actions: > tc filter add dev lo parent ffff: protocol ip prio 10 u32 match u32 0 0 > flowid 1:1 action ipt -j MARK --set-mark 1 action mirred egress > redirect eth2 > I'm not using this myself and don't have detailed knowledge in this area. I couldn't get the above command to work, instead I tested with this: sudo iptables -N mark sudo ./tc/tc qdisc add dev lo ingress sudo ./tc/tc filter add dev lo parent ffff: protocol ip prio 10 u32 \ match ip src 127.1.1.1/32 \ action ipt -j MARK --set-mark 1 sudo ./tc/tc filter show parent ffff: dev lo sudo ./tc/tc qdisc del dev lo ingress Your feedback would be appreciated! PS. I've notified Jamal (of net...@vger.kernel.org fame) who has been working on this before about the issue. Hopefully we'll be able to get it solved soon. Sooner if you help. ;) -- Andreas Henriksson
diff --git a/Makefile b/Makefile index 6096a99..f8256fb 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ ADDLIB+=ipx_ntop.o ipx_pton.o CC = gcc HOSTCC = gcc -CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall +CCOPTS = -D_GNU_SOURCE -O0 -g -Wstrict-prototypes -Wall CFLAGS = $(CCOPTS) -I../include $(DEFINES) YACCFLAGS = -d -t -v diff --git a/configure b/configure index df40370..fe31391 100755 --- a/configure +++ b/configure @@ -3,12 +3,16 @@ # INCLUDE=${1:-"$PWD/include"} +TEST_DIR=$(mktemp -d iproute.XXXXXXXXXX) + +echo $TEST_DIR + echo "# Generated config based on" $INCLUDE >Config echo "TC schedulers" echo -n " ATM " -cat >/tmp/atmtest.c <<EOF +cat > $TEST_DIR/atm.c <<EOF #include <atm.h> int main(int argc, char **argv) { struct atm_qos qos; @@ -16,7 +20,7 @@ int main(int argc, char **argv) { return 0; } EOF -gcc -I$INCLUDE -o /tmp/atmtest /tmp/atmtest.c -latm >/dev/null 2>&1 +gcc -I$INCLUDE -o $TEST_DIR/atm $TEST_DIR/atm.c -latm >/dev/null 2>&1 if [ $? -eq 0 ] then echo "TC_CONFIG_ATM:=y" >>Config @@ -24,71 +28,41 @@ then else echo no fi -rm -f /tmp/atmtest.c /tmp/atmtest +rm -f $TEST_DIR/atm $TEST_DIR/atm.c echo -n " IPT " -#check if we need dont our internal header .. -cat >/tmp/ipttest.c <<EOF +#check if xtables is available. +cat > $TEST_DIR/xt.c <<EOF #include <xtables.h> +#include <linux/netfilter.h> char *lib_dir; -unsigned int global_option_offset = 0; -const char *program_version = XTABLES_VERSION; -const char *program_name = "tc-ipt"; -struct afinfo afinfo = { - .libprefix = "libxt_", +static struct xtables_globals xtparams = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = XTABLES_VERSION, + .orig_opts = NULL, + .opts = NULL, + .exit_err = NULL, }; -void exit_error(enum exittype status, const char *msg, ...) +int main(int argc, char **argv) { -} - -int main(int argc, char **argv) { + xtables_init_all(&xtparams, NFPROTO_IPV4); return 0; } EOF -gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 +gcc -I$INCLUDE $IPTC -o $TEST_DIR/xt $TEST_DIR/xt.c $IPTL -ldl -lxtables >/dev/null 2>&1 if [ $? -eq 0 ] then echo "TC_CONFIG_XT:=y" >>Config - echo "using xtables seems no need for internal.h" + echo "using xtables instead of iptables" else - echo "failed test 2" + echo "using iptables" fi -#check if we need our own internal.h -cat >/tmp/ipttest.c <<EOF -#include <xtables.h> -#include "xt-internal.h" -char *lib_dir; -unsigned int global_option_offset = 0; -const char *program_version = XTABLES_VERSION; -const char *program_name = "tc-ipt"; -struct afinfo afinfo = { - .libprefix = "libxt_", -}; - -void exit_error(enum exittype status, const char *msg, ...) -{ -} - -int main(int argc, char **argv) { - - return 0; -} - -EOF -gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 - -if [ $? -eq 0 ] -then - echo "using xtables instead of iptables (need for internal.h)" - echo "TC_CONFIG_XT_H:=y" >>Config - -else - echo "failed test 3 using iptables" -fi -rm -f /tmp/ipttest.c /tmp/ipttest +rm -f $TEST_DIR/xt $TEST_DIR/xt.c +rmdir $TEST_DIR diff --git a/tc/Makefile b/tc/Makefile index 227fc40..93b47bf 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -46,13 +46,7 @@ ifeq ($(TC_CONFIG_XT),y) TCMODULES += m_xt.o LDLIBS += -lxtables else - ifeq ($(TC_CONFIG_XT_H),y) - CFLAGS += -DTC_CONFIG_XT_H - TCMODULES += m_xt.o - LDLIBS += -lxtables - else TCMODULES += m_ipt.o - endif endif TCOBJ += $(TCMODULES) diff --git a/tc/m_xt.c b/tc/m_xt.c index d4b7a35..d16f22e 100644 --- a/tc/m_xt.c +++ b/tc/m_xt.c @@ -38,13 +38,13 @@ #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> -#ifdef TC_CONFIG_XT_H -#include "xt-internal.h" +#ifndef XT_LIB_DIR +# define XT_LIB_DIR "/lib/xtables" #endif -static const char *pname = "tc-ipt"; static const char *tname = "mangle"; -static const char *pversion = "0.2"; + +char *lib_dir; static const char *ipthooks[] = { "NF_IP_PRE_ROUTING", @@ -55,113 +55,23 @@ static const char *ipthooks[] = { }; static struct option original_opts[] = { - {"jump", 1, 0, 'j'}, + { + .name = "jump", + .has_arg = 1, + .val = 'j' + }, {0, 0, 0, 0} }; -static struct option *opts = original_opts; -static unsigned int global_option_offset = 0; -char *lib_dir; -const char *program_version = XTABLES_VERSION; -const char *program_name = "tc-ipt"; -struct afinfo afinfo = { - .family = AF_INET, - .libprefix = "libxt_", - .ipproto = IPPROTO_IP, - .kmod = "ip_tables", - .so_rev_target = IPT_SO_GET_REVISION_TARGET, +static struct xtables_globals tcipt_globals = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = "0.2", + .orig_opts = original_opts, + .opts = original_opts, + .exit_err = NULL, }; - -#define OPTION_OFFSET 256 - -/*XXX: TC_CONFIG_XT_H */ -static void free_opts(struct option *local_opts) -{ - if (local_opts != original_opts) { - free(local_opts); - opts = original_opts; - global_option_offset = 0; - } -} - -/*XXX: TC_CONFIG_XT_H */ -static struct option * -merge_options(struct option *oldopts, const struct option *newopts, - unsigned int *option_offset) -{ - struct option *merge; - unsigned int num_old, num_new, i; - - for (num_old = 0; oldopts[num_old].name; num_old++) ; - for (num_new = 0; newopts[num_new].name; num_new++) ; - - *option_offset = global_option_offset + OPTION_OFFSET; - - merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); - memcpy(merge, oldopts, num_old * sizeof (struct option)); - for (i = 0; i < num_new; i++) { - merge[num_old + i] = newopts[i]; - merge[num_old + i].val += *option_offset; - } - memset(merge + num_old + num_new, 0, sizeof (struct option)); - - return merge; -} - - -/*XXX: TC_CONFIG_XT_H */ -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/*XXX: TC_CONFIG_XT_H */ -int -check_inverse(const char option[], int *invert, int *my_optind, int argc) -{ - if (option && strcmp(option, "!") == 0) { - if (*invert) - exit_error(PARAMETER_PROBLEM, - "Multiple `!' flags not allowed"); - *invert = TRUE; - if (my_optind != NULL) { - ++*my_optind; - if (argc && *my_optind > argc) - exit_error(PARAMETER_PROBLEM, - "no argument following `!'"); - } - - return TRUE; - } - return FALSE; -} - -/*XXX: TC_CONFIG_XT_H */ -void exit_error(enum exittype status, const char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "%s v%s: ", pname, pversion); - vfprintf(stderr, msg, args); - va_end(args); - fprintf(stderr, "\n"); - /* On error paths, make sure that we don't leak memory */ - exit(status); -} - -/*XXX: TC_CONFIG_XT_H */ -static void set_revision(char *name, u_int8_t revision) -{ - /* Old kernel sources don't have ".revision" field, - * but we stole a byte from name. */ - name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; - name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; -} - /* * we may need to check for version mismatch */ @@ -173,10 +83,10 @@ build_st(struct xtables_target *target, struct xt_entry_target *t) XT_ALIGN(sizeof (struct xt_entry_target)) + target->size; if (NULL == t) { - target->t = fw_calloc(1, size); + target->t = xtables_calloc(1, size); target->t->u.target_size = size; strcpy(target->t->u.user.name, target->name); - set_revision(target->t->u.user.name, target->revision); + xtables_set_revision(target->t->u.user.name, target->revision); if (target->init != NULL) target->init(target->t); @@ -218,6 +128,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, __u32 hook = 0, index = 0; res = 0; + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); set_lib_dir(); { @@ -236,21 +147,22 @@ static int parse_ipt(struct action_util *a,int *argc_p, } while (1) { - c = getopt_long(argc, argv, "j:", opts, NULL); + c = getopt_long(argc, argv, "j:", tcipt_globals.opts, NULL); if (c == -1) break; switch (c) { case 'j': - m = find_target(optarg, TRY_LOAD); + m = xtables_find_target(optarg, XTF_TRY_LOAD); if (NULL != m) { if (0 > build_st(m, NULL)) { printf(" %s error \n", m->name); return -1; } - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); } else { fprintf(stderr," failed to find target %s\n\n", optarg); return -1; @@ -278,7 +190,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, if (matches(argv[optind], "index") == 0) { if (get_u32(&index, argv[optind + 1], 10)) { fprintf(stderr, "Illegal \"index\"\n"); - free_opts(opts); + xtables_free_opts(1); return -1; } iok++; @@ -293,7 +205,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, } /* check that we passed the correct parameters to the target */ - if (m) + if (m && m->final_check) m->final_check(m->tflags); { @@ -336,7 +248,7 @@ static int parse_ipt(struct action_util *a,int *argc_p, *argv_p = argv; optind = 0; - free_opts(opts); + xtables_free_opts(1); /* Clear flags if target will be used again */ m->tflags=0; m->used=0; @@ -358,6 +270,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) if (arg == NULL) return -1; + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); set_lib_dir(); parse_rtattr_nested(tb, TCA_IPT_MAX, arg); @@ -384,16 +297,17 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) } else { struct xtables_target *m = NULL; t = RTA_DATA(tb[TCA_IPT_TARG]); - m = find_target(t->u.user.name, TRY_LOAD); + m = xtables_find_target(t->u.user.name, XTF_TRY_LOAD); if (NULL != m) { if (0 > build_st(m, t)) { fprintf(stderr, " %s error \n", m->name); return -1; } - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); } else { fprintf(stderr, " failed to find target %s\n\n", t->u.user.name); @@ -422,7 +336,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) fprintf(f, " \n"); } - free_opts(opts); + xtables_free_opts(1); return 0; }
signature.asc
Description: Digital signature