Commit 6343d369 authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

New upstream version 1.8.7

parent 9caffe92
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for iptables 1.8.6. # Generated by GNU Autoconf 2.69 for iptables 1.8.7.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
...@@ -587,8 +587,8 @@ MAKEFLAGS= ...@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='iptables' PACKAGE_NAME='iptables'
PACKAGE_TARNAME='iptables' PACKAGE_TARNAME='iptables'
PACKAGE_VERSION='1.8.6' PACKAGE_VERSION='1.8.7'
PACKAGE_STRING='iptables 1.8.6' PACKAGE_STRING='iptables 1.8.7'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
...@@ -1406,7 +1406,7 @@ if test "$ac_init_help" = "long"; then ...@@ -1406,7 +1406,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures iptables 1.8.6 to adapt to many kinds of systems. \`configure' configures iptables 1.8.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
...@@ -1477,7 +1477,7 @@ fi ...@@ -1477,7 +1477,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of iptables 1.8.6:";; short | recursive ) echo "Configuration of iptables 1.8.7:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
...@@ -1628,7 +1628,7 @@ fi ...@@ -1628,7 +1628,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
iptables configure 1.8.6 iptables configure 1.8.7
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
...@@ -2176,7 +2176,7 @@ cat >config.log <<_ACEOF ...@@ -2176,7 +2176,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by iptables $as_me 1.8.6, which was It was created by iptables $as_me 1.8.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
...@@ -2526,8 +2526,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ...@@ -2526,8 +2526,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# See libtool.info "Libtool's versioning system" # See libtool.info "Libtool's versioning system"
libxtables_vcurrent=15 libxtables_vcurrent=16
libxtables_vage=3 libxtables_vage=4
ac_aux_dir= ac_aux_dir=
for ac_dir in build-aux "$srcdir"/build-aux; do for ac_dir in build-aux "$srcdir"/build-aux; do
...@@ -3047,7 +3047,7 @@ fi ...@@ -3047,7 +3047,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='iptables' PACKAGE='iptables'
VERSION='1.8.6' VERSION='1.8.7'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
...@@ -13880,7 +13880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ...@@ -13880,7 +13880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by iptables $as_me 1.8.6, which was This file was extended by iptables $as_me 1.8.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
...@@ -13946,7 +13946,7 @@ _ACEOF ...@@ -13946,7 +13946,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
iptables config.status 1.8.6 iptables config.status 1.8.7
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
......
AC_INIT([iptables], [1.8.6]) AC_INIT([iptables], [1.8.7])
# See libtool.info "Libtool's versioning system" # See libtool.info "Libtool's versioning system"
libxtables_vcurrent=15 libxtables_vcurrent=16
libxtables_vage=3 libxtables_vage=4
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
......
...@@ -130,15 +130,6 @@ static void arpmangle_final_check(unsigned int flags) ...@@ -130,15 +130,6 @@ static void arpmangle_final_check(unsigned int flags)
{ {
} }
static void print_mac(const unsigned char *mac, int l)
{
int j;
for (j = 0; j < l; j++)
printf("%02x%s", mac[j],
(j==l-1) ? "" : ":");
}
static const char *ipaddr_to(const struct in_addr *addrp, int numeric) static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
{ {
if (numeric) if (numeric)
...@@ -159,7 +150,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target, ...@@ -159,7 +150,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
} }
if (m->flags & ARPT_MANGLE_SDEV) { if (m->flags & ARPT_MANGLE_SDEV) {
printf(" --mangle-mac-s "); printf(" --mangle-mac-s ");
print_mac((unsigned char *)m->src_devaddr, 6); xtables_print_mac((unsigned char *)m->src_devaddr);
} }
if (m->flags & ARPT_MANGLE_TIP) { if (m->flags & ARPT_MANGLE_TIP) {
printf(" --mangle-ip-d %s", printf(" --mangle-ip-d %s",
...@@ -167,7 +158,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target, ...@@ -167,7 +158,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
} }
if (m->flags & ARPT_MANGLE_TDEV) { if (m->flags & ARPT_MANGLE_TDEV) {
printf(" --mangle-mac-d "); printf(" --mangle-mac-d ");
print_mac((unsigned char *)m->tgt_devaddr, 6); xtables_print_mac((unsigned char *)m->tgt_devaddr);
} }
if (m->target != NF_ACCEPT) { if (m->target != NF_ACCEPT) {
printf(" --mangle-target %s", printf(" --mangle-target %s",
......
...@@ -161,54 +161,6 @@ static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk) ...@@ -161,54 +161,6 @@ static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
*addr = *addr & *msk; *addr = *addr & *msk;
} }
static int brarp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask)
{
char *p;
int i;
struct ether_addr *addr = NULL;
static const unsigned char mac_type_unicast[ETH_ALEN];
static const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0};
static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
if (strcasecmp(from, "Unicast") == 0) {
memcpy(to, mac_type_unicast, ETH_ALEN);
memcpy(mask, msk_type_unicast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "Multicast") == 0) {
memcpy(to, mac_type_multicast, ETH_ALEN);
memcpy(mask, mac_type_multicast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "Broadcast") == 0) {
memcpy(to, mac_type_broadcast, ETH_ALEN);
memcpy(mask, mac_type_broadcast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "BGA") == 0) {
memcpy(to, mac_type_bridge_group, ETH_ALEN);
memcpy(mask, msk_type_bridge_group, ETH_ALEN);
return 0;
}
if ( (p = strrchr(from, '/')) != NULL) {
*p = '\0';
if (!(addr = ether_aton(p + 1)))
return -1;
memcpy(mask, addr, ETH_ALEN);
} else
memset(mask, 0xff, ETH_ALEN);
if (!(addr = ether_aton(from)))
return -1;
memcpy(to, addr, ETH_ALEN);
for (i = 0; i < ETH_ALEN; i++)
to[i] &= mask[i];
return 0;
}
static int static int
brarp_parse(int c, char **argv, int invert, unsigned int *flags, brarp_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match) const void *entry, struct xt_entry_match **match)
...@@ -317,7 +269,7 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags, ...@@ -317,7 +269,7 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags,
else else
arpinfo->invflags |= EBT_ARP_DST_MAC; arpinfo->invflags |= EBT_ARP_DST_MAC;
} }
if (brarp_get_mac_and_mask(optarg, maddr, mmask)) if (xtables_parse_mac_and_mask(optarg, maddr, mmask))
xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument"); xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument");
break; break;
case ARP_GRAT: case ARP_GRAT:
......
...@@ -150,54 +150,6 @@ static void print_range(unsigned int l, unsigned int u) ...@@ -150,54 +150,6 @@ static void print_range(unsigned int l, unsigned int u)
printf("%u:%u ", l, u); printf("%u:%u ", l, u);
} }
static int brstp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask)
{
char *p;
int i;
struct ether_addr *addr = NULL;
static const unsigned char mac_type_unicast[ETH_ALEN];
static const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0};
static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
if (strcasecmp(from, "Unicast") == 0) {
memcpy(to, mac_type_unicast, ETH_ALEN);
memcpy(mask, msk_type_unicast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "Multicast") == 0) {
memcpy(to, mac_type_multicast, ETH_ALEN);
memcpy(mask, mac_type_multicast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "Broadcast") == 0) {
memcpy(to, mac_type_broadcast, ETH_ALEN);
memcpy(mask, mac_type_broadcast, ETH_ALEN);
return 0;
}
if (strcasecmp(from, "BGA") == 0) {
memcpy(to, mac_type_bridge_group, ETH_ALEN);
memcpy(mask, msk_type_bridge_group, ETH_ALEN);
return 0;
}
if ( (p = strrchr(from, '/')) != NULL) {
*p = '\0';
if (!(addr = ether_aton(p + 1)))
return -1;
memcpy(mask, addr, ETH_ALEN);
} else
memset(mask, 0xff, ETH_ALEN);
if (!(addr = ether_aton(from)))
return -1;
memcpy(to, addr, ETH_ALEN);
for (i = 0; i < ETH_ALEN; i++)
to[i] &= mask[i];
return 0;
}
static int static int
brstp_parse(int c, char **argv, int invert, unsigned int *flags, brstp_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match) const void *entry, struct xt_entry_match **match)
...@@ -280,15 +232,15 @@ brstp_parse(int c, char **argv, int invert, unsigned int *flags, ...@@ -280,15 +232,15 @@ brstp_parse(int c, char **argv, int invert, unsigned int *flags,
xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range"); xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range");
break; break;
case EBT_STP_ROOTADDR: case EBT_STP_ROOTADDR:
if (brstp_get_mac_and_mask(argv[optind-1], if (xtables_parse_mac_and_mask(argv[optind-1],
(unsigned char *)stpinfo->config.root_addr, stpinfo->config.root_addr,
(unsigned char *)stpinfo->config.root_addrmsk)) stpinfo->config.root_addrmsk))
xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address"); xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address");
break; break;
case EBT_STP_SENDERADDR: case EBT_STP_SENDERADDR:
if (brstp_get_mac_and_mask(argv[optind-1], if (xtables_parse_mac_and_mask(argv[optind-1],
(unsigned char *)stpinfo->config.sender_addr, stpinfo->config.sender_addr,
(unsigned char *)stpinfo->config.sender_addrmsk)) stpinfo->config.sender_addrmsk))
xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address"); xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address");
break; break;
default: default:
......
...@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = { ...@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
[DCCP_PKT_INVALID] = "INVALID", [DCCP_PKT_INVALID] = "INVALID",
}; };
/* Bits for type values 11-15 */
#define INVALID_OTHER_TYPE_MASK 0xf800
static uint16_t static uint16_t
parse_dccp_types(const char *typestring) parse_dccp_types(const char *typestring)
{ {
...@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring) ...@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Unknown DCCP type `%s'", ptr); "Unknown DCCP type `%s'", ptr);
} }
if (typemask & (1 << DCCP_PKT_INVALID))
typemask |= INVALID_OTHER_TYPE_MASK;
free(buffer); free(buffer);
return typemask; return typemask;
...@@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric) ...@@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric)
if (numeric) if (numeric)
printf("%u", i); printf("%u", i);
else else {
printf("%s", dccp_pkt_types[i]); printf("%s", dccp_pkt_types[i]);
if (i == DCCP_PKT_INVALID)
break;
}
types &= ~(1 << i); types &= ~(1 << i);
} }
} }
...@@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = { ...@@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = {
[DCCP_PKT_RESET] = "reset", [DCCP_PKT_RESET] = "reset",
[DCCP_PKT_SYNC] = "sync", [DCCP_PKT_SYNC] = "sync",
[DCCP_PKT_SYNCACK] = "syncack", [DCCP_PKT_SYNCACK] = "syncack",
[DCCP_PKT_INVALID] = "10-15",
}; };
static int dccp_type_xlate(const struct xt_dccp_info *einfo, static int dccp_type_xlate(const struct xt_dccp_info *einfo,
...@@ -296,10 +307,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo, ...@@ -296,10 +307,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo,
bool have_type = false, set_need = false; bool have_type = false, set_need = false;
uint16_t types = einfo->typemask; uint16_t types = einfo->typemask;
if (types & (1 << DCCP_PKT_INVALID)) if (types & INVALID_OTHER_TYPE_MASK) {
return 0; types &= ~INVALID_OTHER_TYPE_MASK;
types |= 1 << DCCP_PKT_INVALID;
xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : ""); }
if ((types != 0) && !(types == (types & -types))) { if ((types != 0) && !(types == (types & -types))) {
xt_xlate_add(xl, "{"); xt_xlate_add(xl, "{");
...@@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl, ...@@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl,
char *space = ""; char *space = "";
int ret = 1; int ret = 1;
xt_xlate_add(xl, "dccp ");
if (einfo->flags & XT_DCCP_SRC_PORTS) { if (einfo->flags & XT_DCCP_SRC_PORTS) {
if (einfo->spts[0] != einfo->spts[1]) xt_xlate_add(xl, "dccp sport%s %u",
xt_xlate_add(xl, "sport%s %u-%u",
einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
einfo->spts[0], einfo->spts[1]);
else
xt_xlate_add(xl, "sport%s %u",
einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "", einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
einfo->spts[0]); einfo->spts[0]);
if (einfo->spts[0] != einfo->spts[1])
xt_xlate_add(xl, "-%u", einfo->spts[1]);
space = " "; space = " ";
} }
if (einfo->flags & XT_DCCP_DEST_PORTS) { if (einfo->flags & XT_DCCP_DEST_PORTS) {
if (einfo->dpts[0] != einfo->dpts[1]) xt_xlate_add(xl, "%sdccp dport%s %u", space,
xt_xlate_add(xl, "%sdport%s %u-%u", space,
einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
einfo->dpts[0], einfo->dpts[1]);
else
xt_xlate_add(xl, "%sdport%s %u", space,
einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "", einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
einfo->dpts[0]); einfo->dpts[0]);
if (einfo->dpts[0] != einfo->dpts[1])
xt_xlate_add(xl, "-%u", einfo->dpts[1]);
space = " ";
} }
if (einfo->flags & XT_DCCP_TYPE) if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
xt_xlate_add(xl, "%sdccp type%s ", space,
einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
ret = dccp_type_xlate(einfo, xl); ret = dccp_type_xlate(einfo, xl);
space = " ";
}
/* FIXME: no dccp option support in nftables yet */
if (einfo->flags & XT_DCCP_OPTION) if (einfo->flags & XT_DCCP_OPTION)
ret = 0; ret = 0;
......
...@@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter ...@@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter
iptables-translate -A INPUT -p dccp -m dccp ! --dport 100 iptables-translate -A INPUT -p dccp -m dccp ! --dport 100
nft add rule ip filter INPUT dccp dport != 100 counter nft add rule ip filter INPUT dccp dport != 100 counter
iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter nft add rule ip filter INPUT dccp type close counter
iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID
nft add rule ip filter INPUT dccp type 10-15 counter
iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID
nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter
iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100 iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100
nft add rule ip filter INPUT dccp sport 200 dport 100 counter nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
...@@ -37,15 +37,6 @@ static void mac_parse(struct xt_option_call *cb) ...@@ -37,15 +37,6 @@ static void mac_parse(struct xt_option_call *cb)
macinfo->invert = 1; macinfo->invert = 1;
} }
static void print_mac(const unsigned char *macaddress)
{
unsigned int i;
printf(" %02X", macaddress[0]);
for (i = 1; i < ETH_ALEN; ++i)
printf(":%02X", macaddress[i]);
}
static void static void
mac_print(const void *ip, const struct xt_entry_match *match, int numeric) mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
{ {
...@@ -56,7 +47,7 @@ mac_print(const void *ip, const struct xt_entry_match *match, int numeric) ...@@ -56,7 +47,7 @@ mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
if (info->invert) if (info->invert)
printf(" !"); printf(" !");
print_mac(info->srcaddr); xtables_print_mac(info->srcaddr);
} }
static void mac_save(const void *ip, const struct xt_entry_match *match) static void mac_save(const void *ip, const struct xt_entry_match *match)
...@@ -66,8 +57,8 @@ static void mac_save(const void *ip, const struct xt_entry_match *match) ...@@ -66,8 +57,8 @@ static void mac_save(const void *ip, const struct xt_entry_match *match)
if (info->invert) if (info->invert)
printf(" !"); printf(" !");
printf(" --mac-source"); printf(" --mac-source ");
print_mac(info->srcaddr); xtables_print_mac(info->srcaddr);
} }
static void print_mac_xlate(const unsigned char *macaddress, static void print_mac_xlate(const unsigned char *macaddress,
......
...@@ -557,6 +557,9 @@ extern void xtables_save_string(const char *value); ...@@ -557,6 +557,9 @@ extern void xtables_save_string(const char *value);
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab)) #define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
extern void xtables_print_num(uint64_t number, unsigned int format); extern void xtables_print_num(uint64_t number, unsigned int format);
extern int xtables_parse_mac_and_mask(const char *from, void *to, void *mask);
extern int xtables_print_well_known_mac_and_mask(const void *mac,
const void *mask);
extern void xtables_print_mac(const unsigned char *macaddress); extern void xtables_print_mac(const unsigned char *macaddress);
extern void xtables_print_mac_and_mask(const unsigned char *mac, extern void xtables_print_mac_and_mask(const unsigned char *mac,
const unsigned char *mask); const unsigned char *mask);
......
...@@ -310,7 +310,7 @@ def show_missing(): ...@@ -310,7 +310,7 @@ def show_missing():
# #
def main(): def main():
parser = argparse.ArgumentParser(description='Run iptables tests') parser = argparse.ArgumentParser(description='Run iptables tests')
parser.add_argument('filename', nargs='?', parser.add_argument('filename', nargs='*',
metavar='path/to/file.t', metavar='path/to/file.t',
help='Run only this test') help='Run only this test')
parser.add_argument('-H', '--host', action='store_true', parser.add_argument('-H', '--host', action='store_true',
...@@ -359,13 +359,20 @@ def main(): ...@@ -359,13 +359,20 @@ def main():
return return
if args.filename: if args.filename:
file_list = [args.filename] file_list = args.filename
else: else:
file_list = [os.path.join(EXTENSIONS_PATH, i) file_list = [os.path.join(EXTENSIONS_PATH, i)
for i in os.listdir(EXTENSIONS_PATH) for i in os.listdir(EXTENSIONS_PATH)
if i.endswith('.t')] if i.endswith('.t')]
file_list.sort() file_list.sort()
if not args.netns:
try:
import unshare
unshare.unshare(unshare.CLONE_NEWNET)
except:
print("Cannot run in own namespace, connectivity might break")
for filename in file_list: for filename in file_list:
file_tests, file_passed = run_test_file(filename, args.netns) file_tests, file_passed = run_test_file(filename, args.netns)
if file_tests: if file_tests:
......
...@@ -38,7 +38,7 @@ xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \ ...@@ -38,7 +38,7 @@ xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \
nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \ nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \
xtables-monitor.c nft-cache.c \ xtables-monitor.c nft-cache.c \
xtables-arp-standalone.c xtables-arp.c \ xtables-arp-standalone.c xtables-arp.c \
nft-bridge.c nft-cmd.c \ nft-bridge.c nft-cmd.c nft-chain.c \
xtables-eb-standalone.c xtables-eb.c \ xtables-eb-standalone.c xtables-eb.c \
xtables-eb-translate.c \ xtables-eb-translate.c \
xtables-translate.c xtables-translate.c
......
...@@ -158,8 +158,8 @@ am__xtables_nft_multi_SOURCES_DIST = xtables-nft-multi.c \ ...@@ -158,8 +158,8 @@ am__xtables_nft_multi_SOURCES_DIST = xtables-nft-multi.c \
xtables-standalone.c xtables.c nft.c nft-shared.c nft-ipv4.c \ xtables-standalone.c xtables.c nft.c nft-shared.c nft-ipv4.c \
nft-ipv6.c nft-arp.c xtables-monitor.c nft-cache.c \ nft-ipv6.c nft-arp.c xtables-monitor.c nft-cache.c \
xtables-arp-standalone.c xtables-arp.c nft-bridge.c nft-cmd.c \ xtables-arp-standalone.c xtables-arp.c nft-bridge.c nft-cmd.c \
xtables-eb-standalone.c xtables-eb.c xtables-eb-translate.c \ nft-chain.c xtables-eb-standalone.c xtables-eb.c \
xtables-translate.c xshared.c xtables-eb-translate.c xtables-translate.c xshared.c
@ENABLE_NFTABLES_TRUE@am_xtables_nft_multi_OBJECTS = xtables_nft_multi-xtables-nft-multi.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@am_xtables_nft_multi_OBJECTS = xtables_nft_multi-xtables-nft-multi.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-iptables-xml.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-iptables-xml.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-save.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-save.$(OBJEXT) \
...@@ -177,6 +177,7 @@ am__xtables_nft_multi_SOURCES_DIST = xtables-nft-multi.c \ ...@@ -177,6 +177,7 @@ am__xtables_nft_multi_SOURCES_DIST = xtables-nft-multi.c \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-arp.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-arp.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-bridge.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-bridge.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-cmd.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-cmd.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-chain.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-standalone.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-standalone.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-translate.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-translate.$(OBJEXT) \
...@@ -256,6 +257,7 @@ am__depfiles_remade = \ ...@@ -256,6 +257,7 @@ am__depfiles_remade = \
./$(DEPDIR)/xtables_nft_multi-nft-arp.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po \
./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po \
./$(DEPDIR)/xtables_nft_multi-nft-cache.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po \
./$(DEPDIR)/xtables_nft_multi-nft-chain.Po \
./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po \
./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po \
./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po \
...@@ -497,8 +499,8 @@ xtables_legacy_multi_LDADD = ../extensions/libext.a $(am__append_4) \ ...@@ -497,8 +499,8 @@ xtables_legacy_multi_LDADD = ../extensions/libext.a $(am__append_4) \
@ENABLE_NFTABLES_TRUE@ nft-ipv6.c nft-arp.c xtables-monitor.c \ @ENABLE_NFTABLES_TRUE@ nft-ipv6.c nft-arp.c xtables-monitor.c \
@ENABLE_NFTABLES_TRUE@ nft-cache.c xtables-arp-standalone.c \ @ENABLE_NFTABLES_TRUE@ nft-cache.c xtables-arp-standalone.c \
@ENABLE_NFTABLES_TRUE@ xtables-arp.c nft-bridge.c nft-cmd.c \ @ENABLE_NFTABLES_TRUE@ xtables-arp.c nft-bridge.c nft-cmd.c \
@ENABLE_NFTABLES_TRUE@ xtables-eb-standalone.c xtables-eb.c \ @ENABLE_NFTABLES_TRUE@ nft-chain.c xtables-eb-standalone.c \
@ENABLE_NFTABLES_TRUE@ xtables-eb-translate.c \ @ENABLE_NFTABLES_TRUE@ xtables-eb.c xtables-eb-translate.c \
@ENABLE_NFTABLES_TRUE@ xtables-translate.c xshared.c @ENABLE_NFTABLES_TRUE@ xtables-translate.c xshared.c
@ENABLE_NFTABLES_TRUE@xtables_nft_multi_CFLAGS = ${AM_CFLAGS} \ @ENABLE_NFTABLES_TRUE@xtables_nft_multi_CFLAGS = ${AM_CFLAGS} \
@ENABLE_NFTABLES_TRUE@ $(am__append_8) -DENABLE_NFTABLES \ @ENABLE_NFTABLES_TRUE@ $(am__append_8) -DENABLE_NFTABLES \
...@@ -707,6 +709,7 @@ distclean-compile: ...@@ -707,6 +709,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-arp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-arp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cache.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cache.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-chain.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po@am__quote@ # am--include-marker
...@@ -1117,6 +1120,20 @@ xtables_nft_multi-nft-cmd.obj: nft-cmd.c ...@@ -1117,6 +1120,20 @@ xtables_nft_multi-nft-cmd.obj: nft-cmd.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-cmd.obj `if test -f 'nft-cmd.c'; then $(CYGPATH_W) 'nft-cmd.c'; else $(CYGPATH_W) '$(srcdir)/nft-cmd.c'; fi` @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-cmd.obj `if test -f 'nft-cmd.c'; then $(CYGPATH_W) 'nft-cmd.c'; else $(CYGPATH_W) '$(srcdir)/nft-cmd.c'; fi`
xtables_nft_multi-nft-chain.o: nft-chain.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-nft-chain.o -MD -MP -MF $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo -c -o xtables_nft_multi-nft-chain.o `test -f 'nft-chain.c' || echo '$(srcdir)/'`nft-chain.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo $(DEPDIR)/xtables_nft_multi-nft-chain.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nft-chain.c' object='xtables_nft_multi-nft-chain.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-chain.o `test -f 'nft-chain.c' || echo '$(srcdir)/'`nft-chain.c
xtables_nft_multi-nft-chain.obj: nft-chain.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-nft-chain.obj -MD -MP -MF $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo -c -o xtables_nft_multi-nft-chain.obj `if test -f 'nft-chain.c'; then $(CYGPATH_W) 'nft-chain.c'; else $(CYGPATH_W) '$(srcdir)/nft-chain.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo $(DEPDIR)/xtables_nft_multi-nft-chain.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nft-chain.c' object='xtables_nft_multi-nft-chain.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-chain.obj `if test -f 'nft-chain.c'; then $(CYGPATH_W) 'nft-chain.c'; else $(CYGPATH_W) '$(srcdir)/nft-chain.c'; fi`
xtables_nft_multi-xtables-eb-standalone.o: xtables-eb-standalone.c xtables_nft_multi-xtables-eb-standalone.o: xtables-eb-standalone.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-xtables-eb-standalone.o -MD -MP -MF $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo -c -o xtables_nft_multi-xtables-eb-standalone.o `test -f 'xtables-eb-standalone.c' || echo '$(srcdir)/'`xtables-eb-standalone.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-xtables-eb-standalone.o -MD -MP -MF $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo -c -o xtables_nft_multi-xtables-eb-standalone.o `test -f 'xtables-eb-standalone.c' || echo '$(srcdir)/'`xtables-eb-standalone.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Po @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Po
...@@ -1445,6 +1462,7 @@ distclean: distclean-am ...@@ -1445,6 +1462,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-chain.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po
...@@ -1522,6 +1540,7 @@ maintainer-clean: maintainer-clean-am ...@@ -1522,6 +1540,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-chain.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po
......
...@@ -45,10 +45,6 @@ ...@@ -45,10 +45,6 @@
#include "ip6tables-multi.h" #include "ip6tables-multi.h"
#include "xshared.h" #include "xshared.h"
#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
static const char optflags[]
= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'};
static const char unsupported_rev[] = " [unsupported revision]"; static const char unsupported_rev[] = " [unsupported revision]";
static struct option original_opts[] = { static struct option original_opts[] = {
...@@ -100,36 +96,6 @@ struct xtables_globals ip6tables_globals = { ...@@ -100,36 +96,6 @@ struct xtables_globals ip6tables_globals = {
.compat_rev = xtables_compatible_revision, .compat_rev = xtables_compatible_revision,
}; };
/* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal (applies to
* CMD_LIST and CMD_ZERO only).
* Key:
* + compulsory
* x illegal
* optional
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/* Well, it's better than "Re: Linux vs FreeBSD" */
{
/* -n -s -d -p -j -v -x -i -o --line -c */
/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x'},
/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x'},
/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' '},
/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x'},
/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
};
static const unsigned int inverse_for_options[NUMBER_OF_OPT] = static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
{ {
/* -n */ 0, /* -n */ 0,
...@@ -264,51 +230,6 @@ ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...) ...@@ -264,51 +230,6 @@ ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...)
exit(status); exit(status);
} }
static void
generic_opt_check(int command, int options)
{
int i, j, legal = 0;
/* Check that commands are valid with options. Complicated by the
* fact that if an option is legal with *any* command given, it is
* legal overall (ie. -z and -l).
*/
for (i = 0; i < NUMBER_OF_OPT; i++) {
legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
for (j = 0; j < NUMBER_OF_CMD; j++) {
if (!(command & (1<<j)))
continue;
if (!(options & (1<<i))) {
if (commands_v_options[j][i] == '+')
xtables_error(PARAMETER_PROBLEM,
"You need to supply the `-%c' "
"option for this command\n",
optflags[i]);
} else {
if (commands_v_options[j][i] != 'x')
legal = 1;
else if (legal == 0)
legal = -1;
}
}
if (legal == -1)
xtables_error(PARAMETER_PROBLEM,
"Illegal option `-%c' with this command\n",
optflags[i]);
}
}
static char
opt2char(int option)
{
const char *ptr;
for (ptr = optflags; option > 1; option >>= 1, ptr++);
return *ptr;
}
/* /*
* All functions starting with "parse" should succeed, otherwise * All functions starting with "parse" should succeed, otherwise
* the program fails. * the program fails.
......
...@@ -41,11 +41,6 @@ ...@@ -41,11 +41,6 @@
#include <fcntl.h> #include <fcntl.h>
#include "xshared.h" #include "xshared.h"
#define OPT_FRAGMENT 0x00800U
#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
static const char optflags[]
= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
static const char unsupported_rev[] = " [unsupported revision]"; static const char unsupported_rev[] = " [unsupported revision]";
static struct option original_opts[] = { static struct option original_opts[] = {
...@@ -99,36 +94,6 @@ struct xtables_globals iptables_globals = { ...@@ -99,36 +94,6 @@ struct xtables_globals iptables_globals = {
.compat_rev = xtables_compatible_revision, .compat_rev = xtables_compatible_revision,
}; };
/* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal (applies to
* CMD_LIST and CMD_ZERO only).
* Key:
* + compulsory
* x illegal
* optional
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
/* Well, it's better than "Re: Linux vs FreeBSD" */
{
/* -n -s -d -p -j -v -x -i -o --line -c -f */
/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'},
/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'},
/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
};
static const int inverse_for_options[NUMBER_OF_OPT] = static const int inverse_for_options[NUMBER_OF_OPT] =
{ {
/* -n */ 0, /* -n */ 0,
...@@ -263,51 +228,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...) ...@@ -263,51 +228,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...)
exit(status); exit(status);
} }
static void
generic_opt_check(int command, int options)
{
int i, j, legal = 0;
/* Check that commands are valid with options. Complicated by the
* fact that if an option is legal with *any* command given, it is
* legal overall (ie. -z and -l).
*/
for (i = 0; i < NUMBER_OF_OPT; i++) {
legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
for (j = 0; j < NUMBER_OF_CMD; j++) {
if (!(command & (1<<j)))
continue;
if (!(options & (1<<i))) {
if (commands_v_options[j][i] == '+')
xtables_error(PARAMETER_PROBLEM,
"You need to supply the `-%c' "
"option for this command\n",
optflags[i]);
} else {
if (commands_v_options[j][i] != 'x')
legal = 1;
else if (legal == 0)
legal = -1;
}
}
if (legal == -1)
xtables_error(PARAMETER_PROBLEM,
"Illegal option `-%c' with this command\n",
optflags[i]);
}
}
static char
opt2char(int option)
{
const char *ptr;
for (ptr = optflags; option > 1; option >>= 1, ptr++);
return *ptr;
}
/* /*
* All functions starting with "parse" should succeed, otherwise * All functions starting with "parse" should succeed, otherwise
* the program fails. * the program fails.
......
...@@ -134,34 +134,34 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ...@@ -134,34 +134,34 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
int ret = 0; int ret = 0;
if (fw->arp.iniface[0] != '\0') { if (fw->arp.iniface[0] != '\0') {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN);
add_iniface(r, fw->arp.iniface, op); add_iniface(r, fw->arp.iniface, op);
} }
if (fw->arp.outiface[0] != '\0') { if (fw->arp.outiface[0] != '\0') {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT);
add_outiface(r, fw->arp.outiface, op); add_outiface(r, fw->arp.outiface, op);
} }
if (fw->arp.arhrd != 0 || if (fw->arp.arhrd != 0 ||
fw->arp.invflags & ARPT_INV_ARPHRD) { fw->arp.invflags & IPT_INV_ARPHRD) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
add_payload(r, offsetof(struct arphdr, ar_hrd), 2, add_payload(r, offsetof(struct arphdr, ar_hrd), 2,
NFT_PAYLOAD_NETWORK_HEADER); NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arhrd, op); add_cmp_u16(r, fw->arp.arhrd, op);
} }
if (fw->arp.arpro != 0 || if (fw->arp.arpro != 0 ||
fw->arp.invflags & ARPT_INV_ARPPRO) { fw->arp.invflags & IPT_INV_PROTO) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
add_payload(r, offsetof(struct arphdr, ar_pro), 2, add_payload(r, offsetof(struct arphdr, ar_pro), 2,
NFT_PAYLOAD_NETWORK_HEADER); NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpro, op); add_cmp_u16(r, fw->arp.arpro, op);
} }
if (fw->arp.arhln != 0 || if (fw->arp.arhln != 0 ||
fw->arp.invflags & ARPT_INV_ARPHLN) { fw->arp.invflags & IPT_INV_ARPHLN) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN);
add_proto(r, offsetof(struct arphdr, ar_hln), 1, add_proto(r, offsetof(struct arphdr, ar_hln), 1,
fw->arp.arhln, op); fw->arp.arhln, op);
} }
...@@ -169,16 +169,17 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ...@@ -169,16 +169,17 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ); add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
if (fw->arp.arpop != 0 || if (fw->arp.arpop != 0 ||
fw->arp.invflags & ARPT_INV_ARPOP) { fw->arp.invflags & IPT_INV_ARPOP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
add_payload(r, offsetof(struct arphdr, ar_op), 2, add_payload(r, offsetof(struct arphdr, ar_op), 2,
NFT_PAYLOAD_NETWORK_HEADER); NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpop, op); add_cmp_u16(r, fw->arp.arpop, op);
} }
if (need_devaddr(&fw->arp.src_devaddr)) { if (need_devaddr(&fw->arp.src_devaddr)) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR);
add_addr(r, sizeof(struct arphdr), add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr),
&fw->arp.src_devaddr.addr, &fw->arp.src_devaddr.addr,
&fw->arp.src_devaddr.mask, &fw->arp.src_devaddr.mask,
fw->arp.arhln, op); fw->arp.arhln, op);
...@@ -187,17 +188,19 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ...@@ -187,17 +188,19 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
if (fw->arp.src.s_addr != 0 || if (fw->arp.src.s_addr != 0 ||
fw->arp.smsk.s_addr != 0 || fw->arp.smsk.s_addr != 0 ||
fw->arp.invflags & ARPT_INV_SRCIP) { fw->arp.invflags & IPT_INV_SRCIP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln, add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr) + fw->arp.arhln,
&fw->arp.src.s_addr, &fw->arp.smsk.s_addr, &fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
sizeof(struct in_addr), op); sizeof(struct in_addr), op);
} }
if (need_devaddr(&fw->arp.tgt_devaddr)) { if (need_devaddr(&fw->arp.tgt_devaddr)) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr), add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
&fw->arp.tgt_devaddr.addr, &fw->arp.tgt_devaddr.addr,
&fw->arp.tgt_devaddr.mask, &fw->arp.tgt_devaddr.mask,
fw->arp.arhln, op); fw->arp.arhln, op);
...@@ -205,9 +208,10 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ...@@ -205,9 +208,10 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
if (fw->arp.tgt.s_addr != 0 || if (fw->arp.tgt.s_addr != 0 ||
fw->arp.tmsk.s_addr != 0 || fw->arp.tmsk.s_addr != 0 ||
fw->arp.invflags & ARPT_INV_TGTIP) { fw->arp.invflags & IPT_INV_DSTIP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP); op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln, add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
&fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr, &fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
sizeof(struct in_addr), op); sizeof(struct in_addr), op);
} }
...@@ -236,28 +240,6 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ...@@ -236,28 +240,6 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
return ret; return ret;
} }
static uint16_t ipt_to_arpt_flags(uint8_t invflags)
{
uint16_t result = 0;
if (invflags & IPT_INV_VIA_IN)
result |= ARPT_INV_VIA_IN;
if (invflags & IPT_INV_VIA_OUT)
result |= ARPT_INV_VIA_OUT;
if (invflags & IPT_INV_SRCIP)
result |= ARPT_INV_SRCIP;
if (invflags & IPT_INV_DSTIP)
result |= ARPT_INV_TGTIP;
if (invflags & IPT_INV_PROTO)
result |= ARPT_INV_ARPPRO;
return result;
}
static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e, static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
void *data) void *data)
{ {
...@@ -269,7 +251,7 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e, ...@@ -269,7 +251,7 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
fw->arp.outiface, fw->arp.outiface_mask, fw->arp.outiface, fw->arp.outiface_mask,
&flags); &flags);
fw->arp.invflags |= ipt_to_arpt_flags(flags); fw->arp.invflags |= flags;
} }
static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto, static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
...@@ -303,7 +285,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx, ...@@ -303,7 +285,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx,
memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN); memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE; ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else { } else {
memset(info->mask, 0xff, ETH_ALEN); memset(info->mask, 0xff,
min(ctx->payload.len, ETH_ALEN));
} }
return inv; return inv;
...@@ -325,33 +308,33 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, ...@@ -325,33 +308,33 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
fw->arp.arhrd = ar_hrd; fw->arp.arhrd = ar_hrd;
fw->arp.arhrd_mask = 0xffff; fw->arp.arhrd_mask = 0xffff;
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_ARPHRD; fw->arp.invflags |= IPT_INV_ARPHRD;
break; break;
case offsetof(struct arphdr, ar_pro): case offsetof(struct arphdr, ar_pro):
get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv); get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
fw->arp.arpro = ar_pro; fw->arp.arpro = ar_pro;
fw->arp.arpro_mask = 0xffff; fw->arp.arpro_mask = 0xffff;
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_ARPPRO; fw->arp.invflags |= IPT_INV_PROTO;
break; break;
case offsetof(struct arphdr, ar_op): case offsetof(struct arphdr, ar_op):
get_cmp_data(e, &ar_op, sizeof(ar_op), &inv); get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
fw->arp.arpop = ar_op; fw->arp.arpop = ar_op;
fw->arp.arpop_mask = 0xffff; fw->arp.arpop_mask = 0xffff;
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_ARPOP; fw->arp.invflags |= IPT_INV_ARPOP;
break; break;
case offsetof(struct arphdr, ar_hln): case offsetof(struct arphdr, ar_hln):
get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv); get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
fw->arp.arhln = ar_hln; fw->arp.arhln = ar_hln;
fw->arp.arhln_mask = 0xff; fw->arp.arhln_mask = 0xff;
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_ARPOP; fw->arp.invflags |= IPT_INV_ARPOP;
break; break;
default: default:
if (ctx->payload.offset == sizeof(struct arphdr)) { if (ctx->payload.offset == sizeof(struct arphdr)) {
if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr)) if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr))
fw->arp.invflags |= ARPT_INV_SRCDEVADDR; fw->arp.invflags |= IPT_INV_SRCDEVADDR;
} else if (ctx->payload.offset == sizeof(struct arphdr) + } else if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln) { fw->arp.arhln) {
get_cmp_data(e, &addr, sizeof(addr), &inv); get_cmp_data(e, &addr, sizeof(addr), &inv);
...@@ -360,16 +343,18 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, ...@@ -360,16 +343,18 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
parse_mask_ipv4(ctx, &fw->arp.smsk); parse_mask_ipv4(ctx, &fw->arp.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE; ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else { } else {
fw->arp.smsk.s_addr = 0xffffffff; memset(&fw->arp.smsk, 0xff,
min(ctx->payload.len,
sizeof(struct in_addr)));
} }
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_SRCIP; fw->arp.invflags |= IPT_INV_SRCIP;
} else if (ctx->payload.offset == sizeof(struct arphdr) + } else if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln + fw->arp.arhln +
sizeof(struct in_addr)) { sizeof(struct in_addr)) {
if (nft_arp_parse_devaddr(ctx, e, &fw->arp.tgt_devaddr)) if (nft_arp_parse_devaddr(ctx, e, &fw->arp.tgt_devaddr))
fw->arp.invflags |= ARPT_INV_TGTDEVADDR; fw->arp.invflags |= IPT_INV_TGTDEVADDR;
} else if (ctx->payload.offset == sizeof(struct arphdr) + } else if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln + fw->arp.arhln +
sizeof(struct in_addr) + sizeof(struct in_addr) +
...@@ -380,11 +365,13 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, ...@@ -380,11 +365,13 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
parse_mask_ipv4(ctx, &fw->arp.tmsk); parse_mask_ipv4(ctx, &fw->arp.tmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE; ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else { } else {
fw->arp.tmsk.s_addr = 0xffffffff; memset(&fw->arp.tmsk, 0xff,
min(ctx->payload.len,
sizeof(struct in_addr)));
} }
if (inv) if (inv)
fw->arp.invflags |= ARPT_INV_TGTIP; fw->arp.invflags |= IPT_INV_DSTIP;
} }
break; break;
} }
...@@ -439,7 +426,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, ...@@ -439,7 +426,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
else strcat(iface, "any"); else strcat(iface, "any");
} }
if (print_iface) { if (print_iface) {
printf("%s%s-i %s", sep, fw->arp.invflags & ARPT_INV_VIA_IN ? printf("%s%s-i %s", sep, fw->arp.invflags & IPT_INV_VIA_IN ?
"! " : "", iface); "! " : "", iface);
sep = " "; sep = " ";
} }
...@@ -457,13 +444,13 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, ...@@ -457,13 +444,13 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
else strcat(iface, "any"); else strcat(iface, "any");
} }
if (print_iface) { if (print_iface) {
printf("%s%s-o %s", sep, fw->arp.invflags & ARPT_INV_VIA_OUT ? printf("%s%s-o %s", sep, fw->arp.invflags & IPT_INV_VIA_OUT ?
"! " : "", iface); "! " : "", iface);
sep = " "; sep = " ";
} }
if (fw->arp.smsk.s_addr != 0L) { if (fw->arp.smsk.s_addr != 0L) {
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCIP printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCIP
? "! " : ""); ? "! " : "");
if (format & FMT_NUMERIC) if (format & FMT_NUMERIC)
sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src))); sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src)));
...@@ -480,7 +467,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, ...@@ -480,7 +467,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
break; break;
if (i == ARPT_DEV_ADDR_LEN_MAX) if (i == ARPT_DEV_ADDR_LEN_MAX)
goto after_devsrc; goto after_devsrc;
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCDEVADDR printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCDEVADDR
? "! " : ""); ? "! " : "");
printf("--src-mac "); printf("--src-mac ");
xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr, xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr,
...@@ -489,7 +476,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, ...@@ -489,7 +476,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
after_devsrc: after_devsrc:
if (fw->arp.tmsk.s_addr != 0L) { if (fw->arp.tmsk.s_addr != 0L) {
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTIP printf("%s%s", sep, fw->arp.invflags & IPT_INV_DSTIP
? "! " : ""); ? "! " : "");
if (format & FMT_NUMERIC) if (format & FMT_NUMERIC)
sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt))); sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt)));
...@@ -506,7 +493,7 @@ after_devsrc: ...@@ -506,7 +493,7 @@ after_devsrc:
break; break;
if (i == ARPT_DEV_ADDR_LEN_MAX) if (i == ARPT_DEV_ADDR_LEN_MAX)
goto after_devdst; goto after_devdst;
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTDEVADDR printf("%s%s", sep, fw->arp.invflags & IPT_INV_TGTDEVADDR
? "! " : ""); ? "! " : "");
printf("--dst-mac "); printf("--dst-mac ");
xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr, xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
...@@ -516,7 +503,7 @@ after_devsrc: ...@@ -516,7 +503,7 @@ after_devsrc:
after_devdst: after_devdst:
if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) { if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) {
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN
? "! " : ""); ? "! " : "");
printf("--h-length %d", fw->arp.arhln); printf("--h-length %d", fw->arp.arhln);
if (fw->arp.arhln_mask != 255) if (fw->arp.arhln_mask != 255)
...@@ -527,7 +514,7 @@ after_devdst: ...@@ -527,7 +514,7 @@ after_devdst:
if (fw->arp.arpop_mask != 0) { if (fw->arp.arpop_mask != 0) {
int tmp = ntohs(fw->arp.arpop); int tmp = ntohs(fw->arp.arpop);
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPOP printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPOP
? "! " : ""); ? "! " : "");
if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC)) if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC))
printf("--opcode %s", arp_opcodes[tmp-1]); printf("--opcode %s", arp_opcodes[tmp-1]);
...@@ -542,7 +529,7 @@ after_devdst: ...@@ -542,7 +529,7 @@ after_devdst:
if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) { if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) {
uint16_t tmp = ntohs(fw->arp.arhrd); uint16_t tmp = ntohs(fw->arp.arhrd);
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD
? "! " : ""); ? "! " : "");
if (tmp == 1 && !(format & FMT_NUMERIC)) if (tmp == 1 && !(format & FMT_NUMERIC))
printf("--h-type %s", "Ethernet"); printf("--h-type %s", "Ethernet");
...@@ -556,7 +543,7 @@ after_devdst: ...@@ -556,7 +543,7 @@ after_devdst:
if (fw->arp.arpro_mask != 0) { if (fw->arp.arpro_mask != 0) {
int tmp = ntohs(fw->arp.arpro); int tmp = ntohs(fw->arp.arpro);
printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPPRO printf("%s%s", sep, fw->arp.invflags & IPT_INV_PROTO
? "! " : ""); ? "! " : "");
if (tmp == 0x0800 && !(format & FMT_NUMERIC)) if (tmp == 0x0800 && !(format & FMT_NUMERIC))
printf("--proto-type %s", "IPv4"); printf("--proto-type %s", "IPv4");
......
...@@ -4,4 +4,11 @@ ...@@ -4,4 +4,11 @@
extern char *arp_opcodes[]; extern char *arp_opcodes[];
#define NUMOPCODES 9 #define NUMOPCODES 9
/* define invflags which won't collide with IPT ones */
#define IPT_INV_SRCDEVADDR 0x0080
#define IPT_INV_TGTDEVADDR 0x0100
#define IPT_INV_ARPHLN 0x0200
#define IPT_INV_ARPOP 0x0400
#define IPT_INV_ARPHRD 0x0800
#endif #endif
...@@ -58,44 +58,11 @@ void ebt_cs_clean(struct iptables_command_state *cs) ...@@ -58,44 +58,11 @@ void ebt_cs_clean(struct iptables_command_state *cs)
} }
} }
static void ebt_print_mac(const unsigned char *mac)
{
int j;
for (j = 0; j < ETH_ALEN; j++)
printf("%02x%s", mac[j], (j==ETH_ALEN-1) ? "" : ":");
}
static bool mac_all_ones(const unsigned char *mac)
{
static const char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
return memcmp(mac, hlpmsk, sizeof(hlpmsk)) == 0;
}
/* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */ /* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */
static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask) static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
{ {
if (xtables_print_well_known_mac_and_mask(mac, mask))
if (!memcmp(mac, eb_mac_type_unicast, 6) && xtables_print_mac_and_mask(mac, mask);
!memcmp(mask, eb_msk_type_unicast, 6))
printf("Unicast");
else if (!memcmp(mac, eb_mac_type_multicast, 6) &&
!memcmp(mask, eb_msk_type_multicast, 6))
printf("Multicast");
else if (!memcmp(mac, eb_mac_type_broadcast, 6) &&
!memcmp(mask, eb_msk_type_broadcast, 6))
printf("Broadcast");
else if (!memcmp(mac, eb_mac_type_bridge_group, 6) &&
!memcmp(mask, eb_msk_type_bridge_group, 6))
printf("BGA");
else {
ebt_print_mac(mac);
if (!mac_all_ones(mask)) {
printf("/");
ebt_print_mac(mask);
}
}
} }
static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op) static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
...@@ -159,20 +126,16 @@ static int nft_bridge_add(struct nft_handle *h, ...@@ -159,20 +126,16 @@ static int nft_bridge_add(struct nft_handle *h,
if (fw->bitmask & EBT_ISOURCE) { if (fw->bitmask & EBT_ISOURCE) {
op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE); op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE);
add_payload(r, offsetof(struct ethhdr, h_source), 6, add_addr(r, NFT_PAYLOAD_LL_HEADER,
NFT_PAYLOAD_LL_HEADER); offsetof(struct ethhdr, h_source),
if (!mac_all_ones(fw->sourcemsk)) fw->sourcemac, fw->sourcemsk, ETH_ALEN, op);
add_bitwise(r, fw->sourcemsk, 6);
add_cmp_ptr(r, op, fw->sourcemac, 6);
} }
if (fw->bitmask & EBT_IDEST) { if (fw->bitmask & EBT_IDEST) {
op = nft_invflags2cmp(fw->invflags, EBT_IDEST); op = nft_invflags2cmp(fw->invflags, EBT_IDEST);
add_payload(r, offsetof(struct ethhdr, h_dest), 6, add_addr(r, NFT_PAYLOAD_LL_HEADER,
NFT_PAYLOAD_LL_HEADER); offsetof(struct ethhdr, h_dest),
if (!mac_all_ones(fw->destmsk)) fw->destmac, fw->destmsk, ETH_ALEN, op);
add_bitwise(r, fw->destmsk, 6);
add_cmp_ptr(r, op, fw->destmac, 6);
} }
if ((fw->bitmask & EBT_NOPROTO) == 0) { if ((fw->bitmask & EBT_NOPROTO) == 0) {
...@@ -258,7 +221,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, ...@@ -258,7 +221,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN); memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE; ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else { } else {
memset(&fw->destmsk, 0xff, ETH_ALEN); memset(&fw->destmsk, 0xff,
min(ctx->payload.len, ETH_ALEN));
} }
fw->bitmask |= EBT_IDEST; fw->bitmask |= EBT_IDEST;
break; break;
...@@ -272,7 +236,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, ...@@ -272,7 +236,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN); memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE; ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else { } else {
memset(&fw->sourcemsk, 0xff, ETH_ALEN); memset(&fw->sourcemsk, 0xff,
min(ctx->payload.len, ETH_ALEN));
} }
fw->bitmask |= EBT_ISOURCE; fw->bitmask |= EBT_ISOURCE;
break; break;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "nft.h" #include "nft.h"
#include "nft-cache.h" #include "nft-cache.h"
#include "nft-chain.h"
static void cache_chain_list_insert(struct list_head *list, const char *name) static void cache_chain_list_insert(struct list_head *list, const char *name)
{ {
...@@ -153,9 +154,7 @@ static int fetch_table_cache(struct nft_handle *h) ...@@ -153,9 +154,7 @@ static int fetch_table_cache(struct nft_handle *h)
if (!h->tables[i].name) if (!h->tables[i].name)
continue; continue;
h->cache->table[type].chains = nftnl_chain_list_alloc(); h->cache->table[type].chains = nft_chain_list_alloc();
if (!h->cache->table[type].chains)
return 0;
h->cache->table[type].sets = nftnl_set_list_alloc(); h->cache->table[type].sets = nftnl_set_list_alloc();
if (!h->cache->table[type].sets) if (!h->cache->table[type].sets)
...@@ -165,6 +164,83 @@ static int fetch_table_cache(struct nft_handle *h) ...@@ -165,6 +164,83 @@ static int fetch_table_cache(struct nft_handle *h)
return 1; return 1;
} }
static uint32_t djb_hash(const char *key)
{
uint32_t i, hash = 5381;
for (i = 0; i < strlen(key); i++)
hash = ((hash << 5) + hash) + key[i];
return hash;
}
static struct hlist_head *chain_name_hlist(struct nft_handle *h,
const struct builtin_table *t,
const char *chain)
{
int key = djb_hash(chain) % CHAIN_NAME_HSIZE;
return &h->cache->table[t->type].chains->names[key];
}
struct nft_chain *
nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
{
const struct builtin_table *t;
struct hlist_node *node;
struct nft_chain *c;
t = nft_table_builtin_find(h, table);
if (!t)
return NULL;
hlist_for_each_entry(c, node, chain_name_hlist(h, t, chain), hnode) {
if (!strcmp(nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME),
chain))
return c;
}
return NULL;
}
int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t,
struct nftnl_chain *c)
{
const char *cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
struct nft_chain *nc = nft_chain_alloc(c);
if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
uint32_t hooknum = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM);
if (hooknum >= NF_INET_NUMHOOKS) {
nft_chain_free(nc);
return -EINVAL;
}
if (h->cache->table[t->type].base_chains[hooknum]) {
nft_chain_free(nc);
return -EEXIST;
}
h->cache->table[t->type].base_chains[hooknum] = nc;
} else {
struct nft_chain_list *clist = h->cache->table[t->type].chains;
struct list_head *pos = &clist->list;
struct nft_chain *cur;
const char *n;
list_for_each_entry(cur, &clist->list, head) {
n = nftnl_chain_get_str(cur->nftnl, NFTNL_CHAIN_NAME);
if (strcmp(cname, n) <= 0) {
pos = &cur->head;
break;
}
}
list_add_tail(&nc->head, pos);
}
hlist_add_head(&nc->hnode, chain_name_hlist(h, t, cname));
return 0;
}
struct nftnl_chain_list_cb_data { struct nftnl_chain_list_cb_data {
struct nft_handle *h; struct nft_handle *h;
const struct builtin_table *t; const struct builtin_table *t;
...@@ -174,7 +250,6 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) ...@@ -174,7 +250,6 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
{ {
struct nftnl_chain_list_cb_data *d = data; struct nftnl_chain_list_cb_data *d = data;
const struct builtin_table *t = d->t; const struct builtin_table *t = d->t;
struct nftnl_chain_list *list;
struct nft_handle *h = d->h; struct nft_handle *h = d->h;
struct nftnl_chain *c; struct nftnl_chain *c;
const char *tname; const char *tname;
...@@ -196,8 +271,8 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) ...@@ -196,8 +271,8 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
goto out; goto out;
} }
list = h->cache->table[t->type].chains; if (nft_cache_add_chain(h, t, c))
nftnl_chain_list_add_tail(c, list); goto out;
return MNL_CB_OK; return MNL_CB_OK;
out: out:
...@@ -414,8 +489,9 @@ static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data) ...@@ -414,8 +489,9 @@ static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK; return MNL_CB_OK;
} }
static int nft_rule_list_update(struct nftnl_chain *c, void *data) static int nft_rule_list_update(struct nft_chain *nc, void *data)
{ {
struct nftnl_chain *c = nc->nftnl;
struct nft_handle *h = data; struct nft_handle *h = data;
char buf[16536]; char buf[16536];
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
...@@ -455,20 +531,15 @@ static int fetch_rule_cache(struct nft_handle *h, ...@@ -455,20 +531,15 @@ static int fetch_rule_cache(struct nft_handle *h,
{ {
int i; int i;
if (t) { if (t)
struct nftnl_chain_list *list = return nft_chain_foreach(h, t->name, nft_rule_list_update, h);
h->cache->table[t->type].chains;
return nftnl_chain_list_foreach(list, nft_rule_list_update, h);
}
for (i = 0; i < NFT_TABLE_MAX; i++) { for (i = 0; i < NFT_TABLE_MAX; i++) {
enum nft_table_type type = h->tables[i].type;
if (!h->tables[i].name) if (!h->tables[i].name)
continue; continue;
if (nftnl_chain_list_foreach(h->cache->table[type].chains, if (nft_chain_foreach(h, h->tables[i].name,
nft_rule_list_update, h)) nft_rule_list_update, h))
return -1; return -1;
} }
...@@ -535,31 +606,25 @@ static int ____flush_rule_cache(struct nftnl_rule *r, void *data) ...@@ -535,31 +606,25 @@ static int ____flush_rule_cache(struct nftnl_rule *r, void *data)
return 0; return 0;
} }
static int __flush_rule_cache(struct nftnl_chain *c, void *data) static int __flush_rule_cache(struct nft_chain *c, void *data)
{ {
return nftnl_rule_foreach(c, ____flush_rule_cache, NULL); return nftnl_rule_foreach(c->nftnl, ____flush_rule_cache, NULL);
} }
int flush_rule_cache(struct nft_handle *h, const char *table, int flush_rule_cache(struct nft_handle *h, const char *table,
struct nftnl_chain *c) struct nft_chain *c)
{ {
const struct builtin_table *t;
if (c) if (c)
return __flush_rule_cache(c, NULL); return __flush_rule_cache(c, NULL);
t = nft_table_builtin_find(h, table); nft_chain_foreach(h, table, __flush_rule_cache, NULL);
if (!t || !h->cache->table[t->type].chains)
return 0; return 0;
return nftnl_chain_list_foreach(h->cache->table[t->type].chains,
__flush_rule_cache, NULL);
} }
static int __flush_chain_cache(struct nftnl_chain *c, void *data) static int __flush_chain_cache(struct nft_chain *c, void *data)
{ {
nftnl_chain_list_del(c); nft_chain_list_del(c);
nftnl_chain_free(c); nft_chain_free(c);
return 0; return 0;
} }
...@@ -572,6 +637,19 @@ static int __flush_set_cache(struct nftnl_set *s, void *data) ...@@ -572,6 +637,19 @@ static int __flush_set_cache(struct nftnl_set *s, void *data)
return 0; return 0;
} }
static void flush_base_chain_cache(struct nft_chain **base_chains)
{
int i;
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
if (!base_chains[i])
continue;
hlist_del(&base_chains[i]->hnode);
nft_chain_free(base_chains[i]);
base_chains[i] = NULL;
}
}
static int flush_cache(struct nft_handle *h, struct nft_cache *c, static int flush_cache(struct nft_handle *h, struct nft_cache *c,
const char *tablename) const char *tablename)
{ {
...@@ -582,9 +660,10 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c, ...@@ -582,9 +660,10 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c,
table = nft_table_builtin_find(h, tablename); table = nft_table_builtin_find(h, tablename);
if (!table) if (!table)
return 0; return 0;
if (c->table[table->type].chains)
nftnl_chain_list_foreach(c->table[table->type].chains, flush_base_chain_cache(c->table[table->type].base_chains);
__flush_chain_cache, NULL); nft_chain_foreach(h, tablename, __flush_chain_cache, NULL);
if (c->table[table->type].sets) if (c->table[table->type].sets)
nftnl_set_list_foreach(c->table[table->type].sets, nftnl_set_list_foreach(c->table[table->type].sets,
__flush_set_cache, NULL); __flush_set_cache, NULL);
...@@ -595,10 +674,12 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c, ...@@ -595,10 +674,12 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c,
if (h->tables[i].name == NULL) if (h->tables[i].name == NULL)
continue; continue;
flush_base_chain_cache(c->table[i].base_chains);
if (c->table[i].chains) { if (c->table[i].chains) {
nftnl_chain_list_free(c->table[i].chains); nft_chain_list_free(c->table[i].chains);
c->table[i].chains = NULL; c->table[i].chains = NULL;
} }
if (c->table[i].sets) { if (c->table[i].sets) {
nftnl_set_list_free(c->table[i].sets); nftnl_set_list_free(c->table[i].sets);
c->table[i].sets = NULL; c->table[i].sets = NULL;
...@@ -689,16 +770,3 @@ nft_set_list_get(struct nft_handle *h, const char *table, const char *set) ...@@ -689,16 +770,3 @@ nft_set_list_get(struct nft_handle *h, const char *table, const char *set)
return h->cache->table[t->type].sets; return h->cache->table[t->type].sets;
} }
struct nftnl_chain_list *
nft_chain_list_get(struct nft_handle *h, const char *table, const char *chain)
{
const struct builtin_table *t;
t = nft_table_builtin_find(h, table);
if (!t)
return NULL;
return h->cache->table[t->type].chains;
}
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
#define _NFT_CACHE_H_ #define _NFT_CACHE_H_
struct nft_handle; struct nft_handle;
struct nft_chain;
struct nft_cmd; struct nft_cmd;
struct builtin_table;
void nft_cache_level_set(struct nft_handle *h, int level, void nft_cache_level_set(struct nft_handle *h, int level,
const struct nft_cmd *cmd); const struct nft_cmd *cmd);
...@@ -10,11 +12,14 @@ void nft_rebuild_cache(struct nft_handle *h); ...@@ -10,11 +12,14 @@ void nft_rebuild_cache(struct nft_handle *h);
void nft_release_cache(struct nft_handle *h); void nft_release_cache(struct nft_handle *h);
void flush_chain_cache(struct nft_handle *h, const char *tablename); void flush_chain_cache(struct nft_handle *h, const char *tablename);
int flush_rule_cache(struct nft_handle *h, const char *table, int flush_rule_cache(struct nft_handle *h, const char *table,
struct nftnl_chain *c); struct nft_chain *c);
void nft_cache_build(struct nft_handle *h); void nft_cache_build(struct nft_handle *h);
int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t,
struct nftnl_chain *c);
struct nft_chain *
nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
struct nftnl_chain_list *
nft_chain_list_get(struct nft_handle *h, const char *table, const char *chain);
struct nftnl_set_list * struct nftnl_set_list *
nft_set_list_get(struct nft_handle *h, const char *table, const char *set); nft_set_list_get(struct nft_handle *h, const char *table, const char *set);
......
/*
* Copyright (c) 2020 Red Hat GmbH. Author: Phil Sutter <phil@nwl.cc>
*
* 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 <stdlib.h>
#include <xtables.h>
#include "nft-chain.h"
struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl)
{
struct nft_chain *c = xtables_malloc(sizeof(*c));
INIT_LIST_HEAD(&c->head);
c->nftnl = nftnl;
return c;
}
void nft_chain_free(struct nft_chain *c)
{
if (c->nftnl)
nftnl_chain_free(c->nftnl);
free(c);
}
struct nft_chain_list *nft_chain_list_alloc(void)
{
struct nft_chain_list *list = xtables_malloc(sizeof(*list));
int i;
INIT_LIST_HEAD(&list->list);
for (i = 0; i < CHAIN_NAME_HSIZE; i++)
INIT_HLIST_HEAD(&list->names[i]);
return list;
}
void nft_chain_list_del(struct nft_chain *c)
{
list_del(&c->head);
hlist_del(&c->hnode);
}
void nft_chain_list_free(struct nft_chain_list *list)
{
struct nft_chain *c, *c2;
list_for_each_entry_safe(c, c2, &list->list, head) {
nft_chain_list_del(c);
nft_chain_free(c);
}
free(list);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment