From patchwork Wed Apr 11 08:24:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Westphal X-Patchwork-Id: 897089 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=strlen.de Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LcbQ3mF9z9s3D for ; Wed, 11 Apr 2018 18:27:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750743AbeDKI1N (ORCPT ); Wed, 11 Apr 2018 04:27:13 -0400 Received: from Chamillionaire.breakpoint.cc ([146.0.238.67]:54374 "EHLO Chamillionaire.breakpoint.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750734AbeDKI1L (ORCPT ); Wed, 11 Apr 2018 04:27:11 -0400 Received: from fw by Chamillionaire.breakpoint.cc with local (Exim 4.89) (envelope-from ) id 1f6B5x-00051q-RA; Wed, 11 Apr 2018 10:27:09 +0200 From: Florian Westphal To: Cc: Florian Westphal Subject: [PATCH iptables] ebtables-compat: add initial translations Date: Wed, 11 Apr 2018 10:24:37 +0200 Message-Id: <20180411082437.7369-1-fw@strlen.de> X-Mailer: git-send-email 2.16.1 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org add translations for ip, limit, log, mark, mark_m, nflog. Signed-off-by: Florian Westphal --- NB: No tests yet, I need to implement 'ebtables-translate' first :-) extensions/libebt_ip.c | 128 +++++++++++++++++++++++++++++++++++++++++++++ extensions/libebt_limit.c | 26 +++++++++ extensions/libebt_log.c | 22 ++++++++ extensions/libebt_mark.c | 44 ++++++++++++++++ extensions/libebt_mark_m.c | 25 +++++++++ extensions/libebt_nflog.c | 25 +++++++++ 6 files changed, 270 insertions(+) diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c index 4ca63e939066..1a87585c533f 100644 --- a/extensions/libebt_ip.c +++ b/extensions/libebt_ip.c @@ -291,6 +291,133 @@ static void brip_print(const void *ip, const struct xt_entry_match *match, } } +static const char *brip_xlate_proto_to_name(uint8_t proto) +{ + switch (proto) { + case IPPROTO_TCP: + return "tcp"; + case IPPROTO_UDP: + return "udp"; + case IPPROTO_UDPLITE: + return "udplite"; + case IPPROTO_SCTP: + return "sctp"; + case IPPROTO_DCCP: + return "dccp"; + default: + return NULL; + } +} + +static void brip_xlate_th(struct xt_xlate *xl, + const struct ebt_ip_info *info, int bit, + const char *pname) +{ + const uint16_t *ports; + + if ((info->bitmask & bit) == 0) + return; + + switch (bit) { + case EBT_IP_SPORT: + if (pname) + xt_xlate_add(xl, "%s sport ", pname); + else + xt_xlate_add(xl, "@th,0,16 "); + + ports = info->sport; + break; + case EBT_IP_DPORT: + if (pname) + xt_xlate_add(xl, "%s dport ", pname); + else + xt_xlate_add(xl, "@th,16,16 "); + + ports = info->dport; + break; + default: + return; + } + + if (info->invflags & bit) + xt_xlate_add(xl, "!= "); + + if (ports[0] == ports[1]) + xt_xlate_add(xl, "%d ", ports[0]); + else + xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]); +} + +static void brip_xlate_nh(struct xt_xlate *xl, + const struct ebt_ip_info *info, int bit) +{ + struct in_addr *addrp, *maskp; + + if ((info->bitmask & bit) == 0) + return; + + switch (bit) { + case EBT_IP_SOURCE: + xt_xlate_add(xl, "ip saddr "); + addrp = (struct in_addr *)&info->saddr; + maskp = (struct in_addr *)&info->smsk; + break; + case EBT_IP_DEST: + xt_xlate_add(xl, "ip daddr "); + addrp = (struct in_addr *)&info->daddr; + maskp = (struct in_addr *)&info->dmsk; + break; + default: + return; + } + + if (info->invflags & bit) + xt_xlate_add(xl, "!= "); + + xt_xlate_add(xl, "%s%s ", xtables_ipaddr_to_numeric(addrp), + xtables_ipmask_to_numeric(maskp)); +} + +static int brip_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) +{ + const struct ebt_ip_info *info = (const void *)params->match->data; + const char *pname = NULL; + + brip_xlate_nh(xl, info, EBT_IP_SOURCE); + brip_xlate_nh(xl, info, EBT_IP_DEST); + + if (info->bitmask & EBT_IP_TOS) { + xt_xlate_add(xl, "ip dscp "); + if (info->invflags & EBT_IP_TOS) + xt_xlate_add(xl, "!= "); + xt_xlate_add(xl, "0x%02X ", info->tos & ~0x3); /* remove ECN bits */ + } + if (info->bitmask & EBT_IP_PROTO) { + struct protoent *pe; + + if (info->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) && + (info->invflags & EBT_IP_PROTO) == 0) { + /* port number given and not inverted, no need to print this */ + pname = brip_xlate_proto_to_name(info->protocol); + } else { + xt_xlate_add(xl, "ip protocol "); + if (info->invflags & EBT_IP_PROTO) + xt_xlate_add(xl, "!= "); + pe = getprotobynumber(info->protocol); + if (pe == NULL) + xt_xlate_add(xl, "%d ", info->protocol); + else + xt_xlate_add(xl, "%s ", pe->p_name); + } + } + + brip_xlate_th(xl, info, EBT_IP_SPORT, pname); + brip_xlate_th(xl, info, EBT_IP_DPORT, pname); + + return 1; +} + static struct xtables_match brip_match = { .name = "ip", .revision = 0, @@ -303,6 +430,7 @@ static struct xtables_match brip_match = { .parse = brip_parse, .final_check = brip_final_check, .print = brip_print, + .xlate = brip_xlate, .extra_opts = brip_opts, }; diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c index 988f678a5169..75c066bf694c 100644 --- a/extensions/libebt_limit.c +++ b/extensions/libebt_limit.c @@ -159,6 +159,31 @@ static void brlimit_print(const void *ip, const struct xt_entry_match *match, printf("--limit-burst %u ", r->burst); } +static void print_rate_xlate(struct xt_xlate *xl, uint32_t period) +{ + unsigned int i; + + for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++) + if (period > g_rates[i].mult || + g_rates[i].mult/period < g_rates[i].mult%period) + break; + + xt_xlate_add(xl, "%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name); +} + +static int brlimit_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) +{ + const struct ebt_limit_info *r = (const void *)params->match->data; + + xt_xlate_add(xl, "limit rate "); + print_rate_xlate(xl, r->avg); + if (r->burst != 0) + xt_xlate_add(xl, " burst %u packets", r->burst); + + return 1; +} + static struct xtables_match brlimit_match = { .name = "limit", .revision = 0, @@ -170,6 +195,7 @@ static struct xtables_match brlimit_match = { .help = brlimit_print_help, .parse = brlimit_parse, .print = brlimit_print, + .xlate = brlimit_xlate, .extra_opts = brlimit_opts, }; diff --git a/extensions/libebt_log.c b/extensions/libebt_log.c index f170af0334ee..a86bdebaaae0 100644 --- a/extensions/libebt_log.c +++ b/extensions/libebt_log.c @@ -176,6 +176,27 @@ static void brlog_print(const void *ip, const struct xt_entry_target *target, printf(" "); } +static int brlog_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct ebt_log_info *loginfo = (const void *)params->target->data; + + xt_xlate_add(xl, "log"); + if (loginfo->prefix[0]) { + if (params->escape_quotes) + xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); + else + xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); + } + + if (loginfo->loglevel != LOG_DEFAULT_LEVEL) + xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name); + + xt_xlate_add(xl, " flags ether "); + + return 1; +} + static struct xtables_target brlog_target = { .name = "log", .revision = 0, @@ -188,6 +209,7 @@ static struct xtables_target brlog_target = { .parse = brlog_parse, .final_check = brlog_final_check, .print = brlog_print, + .xlate = brlog_xlate, .extra_opts = brlog_opts, }; diff --git a/extensions/libebt_mark.c b/extensions/libebt_mark.c index 7b80b22e63c0..94f489e37e01 100644 --- a/extensions/libebt_mark.c +++ b/extensions/libebt_mark.c @@ -170,6 +170,49 @@ static void brmark_final_check(unsigned int flags) "You must specify some option"); } +static const char* brmark_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 brmark_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct ebt_mark_t_info *info = (const void*)params->target->data; + int tmp; + + tmp = info->target & ~EBT_VERDICT_BITS; + + xt_xlate_add(xl, "meta mark set "); + + switch (tmp) { + case MARK_SET_VALUE: + break; + case MARK_OR_VALUE: + xt_xlate_add(xl, "meta mark or "); + break; + case MARK_XOR_VALUE: + xt_xlate_add(xl, "meta mark xor "); + break; + case MARK_AND_VALUE: + xt_xlate_add(xl, "meta mark and "); + break; + default: + return 0; + } + + tmp = info->target & EBT_VERDICT_BITS; + xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp)); + return 1; +} + static struct xtables_target brmark_target = { .name = "mark", .revision = 0, @@ -182,6 +225,7 @@ static struct xtables_target brmark_target = { .parse = brmark_parse, .final_check = brmark_final_check, .print = brmark_print, + .xlate = brmark_xlate, .extra_opts = brmark_opts, }; diff --git a/extensions/libebt_mark_m.c b/extensions/libebt_mark_m.c index eb08dbabbb46..1e8d21db5e2e 100644 --- a/extensions/libebt_mark_m.c +++ b/extensions/libebt_mark_m.c @@ -97,6 +97,30 @@ static void brmark_m_print(const void *ip, const struct xt_entry_match *match, printf("0x%lx ", info->mark); } +static int brmark_m_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) +{ + const struct ebt_mark_m_info *info = (const void*)params->match->data; + enum xt_op op = XT_OP_EQ; + + if (info->invert) + op = XT_OP_NEQ; + + xt_xlate_add(xl, "meta mark "); + + if (info->bitmask == EBT_MARK_OR) { + xt_xlate_add(xl, " and %0x%x %s0", info->mask, + info->invert ? "" : "!= "); + } else if (info->mask != 0xffffffffU) { + xt_xlate_add(xl, " and 0x%x %s 0x%x", info->mask, + op == XT_OP_EQ ? "==" : "!=", info->mark); + } else { + xt_xlate_add(xl, " %s0x%x", + op == XT_OP_EQ ? "" : "!= ", info->mark); + } + + return 1; +} static struct xtables_match brmark_m_match = { .name = "mark_m", .revision = 0, @@ -109,6 +133,7 @@ static struct xtables_match brmark_m_match = { .parse = brmark_m_parse, .final_check = brmark_m_final_check, .print = brmark_m_print, + .xlate = brmark_m_xlate, .extra_opts = brmark_m_opts, }; diff --git a/extensions/libebt_nflog.c b/extensions/libebt_nflog.c index 5f1d13b1251a..57f092919cf9 100644 --- a/extensions/libebt_nflog.c +++ b/extensions/libebt_nflog.c @@ -124,6 +124,30 @@ brnflog_print(const void *ip, const struct xt_entry_target *target, printf("--nflog-threshold %d ", info->threshold); } +static int brnflog_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct ebt_nflog_info *info = (void *)params->target->data; + + xt_xlate_add(xl, "log "); + if (info->prefix[0] != '\0') { + if (params->escape_quotes) + xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix); + else + xt_xlate_add(xl, "prefix \"%s\" ", info->prefix); + + } + + xt_xlate_add(xl, "group %u ", info->group); + + if (info->len) + xt_xlate_add(xl, "snaplen %u ", info->len); + if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD) + xt_xlate_add(xl, "queue-threshold %u ", info->threshold); + + return 1; +} + static struct xtables_target brnflog_watcher = { .name = "nflog", .revision = 0, @@ -135,6 +159,7 @@ static struct xtables_target brnflog_watcher = { .help = brnflog_help, .parse = brnflog_parse, .print = brnflog_print, + .xlate = brnflog_xlate, .extra_opts = brnflog_opts, };