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

New upstream version 1.8.7

parent 9caffe92
#! /bin/sh
# 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.
......@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='iptables'
PACKAGE_TARNAME='iptables'
PACKAGE_VERSION='1.8.6'
PACKAGE_STRING='iptables 1.8.6'
PACKAGE_VERSION='1.8.7'
PACKAGE_STRING='iptables 1.8.7'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
......@@ -1406,7 +1406,7 @@ if test "$ac_init_help" = "long"; then
# 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.
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]...
......@@ -1477,7 +1477,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of iptables 1.8.6:";;
short | recursive ) echo "Configuration of iptables 1.8.7:";;
esac
cat <<\_ACEOF
......@@ -1628,7 +1628,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
iptables configure 1.8.6
iptables configure 1.8.7
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
......@@ -2176,7 +2176,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
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
$ $0 $@
......@@ -2526,8 +2526,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# See libtool.info "Libtool's versioning system"
libxtables_vcurrent=15
libxtables_vage=3
libxtables_vcurrent=16
libxtables_vage=4
ac_aux_dir=
for ac_dir in build-aux "$srcdir"/build-aux; do
......@@ -3047,7 +3047,7 @@ fi
# Define the identity of the package.
PACKAGE='iptables'
VERSION='1.8.6'
VERSION='1.8.7'
cat >>confdefs.h <<_ACEOF
......@@ -13880,7 +13880,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
......@@ -13946,7 +13946,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
iptables config.status 1.8.6
iptables config.status 1.8.7
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
......
AC_INIT([iptables], [1.8.6])
AC_INIT([iptables], [1.8.7])
# See libtool.info "Libtool's versioning system"
libxtables_vcurrent=15
libxtables_vage=3
libxtables_vcurrent=16
libxtables_vage=4
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
......
......@@ -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)
{
if (numeric)
......@@ -159,7 +150,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
}
if (m->flags & ARPT_MANGLE_SDEV) {
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) {
printf(" --mangle-ip-d %s",
......@@ -167,7 +158,7 @@ arpmangle_print(const void *ip, const struct xt_entry_target *target,
}
if (m->flags & ARPT_MANGLE_TDEV) {
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) {
printf(" --mangle-target %s",
......
......@@ -161,54 +161,6 @@ static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *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
brarp_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
......@@ -317,7 +269,7 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags,
else
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");
break;
case ARP_GRAT:
......
......@@ -150,54 +150,6 @@ static void print_range(unsigned int l, unsigned int 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
brstp_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
......@@ -280,15 +232,15 @@ brstp_parse(int c, char **argv, int invert, unsigned int *flags,
xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range");
break;
case EBT_STP_ROOTADDR:
if (brstp_get_mac_and_mask(argv[optind-1],
(unsigned char *)stpinfo->config.root_addr,
(unsigned char *)stpinfo->config.root_addrmsk))
if (xtables_parse_mac_and_mask(argv[optind-1],
stpinfo->config.root_addr,
stpinfo->config.root_addrmsk))
xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address");
break;
case EBT_STP_SENDERADDR:
if (brstp_get_mac_and_mask(argv[optind-1],
(unsigned char *)stpinfo->config.sender_addr,
(unsigned char *)stpinfo->config.sender_addrmsk))
if (xtables_parse_mac_and_mask(argv[optind-1],
stpinfo->config.sender_addr,
stpinfo->config.sender_addrmsk))
xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address");
break;
default:
......
......@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
[DCCP_PKT_INVALID] = "INVALID",
};
/* Bits for type values 11-15 */
#define INVALID_OTHER_TYPE_MASK 0xf800
static uint16_t
parse_dccp_types(const char *typestring)
{
......@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
xtables_error(PARAMETER_PROBLEM,
"Unknown DCCP type `%s'", ptr);
}
if (typemask & (1 << DCCP_PKT_INVALID))
typemask |= INVALID_OTHER_TYPE_MASK;
free(buffer);
return typemask;
......@@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric)
if (numeric)
printf("%u", i);
else
else {
printf("%s", dccp_pkt_types[i]);
if (i == DCCP_PKT_INVALID)
break;
}
types &= ~(1 << i);
}
}
......@@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = {
[DCCP_PKT_RESET] = "reset",
[DCCP_PKT_SYNC] = "sync",
[DCCP_PKT_SYNCACK] = "syncack",
[DCCP_PKT_INVALID] = "10-15",
};
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;
uint16_t types = einfo->typemask;
if (types & (1 << DCCP_PKT_INVALID))
return 0;
xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
if (types & INVALID_OTHER_TYPE_MASK) {
types &= ~INVALID_OTHER_TYPE_MASK;
types |= 1 << DCCP_PKT_INVALID;
}
if ((types != 0) && !(types == (types & -types))) {
xt_xlate_add(xl, "{");
......@@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl,
char *space = "";
int ret = 1;
xt_xlate_add(xl, "dccp ");
if (einfo->flags & XT_DCCP_SRC_PORTS) {
xt_xlate_add(xl, "dccp sport%s %u",
einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
einfo->spts[0]);
if (einfo->spts[0] != einfo->spts[1])
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->spts[0]);
xt_xlate_add(xl, "-%u", einfo->spts[1]);
space = " ";
}
if (einfo->flags & XT_DCCP_DEST_PORTS) {
xt_xlate_add(xl, "%sdccp dport%s %u", space,
einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
einfo->dpts[0]);
if (einfo->dpts[0] != einfo->dpts[1])
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->dpts[0]);
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);
space = " ";
}
/* FIXME: no dccp option support in nftables yet */
if (einfo->flags & XT_DCCP_OPTION)
ret = 0;
......
......@@ -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
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
nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter
iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
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
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)
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
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)
printf(" !");
print_mac(info->srcaddr);
xtables_print_mac(info->srcaddr);
}
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)
printf(" !");
printf(" --mac-source");
print_mac(info->srcaddr);
printf(" --mac-source ");
xtables_print_mac(info->srcaddr);
}
static void print_mac_xlate(const unsigned char *macaddress,
......
......@@ -557,6 +557,9 @@ extern void xtables_save_string(const char *value);
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
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_and_mask(const unsigned char *mac,
const unsigned char *mask);
......
......@@ -310,7 +310,7 @@ def show_missing():
#
def main():
parser = argparse.ArgumentParser(description='Run iptables tests')
parser.add_argument('filename', nargs='?',
parser.add_argument('filename', nargs='*',
metavar='path/to/file.t',
help='Run only this test')
parser.add_argument('-H', '--host', action='store_true',
......@@ -359,13 +359,20 @@ def main():
return
if args.filename:
file_list = [args.filename]
file_list = args.filename
else:
file_list = [os.path.join(EXTENSIONS_PATH, i)
for i in os.listdir(EXTENSIONS_PATH)
if i.endswith('.t')]
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:
file_tests, file_passed = run_test_file(filename, args.netns)
if file_tests:
......
......@@ -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 \
xtables-monitor.c nft-cache.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-translate.c \
xtables-translate.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 \
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-eb-standalone.c xtables-eb.c xtables-eb-translate.c \
xtables-translate.c xshared.c
nft-chain.c xtables-eb-standalone.c xtables-eb.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@ xtables_nft_multi-iptables-xml.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-save.$(OBJEXT) \
......@@ -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-nft-bridge.$(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.$(OBJEXT) \
@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-translate.$(OBJEXT) \
......@@ -256,6 +257,7 @@ am__depfiles_remade = \
./$(DEPDIR)/xtables_nft_multi-nft-arp.Po \
./$(DEPDIR)/xtables_nft_multi-nft-bridge.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-ipv4.Po \
./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po \
......@@ -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-cache.c xtables-arp-standalone.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@ xtables-eb-translate.c \
@ENABLE_NFTABLES_TRUE@ nft-chain.c xtables-eb-standalone.c \
@ENABLE_NFTABLES_TRUE@ xtables-eb.c xtables-eb-translate.c \
@ENABLE_NFTABLES_TRUE@ xtables-translate.c xshared.c
@ENABLE_NFTABLES_TRUE@xtables_nft_multi_CFLAGS = ${AM_CFLAGS} \
@ENABLE_NFTABLES_TRUE@ $(am__append_8) -DENABLE_NFTABLES \
......@@ -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-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-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-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
......@@ -1117,6 +1120,20 @@ xtables_nft_multi-nft-cmd.obj: nft-cmd.c
@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`
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
@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
......@@ -1445,6 +1462,7 @@ distclean: distclean-am
-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-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-ipv4.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po
......@@ -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-bridge.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-ipv4.Po
-rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po
......
......@@ -45,10 +45,6 @@
#include "ip6tables-multi.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 struct option original_opts[] = {
......@@ -100,36 +96,6 @@ struct xtables_globals ip6tables_globals = {
.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] =
{
/* -n */ 0,
......@@ -264,51 +230,6 @@ ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...)
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
* the program fails.
......
......@@ -41,11 +41,6 @@
#include <fcntl.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 struct option original_opts[] = {
......@@ -99,36 +94,6 @@ struct xtables_globals iptables_globals = {
.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] =
{
/* -n */ 0,
......@@ -263,51 +228,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...)
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
* the program fails.
......
......@@ -134,34 +134,34 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
int ret = 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);
}
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);
}
if (fw->arp.arhrd != 0 ||
fw->arp.invflags & ARPT_INV_ARPHRD) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
fw->arp.invflags & IPT_INV_ARPHRD) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
add_payload(r, offsetof(struct arphdr, ar_hrd), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arhrd, op);
}
if (fw->arp.arpro != 0 ||
fw->arp.invflags & ARPT_INV_ARPPRO) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
fw->arp.invflags & IPT_INV_PROTO) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
add_payload(r, offsetof(struct arphdr, ar_pro), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpro, op);
}
if (fw->arp.arhln != 0 ||
fw->arp.invflags & ARPT_INV_ARPHLN) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
fw->arp.invflags & IPT_INV_ARPHLN) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN);
add_proto(r, offsetof(struct arphdr, ar_hln), 1,
fw->arp.arhln, op);
}
......@@ -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);
if (fw->arp.arpop != 0 ||
fw->arp.invflags & ARPT_INV_ARPOP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
fw->arp.invflags & IPT_INV_ARPOP) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
add_payload(r, offsetof(struct arphdr, ar_op), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpop, op);
}
if (need_devaddr(&fw->arp.src_devaddr)) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
add_addr(r, sizeof(struct arphdr),
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR);
add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr),
&fw->arp.src_devaddr.addr,
&fw->arp.src_devaddr.mask,
fw->arp.arhln, op);
......@@ -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 ||
fw->arp.smsk.s_addr != 0 ||
fw->arp.invflags & ARPT_INV_SRCIP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
fw->arp.invflags & IPT_INV_SRCIP) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP);
add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
sizeof(struct arphdr) + fw->arp.arhln,
&fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
sizeof(struct in_addr), op);
}
if (need_devaddr(&fw->arp.tgt_devaddr)) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR);
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.mask,
fw->arp.arhln, op);
......@@ -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 ||
fw->arp.tmsk.s_addr != 0 ||
fw->arp.invflags & ARPT_INV_TGTIP) {
op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
fw->arp.invflags & IPT_INV_DSTIP) {
op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP);
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,
sizeof(struct in_addr), op);
}
......@@ -236,28 +240,6 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
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,
void *data)
{
......@@ -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,
&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,
......@@ -303,7 +285,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx,
memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
memset(info->mask, 0xff, ETH_ALEN);
memset(info->mask, 0xff,
min(ctx->payload.len, ETH_ALEN));
}
return inv;
......@@ -325,33 +308,33 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
fw->arp.arhrd = ar_hrd;
fw->arp.arhrd_mask = 0xffff;
if (inv)
fw->arp.invflags |= ARPT_INV_ARPHRD;
fw->arp.invflags |= IPT_INV_ARPHRD;
break;
case offsetof(struct arphdr, ar_pro):
get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
fw->arp.arpro = ar_pro;
fw->arp.arpro_mask = 0xffff;
if (inv)
fw->arp.invflags |= ARPT_INV_ARPPRO;
fw->arp.invflags |= IPT_INV_PROTO;
break;
case offsetof(struct arphdr, ar_op):
get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
fw->arp.arpop = ar_op;
fw->arp.arpop_mask = 0xffff;
if (inv)
fw->arp.invflags |= ARPT_INV_ARPOP;
fw->arp.invflags |= IPT_INV_ARPOP;
break;
case offsetof(struct arphdr, ar_hln):
get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
fw->arp.arhln = ar_hln;
fw->arp.arhln_mask = 0xff;
if (inv)
fw->arp.invflags |= ARPT_INV_ARPOP;
fw->arp.invflags |= IPT_INV_ARPOP;
break;
default:
if (ctx->payload.offset == sizeof(struct arphdr)) {
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) +
fw->arp.arhln) {
get_cmp_data(e, &addr, sizeof(addr), &inv);
......@@ -360,16 +343,18 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
parse_mask_ipv4(ctx, &fw->arp.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
fw->arp.smsk.s_addr = 0xffffffff;
memset(&fw->arp.smsk, 0xff,
min(ctx->payload.len,
sizeof(struct in_addr)));
}
if (inv)
fw->arp.invflags |= ARPT_INV_SRCIP;
fw->arp.invflags |= IPT_INV_SRCIP;
} else if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln +
sizeof(struct in_addr)) {
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) +
fw->arp.arhln +
sizeof(struct in_addr) +
......@@ -380,11 +365,13 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
parse_mask_ipv4(ctx, &fw->arp.tmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
fw->arp.tmsk.s_addr = 0xffffffff;
memset(&fw->arp.tmsk, 0xff,
min(ctx->payload.len,
sizeof(struct in_addr)));
}
if (inv)
fw->arp.invflags |= ARPT_INV_TGTIP;
fw->arp.invflags |= IPT_INV_DSTIP;
}
break;
}
......@@ -439,7 +426,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
else strcat(iface, "any");
}
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);
sep = " ";
}
......@@ -457,13 +444,13 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
else strcat(iface, "any");
}
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);
sep = " ";
}
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)
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,
break;
if (i == ARPT_DEV_ADDR_LEN_MAX)
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 ");
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,
after_devsrc:
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)
sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt)));
......@@ -506,7 +493,7 @@ after_devsrc:
break;
if (i == ARPT_DEV_ADDR_LEN_MAX)
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 ");
xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
......@@ -516,7 +503,7 @@ after_devsrc:
after_devdst:
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);
if (fw->arp.arhln_mask != 255)
......@@ -527,7 +514,7 @@ after_devdst:
if (fw->arp.arpop_mask != 0) {
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))
printf("--opcode %s", arp_opcodes[tmp-1]);
......@@ -542,7 +529,7 @@ after_devdst:
if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) {
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))
printf("--h-type %s", "Ethernet");
......@@ -556,7 +543,7 @@ after_devdst:
if (fw->arp.arpro_mask != 0) {
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))
printf("--proto-type %s", "IPv4");
......
......@@ -4,4 +4,11 @@
extern char *arp_opcodes[];
#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
......@@ -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. */
static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
{
if (!memcmp(mac, eb_mac_type_unicast, 6) &&
!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);
}
}
if (xtables_print_well_known_mac_and_mask(mac, mask))
xtables_print_mac_and_mask(mac, mask);
}
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,
if (fw->bitmask & EBT_ISOURCE) {
op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE);
add_payload(r, offsetof(struct ethhdr, h_source), 6,
NFT_PAYLOAD_LL_HEADER);
if (!mac_all_ones(fw->sourcemsk))
add_bitwise(r, fw->sourcemsk, 6);
add_cmp_ptr(r, op, fw->sourcemac, 6);
add_addr(r, NFT_PAYLOAD_LL_HEADER,
offsetof(struct ethhdr, h_source),
fw->sourcemac, fw->sourcemsk, ETH_ALEN, op);
}
if (fw->bitmask & EBT_IDEST) {
op = nft_invflags2cmp(fw->invflags, EBT_IDEST);
add_payload(r, offsetof(struct ethhdr, h_dest), 6,
NFT_PAYLOAD_LL_HEADER);
if (!mac_all_ones(fw->destmsk))
add_bitwise(r, fw->destmsk, 6);
add_cmp_ptr(r, op, fw->destmac, 6);
add_addr(r, NFT_PAYLOAD_LL_HEADER,
offsetof(struct ethhdr, h_dest),
fw->destmac, fw->destmsk, ETH_ALEN, op);
}
if ((fw->bitmask & EBT_NOPROTO) == 0) {
......@@ -258,7 +221,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
memset(&fw->destmsk, 0xff, ETH_ALEN);
memset(&fw->destmsk, 0xff,
min(ctx->payload.len, ETH_ALEN));
}
fw->bitmask |= EBT_IDEST;
break;
......@@ -272,7 +236,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
memset(&fw->sourcemsk, 0xff, ETH_ALEN);
memset(&fw->sourcemsk, 0xff,
min(ctx->payload.len, ETH_ALEN));
}
fw->bitmask |= EBT_ISOURCE;
break;
......
......@@ -24,6 +24,7 @@
#include "nft.h"
#include "nft-cache.h"
#include "nft-chain.h"
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)
if (!h->tables[i].name)
continue;
h->cache->table[type].chains = nftnl_chain_list_alloc();
if (!h->cache->table[type].chains)
return 0;
h->cache->table[type].chains = nft_chain_list_alloc();
h->cache->table[type].sets = nftnl_set_list_alloc();
if (!h->cache->table[type].sets)
......@@ -165,6 +164,83 @@ static int fetch_table_cache(struct nft_handle *h)
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 nft_handle *h;
const struct builtin_table *t;
......@@ -174,7 +250,6 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
{
struct nftnl_chain_list_cb_data *d = data;
const struct builtin_table *t = d->t;
struct nftnl_chain_list *list;
struct nft_handle *h = d->h;
struct nftnl_chain *c;
const char *tname;
......@@ -196,8 +271,8 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
goto out;
}
list = h->cache->table[t->type].chains;
nftnl_chain_list_add_tail(c, list);
if (nft_cache_add_chain(h, t, c))
goto out;
return MNL_CB_OK;
out:
......@@ -414,8 +489,9 @@ static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
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;
char buf[16536];
struct nlmsghdr *nlh;
......@@ -455,21 +531,16 @@ static int fetch_rule_cache(struct nft_handle *h,
{
int i;
if (t) {
struct nftnl_chain_list *list =
h->cache->table[t->type].chains;
return nftnl_chain_list_foreach(list, nft_rule_list_update, h);
}
if (t)
return nft_chain_foreach(h, t->name, nft_rule_list_update, h);
for (i = 0; i < NFT_TABLE_MAX; i++) {
enum nft_table_type type = h->tables[i].type;
if (!h->tables[i].name)
continue;
if (nftnl_chain_list_foreach(h->cache->table[type].chains,
nft_rule_list_update, h))
if (nft_chain_foreach(h, h->tables[i].name,
nft_rule_list_update, h))
return -1;
}
return 0;
......@@ -535,31 +606,25 @@ static int ____flush_rule_cache(struct nftnl_rule *r, void *data)
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,
struct nftnl_chain *c)
struct nft_chain *c)
{
const struct builtin_table *t;
if (c)
return __flush_rule_cache(c, NULL);
t = nft_table_builtin_find(h, table);
if (!t || !h->cache->table[t->type].chains)
return 0;
return nftnl_chain_list_foreach(h->cache->table[t->type].chains,
__flush_rule_cache, NULL);
nft_chain_foreach(h, table, __flush_rule_cache, NULL);
return 0;
}
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);
nftnl_chain_free(c);
nft_chain_list_del(c);
nft_chain_free(c);
return 0;
}
......@@ -572,6 +637,19 @@ static int __flush_set_cache(struct nftnl_set *s, void *data)
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,
const char *tablename)
{
......@@ -582,9 +660,10 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c,
table = nft_table_builtin_find(h, tablename);
if (!table)
return 0;
if (c->table[table->type].chains)
nftnl_chain_list_foreach(c->table[table->type].chains,
__flush_chain_cache, NULL);
flush_base_chain_cache(c->table[table->type].base_chains);
nft_chain_foreach(h, tablename, __flush_chain_cache, NULL);
if (c->table[table->type].sets)
nftnl_set_list_foreach(c->table[table->type].sets,
__flush_set_cache, NULL);
......@@ -595,10 +674,12 @@ static int flush_cache(struct nft_handle *h, struct nft_cache *c,
if (h->tables[i].name == NULL)
continue;
flush_base_chain_cache(c->table[i].base_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;
}
if (c->table[i].sets) {
nftnl_set_list_free(c->table[i].sets);
c->table[i].sets = NULL;
......@@ -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;
}
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 @@
#define _NFT_CACHE_H_
struct nft_handle;
struct nft_chain;
struct nft_cmd;
struct builtin_table;
void nft_cache_level_set(struct nft_handle *h, int level,
const struct nft_cmd *cmd);
......@@ -10,11 +12,14 @@ void nft_rebuild_cache(struct nft_handle *h);
void nft_release_cache(struct nft_handle *h);
void flush_chain_cache(struct nft_handle *h, const char *tablename);
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);
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 *
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