xtables: Bootstrap xtables-arptables compatible tool for nftables
PATCH 1/1 xtables: Bootstrap xtables-arptables compatible tool for nftables
xtables: Bootstrap xtables-arptables compatible tool for nftables
--- iptables/Makefile.am | 4 iptables/nft-arptables.c | 214 ++++ iptables/nft-arptables.h | 95 ++ iptables/xtables-arptables-standalone.c | 58 + iptables/xtables-arptables.c | 1632 +++++++++++++++++++++++++++++++ iptables/xtables-multi.c | 1 iptables/xtables-multi.h | 1 7 files changed, 2004 insertions(+), 1 deletions(-) create mode 100644 iptables/nft-arptables.c create mode 100644 iptables/nft-arptables.h create mode 100644 iptables/xtables-arptables-standalone.c create mode 100644 iptables/xtables-arptables.c
iptables/Makefile.am +3 -1
@@ -31,7 +31,9 @@ xtables_multi_SOURCES += xtables-config-parser.y xtables-config-syntax.l xtables_multi_SOURCES += xtables-save.c xtables-restore.c \ xtables-standalone.c xtables.c nft.c \ nft-shared.c nft-ipv4.c nft-ipv6.c \ - xtables-config.c xtables-events.c + xtables-config.c xtables-events.c \ + nft-arptables.c xtables-arptables.c \ + xtables-arptables-standalone.c xtables_multi_LDADD += -lmnl -lnftables ${libmnl_LIBS} ${libnftables_LIBS} xtables_multi_CFLAGS += -DENABLE_NFTABLES # yacc and lex generate dirty code
iptables/nft-arptables.c new file +214 -0
214 lines not on this page · raw message
iptables/nft-arptables.h new file +95 -0
95 lines not on this page · raw message
iptables/xtables-arptables-standalone.c new file +58 -0
58 lines not on this page · raw message
iptables/xtables-arptables.c new file +1632 -0
1,632 lines not on this page · raw message
iptables/xtables-multi.c +1 -0
@@ -42,6 +42,7 @@ static const struct subcommand multi_subcommands[] = { {"xtables-restore", xtables_restore_main}, {"xtables-config", xtables_config_main}, {"xtables-events", xtables_events_main}, + {"xtables-arptables", xtables_arptables_main}, #endif {NULL}, };
iptables/xtables-multi.h +1 -0
@@ -7,5 +7,6 @@ extern int xtables_save_main(int, char **);extern int xtables_restore_main (int ,char **);extern int xtables_config_main (int ,char **);extern int xtables_events_main (int ,char **); +extern int xtables_arptables_main (int ,char **);#endif /* _XTABLES_MULTI_H */
Hi Giuseppe,
Some issues. You should take into account your previous refactoring patches. See:
Quoted 67 lines
xtables: Bootstrap xtables-arptables compatible tool for nftables
Signed-off-by Giuseppe Longo <[email protected]>--- iptables/Makefile.am | 4 iptables/nft-arptables.c | 214 ++++ iptables/nft-arptables.h | 95 ++ iptables/xtables-arptables-standalone.c | 58 + iptables/xtables-arptables.c | 1632 +++++++++++++++++++++++++++++++ iptables/xtables-multi.c | 1 iptables/xtables-multi.h | 1 7 files changed, 2004 insertions(+), 1 deletions(-)create mode 100644
iptables/nft-arptables.ccreate mode 100644iptables/nft-arptables.hcreate mode 100644iptables/xtables-arptables-standalone.ccreate mode 100644iptables/xtables-arptables.ciptables/Makefile.am +3
-1@@ -31,7 +31,9 @@ xtables_multi_SOURCES += xtables-config-parser.y xtables-config-syntax.l xtables_multi_SOURCES += xtables-save.c xtables-restore.c \ xtables-standalone.c xtables.c nft.c \ nft-shared.c nft-ipv4.c nft-ipv6.c \ - xtables-config.c xtables-events.c + xtables-config.c xtables-events.c \ + nft-arptables.c xtables-arptables.c \ + xtables-arptables-standalone.c xtables_multi_LDADD += -lmnl -lnftables ${libmnl_LIBS} ${libnftables_LIBS} xtables_multi_CFLAGS += -DENABLE_NFTABLES # yacc and lex generate dirty codeiptables/nft-arptables.c new file +29
-0@@ -0,0 +1,214 @@ +/* +* (C) 2013 by Giuseppe Longo <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +*/ + +#include <errno.h> + +#include <linux/netlink.h> +#include <linux/netfilter/nfnetlink.h> +#include <linux/netfilter/nf_tables.h> +#include <linux/netfilter/nf_tables_compat.h> + +#include <libiptc/libxtc.h> +#include <libiptc/xtcshared.h> + +#include <stdlib.h> +#include <string.h> + +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter_ipv4/ip_tables.h> +#include <linux/netfilter_ipv6/ip6_tables.h> +#include <netinet/ip6.h> + +#include <libmnl/libmnl.h> +#include <libnftables/table.h>
iptables/nft-arptables.c line 39
Quoted 10 lines
iptables/nft-arptables.c new file +10
-0+#include <libnftables/chain.h> +#include <libnftables/rule.h> +#include <libnftables/expr.h> + +#include "nft-arptables.h" +#include "xshared.h" /* proto_to_name */ +#include "nft-shared.h" +#include "xtables-config-parser.h" + +extern struct builtin_table arp_tables[TABLES_MAX ] = {
No need of extern keyword here.
Quoted 17 lines
iptables/nft-arptables.c new file +17
-0+ [FILTER] = { + .name = "filter", + .chains = { + { + .name = "INPUT", + .type = "filter", + .prio = 0, /* NF_IP_PRI_FILTER */ + .hook = NF_INET_LOCAL_IN, + }, + { + .name = "FORWARD", + .type = "filter", + .prio = 0, /* NF_IP_PRI_FILTER */ + .hook = NF_INET_FORWARD, + }, + { + .name = "OUTPUT",
iptables/nft-arptables.c line 66
Quoted 10 lines
iptables/nft-arptables.c new file +10
-0+ .type = "filter", + .prio = 0, /* NF_IP_PRI_FILTER */ + .hook = NF_INET_LOCAL_OUT, + }, + }, + }, +}; + +static int +nft_arp_chain_user_add(struct nft_handle *h, const char *chain,
No need of that function. You can use nft_chain_user_add() from nft.c, just make it public. Now that from your previous patches, nft_handle is owning the builtin_table pointer.
Quoted 78 lines
iptables/nft-arptables.c new file +78
-0+ const char *table) +{ +char buf[MNL_SOCKET_BUFFER_SIZE ]; +struct nlmsghdr *nlh; +struct nft_chain *c; +int ret; + +/* If built-in chains don't exist for this table, create them */ +if (nft_xtables_config_load (h,ARPTABLES_CONFIG_DEFAULT ,0 ) <0 ) +nft_chain_builtin_init (h, table,NULL ,NF_ACCEPT ); + +nft_chain_builtin_init (h, table,NULL ,NF_ACCEPT ); + + c =nft_chain_alloc (); +if (c ==NULL ) { +DEBUGP ("cannot allocate chain\n" ); +return -1 ; + } + +nft_chain_attr_set (c,NFT_CHAIN_ATTR_TABLE , (char *)table); +nft_chain_attr_set (c,NFT_CHAIN_ATTR_NAME , (char *)chain); + + nlh =nft_chain_nlmsg_build_hdr (buf,NFT_MSG_NEWCHAIN , h->family, +NLM_F_ACK |NLM_F_EXCL , h->seq); +nft_chain_nlmsg_build_payload (nlh, c); +nft_chain_free (c); + + ret =mnl_talk (h, nlh,NULL ,NULL ); +if (ret <0 ) { +if (errno !=EEXIST ) +perror ("mnl_talk:nft_chain_add" ); + } + +/* the core expects 1 for success and 0 for error */ +return ret ==0 ?1 :0 ; +} + +static const char *policy_name[NF_ACCEPT +1 ] = { + [NF_DROP ] ="DROP" , + [NF_ACCEPT ] ="ACCEPT" , +}; + +static void +print_header (unsigned int format,const char *chain,const char *pol, +const struct xt_counters *counters,bool basechain,uint32_t refs) +{ +printf ("Chain %s" , chain); +if (basechain) { +printf (" (policy %s" , pol); +if (!(format &FMT_NOCOUNTS )) { +fputc (' ' , stdout); +print_num (counters->pcnt, (format|FMT_NOTABLE )); +fputs ("packets, " , stdout); +print_num (counters->bcnt, (format|FMT_NOTABLE )); +fputs ("bytes" , stdout); + } +printf (")\n" ); + }else { +printf (" (%u references)\n" , refs); + } + +if (format &FMT_LINENUMBERS ) +printf (FMT ("%-4s " ,"%s " ),"num" ); +if (!(format &FMT_NOCOUNTS )) { +if (format &FMT_KILOMEGAGIGA ) { +printf (FMT ("%5s " ,"%s " ),"pkts" ); +printf (FMT ("%5s " ,"%s " ),"bytes" ); + }else { +printf (FMT ("%8s " ,"%s " ),"pkts" ); +printf (FMT ("%10s " ,"%s " ),"bytes" ); + } + } +if (!(format &FMT_NOTARGET )) +printf (FMT ("%-9s " ,"%s " ),"target" ); +fputs (" prot " , stdout); +if (format &FMT_OPTIONS ) +fputs ("opt" , stdout); +if (format &FMT_VIA ) {
iptables/nft-arptables.c line 154
Quoted 10 lines
iptables/nft-arptables.c new file +10
-0+printf (FMT (" %-6s " ,"%s " ),"in" ); +printf (FMT ("%-6s " ,"%s " ),"out" ); + } +printf (FMT (" %-19s " ,"%s " ),"source" ); +printf (FMT (" %-19s " ," %s " ),"destination" ); +printf ("\n" ); +} + +static int +nft_arp_rule_list(struct nft_handle *h, const char *chain, const char *table,
Ok here you need it, since nft_rule_list from nft.c is using internal print_headers, which is proper to xtables.c
(Though we could think of refactoring to make a generic function, let's say nft_rule_list_full() which would take in 2 more parameters: the print_headers function pointer, and the callback pointer given to __nft_rule_list() inside).
iptables/nft-arptables.c line 164
Quoted 10 lines
iptables/nft-arptables.c new file +10
-0+ int rulenum, unsigned int format) +{ +struct nft_chain_list *list; +struct nft_chain_list_iter *iter; +struct nft_chain *c; +bool found = false; + +/* If built-in chains don't exist for this table, create them */ +if (nft_xtables_config_load (h,ARPTABLES_CONFIG_DEFAULT ,0 ) <0 ) +nft_chain_builtin_init (h, table,NULL ,NF_ACCEPT );
And this is now useless since it's called once in nft_init() with your previous patches.
Quoted 192 lines
iptables/nft-arptables.c new file +50
-0+ + list =nft_chain_dump (h); + + iter =nft_chain_list_iter_create (list); +if (iter ==NULL ) { +DEBUGP ("cannot allocate rule list iterator\n" ); +return 0 ; + } + + c =nft_chain_list_iter_next (iter); +while (c !=NULL ) { +const char *chain_table = +nft_chain_attr_get_str (c,NFT_CHAIN_ATTR_TABLE ); +const char *chain_name = +nft_chain_attr_get_str (c,NFT_CHAIN_ATTR_NAME ); +uint32_t policy = +nft_chain_attr_get_u32 (c,NFT_CHAIN_ATTR_POLICY ); +uint32_t refs = +nft_chain_attr_get_u32 (c,NFT_CHAIN_ATTR_USE ); +struct xt_counters ctrs = { + .pcnt =nft_chain_attr_get_u64 (c,NFT_CHAIN_ATTR_PACKETS ), + .bcnt =nft_chain_attr_get_u64 (c,NFT_CHAIN_ATTR_BYTES ), + }; +bool basechain = false; + +if (nft_chain_attr_get (c,NFT_CHAIN_ATTR_HOOKNUM )) + basechain = true; + +if (strcmp (table, chain_table) !=0 ) + goto next; +if (chain &&strcmp (chain, chain_name) !=0 ) + goto next; + +if (found)printf ("\n" ); + +print_header (format, chain_name, policy_name[policy], &ctrs, + basechain, refs); + +//__nft_rule_list(h, c, table, rulenum, format, print_firewall); + + found = true; + +next: + c =nft_chain_list_iter_next (iter); + } + +nft_chain_list_free (list); + +return 1 ; +}iptables/nft-arptables.h new file +95
-0@@ -0,0 +1,95 @@ +/* +* (C) 2013 by Giuseppe Longo <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +*/ +#ifndef _NFT_ARPTABLES_H_ +#define _NFT_ARPTABLES_H_ + +#include "nft.h" + +typedef char arpt_chainlabel [32 ]; + +enum exittype { +OTHER_PROBLEM =1 , +PARAMETER_PROBLEM , +VERSION_PROBLEM +}; + +/*******************************/ +/* REMOVE LATER, PUT IN KERNEL */ +/*******************************/ +struct arpt_entry_match +{ +int iets; +}; + +/*******************************/ +/* END OF KERNEL REPLACEMENTS */ +/*******************************/ + +/* Include file for additions: new matches and targets. */ + +struct arptables_match +{ +struct arptables_match *next; + +arpt_chainlabel name; + +const char *version; + +/* Size of match data. */ +size_t size; + +/* Size of match data relevent for userspace comparison purposes */ +size_t userspacesize; + +/* Function which prints out usage message. */ +void (*help)(void ); + +/* Initialize the match. */ +void (*init)(struct arpt_entry_match *m,unsigned int *nfcache); + +/* Function which parses command options; returns true if it +ate an option */ +int (*parse)(int c,char **argv,int invert,unsigned int *flags, +const struct arpt_entry *entry, +unsigned int *nfcache, +struct arpt_entry_match **match); + +/* Final check; exit if not ok. */ +void (*final_check)(unsigned int flags); + +/* Prints out the match iff non-NULL: put space at end */ +void (*print)(const struct arpt_arp *ip, +const struct arpt_entry_match *match,int numeric); + +/* Saves the match info in parsable form to stdout. */ +void (*save)(const struct arpt_arp *ip, +const struct arpt_entry_match *match); + +/* Pointer to list of extra command-line options */ +const struct option *extra_opts; + +/* Ignore these men behind the curtain: */ +unsigned int option_offset; +struct arpt_entry_match *m; +unsigned int mflags; +unsigned int used; +unsigned int loaded;/* simulate loading so options are merged properly */ +}; + +const char *program_name, *program_version; + +/* For nft_arptables.c */ +int do_commandarp (struct nft_handle *h,int argc,char *argv[],char **table); + +/* +* Parse config for tables and chain helper functions +*/ +#define ARPTABLES_CONFIG_DEFAULT "/etc/arptables.conf" + +#endif iptables/xtables-arptables-standalone.c new file +35
-0@@ -0,0 +1,58 @@ +/* +* Author: [email protected] and [email protected] +* +* Based on the ipchains code by Paul Russell and Michael Neuling +* +* (C) 2000-2002 by the netfilter coreteam <[email protected]>: +* Paul 'Rusty' Russell <[email protected]> +* Marc Boucher <[email protected]> +* James Morris <[email protected]> +* Harald Welte <[email protected]> +* Jozsef Kadlecsik <[email protected]> +* +* arptables -- IP firewall administration for kernels with +* firewall table (aimed for the 2.3 kernels) +* +* See the accompanying manual page arptables(8) for information +* about proper usage of this program. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <stdio.h> +#include <stdlib.h>
iptables/xtables-arptables-standalone.c line 45
Quoted 10 lines
iptables/xtables-arptables-standalone.c new file +10
-0+#include <errno.h> +#include <string.h> +#include "nft-arptables.h" + +int +xtables_arptables_main (int argc,char *argv[]) +{ +int ret; +char *table ="filter" ; +extern struct builtin_table arp_tables[TABLES_MAX ];
No, global variable should be put as global. And anyway here you don't need it (put it in xtables-arptables.c)
iptables/xtables-arptables-standalone.c line 52
Quoted 7 lines
iptables/xtables-arptables-standalone.c new file +7
-0+struct nft_handle h = { + .family =NFPROTO_ARP , + }; + + program_name ="xtables-arptables" ; + +nft_init (&h, arp_tables,ARPTABLES_CONFIG_DEFAULT );
Don't call nft_init() here. Let do_commandarp() do this (we initialize NFT if only the command is properly parsed).
Quoted 14 lines
iptables/xtables-arptables-standalone.c new file +6
-0+ + ret =do_commandarp (&h, argc, argv, &table); + +exit (!ret); +} +iptables/xtables-arptables.c new file +2
-0@@ -0,0 +1,1632 @@ +/* Code to take an arptables-style command line and do it. */ +
(...)
Quoted 77 lines
iptables/xtables-arptables.c new file +77
-0+default : +break ; +/* FIXME: This scheme doesn't allow two of the same +matches --RR */ +/*if (!target +|| !(target->parse(c - target->option_offset, +argv, invert, +&target->tflags, +&fw, &target->t))) {*/ +/* +for (m = arptables_matches; m; m = m->next) { +if (!m->used) +continue; + +if (m->parse(c - m->option_offset, +argv, invert, +&m->mflags, +&fw, +&fw.nfcache, +&m->m)) +break; +} +*/ + +/* If you listen carefully, you can +actually hear this code suck. */ + +/* some explanations (after four different bugs +* in 3 different releases): If we encountere a +* parameter, that has not been parsed yet, +* it's not an option of an explicitly loaded +* match or a target. However, we support +* implicit loading of the protocol match +* extension. '-p tcp' means 'l4 proto 6' and +* at the same time 'load tcp protocol match on +* demand if we specify --dport'. +* +* To make this work, we need to make sure: +* - the parameter has not been parsed by +* a match (m above) +* - a protocol has been specified +* - the protocol extension has not been +* loaded yet, or is loaded and unused +* [think of arptables-restore!] +* - the protocol extension can be successively +* loaded +*/ +/* +if (m == NULL +&& protocol +&& (!find_proto(protocol, DONT_LOAD, +options&OPT_NUMERIC) +|| (find_proto(protocol, DONT_LOAD, +options&OPT_NUMERIC) +&& (proto_used == 0)) +) +&& (m = find_proto(protocol, TRY_LOAD, +options&OPT_NUMERIC))) { +Try loading protocol */ +/* +size_t size; + +proto_used = 1; + +size = ARPT_ALIGN(sizeof(struct arpt_entry_match)) ++ m->size; + +m->m = fw_calloc(1, size); +m->m->u.match_size = size; +strcpy(m->m->u.user.name, m->name); +m->init(m->m, &fw.nfcache); + +opts = merge_options(opts, +m->extra_opts, &m->option_offset); + +optind--; +continue;
iptables/xtables-arptables.c line 1429
Quoted 10 lines
iptables/xtables-arptables.c new file +10
-0+} +if (!m) +exit_error(PARAMETER_PROBLEM, +"Unknown arg `%s'", +argv[optind-1]); +*/ +//} + } + invert = FALSE; + }
You need to call nft_init() here, as in xtables.c
Cheers,
Tomasz