From 24ce7465056ae1a8e29405e58849c15860999f39 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 10 Apr 2018 11:15:26 +0200 Subject: ebtables-compat: add redirect match extension No translation. The kernel match will alter packet type (meta set pkttype), but also replace dst mac with the bridges' mac address, however nft currently doesn't allow to retrieve this at runtime. So just add this without the xlate part for now. Signed-off-by: Florian Westphal --- extensions/libebt_redirect.c | 109 +++++++++++++++++++++++++++++++++++++++++++ iptables/xtables-eb.c | 1 + 2 files changed, 110 insertions(+) create mode 100644 extensions/libebt_redirect.c diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c new file mode 100644 index 00000000..a88713d3 --- /dev/null +++ b/extensions/libebt_redirect.c @@ -0,0 +1,109 @@ +/* ebt_redirect + * + * Authors: + * Bart De Schuymer + * + * April, 2002 + */ + +#include +#include +#include +#include +#include +#include +#include "iptables/nft.h" +#include "iptables/nft-bridge.h" + +#define REDIRECT_TARGET '1' +static const struct option brredir_opts[] = +{ + { "redirect-target", required_argument, 0, REDIRECT_TARGET }, + { 0 } +}; + +static void brredir_print_help(void) +{ + printf( + "redirect option:\n" + " --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n"); +} + +static void brredir_init(struct xt_entry_target *target) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)target->data; + + redirectinfo->target = EBT_ACCEPT; +} + +#define OPT_REDIRECT_TARGET 0x01 +static int brredir_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)(*target)->data; + + switch (c) { + case REDIRECT_TARGET: + EBT_CHECK_OPTION(flags, OPT_REDIRECT_TARGET); + if (ebt_fill_target(optarg, (unsigned int *)&redirectinfo->target)) + xtables_error(PARAMETER_PROBLEM, "Illegal --redirect-target target"); + break; + default: + return 0; + } + return 1; +} + +static void brredir_print(const void *ip, const struct xt_entry_target *target, int numeric) +{ + struct ebt_redirect_info *redirectinfo = + (struct ebt_redirect_info *)target->data; + + if (redirectinfo->target == EBT_ACCEPT) + return; + printf(" --redirect-target %s", ebt_target_name(redirectinfo->target)); +} + +static const char* brredir_verdict(int verdict) +{ + switch (verdict) { + case EBT_ACCEPT: return "accept"; + case EBT_DROP: return "drop"; + case EBT_CONTINUE: return "continue"; + case EBT_RETURN: return "return"; + } + + return ""; +} + +static int brredir_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct ebt_redirect_info *red = (const void*)params->target->data; + + xt_xlate_add(xl, "meta set pkttype host"); + if (red->target != EBT_ACCEPT) + xt_xlate_add(xl, " %s ", brredir_verdict(red->target)); + return 0; +} + +static struct xtables_target brredirect_target = { + .name = "redirect", + .version = XTABLES_VERSION, + .family = NFPROTO_BRIDGE, + .size = XT_ALIGN(sizeof(struct ebt_redirect_info)), + .userspacesize = XT_ALIGN(sizeof(struct ebt_redirect_info)), + .help = brredir_print_help, + .init = brredir_init, + .parse = brredir_parse, + .print = brredir_print, + .xlate = brredir_xlate, + .extra_opts = brredir_opts, +}; + +void _init(void) +{ + xtables_register_target(&brredirect_target); +} diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c index a72c9073..1230125f 100644 --- a/iptables/xtables-eb.c +++ b/iptables/xtables-eb.c @@ -678,6 +678,7 @@ void ebt_load_match_extensions(void) ebt_load_target("mark"); ebt_load_target("dnat"); ebt_load_target("snat"); + ebt_load_target("redirect"); } void ebt_add_match(struct xtables_match *m, -- cgit v1.2.3