diff --git a/.ebtables.metadata b/.ebtables.metadata new file mode 100644 index 0000000..20058f5 --- /dev/null +++ b/.ebtables.metadata @@ -0,0 +1 @@ +791b3b535181aa66f302356c2984cf244f76a247 SOURCES/ebtables-2.0.11.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ecada6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +BUILD +BUILDROOT +RPMS +SRPMS + +SOURCES/ebtables-2.0.11.tar.bz2 diff --git a/SOURCES/0001-add-RARP-and-update-iana-url.patch b/SOURCES/0001-add-RARP-and-update-iana-url.patch new file mode 100644 index 0000000..f4f1766 --- /dev/null +++ b/SOURCES/0001-add-RARP-and-update-iana-url.patch @@ -0,0 +1,46 @@ +From f2f5c8169619e1ea5fd3849a389da349840cfd4e Mon Sep 17 00:00:00 2001 +From: Bart De Schuymer +Date: Tue, 3 Jul 2012 18:47:32 +0000 +Subject: [PATCH] add RARP and update iana url + +Signed-off-by: Phil Sutter +--- + ethertypes | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/ethertypes b/ethertypes +index 5e700f6639879..813177b74588c 100644 +--- a/ethertypes ++++ b/ethertypes +@@ -5,6 +5,7 @@ + # + # This list could be found on: + # http://www.iana.org/assignments/ethernet-numbers ++# http://www.iana.org/assignments/ieee-802-numbers + # + # ... #Comment + # +@@ -21,15 +22,16 @@ LAT 6004 # DEC LAT + DIAG 6005 # DEC Diagnostics + CUST 6006 # DEC Customer use + SCA 6007 # DEC Systems Comms Arch +-TEB 6558 # Trans Ether Bridging [RFC1701] +-RAW_FR 6559 # Raw Frame Relay [RFC1701] ++TEB 6558 # Trans Ether Bridging [RFC1701] ++RAW_FR 6559 # Raw Frame Relay [RFC1701] ++RARP 8035 # Reverse ARP [RFC903] + AARP 80F3 # Appletalk AARP +-ATALK 809B # Appletalk ++ATALK 809B # Appletalk + 802_1Q 8100 8021q 1q 802.1q dot1q # 802.1Q Virtual LAN tagged frame + IPX 8137 # Novell IPX + NetBEUI 8191 # NetBEUI + IPv6 86DD ip6 # IP version 6 +-PPP 880B # PPP ++PPP 880B # PPP + ATMMPOA 884C # MultiProtocol over ATM + PPP_DISC 8863 # PPPoE discovery messages + PPP_SES 8864 # PPPoE session messages +-- +2.21.0 + diff --git a/SOURCES/0002-fix-compilation-warning.patch b/SOURCES/0002-fix-compilation-warning.patch new file mode 100644 index 0000000..46a7b99 --- /dev/null +++ b/SOURCES/0002-fix-compilation-warning.patch @@ -0,0 +1,26 @@ +From 10f6865652777ba7f26825d46e8b419f784463dc Mon Sep 17 00:00:00 2001 +From: Petri Gynther +Date: Sun, 24 Feb 2013 10:56:59 +0100 +Subject: [PATCH] fix compilation warning + +Signed-off-by: Phil Sutter +--- + communication.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/communication.c b/communication.c +index 62ed667deac13..ba058c05a68b4 100644 +--- a/communication.c ++++ b/communication.c +@@ -282,7 +282,7 @@ static int store_counters_in_file(char *filename, struct ebt_u_replace *repl) + } + close_file: + fclose(file); +- return 0; ++ return ret; + } + + /* Gets executed after ebt_deliver_table. Delivers the counters to the kernel +-- +2.21.0 + diff --git a/SOURCES/0003-add-info-about-Wl-no-as-needed.patch b/SOURCES/0003-add-info-about-Wl-no-as-needed.patch new file mode 100644 index 0000000..620d32c --- /dev/null +++ b/SOURCES/0003-add-info-about-Wl-no-as-needed.patch @@ -0,0 +1,26 @@ +From 99e7c5f7976707dc59f1dfbccf12d2574eee3dab Mon Sep 17 00:00:00 2001 +From: Bart De Schuymer +Date: Wed, 3 Jul 2013 22:12:47 +0200 +Subject: [PATCH] add info about -Wl,-no-as-needed + +Signed-off-by: Phil Sutter +--- + INSTALL | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/INSTALL b/INSTALL +index 4a05c678caab0..e90d5c103bdc4 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -39,6 +39,8 @@ That's all + You can also use a base directory different from the root directory (/), + using the DESTDIR option. See the Makefile for more details. + ++You might need to set LDFLAGS=-Wl,-no-as-needed to build ebtables correctly ++on your system. + + ADDITIONAL PROGRAMS: + ---------------------- +-- +2.21.0 + diff --git a/SOURCES/0004-workaround-for-kernel-regression-bug-IPv6-source-des.patch b/SOURCES/0004-workaround-for-kernel-regression-bug-IPv6-source-des.patch new file mode 100644 index 0000000..fd6d97e --- /dev/null +++ b/SOURCES/0004-workaround-for-kernel-regression-bug-IPv6-source-des.patch @@ -0,0 +1,29 @@ +From 32e8e2b169b215cca038121268d6e6968719f268 Mon Sep 17 00:00:00 2001 +From: Luis Fernando +Date: Wed, 3 Jul 2013 22:19:55 +0200 +Subject: [PATCH] workaround for kernel regression bug: IPv6 source/destination + addresses are potentially not matched correctly + +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip6.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c +index 0465e77b5d906..bbdc4aef9a172 100644 +--- a/extensions/ebt_ip6.c ++++ b/extensions/ebt_ip6.c +@@ -312,6 +312,10 @@ static void init(struct ebt_entry_match *match) + + ipinfo->invflags = 0; + ipinfo->bitmask = 0; ++ memset(ipinfo->saddr.s6_addr, 0, sizeof(ipinfo->saddr.s6_addr)); ++ memset(ipinfo->smsk.s6_addr, 0, sizeof(ipinfo->smsk.s6_addr)); ++ memset(ipinfo->daddr.s6_addr, 0, sizeof(ipinfo->daddr.s6_addr)); ++ memset(ipinfo->dmsk.s6_addr, 0, sizeof(ipinfo->dmsk.s6_addr)); + } + + #define OPT_SOURCE 0x01 +-- +2.21.0 + diff --git a/SOURCES/0005-Add-noflush-command-line-support-for-ebtables-restor.patch b/SOURCES/0005-Add-noflush-command-line-support-for-ebtables-restor.patch new file mode 100644 index 0000000..061466b --- /dev/null +++ b/SOURCES/0005-Add-noflush-command-line-support-for-ebtables-restor.patch @@ -0,0 +1,76 @@ +From d1d746dde7089b39598f2d7b7fef61fc52f52c25 Mon Sep 17 00:00:00 2001 +From: Sanket Shah +Date: Wed, 31 Jul 2013 21:40:08 +0200 +Subject: [PATCH] Add --noflush command line support for ebtables-restore + +Signed-off-by: Phil Sutter +--- + ebtables-restore.c | 29 +++++++++++++++++++++++++---- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/ebtables-restore.c b/ebtables-restore.c +index ea0296055212e..bb4d0cffda1cc 100644 +--- a/ebtables-restore.c ++++ b/ebtables-restore.c +@@ -22,13 +22,25 @@ + #include + #include + #include ++#include + #include "include/ebtables_u.h" + ++static const struct option options[] = { ++ {.name = "noflush", .has_arg = 0, .val = 'n'}, ++ { 0 } ++}; ++ + static struct ebt_u_replace replace[3]; + void ebt_early_init_once(); + + #define OPT_KERNELDATA 0x800 /* Also defined in ebtables.c */ + ++static void print_usage() ++{ ++ fprintf(stderr, "Usage: ebtables-restore [ --noflush ]\n"); ++ exit(1); ++} ++ + static void copy_table_names() + { + strcpy(replace[0].name, "filter"); +@@ -41,11 +53,20 @@ static void copy_table_names() + int main(int argc_, char *argv_[]) + { + char *argv[EBTD_ARGC_MAX], cmdline[EBTD_CMDLINE_MAXLN]; +- int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace; ++ int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace, c, flush = 1; + char ebtables_str[] = "ebtables"; + +- if (argc_ != 1) +- ebtrest_print_error("options are not supported"); ++ while ((c = getopt_long(argc_, argv_, "n", options, NULL)) != -1) { ++ switch(c) { ++ case 'n': ++ flush = 0; ++ break; ++ default: ++ print_usage(); ++ break; ++ } ++ } ++ + ebt_silent = 0; + copy_table_names(); + ebt_early_init_once(); +@@ -68,7 +89,7 @@ int main(int argc_, char *argv_[]) + ebtrest_print_error("table '%s' was not recognized", cmdline+1); + table_nr = i; + replace[table_nr].command = 11; +- ebt_get_kernel_table(&replace[table_nr], 1); ++ ebt_get_kernel_table(&replace[table_nr], flush); + replace[table_nr].command = 0; + replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */ + continue; +-- +2.21.0 + diff --git a/SOURCES/0006-don-t-print-IPv6-mask-if-it-s-all-ones-based-on-patc.patch b/SOURCES/0006-don-t-print-IPv6-mask-if-it-s-all-ones-based-on-patc.patch new file mode 100644 index 0000000..5deb6f9 --- /dev/null +++ b/SOURCES/0006-don-t-print-IPv6-mask-if-it-s-all-ones-based-on-patc.patch @@ -0,0 +1,70 @@ +From 657c50fea3cc6a05dca5f055f4377ab412fe21f0 Mon Sep 17 00:00:00 2001 +From: Bart De Schuymer +Date: Mon, 14 Apr 2014 22:04:55 +0200 +Subject: [PATCH] don't print IPv6 mask if it's all ones (based on patch by + Mariusz Mazur ) + +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip6.c | 4 ++-- + include/ebtables_u.h | 1 + + useful_functions.c | 13 +++++++++++++ + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c +index bbdc4aef9a172..e3e0956e00f01 100644 +--- a/extensions/ebt_ip6.c ++++ b/extensions/ebt_ip6.c +@@ -449,14 +449,14 @@ static void print(const struct ebt_u_entry *entry, + if (ipinfo->invflags & EBT_IP6_SOURCE) + printf("! "); + printf("%s", ebt_ip6_to_numeric(&ipinfo->saddr)); +- printf("/%s ", ebt_ip6_to_numeric(&ipinfo->smsk)); ++ printf("%s ", ebt_ip6_mask_to_string(&ipinfo->smsk)); + } + if (ipinfo->bitmask & EBT_IP6_DEST) { + printf("--ip6-dst "); + if (ipinfo->invflags & EBT_IP6_DEST) + printf("! "); + printf("%s", ebt_ip6_to_numeric(&ipinfo->daddr)); +- printf("/%s ", ebt_ip6_to_numeric(&ipinfo->dmsk)); ++ printf("%s ", ebt_ip6_mask_to_string(&ipinfo->dmsk)); + } + if (ipinfo->bitmask & EBT_IP6_TCLASS) { + printf("--ip6-tclass "); +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index ab615c1d59c44..35a5bcc54c865 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -303,6 +303,7 @@ char *ebt_mask_to_dotted(uint32_t mask); + void ebt_parse_ip6_address(char *address, struct in6_addr *addr, + struct in6_addr *msk); + char *ebt_ip6_to_numeric(const struct in6_addr *addrp); ++char *ebt_ip6_mask_to_string(const struct in6_addr *msk); + + + int do_command(int argc, char *argv[], int exec_style, +diff --git a/useful_functions.c b/useful_functions.c +index d20b68e31eabb..d14cbe9dbdba1 100644 +--- a/useful_functions.c ++++ b/useful_functions.c +@@ -411,3 +411,16 @@ char *ebt_ip6_to_numeric(const struct in6_addr *addrp) + static char buf[50+1]; + return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); + } ++ ++char *ebt_ip6_mask_to_string(const struct in6_addr *msk) ++{ ++ /* /0000:0000:0000:0000:0000:000.000.000.000 ++ * /0000:0000:0000:0000:0000:0000:0000:0000 */ ++ static char buf[51+1]; ++ if (msk->s6_addr32[0] == 0xFFFFFFFFL && msk->s6_addr32[1] == 0xFFFFFFFFL && ++ msk->s6_addr32[2] == 0xFFFFFFFFL && msk->s6_addr32[3] == 0xFFFFFFFFL) ++ *buf = '\0'; ++ else ++ sprintf(buf, "/%s", ebt_ip6_to_numeric(msk)); ++ return buf; ++} +-- +2.21.0 + diff --git a/SOURCES/0007-Add-kernel-headers-needed-from-v3.16.patch b/SOURCES/0007-Add-kernel-headers-needed-from-v3.16.patch new file mode 100644 index 0000000..53f3cfc --- /dev/null +++ b/SOURCES/0007-Add-kernel-headers-needed-from-v3.16.patch @@ -0,0 +1,239 @@ +From a29aa9b111e00fcf6dd8268a2a18314df0ea0d4b Mon Sep 17 00:00:00 2001 +From: Pedro Alvarez +Date: Fri, 27 Feb 2015 11:54:10 +0000 +Subject: [PATCH] Add kernel headers needed from v3.16 + +Ebtables fails to compile with versions of the linux headers greater +than v3.16 with this error: + + extensions/ebt_ulog.c:17:45: fatal error: linux/netfilter_bridge/ebt_ulog.h: No such file or directory + #include + +This patch adds netfilter_bridge headers for every supported +extension, including filter.h and types.h, to avoid this problem and +future problems with changes in the kernel headers. + +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + include/linux/netfilter_bridge.h | 2 +- + include/linux/netfilter_bridge/ebt_802_3.h | 7 ++- + include/linux/netfilter_bridge/ebtables.h | 70 ++++++++++------------ + include/linux/types.h | 2 +- + 4 files changed, 37 insertions(+), 44 deletions(-) + +diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h +index 5094ecca9c1b3..c4dbfd91a17b9 100644 +--- a/include/linux/netfilter_bridge.h ++++ b/include/linux/netfilter_bridge.h +@@ -24,4 +24,4 @@ + #define NF_BR_BROUTING 5 + #define NF_BR_NUMHOOKS 6 + +-#endif ++#endif /* __LINUX_BRIDGE_NETFILTER_H */ +diff --git a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h +index 76687d51f0eb8..70028c1523164 100644 +--- a/include/linux/netfilter_bridge/ebt_802_3.h ++++ b/include/linux/netfilter_bridge/ebt_802_3.h +@@ -2,6 +2,7 @@ + #define __LINUX_BRIDGE_EBT_802_3_H + + #include ++#include + + #define EBT_802_3_SAP 0x01 + #define EBT_802_3_TYPE 0x02 +@@ -42,8 +43,8 @@ struct hdr_ni { + }; + + struct ebt_802_3_hdr { +- __u8 daddr[6]; +- __u8 saddr[6]; ++ __u8 daddr[ETH_ALEN]; ++ __u8 saddr[ETH_ALEN]; + __be16 len; + union { + struct hdr_ui ui; +@@ -59,4 +60,4 @@ struct ebt_802_3_info { + __u8 invflags; + }; + +-#endif ++#endif /* __LINUX_BRIDGE_EBT_802_3_H */ +diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h +index 8f520c600b356..19a64448c648e 100644 +--- a/include/linux/netfilter_bridge/ebtables.h ++++ b/include/linux/netfilter_bridge/ebtables.h +@@ -10,7 +10,6 @@ + * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling + */ + +-/* Local copy of the kernel file, needed for Sparc64 support */ + #ifndef __LINUX_BRIDGE_EFF_H + #define __LINUX_BRIDGE_EFF_H + #include +@@ -32,14 +31,31 @@ + * The 4 lsb are more than enough to store the verdict. */ + #define EBT_VERDICT_BITS 0x0000000F + +-struct ebt_counter +-{ ++struct xt_match; ++struct xt_target; ++ ++struct ebt_counter { + uint64_t pcnt; + uint64_t bcnt; + }; + +-struct ebt_replace +-{ ++struct ebt_replace { ++ char name[EBT_TABLE_MAXNAMELEN]; ++ unsigned int valid_hooks; ++ /* nr of rules in the table */ ++ unsigned int nentries; ++ /* total size of the entries */ ++ unsigned int entries_size; ++ /* start of the chains */ ++ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; ++ /* nr of counters userspace expects back */ ++ unsigned int num_counters; ++ /* where the kernel will put the old counters */ ++ struct ebt_counter *counters; ++ char *entries; ++}; ++ ++struct ebt_replace_kernel { + char name[EBT_TABLE_MAXNAMELEN]; + unsigned int valid_hooks; + /* nr of rules in the table */ +@@ -47,21 +63,12 @@ struct ebt_replace + /* total size of the entries */ + unsigned int entries_size; + /* start of the chains */ +-#ifdef KERNEL_64_USERSPACE_32 +- uint64_t hook_entry[NF_BR_NUMHOOKS]; +-#else + struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; +-#endif + /* nr of counters userspace expects back */ + unsigned int num_counters; + /* where the kernel will put the old counters */ +-#ifdef KERNEL_64_USERSPACE_32 +- uint64_t counters; +- uint64_t entries; +-#else + struct ebt_counter *counters; + char *entries; +-#endif + }; + + struct ebt_entries { +@@ -85,7 +92,7 @@ struct ebt_entries { + + /* This is a hack to make a difference between an ebt_entry struct and an + * ebt_entries struct when traversing the entries from start to end. +- * Using this simplifies the code alot, while still being able to use ++ * Using this simplifies the code a lot, while still being able to use + * ebt_entries. + * Contrary, iptables doesn't use something like ebt_entries and therefore uses + * different techniques for naming the policy and such. So, iptables doesn't +@@ -110,56 +117,40 @@ struct ebt_entries { + #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ + | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) + +-struct ebt_entry_match +-{ ++struct ebt_entry_match { + union { + char name[EBT_FUNCTION_MAXNAMELEN]; +- struct ebt_match *match; ++ struct xt_match *match; + } u; + /* size of data */ + unsigned int match_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); + }; + +-struct ebt_entry_watcher +-{ ++struct ebt_entry_watcher { + union { + char name[EBT_FUNCTION_MAXNAMELEN]; +- struct ebt_watcher *watcher; ++ struct xt_target *watcher; + } u; + /* size of data */ + unsigned int watcher_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); + }; + +-struct ebt_entry_target +-{ ++struct ebt_entry_target { + union { + char name[EBT_FUNCTION_MAXNAMELEN]; +- struct ebt_target *target; ++ struct xt_target *target; + } u; + /* size of data */ + unsigned int target_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif + unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); + }; + + #define EBT_STANDARD_TARGET "standard" +-struct ebt_standard_target +-{ ++struct ebt_standard_target { + struct ebt_entry_target target; + int verdict; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif + }; + + /* one entry */ +@@ -167,7 +158,7 @@ struct ebt_entry { + /* this needs to be the first field */ + unsigned int bitmask; + unsigned int invflags; +- uint16_t ethproto; ++ __be16 ethproto; + /* the physical in-dev */ + char in[IFNAMSIZ]; + /* the logical in-dev */ +@@ -202,6 +193,7 @@ struct ebt_entry { + #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) + #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) + ++ + /* blatently stolen from ip_tables.h + * fn returns 0 to continue iteration */ + #define EBT_MATCH_ITERATE(e, fn, args...) \ +diff --git a/include/linux/types.h b/include/linux/types.h +index 630cd3bb01f0a..23ea78fd1847a 100644 +--- a/include/linux/types.h ++++ b/include/linux/types.h +@@ -38,7 +38,7 @@ typedef __u32 __bitwise __wsum; + * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid + * common 32/64-bit compat problems. + * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other +- * architectures) and to 8-byte boundaries on 64-bit architetures. The new ++ * architectures) and to 8-byte boundaries on 64-bit architectures. The new + * aligned_64 type enforces 8-byte alignment so that structs containing + * aligned_64 values have the same alignment on 32-bit and 64-bit architectures. + * No conversions are necessary between 32-bit user-space and a 64-bit kernel. +-- +2.21.0 + diff --git a/SOURCES/0008-extensions-Use-stdint-types.patch b/SOURCES/0008-extensions-Use-stdint-types.patch new file mode 100644 index 0000000..2d7db9f --- /dev/null +++ b/SOURCES/0008-extensions-Use-stdint-types.patch @@ -0,0 +1,68 @@ +From 5bee10734107bd4365fa9aff634c1b492634f454 Mon Sep 17 00:00:00 2001 +From: Felix Janda +Date: Sat, 16 May 2015 12:22:39 +0200 +Subject: [PATCH] extensions: Use stdint types + +Signed-off-by: Felix Janda +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip6.c | 4 ++-- + extensions/ebt_limit.c | 10 +++++----- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c +index e3e0956e00f01..dd48547b0010b 100644 +--- a/extensions/ebt_ip6.c ++++ b/extensions/ebt_ip6.c +@@ -53,8 +53,8 @@ static const struct option opts[] = + + struct icmpv6_names { + const char *name; +- u_int8_t type; +- u_int8_t code_min, code_max; ++ uint8_t type; ++ uint8_t code_min, code_max; + }; + + static const struct icmpv6_names icmpv6_codes[] = { +diff --git a/extensions/ebt_limit.c b/extensions/ebt_limit.c +index ee40e5ccc9172..d189a09aa7cab 100644 +--- a/extensions/ebt_limit.c ++++ b/extensions/ebt_limit.c +@@ -59,11 +59,11 @@ static void print_help(void) + " default %u\n", EBT_LIMIT_BURST); + } + +-static int parse_rate(const char *rate, u_int32_t *val) ++static int parse_rate(const char *rate, uint32_t *val) + { + const char *delim; +- u_int32_t r; +- u_int32_t mult = 1; /* Seconds by default. */ ++ uint32_t r; ++ uint32_t mult = 1; /* Seconds by default. */ + + delim = strchr(rate, '/'); + if (delim) { +@@ -151,7 +151,7 @@ static void final_check(const struct ebt_u_entry *entry, + struct rates + { + const char *name; +- u_int32_t mult; ++ uint32_t mult; + }; + + static struct rates g_rates[] = +@@ -162,7 +162,7 @@ static struct rates g_rates[] = + { "sec", EBT_LIMIT_SCALE } + }; + +-static void print_rate(u_int32_t period) ++static void print_rate(uint32_t period) + { + unsigned int i; + +-- +2.21.0 + diff --git a/SOURCES/0009-ethernetdb.h-Remove-C-specific-compiler-hint-macro-_.patch b/SOURCES/0009-ethernetdb.h-Remove-C-specific-compiler-hint-macro-_.patch new file mode 100644 index 0000000..4339b8d --- /dev/null +++ b/SOURCES/0009-ethernetdb.h-Remove-C-specific-compiler-hint-macro-_.patch @@ -0,0 +1,48 @@ +From 53fb609bce104b316052acec39437c62407634e9 Mon Sep 17 00:00:00 2001 +From: Felix Janda +Date: Sat, 16 May 2015 12:31:58 +0200 +Subject: [PATCH] ethernetdb.h: Remove C++ specific compiler hint macro _THROW + +Fixes compilation with musl libc + +Signed-off-by: Felix Janda +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + include/ethernetdb.h | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/include/ethernetdb.h b/include/ethernetdb.h +index 46d8bfd1b7e58..1683abe01987e 100644 +--- a/include/ethernetdb.h ++++ b/include/ethernetdb.h +@@ -38,21 +38,20 @@ struct ethertypeent { + + /* Open ethertype data base files and mark them as staying open even + after a later search if STAY_OPEN is non-zero. */ +-extern void setethertypeent(int __stay_open) __THROW; ++extern void setethertypeent(int __stay_open); + + /* Close ethertype data base files and clear `stay open' flag. */ +-extern void endethertypeent(void) __THROW; ++extern void endethertypeent(void); + + /* Get next entry from ethertype data base file. Open data base if + necessary. */ +-extern struct ethertypeent *getethertypeent(void) __THROW; ++extern struct ethertypeent *getethertypeent(void); + + /* Return entry from ethertype data base for network with NAME. */ +-extern struct ethertypeent *getethertypebyname(__const char *__name) +- __THROW; ++extern struct ethertypeent *getethertypebyname(__const char *__name); + + /* Return entry from ethertype data base which number is PROTO. */ +-extern struct ethertypeent *getethertypebynumber(int __ethertype) __THROW; ++extern struct ethertypeent *getethertypebynumber(int __ethertype); + + + #endif /* ethernetdb.h */ +-- +2.21.0 + diff --git a/SOURCES/0010-ebtables-Allow-RETURN-target-rules-in-user-defined-c.patch b/SOURCES/0010-ebtables-Allow-RETURN-target-rules-in-user-defined-c.patch new file mode 100644 index 0000000..b54f158 --- /dev/null +++ b/SOURCES/0010-ebtables-Allow-RETURN-target-rules-in-user-defined-c.patch @@ -0,0 +1,48 @@ +From 31b9f879b04314da07d79dd653465c4dc030f819 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alin=20N=C4=83stac?= +Date: Thu, 22 Oct 2015 16:41:03 +0200 +Subject: [PATCH] ebtables: Allow RETURN target rules in user defined chains + +During loop checking ebtables marks entries with '1 << NF_BR_NUMHOOKS' if +they're called from a base chain rather than a user defined chain. + +This can be used by ebtables targets that can encode a special return +value to bail out if e.g. RETURN is used from a base chain. + +Unfortunately, this is broken, since the '1 << NF_BR_NUMHOOKS' is also +copied to called user-defined-chains (i.e., a user defined chain can no +longer be distinguished from a base chain): + +root@OpenWrt:~# ebtables -N foo +root@OpenWrt:~# ebtables -A OUTPUT -j foo +root@OpenWrt:~# ebtables -A foo -j mark --mark-or 3 --mark-target RETURN +--mark-target RETURN not allowed on base chain. + +This works if -A OUTPUT -j foo is omitted, but will still appear +if we try to call foo from OUTPUT afterwards. + +After this patch we still reject +'-A OUTPUT -j mark .. --mark-target RETURN'. + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + libebtc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libebtc.c b/libebtc.c +index 17ba8f243dd45..74830ecf2e91b 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -1102,7 +1102,7 @@ void ebt_check_for_loops(struct ebt_u_replace *replace) + /* check if we've dealt with this chain already */ + if (entries2->hook_mask & (1<hook_mask |= entries->hook_mask; ++ entries2->hook_mask |= entries->hook_mask & ~(1 << NF_BR_NUMHOOKS); + /* Jump to the chain, make sure we know how to get back */ + stack[sp].chain_nr = chain_nr; + stack[sp].n = j; +-- +2.21.0 + diff --git a/SOURCES/0011-ebtables-extensions-Constify-option-struct.patch b/SOURCES/0011-ebtables-extensions-Constify-option-struct.patch new file mode 100644 index 0000000..fc6c3e4 --- /dev/null +++ b/SOURCES/0011-ebtables-extensions-Constify-option-struct.patch @@ -0,0 +1,265 @@ +From d1824930e9c9011c84f162db71d1ed649e14a6d1 Mon Sep 17 00:00:00 2001 +From: Gargi Sharma +Date: Tue, 28 Mar 2017 19:42:39 +0530 +Subject: [PATCH] ebtables: extensions: Constify option struct + +The struct of the type option is only used to initialise a field +inside the ebt_u_watcher or ebt_u_target or ebt_u_match struct and +is not modified anywhere. + +Signed-off-by: Gargi Sharma +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_802_3.c | 2 +- + extensions/ebt_among.c | 2 +- + extensions/ebt_arp.c | 2 +- + extensions/ebt_arpreply.c | 2 +- + extensions/ebt_ip.c | 2 +- + extensions/ebt_limit.c | 2 +- + extensions/ebt_log.c | 2 +- + extensions/ebt_mark.c | 2 +- + extensions/ebt_mark_m.c | 2 +- + extensions/ebt_nat.c | 4 ++-- + extensions/ebt_nflog.c | 2 +- + extensions/ebt_pkttype.c | 2 +- + extensions/ebt_redirect.c | 2 +- + extensions/ebt_standard.c | 2 +- + extensions/ebt_stp.c | 2 +- + extensions/ebt_ulog.c | 2 +- + extensions/ebt_vlan.c | 2 +- + 17 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/extensions/ebt_802_3.c b/extensions/ebt_802_3.c +index dd22eb2605334..458484939231d 100644 +--- a/extensions/ebt_802_3.c ++++ b/extensions/ebt_802_3.c +@@ -17,7 +17,7 @@ + #define _802_3_SAP '1' + #define _802_3_TYPE '2' + +-static struct option opts[] = ++static const struct option opts[] = + { + { "802_3-sap" , required_argument, 0, _802_3_SAP }, + { "802_3-type" , required_argument, 0, _802_3_TYPE }, +diff --git a/extensions/ebt_among.c b/extensions/ebt_among.c +index f97d07ec118ed..e4fc5ac22a005 100644 +--- a/extensions/ebt_among.c ++++ b/extensions/ebt_among.c +@@ -26,7 +26,7 @@ + #define AMONG_DST_F '3' + #define AMONG_SRC_F '4' + +-static struct option opts[] = { ++static const struct option opts[] = { + {"among-dst", required_argument, 0, AMONG_DST}, + {"among-src", required_argument, 0, AMONG_SRC}, + {"among-dst-file", required_argument, 0, AMONG_DST_F}, +diff --git a/extensions/ebt_arp.c b/extensions/ebt_arp.c +index 64d337d5967cf..b2819553ab313 100644 +--- a/extensions/ebt_arp.c ++++ b/extensions/ebt_arp.c +@@ -24,7 +24,7 @@ + #define ARP_MAC_S '6' + #define ARP_MAC_D '7' + #define ARP_GRAT '8' +-static struct option opts[] = ++static const struct option opts[] = + { + { "arp-opcode" , required_argument, 0, ARP_OPCODE }, + { "arp-op" , required_argument, 0, ARP_OPCODE }, +diff --git a/extensions/ebt_arpreply.c b/extensions/ebt_arpreply.c +index c3757f389ba23..51eda66adbff3 100644 +--- a/extensions/ebt_arpreply.c ++++ b/extensions/ebt_arpreply.c +@@ -19,7 +19,7 @@ static int mac_supplied; + + #define REPLY_MAC '1' + #define REPLY_TARGET '2' +-static struct option opts[] = ++static const struct option opts[] = + { + { "arpreply-mac" , required_argument, 0, REPLY_MAC }, + { "arpreply-target" , required_argument, 0, REPLY_TARGET }, +diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c +index 4e0b7f0780302..59559feffa50b 100644 +--- a/extensions/ebt_ip.c ++++ b/extensions/ebt_ip.c +@@ -25,7 +25,7 @@ + #define IP_SPORT '5' + #define IP_DPORT '6' + +-static struct option opts[] = ++static const struct option opts[] = + { + { "ip-source" , required_argument, 0, IP_SOURCE }, + { "ip-src" , required_argument, 0, IP_SOURCE }, +diff --git a/extensions/ebt_limit.c b/extensions/ebt_limit.c +index d189a09aa7cab..2cbf4dee51fb4 100644 +--- a/extensions/ebt_limit.c ++++ b/extensions/ebt_limit.c +@@ -41,7 +41,7 @@ static int string_to_number(const char *s, unsigned int min, unsigned int max, + #define ARG_LIMIT '1' + #define ARG_LIMIT_BURST '2' + +-static struct option opts[] = ++static const struct option opts[] = + { + { "limit", required_argument, 0, ARG_LIMIT }, + { "limit-burst", required_argument, 0, ARG_LIMIT_BURST }, +diff --git a/extensions/ebt_log.c b/extensions/ebt_log.c +index 1cf831a7ec17a..97d50919d25ca 100644 +--- a/extensions/ebt_log.c ++++ b/extensions/ebt_log.c +@@ -61,7 +61,7 @@ static int name_to_loglevel(char* arg) + #define LOG_IP '4' + #define LOG_LOG '5' + #define LOG_IP6 '6' +-static struct option opts[] = ++static const struct option opts[] = + { + { "log-prefix", required_argument, 0, LOG_PREFIX }, + { "log-level" , required_argument, 0, LOG_LEVEL }, +diff --git a/extensions/ebt_mark.c b/extensions/ebt_mark.c +index 5776b1cb24509..4cf1378d5085c 100644 +--- a/extensions/ebt_mark.c ++++ b/extensions/ebt_mark.c +@@ -20,7 +20,7 @@ static int mark_supplied; + #define MARK_ORMARK '3' + #define MARK_ANDMARK '4' + #define MARK_XORMARK '5' +-static struct option opts[] = ++static const struct option opts[] = + { + { "mark-target" , required_argument, 0, MARK_TARGET }, + /* an oldtime messup, we should have always used the scheme +diff --git a/extensions/ebt_mark_m.c b/extensions/ebt_mark_m.c +index 2a259b04368d0..7561f059c0108 100644 +--- a/extensions/ebt_mark_m.c ++++ b/extensions/ebt_mark_m.c +@@ -15,7 +15,7 @@ + + #define MARK '1' + +-static struct option opts[] = ++static const struct option opts[] = + { + { "mark", required_argument, 0, MARK }, + { 0 } +diff --git a/extensions/ebt_nat.c b/extensions/ebt_nat.c +index e6afbf8f3a3f8..00d9cd4083247 100644 +--- a/extensions/ebt_nat.c ++++ b/extensions/ebt_nat.c +@@ -21,7 +21,7 @@ static int to_source_supplied, to_dest_supplied; + #define NAT_S_TARGET '2' + #define NAT_D_TARGET '2' + #define NAT_S_ARP '3' +-static struct option opts_s[] = ++static const struct option opts_s[] = + { + { "to-source" , required_argument, 0, NAT_S }, + { "to-src" , required_argument, 0, NAT_S }, +@@ -30,7 +30,7 @@ static struct option opts_s[] = + { 0 } + }; + +-static struct option opts_d[] = ++static const struct option opts_d[] = + { + { "to-destination", required_argument, 0, NAT_D }, + { "to-dst" , required_argument, 0, NAT_D }, +diff --git a/extensions/ebt_nflog.c b/extensions/ebt_nflog.c +index 0cd10e05f1c33..405673a01f893 100644 +--- a/extensions/ebt_nflog.c ++++ b/extensions/ebt_nflog.c +@@ -25,7 +25,7 @@ enum { + NFLOG_NFLOG = 0x16, + }; + +-static struct option nflog_opts[] = { ++static const struct option nflog_opts[] = { + {"nflog-group", required_argument, NULL, NFLOG_GROUP}, + {"nflog-prefix", required_argument, NULL, NFLOG_PREFIX}, + {"nflog-range", required_argument, NULL, NFLOG_RANGE}, +diff --git a/extensions/ebt_pkttype.c b/extensions/ebt_pkttype.c +index 5b5cb0398d559..486c85c3c3faf 100644 +--- a/extensions/ebt_pkttype.c ++++ b/extensions/ebt_pkttype.c +@@ -27,7 +27,7 @@ char *classes[] = + "\0" + }; + +-static struct option opts[] = ++static const struct option opts[] = + { + { "pkttype-type" , required_argument, 0, '1' }, + { 0 } +diff --git a/extensions/ebt_redirect.c b/extensions/ebt_redirect.c +index e47081894317c..3f8227a917583 100644 +--- a/extensions/ebt_redirect.c ++++ b/extensions/ebt_redirect.c +@@ -14,7 +14,7 @@ + #include + + #define REDIRECT_TARGET '1' +-static struct option opts[] = ++static const struct option opts[] = + { + { "redirect-target", required_argument, 0, REDIRECT_TARGET }, + { 0 } +diff --git a/extensions/ebt_standard.c b/extensions/ebt_standard.c +index 67d4d7cc7046b..81edead71a840 100644 +--- a/extensions/ebt_standard.c ++++ b/extensions/ebt_standard.c +@@ -11,7 +11,7 @@ + #include + #include "../include/ebtables_u.h" + +-static struct option opts[] = ++static const struct option opts[] = + { + {0} + }; +diff --git a/extensions/ebt_stp.c b/extensions/ebt_stp.c +index 2b108a707fe65..5c5fc3334311d 100644 +--- a/extensions/ebt_stp.c ++++ b/extensions/ebt_stp.c +@@ -27,7 +27,7 @@ + #define STP_FWDD 'l' + #define STP_NUMOPS 12 + +-static struct option opts[] = ++static const struct option opts[] = + { + { "stp-type" , required_argument, 0, STP_TYPE}, + { "stp-flags" , required_argument, 0, STP_FLAGS}, +diff --git a/extensions/ebt_ulog.c b/extensions/ebt_ulog.c +index 162586d7a4c35..54eec53f7069f 100644 +--- a/extensions/ebt_ulog.c ++++ b/extensions/ebt_ulog.c +@@ -24,7 +24,7 @@ + #define ULOG_CPRANGE '3' + #define ULOG_QTHRESHOLD '4' + #define ULOG_ULOG '5' +-static struct option opts[] = ++static const struct option opts[] = + { + { "ulog-prefix" , required_argument, 0, ULOG_PREFIX }, + { "ulog-nlgroup" , required_argument, 0, ULOG_NLGROUP }, +diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c +index 6714c82d4d1ac..0a37067b5ebde 100644 +--- a/extensions/ebt_vlan.c ++++ b/extensions/ebt_vlan.c +@@ -25,7 +25,7 @@ + #define VLAN_PRIO '2' + #define VLAN_ENCAP '3' + +-static struct option opts[] = { ++static const struct option opts[] = { + {"vlan-id" , required_argument, NULL, VLAN_ID}, + {"vlan-prio" , required_argument, NULL, VLAN_PRIO}, + {"vlan-encap", required_argument, NULL, VLAN_ENCAP}, +-- +2.21.0 + diff --git a/SOURCES/0012-Use-flock-for-concurrent-option.patch b/SOURCES/0012-Use-flock-for-concurrent-option.patch new file mode 100644 index 0000000..11becfd --- /dev/null +++ b/SOURCES/0012-Use-flock-for-concurrent-option.patch @@ -0,0 +1,126 @@ +From 908ec85f171a1307eeee48499f43d3778c96a210 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 6 Oct 2017 12:48:50 +0200 +Subject: [PATCH] Use flock() for --concurrent option + +The previous locking mechanism was not atomic, hence it was possible +that a killed ebtables process would leave the lock file in place which +in turn made future ebtables processes wait indefinitely for the lock to +become free. + +Fix this by using flock(). This also simplifies code quite a bit because +there is no need for a custom signal handler or an __exit routine +anymore. + +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + ebtables.c | 8 -------- + libebtc.c | 49 +++++-------------------------------------------- + 2 files changed, 5 insertions(+), 52 deletions(-) + +diff --git a/ebtables.c b/ebtables.c +index 62f1ba80063d8..f7dfccf4b2f31 100644 +--- a/ebtables.c ++++ b/ebtables.c +@@ -528,12 +528,6 @@ void ebt_early_init_once() + ebt_iterate_targets(merge_target); + } + +-/* signal handler, installed when the option --concurrent is specified. */ +-static void sighandler(int signum) +-{ +- exit(-1); +-} +- + /* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */ + int do_command(int argc, char *argv[], int exec_style, + struct ebt_u_replace *replace_) +@@ -1047,8 +1041,6 @@ big_iface_length: + strcpy(replace->filename, optarg); + break; + case 13 : /* concurrent */ +- signal(SIGINT, sighandler); +- signal(SIGTERM, sighandler); + use_lockfd = 1; + break; + case 1 : +diff --git a/libebtc.c b/libebtc.c +index 74830ecf2e91b..c0ff8ccfa66db 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -31,6 +31,7 @@ + #include "include/ethernetdb.h" + #include + #include ++#include + #include + #include + #include +@@ -137,58 +138,18 @@ void ebt_list_extensions() + #define LOCKDIR "/var/lib/ebtables" + #define LOCKFILE LOCKDIR"/lock" + #endif +-static int lockfd = -1, locked; + int use_lockfd; + /* Returns 0 on success, -1 when the file is locked by another process + * or -2 on any other error. */ + static int lock_file() + { +- int try = 0; +- int ret = 0; +- sigset_t sigset; +- +-tryagain: +- /* the SIGINT handler will call unlock_file. To make sure the state +- * of the variable locked is correct, we need to temporarily mask the +- * SIGINT interrupt. */ +- sigemptyset(&sigset); +- sigaddset(&sigset, SIGINT); +- sigprocmask(SIG_BLOCK, &sigset, NULL); +- lockfd = open(LOCKFILE, O_CREAT | O_EXCL | O_WRONLY, 00600); +- if (lockfd < 0) { +- if (errno == EEXIST) +- ret = -1; +- else if (try == 1) +- ret = -2; +- else { +- if (mkdir(LOCKDIR, 00700)) +- ret = -2; +- else { +- try = 1; +- goto tryagain; +- } +- } +- } else { +- close(lockfd); +- locked = 1; +- } +- sigprocmask(SIG_UNBLOCK, &sigset, NULL); +- return ret; +-} ++ int fd = open(LOCKFILE, O_CREAT, 00600); + +-void unlock_file() +-{ +- if (locked) { +- remove(LOCKFILE); +- locked = 0; +- } ++ if (fd < 0) ++ return -2; ++ return flock(fd, LOCK_EX); + } + +-void __attribute__ ((destructor)) onexit() +-{ +- if (use_lockfd) +- unlock_file(); +-} + /* Get the table from the kernel or from a binary file + * init: 1 = ask the kernel for the initial contents of a table, i.e. the + * way it looks when the table is insmod'ed +-- +2.21.0 + diff --git a/SOURCES/0013-Fix-locking-if-LOCKDIR-does-not-exist.patch b/SOURCES/0013-Fix-locking-if-LOCKDIR-does-not-exist.patch new file mode 100644 index 0000000..4d5ca65 --- /dev/null +++ b/SOURCES/0013-Fix-locking-if-LOCKDIR-does-not-exist.patch @@ -0,0 +1,46 @@ +From b3d4dbcbfe2986711492634c193f32db14f06a22 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 15 Jan 2018 16:27:31 +0100 +Subject: [PATCH] Fix locking if LOCKDIR does not exist + +The previous conversion to using flock() missed a crucial bit of code +which tries to create LOCKDIR once in case opening the lock failed - +This patch reestablishes the old behaviour. + +Reported-by: Tangchen (UVP) +Fixes: 6a826591878db ("Use flock() for --concurrent option") +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + libebtc.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/libebtc.c b/libebtc.c +index c0ff8ccfa66db..d47424872dc51 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -143,10 +143,16 @@ int use_lockfd; + * or -2 on any other error. */ + static int lock_file() + { +- int fd = open(LOCKFILE, O_CREAT, 00600); +- +- if (fd < 0) +- return -2; ++ int fd, try = 0; ++ ++retry: ++ fd = open(LOCKFILE, O_CREAT, 00600); ++ if (fd < 0) { ++ if (try == 1 || mkdir(LOCKDIR, 00700)) ++ return -2; ++ try = 1; ++ goto retry; ++ } + return flock(fd, LOCK_EX); + } + +-- +2.21.0 + diff --git a/SOURCES/0014-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch b/SOURCES/0014-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch new file mode 100644 index 0000000..103e78f --- /dev/null +++ b/SOURCES/0014-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch @@ -0,0 +1,54 @@ +From e3335b04db67142173124e28914b4fc5db2cfc38 Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Sun, 4 Mar 2018 09:28:55 +0100 +Subject: [PATCH] include: sync linux/netfilter_bridge/ebt_ip.h with kernel + +Signed-off-by: Matthias Schiffer +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + include/linux/netfilter_bridge/ebt_ip.h | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h +index c4bbc41b0ea47..46d6261370b0c 100644 +--- a/include/linux/netfilter_bridge/ebt_ip.h ++++ b/include/linux/netfilter_bridge/ebt_ip.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + /* + * ebt_ip + * +@@ -23,8 +24,10 @@ + #define EBT_IP_PROTO 0x08 + #define EBT_IP_SPORT 0x10 + #define EBT_IP_DPORT 0x20 ++#define EBT_IP_ICMP 0x40 ++#define EBT_IP_IGMP 0x80 + #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ +- EBT_IP_SPORT | EBT_IP_DPORT ) ++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP) + #define EBT_IP_MATCH "ip" + + /* the same values are used for the invflags */ +@@ -37,8 +40,15 @@ struct ebt_ip_info { + __u8 protocol; + __u8 bitmask; + __u8 invflags; +- __u16 sport[2]; +- __u16 dport[2]; ++ union { ++ __u16 sport[2]; ++ __u8 icmp_type[2]; ++ __u8 igmp_type[2]; ++ }; ++ union { ++ __u16 dport[2]; ++ __u8 icmp_code[2]; ++ }; + }; + + #endif +-- +2.21.0 + diff --git a/SOURCES/0015-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch b/SOURCES/0015-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch new file mode 100644 index 0000000..7ef7b54 --- /dev/null +++ b/SOURCES/0015-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch @@ -0,0 +1,464 @@ +From 67de7ef4ab4d3042f8f24f7f5ef20d5711e6820b Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Sun, 4 Mar 2018 09:28:56 +0100 +Subject: [PATCH] Move ICMP type handling functions from ebt_ip6 to + useful_functions.c + +Allow using these functions for ebt_ip as well. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip6.c | 165 +++---------------------------------------- + include/ebtables_u.h | 17 ++++- + useful_functions.c | 151 ++++++++++++++++++++++++++++++++++++++- + 3 files changed, 174 insertions(+), 159 deletions(-) + +diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c +index dd48547b0010b..347797b4afe18 100644 +--- a/extensions/ebt_ip6.c ++++ b/extensions/ebt_ip6.c +@@ -11,9 +11,6 @@ + * + */ + +-#include +-#include +-#include + #include + #include + #include +@@ -51,13 +48,7 @@ static const struct option opts[] = + }; + + +-struct icmpv6_names { +- const char *name; +- uint8_t type; +- uint8_t code_min, code_max; +-}; +- +-static const struct icmpv6_names icmpv6_codes[] = { ++static const struct ebt_icmp_names icmpv6_codes[] = { + { "destination-unreachable", 1, 0, 0xFF }, + { "no-route", 1, 0, 0 }, + { "communication-prohibited", 1, 1, 1 }, +@@ -141,97 +132,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports) + free(buffer); + } + +-static char* +-parse_num(const char *str, long min, long max, long *num) +-{ +- char *end; +- +- errno = 0; +- *num = strtol(str, &end, 10); +- if (errno && (*num == LONG_MIN || *num == LONG_MAX)) { +- ebt_print_error("Invalid number %s: %s", str, strerror(errno)); +- return NULL; +- } +- if (min <= max) { +- if (*num > max || *num < min) { +- ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max); +- return NULL; +- } +- } +- if (*num == 0 && str == end) +- return NULL; +- return end; +-} +- +-static char * +-parse_range(const char *str, long min, long max, long num[]) +-{ +- char *next; +- +- next = parse_num(str, min, max, num); +- if (next == NULL) +- return NULL; +- if (next && *next == ':') +- next = parse_num(next+1, min, max, &num[1]); +- else +- num[1] = num[0]; +- return next; +-} +- +-static int +-parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[]) +-{ +- static const unsigned int limit = ARRAY_SIZE(icmpv6_codes); +- unsigned int match = limit; +- unsigned int i; +- long number[2]; +- +- for (i = 0; i < limit; i++) { +- if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type))) +- continue; +- if (match != limit) +- ebt_print_error("Ambiguous ICMPv6 type `%s':" +- " `%s' or `%s'?", +- icmpv6type, icmpv6_codes[match].name, +- icmpv6_codes[i].name); +- match = i; +- } +- +- if (match < limit) { +- type[0] = type[1] = icmpv6_codes[match].type; +- code[0] = icmpv6_codes[match].code_min; +- code[1] = icmpv6_codes[match].code_max; +- } else { +- char *next = parse_range(icmpv6type, 0, 255, number); +- if (!next) { +- ebt_print_error("Unknown ICMPv6 type `%s'", +- icmpv6type); +- return -1; +- } +- type[0] = (uint8_t) number[0]; +- type[1] = (uint8_t) number[1]; +- switch (*next) { +- case 0: +- code[0] = 0; +- code[1] = 255; +- return 0; +- case '/': +- next = parse_range(next+1, 0, 255, number); +- code[0] = (uint8_t) number[0]; +- code[1] = (uint8_t) number[1]; +- if (next == NULL) +- return -1; +- if (next && *next == 0) +- return 0; +- /* fallthrough */ +- default: +- ebt_print_error("unknown character %c", *next); +- return -1; +- } +- } +- return 0; +-} +- + static void print_port_range(uint16_t *ports) + { + if (ports[0] == ports[1]) +@@ -240,58 +140,6 @@ static void print_port_range(uint16_t *ports) + printf("%d:%d ", ports[0], ports[1]); + } + +-static void print_icmp_code(uint8_t *code) +-{ +- if (code[0] == code[1]) +- printf("/%"PRIu8 " ", code[0]); +- else +- printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]); +-} +- +-static void print_icmp_type(uint8_t *type, uint8_t *code) +-{ +- unsigned int i; +- +- if (type[0] != type[1]) { +- printf("%"PRIu8 ":%" PRIu8, type[0], type[1]); +- print_icmp_code(code); +- return; +- } +- +- for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) { +- if (icmpv6_codes[i].type != type[0]) +- continue; +- +- if (icmpv6_codes[i].code_min == code[0] && +- icmpv6_codes[i].code_max == code[1]) { +- printf("%s ", icmpv6_codes[i].name); +- return; +- } +- } +- printf("%"PRIu8, type[0]); +- print_icmp_code(code); +-} +- +-static void print_icmpv6types(void) +-{ +- unsigned int i; +- printf("Valid ICMPv6 Types:"); +- +- for (i=0; i < ARRAY_SIZE(icmpv6_codes); i++) { +- if (i && icmpv6_codes[i].type == icmpv6_codes[i-1].type) { +- if (icmpv6_codes[i].code_min == icmpv6_codes[i-1].code_min +- && (icmpv6_codes[i].code_max +- == icmpv6_codes[i-1].code_max)) +- printf(" (%s)", icmpv6_codes[i].name); +- else +- printf("\n %s", icmpv6_codes[i].name); +- } +- else +- printf("\n%s", icmpv6_codes[i].name); +- } +- printf("\n"); +-} +- + static void print_help() + { + printf( +@@ -303,7 +151,9 @@ static void print_help() + "--ip6-sport [!] port[:port] : tcp/udp source port or port range\n" + "--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n" + "--ip6-icmp-type [!] type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n"); +-print_icmpv6types(); ++ ++ printf("\nValid ICMPv6 Types:\n"); ++ ebt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes)); + } + + static void init(struct ebt_entry_match *match) +@@ -374,7 +224,9 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + ipinfo->bitmask |= EBT_IP6_ICMP6; + if (ebt_check_inverse2(optarg)) + ipinfo->invflags |= EBT_IP6_ICMP6; +- if (parse_icmpv6(optarg, ipinfo->icmpv6_type, ipinfo->icmpv6_code)) ++ if (ebt_parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), ++ optarg, ipinfo->icmpv6_type, ++ ipinfo->icmpv6_code)) + return 0; + break; + +@@ -493,7 +345,8 @@ static void print(const struct ebt_u_entry *entry, + printf("--ip6-icmp-type "); + if (ipinfo->invflags & EBT_IP6_ICMP6) + printf("! "); +- print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code); ++ ebt_print_icmp_type(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), ++ ipinfo->icmpv6_type, ipinfo->icmpv6_code); + } + } + +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 35a5bcc54c865..17afa9487f5ad 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -222,6 +222,15 @@ struct ebt_u_target + struct ebt_u_target *next; + }; + ++ ++struct ebt_icmp_names { ++ const char *name; ++ uint8_t type; ++ uint8_t code_min, code_max; ++}; ++ ++ ++ + /* libebtc.c */ + + extern struct ebt_u_table *ebt_tables; +@@ -300,11 +309,17 @@ void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask) + int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask); + void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk); + char *ebt_mask_to_dotted(uint32_t mask); +-void ebt_parse_ip6_address(char *address, struct in6_addr *addr, ++void ebt_parse_ip6_address(char *address, struct in6_addr *addr, + struct in6_addr *msk); + char *ebt_ip6_to_numeric(const struct in6_addr *addrp); + char *ebt_ip6_mask_to_string(const struct in6_addr *msk); + ++int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes, ++ const char *icmptype, uint8_t type[], uint8_t code[]); ++void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes, ++ size_t n_codes, uint8_t *type, uint8_t *code); ++void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes, ++ size_t n_codes); + + int do_command(int argc, char *argv[], int exec_style, + struct ebt_u_replace *replace_); +diff --git a/useful_functions.c b/useful_functions.c +index d14cbe9dbdba1..8f54bae83fae8 100644 +--- a/useful_functions.c ++++ b/useful_functions.c +@@ -24,6 +24,9 @@ + */ + #include "include/ebtables_u.h" + #include "include/ethernetdb.h" ++#include ++#include ++#include + #include + #include + #include +@@ -34,6 +37,7 @@ + #include + #include + ++ + const unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0}; + const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; + const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; +@@ -188,7 +192,7 @@ static int undot_ip(char *ip, unsigned char *ip2) + return -1; + *q = '\0'; + onebyte = strtol(p, &end, 10); +- if (*end != '\0' || onebyte > 255 || onebyte < 0) ++ if (*end != '\0' || onebyte > 255 || onebyte < 0) + return -1; + ip2[i] = (unsigned char)onebyte; + p = q + 1; +@@ -275,7 +279,7 @@ char *ebt_mask_to_dotted(uint32_t mask) + *buf = '\0'; + else + /* Mask was not a decent combination of 1's and 0's */ +- sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], ++ sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], + ((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2], + ((unsigned char *)&mask)[3]); + +@@ -424,3 +428,146 @@ char *ebt_ip6_mask_to_string(const struct in6_addr *msk) + sprintf(buf, "/%s", ebt_ip6_to_numeric(msk)); + return buf; + } ++ ++static char* ++parse_num(const char *str, long min, long max, long *num) ++{ ++ char *end; ++ ++ errno = 0; ++ *num = strtol(str, &end, 10); ++ if (errno && (*num == LONG_MIN || *num == LONG_MAX)) { ++ ebt_print_error("Invalid number %s: %s", str, strerror(errno)); ++ return NULL; ++ } ++ if (min <= max) { ++ if (*num > max || *num < min) { ++ ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max); ++ return NULL; ++ } ++ } ++ if (*num == 0 && str == end) ++ return NULL; ++ return end; ++} ++ ++static char * ++parse_range(const char *str, long min, long max, long num[]) ++{ ++ char *next; ++ ++ next = parse_num(str, min, max, num); ++ if (next == NULL) ++ return NULL; ++ if (next && *next == ':') ++ next = parse_num(next+1, min, max, &num[1]); ++ else ++ num[1] = num[0]; ++ return next; ++} ++ ++int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes, ++ const char *icmptype, uint8_t type[], uint8_t code[]) ++{ ++ unsigned int match = n_codes; ++ unsigned int i; ++ long number[2]; ++ ++ for (i = 0; i < n_codes; i++) { ++ if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype))) ++ continue; ++ if (match != n_codes) ++ ebt_print_error("Ambiguous ICMP type `%s':" ++ " `%s' or `%s'?", ++ icmptype, icmp_codes[match].name, ++ icmp_codes[i].name); ++ match = i; ++ } ++ ++ if (match < n_codes) { ++ type[0] = type[1] = icmp_codes[match].type; ++ code[0] = icmp_codes[match].code_min; ++ code[1] = icmp_codes[match].code_max; ++ } else { ++ char *next = parse_range(icmptype, 0, 255, number); ++ if (!next) { ++ ebt_print_error("Unknown ICMP type `%s'", ++ icmptype); ++ return -1; ++ } ++ type[0] = (uint8_t) number[0]; ++ type[1] = (uint8_t) number[1]; ++ switch (*next) { ++ case 0: ++ code[0] = 0; ++ code[1] = 255; ++ return 0; ++ case '/': ++ next = parse_range(next+1, 0, 255, number); ++ code[0] = (uint8_t) number[0]; ++ code[1] = (uint8_t) number[1]; ++ if (next == NULL) ++ return -1; ++ if (next && *next == 0) ++ return 0; ++ /* fallthrough */ ++ default: ++ ebt_print_error("unknown character %c", *next); ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++static void print_icmp_code(uint8_t *code) ++{ ++ if (code[0] == code[1]) ++ printf("/%"PRIu8 " ", code[0]); ++ else ++ printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]); ++} ++ ++void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes, ++ size_t n_codes, uint8_t *type, uint8_t *code) ++{ ++ unsigned int i; ++ ++ if (type[0] != type[1]) { ++ printf("%"PRIu8 ":%" PRIu8, type[0], type[1]); ++ print_icmp_code(code); ++ return; ++ } ++ ++ for (i = 0; i < n_codes; i++) { ++ if (icmp_codes[i].type != type[0]) ++ continue; ++ ++ if (icmp_codes[i].code_min == code[0] && ++ icmp_codes[i].code_max == code[1]) { ++ printf("%s ", icmp_codes[i].name); ++ return; ++ } ++ } ++ printf("%"PRIu8, type[0]); ++ print_icmp_code(code); ++} ++ ++void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes, ++ size_t n_codes) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < n_codes; i++) { ++ if (i && icmp_codes[i].type == icmp_codes[i-1].type) { ++ if (icmp_codes[i].code_min == icmp_codes[i-1].code_min ++ && (icmp_codes[i].code_max ++ == icmp_codes[i-1].code_max)) ++ printf(" (%s)", icmp_codes[i].name); ++ else ++ printf("\n %s", icmp_codes[i].name); ++ } ++ else ++ printf("\n%s", icmp_codes[i].name); ++ } ++ printf("\n"); ++} +-- +2.21.0 + diff --git a/SOURCES/0016-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch b/SOURCES/0016-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch new file mode 100644 index 0000000..98921b6 --- /dev/null +++ b/SOURCES/0016-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch @@ -0,0 +1,180 @@ +From fca4a7f4d3242ff4ad58081e69bc70ba1f6c46a5 Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Sun, 4 Mar 2018 09:28:57 +0100 +Subject: [PATCH] ebt_ip: add support for matching ICMP type and code + +We already have ICMPv6 type/code matches. This adds support for IPv4 ICMP +matches in the same way. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 94 insertions(+), 2 deletions(-) + +diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c +index 59559feffa50b..42660d4564fbf 100644 +--- a/extensions/ebt_ip.c ++++ b/extensions/ebt_ip.c +@@ -24,6 +24,7 @@ + #define IP_PROTO '4' + #define IP_SPORT '5' + #define IP_DPORT '6' ++#define IP_ICMP '7' + + static const struct option opts[] = + { +@@ -38,9 +39,64 @@ static const struct option opts[] = + { "ip-sport" , required_argument, 0, IP_SPORT }, + { "ip-destination-port" , required_argument, 0, IP_DPORT }, + { "ip-dport" , required_argument, 0, IP_DPORT }, ++ { "ip-icmp-type" , required_argument, 0, IP_ICMP }, + { 0 } + }; + ++static const struct ebt_icmp_names icmp_codes[] = { ++ { "echo-reply", 0, 0, 0xFF }, ++ /* Alias */ { "pong", 0, 0, 0xFF }, ++ ++ { "destination-unreachable", 3, 0, 0xFF }, ++ { "network-unreachable", 3, 0, 0 }, ++ { "host-unreachable", 3, 1, 1 }, ++ { "protocol-unreachable", 3, 2, 2 }, ++ { "port-unreachable", 3, 3, 3 }, ++ { "fragmentation-needed", 3, 4, 4 }, ++ { "source-route-failed", 3, 5, 5 }, ++ { "network-unknown", 3, 6, 6 }, ++ { "host-unknown", 3, 7, 7 }, ++ { "network-prohibited", 3, 9, 9 }, ++ { "host-prohibited", 3, 10, 10 }, ++ { "TOS-network-unreachable", 3, 11, 11 }, ++ { "TOS-host-unreachable", 3, 12, 12 }, ++ { "communication-prohibited", 3, 13, 13 }, ++ { "host-precedence-violation", 3, 14, 14 }, ++ { "precedence-cutoff", 3, 15, 15 }, ++ ++ { "source-quench", 4, 0, 0xFF }, ++ ++ { "redirect", 5, 0, 0xFF }, ++ { "network-redirect", 5, 0, 0 }, ++ { "host-redirect", 5, 1, 1 }, ++ { "TOS-network-redirect", 5, 2, 2 }, ++ { "TOS-host-redirect", 5, 3, 3 }, ++ ++ { "echo-request", 8, 0, 0xFF }, ++ /* Alias */ { "ping", 8, 0, 0xFF }, ++ ++ { "router-advertisement", 9, 0, 0xFF }, ++ ++ { "router-solicitation", 10, 0, 0xFF }, ++ ++ { "time-exceeded", 11, 0, 0xFF }, ++ /* Alias */ { "ttl-exceeded", 11, 0, 0xFF }, ++ { "ttl-zero-during-transit", 11, 0, 0 }, ++ { "ttl-zero-during-reassembly", 11, 1, 1 }, ++ ++ { "parameter-problem", 12, 0, 0xFF }, ++ { "ip-header-bad", 12, 0, 0 }, ++ { "required-option-missing", 12, 1, 1 }, ++ ++ { "timestamp-request", 13, 0, 0xFF }, ++ ++ { "timestamp-reply", 14, 0, 0xFF }, ++ ++ { "address-mask-request", 17, 0, 0xFF }, ++ ++ { "address-mask-reply", 18, 0, 0xFF } ++}; ++ + /* put the mask into 4 bytes */ + /* transform a protocol and service name into a port number */ + static uint16_t parse_port(const char *protocol, const char *name) +@@ -105,7 +161,11 @@ static void print_help() + "--ip-tos [!] tos : ip tos specification\n" + "--ip-proto [!] protocol : ip protocol specification\n" + "--ip-sport [!] port[:port] : tcp/udp source port or port range\n" +-"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n"); ++"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n" ++"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n"); ++ ++ printf("\nValid ICMP Types:\n"); ++ ebt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes)); + } + + static void init(struct ebt_entry_match *match) +@@ -122,6 +182,7 @@ static void init(struct ebt_entry_match *match) + #define OPT_PROTO 0x08 + #define OPT_SPORT 0x10 + #define OPT_DPORT 0x20 ++#define OPT_ICMP 0x40 + static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + unsigned int *flags, struct ebt_entry_match **match) + { +@@ -170,6 +231,16 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + parse_port_range(NULL, optarg, ipinfo->dport); + break; + ++ case IP_ICMP: ++ ebt_check_option2(flags, OPT_ICMP); ++ ipinfo->bitmask |= EBT_IP_ICMP; ++ if (ebt_check_inverse2(optarg)) ++ ipinfo->invflags |= EBT_IP_ICMP; ++ if (ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg, ++ ipinfo->icmp_type, ipinfo->icmp_code)) ++ return 0; ++ break; ++ + case IP_myTOS: + ebt_check_option2(flags, OPT_TOS); + if (ebt_check_inverse2(optarg)) +@@ -219,10 +290,17 @@ static void final_check(const struct ebt_u_entry *entry, + (ipinfo->protocol!=IPPROTO_TCP && + ipinfo->protocol!=IPPROTO_UDP && + ipinfo->protocol!=IPPROTO_SCTP && +- ipinfo->protocol!=IPPROTO_DCCP))) ++ ipinfo->protocol!=IPPROTO_DCCP))) { + ebt_print_error("For port filtering the IP protocol must be " + "either 6 (tcp), 17 (udp), 33 (dccp) or " + "132 (sctp)"); ++ } else if ((ipinfo->bitmask & EBT_IP_ICMP) && ++ (!(ipinfo->bitmask & EBT_IP_PROTO) || ++ ipinfo->invflags & EBT_IP_PROTO || ++ ipinfo->protocol != IPPROTO_ICMP)) { ++ ebt_print_error("For ICMP filtering the IP protocol must be " ++ "1 (icmp)"); ++ } + } + + static void print(const struct ebt_u_entry *entry, +@@ -280,6 +358,13 @@ static void print(const struct ebt_u_entry *entry, + printf("! "); + print_port_range(ipinfo->dport); + } ++ if (ipinfo->bitmask & EBT_IP_ICMP) { ++ printf("--ip-icmp-type "); ++ if (ipinfo->invflags & EBT_IP_ICMP) ++ printf("! "); ++ ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes), ++ ipinfo->icmp_type, ipinfo->icmp_code); ++ } + } + + static int compare(const struct ebt_entry_match *m1, +@@ -322,6 +407,13 @@ static int compare(const struct ebt_entry_match *m1, + ipinfo1->dport[1] != ipinfo2->dport[1]) + return 0; + } ++ if (ipinfo1->bitmask & EBT_IP_ICMP) { ++ if (ipinfo1->icmp_type[0] != ipinfo2->icmp_type[0] || ++ ipinfo1->icmp_type[1] != ipinfo2->icmp_type[1] || ++ ipinfo1->icmp_code[0] != ipinfo2->icmp_code[0] || ++ ipinfo1->icmp_code[1] != ipinfo2->icmp_code[1]) ++ return 0; ++ } + return 1; + } + +-- +2.21.0 + diff --git a/SOURCES/0017-ebt_ip-add-support-for-matching-IGMP-type.patch b/SOURCES/0017-ebt_ip-add-support-for-matching-IGMP-type.patch new file mode 100644 index 0000000..9a1cd74 --- /dev/null +++ b/SOURCES/0017-ebt_ip-add-support-for-matching-IGMP-type.patch @@ -0,0 +1,206 @@ +From 4808d6bfc74e9cf79609245c0ff3c6e079249ce5 Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Sun, 4 Mar 2018 09:28:58 +0100 +Subject: [PATCH] ebt_ip: add support for matching IGMP type + +We already have ICMPv6 type/code matches (which can be used to distinguish +different types of MLD packets). Add support for IPv4 IGMP matches in the +same way. + +To reuse as much code as possible, the ICMP type/code handling functions +are extended to allow passing a NULL code range. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_ip.c | 44 +++++++++++++++++++++++++++++++++++++++++++- + useful_functions.c | 35 ++++++++++++++++++++++------------- + 2 files changed, 65 insertions(+), 14 deletions(-) + +diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c +index 42660d4564fbf..1ffdb95f156df 100644 +--- a/extensions/ebt_ip.c ++++ b/extensions/ebt_ip.c +@@ -25,6 +25,7 @@ + #define IP_SPORT '5' + #define IP_DPORT '6' + #define IP_ICMP '7' ++#define IP_IGMP '8' + + static const struct option opts[] = + { +@@ -40,6 +41,7 @@ static const struct option opts[] = + { "ip-destination-port" , required_argument, 0, IP_DPORT }, + { "ip-dport" , required_argument, 0, IP_DPORT }, + { "ip-icmp-type" , required_argument, 0, IP_ICMP }, ++ { "ip-igmp-type" , required_argument, 0, IP_IGMP }, + { 0 } + }; + +@@ -97,6 +99,14 @@ static const struct ebt_icmp_names icmp_codes[] = { + { "address-mask-reply", 18, 0, 0xFF } + }; + ++static const struct ebt_icmp_names igmp_types[] = { ++ { "membership-query", 0x11 }, ++ { "membership-report-v1", 0x12 }, ++ { "membership-report-v2", 0x16 }, ++ { "leave-group", 0x17 }, ++ { "membership-report-v3", 0x22 }, ++}; ++ + /* put the mask into 4 bytes */ + /* transform a protocol and service name into a port number */ + static uint16_t parse_port(const char *protocol, const char *name) +@@ -162,10 +172,13 @@ static void print_help() + "--ip-proto [!] protocol : ip protocol specification\n" + "--ip-sport [!] port[:port] : tcp/udp source port or port range\n" + "--ip-dport [!] port[:port] : tcp/udp destination port or port range\n" +-"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n"); ++"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n" ++"--ip-igmp-type [!] type[:type] : igmp type or type range\n"); + + printf("\nValid ICMP Types:\n"); + ebt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes)); ++ printf("\nValid IGMP Types:\n"); ++ ebt_print_icmp_types(igmp_types, ARRAY_SIZE(igmp_types)); + } + + static void init(struct ebt_entry_match *match) +@@ -183,6 +196,7 @@ static void init(struct ebt_entry_match *match) + #define OPT_SPORT 0x10 + #define OPT_DPORT 0x20 + #define OPT_ICMP 0x40 ++#define OPT_IGMP 0x80 + static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + unsigned int *flags, struct ebt_entry_match **match) + { +@@ -241,6 +255,16 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + return 0; + break; + ++ case IP_IGMP: ++ ebt_check_option2(flags, OPT_IGMP); ++ ipinfo->bitmask |= EBT_IP_IGMP; ++ if (ebt_check_inverse2(optarg)) ++ ipinfo->invflags |= EBT_IP_IGMP; ++ if (ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg, ++ ipinfo->igmp_type, NULL)) ++ return 0; ++ break; ++ + case IP_myTOS: + ebt_check_option2(flags, OPT_TOS); + if (ebt_check_inverse2(optarg)) +@@ -300,6 +324,12 @@ static void final_check(const struct ebt_u_entry *entry, + ipinfo->protocol != IPPROTO_ICMP)) { + ebt_print_error("For ICMP filtering the IP protocol must be " + "1 (icmp)"); ++ } else if ((ipinfo->bitmask & EBT_IP_IGMP) && ++ (!(ipinfo->bitmask & EBT_IP_PROTO) || ++ ipinfo->invflags & EBT_IP_PROTO || ++ ipinfo->protocol != IPPROTO_IGMP)) { ++ ebt_print_error("For IGMP filtering the IP protocol must be " ++ "2 (igmp)"); + } + } + +@@ -365,6 +395,13 @@ static void print(const struct ebt_u_entry *entry, + ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes), + ipinfo->icmp_type, ipinfo->icmp_code); + } ++ if (ipinfo->bitmask & EBT_IP_IGMP) { ++ printf("--ip-igmp-type "); ++ if (ipinfo->invflags & EBT_IP_IGMP) ++ printf("! "); ++ ebt_print_icmp_type(igmp_types, ARRAY_SIZE(igmp_types), ++ ipinfo->igmp_type, NULL); ++ } + } + + static int compare(const struct ebt_entry_match *m1, +@@ -414,6 +451,11 @@ static int compare(const struct ebt_entry_match *m1, + ipinfo1->icmp_code[1] != ipinfo2->icmp_code[1]) + return 0; + } ++ if (ipinfo1->bitmask & EBT_IP_IGMP) { ++ if (ipinfo1->igmp_type[0] != ipinfo2->igmp_type[0] || ++ ipinfo1->igmp_type[1] != ipinfo2->igmp_type[1]) ++ return 0; ++ } + return 1; + } + +diff --git a/useful_functions.c b/useful_functions.c +index 8f54bae83fae8..8a34f820f230b 100644 +--- a/useful_functions.c ++++ b/useful_functions.c +@@ -486,8 +486,10 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes, + + if (match < n_codes) { + type[0] = type[1] = icmp_codes[match].type; +- code[0] = icmp_codes[match].code_min; +- code[1] = icmp_codes[match].code_max; ++ if (code) { ++ code[0] = icmp_codes[match].code_min; ++ code[1] = icmp_codes[match].code_max; ++ } + } else { + char *next = parse_range(icmptype, 0, 255, number); + if (!next) { +@@ -499,17 +501,21 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes, + type[1] = (uint8_t) number[1]; + switch (*next) { + case 0: +- code[0] = 0; +- code[1] = 255; ++ if (code) { ++ code[0] = 0; ++ code[1] = 255; ++ } + return 0; + case '/': +- next = parse_range(next+1, 0, 255, number); +- code[0] = (uint8_t) number[0]; +- code[1] = (uint8_t) number[1]; +- if (next == NULL) +- return -1; +- if (next && *next == 0) +- return 0; ++ if (code) { ++ next = parse_range(next+1, 0, 255, number); ++ code[0] = (uint8_t) number[0]; ++ code[1] = (uint8_t) number[1]; ++ if (next == NULL) ++ return -1; ++ if (next && *next == 0) ++ return 0; ++ } + /* fallthrough */ + default: + ebt_print_error("unknown character %c", *next); +@@ -521,6 +527,9 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes, + + static void print_icmp_code(uint8_t *code) + { ++ if (!code) ++ return; ++ + if (code[0] == code[1]) + printf("/%"PRIu8 " ", code[0]); + else +@@ -542,8 +551,8 @@ void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes, + if (icmp_codes[i].type != type[0]) + continue; + +- if (icmp_codes[i].code_min == code[0] && +- icmp_codes[i].code_max == code[1]) { ++ if (!code || (icmp_codes[i].code_min == code[0] && ++ icmp_codes[i].code_max == code[1])) { + printf("%s ", icmp_codes[i].name); + return; + } +-- +2.21.0 + diff --git a/SOURCES/0018-extensions-Add-string-filter-to-ebtables.patch b/SOURCES/0018-extensions-Add-string-filter-to-ebtables.patch new file mode 100644 index 0000000..d9ab70e --- /dev/null +++ b/SOURCES/0018-extensions-Add-string-filter-to-ebtables.patch @@ -0,0 +1,497 @@ +From 746a409113ab837c55b8cfaf819c7905c8f9e295 Mon Sep 17 00:00:00 2001 +From: Bernie Harris +Date: Wed, 21 Mar 2018 15:42:29 +1300 +Subject: [PATCH] extensions: Add string filter to ebtables + +This patch is part of a proposal to add a string filter to +ebtables, which would be similar to the string filter in +iptables. + +Like iptables, the ebtables filter uses the xt_string module, +however some modifications have been made for this to work +correctly. + +Currently ebtables assumes that the revision number of all match +modules is 0. The xt_string module doesn't register a match with +revision 0 so the solution is to modify ebtables to allow +extensions to specify a revision number, similar to iptables. +This gets passed down to the kernel, which is then able to find +the match module correctly. + +Signed-off-by: Bernie Harris +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + ebtables.8 | 20 +++ + extensions/Makefile | 2 +- + extensions/ebt_string.c | 319 ++++++++++++++++++++++++++++++++++++++++ + include/ebtables.h | 16 +- + include/ebtables_u.h | 1 + + libebtc.c | 6 +- + 6 files changed, 359 insertions(+), 5 deletions(-) + create mode 100644 extensions/ebt_string.c + +diff --git a/ebtables.8 b/ebtables.8 +index 45a88b2347de6..00c4562d20036 100644 +--- a/ebtables.8 ++++ b/ebtables.8 +@@ -810,6 +810,26 @@ The hello time timer (0-65535) range. + .TP + .BR "--stp-forward-delay " "[!] [\fIdelay\fP][:\fIdelay\fP]" + The forward delay timer (0-65535) range. ++.SS string ++This module matches on a given string using some pattern matching strategy. ++.TP ++.BR "--string-algo " "\fIalgorithm\fP" ++The pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris) ++.TP ++.BR "--string-from " "\fIoffset\fP" ++The lowest offset from which a match can start. (default: 0) ++.TP ++.BR "--string-to " "\fIoffset\fP" ++The highest offset from which a match can start. (default: size of frame) ++.TP ++.BR "--string " "[!] \fIpattern\fP" ++Matches the given pattern. ++.TP ++.BR "--string-hex " "[!] \fIpattern\fP" ++Matches the given pattern in hex notation, e.g. '|0D 0A|', '|0D0A|', 'www|09|netfilter|03|org|00|' ++.TP ++.BR "--string-icase" ++Ignore case when searching. + .SS vlan + Specify 802.1Q Tag Control Information fields. + The protocol must be specified as +diff --git a/extensions/Makefile b/extensions/Makefile +index b3548e81eca85..60a70a2298357 100644 +--- a/extensions/Makefile ++++ b/extensions/Makefile +@@ -1,7 +1,7 @@ + #! /usr/bin/make + + EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \ +- pkttype stp among limit ulog nflog ++ pkttype stp among limit ulog nflog string + EXT_TABLES+=filter nat broute + EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) + EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) +diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c +new file mode 100644 +index 0000000000000..793f5df312f10 +--- /dev/null ++++ b/extensions/ebt_string.c +@@ -0,0 +1,319 @@ ++/* ebt_string ++ * ++ * Author: ++ * Bernie Harris ++ * ++ * February, 2018 ++ * ++ * Based on: ++ * libxt_string.c, Copyright (C) 2000 Emmanuel Roger ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../include/ebtables_u.h" ++#include ++#include ++ ++#define STRING_FROM '1' ++#define STRING_TO '2' ++#define STRING_ALGO '3' ++#define STRING_ICASE '4' ++#define STRING '5' ++#define STRING_HEX '6' ++#define OPT_STRING_FROM (1 << 0) ++#define OPT_STRING_TO (1 << 1) ++#define OPT_STRING_ALGO (1 << 2) ++#define OPT_STRING_ICASE (1 << 3) ++#define OPT_STRING (1 << 4) ++#define OPT_STRING_HEX (1 << 5) ++ ++static const struct option opts[] = ++{ ++ { "string-from" , required_argument, 0, STRING_FROM }, ++ { "string-to" , required_argument, 0, STRING_TO }, ++ { "string-algo" , required_argument, 0, STRING_ALGO }, ++ { "string-icase" , no_argument, 0, STRING_ICASE }, ++ { "string" , required_argument, 0, STRING }, ++ { "string-hex" , required_argument, 0, STRING_HEX }, ++ { 0 } ++}; ++ ++static void print_help() ++{ ++ printf( ++"string options:\n" ++"--string-from offset : Offset to start searching from (default: 0)\n" ++"--string-to offset : Offset to stop searching (default: packet size)\n" ++"--string-algo algorithm : Algorithm (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)\n" ++"--string-icase : Ignore case when searching\n" ++"--string [!] string : Match a string in a packet\n" ++"--string-hex [!] string : Match a hex string in a packet, e.g. |0D 0A|, |0D0A|, netfilter|03|org\n"); ++} ++ ++static void init(struct ebt_entry_match *match) ++{ ++ struct xt_string_info *info = (struct xt_string_info *)match->data; ++ ++ info->to_offset = UINT16_MAX; ++} ++ ++static void parse_string(const char *s, struct xt_string_info *info) ++{ ++ /* xt_string does not need \0 at the end of the pattern */ ++ if (strlen(s) <= XT_STRING_MAX_PATTERN_SIZE) { ++ strncpy(info->pattern, s, XT_STRING_MAX_PATTERN_SIZE); ++ info->patlen = strnlen(s, XT_STRING_MAX_PATTERN_SIZE); ++ return; ++ } ++ ebt_print_error2("STRING too long \"%s\"", s); ++} ++ ++static void parse_hex_string(const char *s, struct xt_string_info *info) ++{ ++ int i=0, slen, sindex=0, schar; ++ short hex_f = 0, literal_f = 0; ++ char hextmp[3]; ++ ++ slen = strlen(s); ++ ++ if (slen == 0) { ++ ebt_print_error2("STRING must contain at least one char"); ++ } ++ ++ while (i < slen) { ++ if (s[i] == '\\' && !hex_f) { ++ literal_f = 1; ++ } else if (s[i] == '\\') { ++ ebt_print_error2("Cannot include literals in hex data"); ++ } else if (s[i] == '|') { ++ if (hex_f) ++ hex_f = 0; ++ else { ++ hex_f = 1; ++ /* get past any initial whitespace just after the '|' */ ++ while (s[i+1] == ' ') ++ i++; ++ } ++ if (i+1 >= slen) ++ break; ++ else ++ i++; /* advance to the next character */ ++ } ++ ++ if (literal_f) { ++ if (i+1 >= slen) { ++ ebt_print_error2("Bad literal placement at end of string"); ++ } ++ info->pattern[sindex] = s[i+1]; ++ i += 2; /* skip over literal char */ ++ literal_f = 0; ++ } else if (hex_f) { ++ if (i+1 >= slen) { ++ ebt_print_error2("Odd number of hex digits"); ++ } ++ if (i+2 >= slen) { ++ /* must end with a "|" */ ++ ebt_print_error2("Invalid hex block"); ++ } ++ if (! isxdigit(s[i])) /* check for valid hex char */ ++ ebt_print_error2("Invalid hex char '%c'", s[i]); ++ if (! isxdigit(s[i+1])) /* check for valid hex char */ ++ ebt_print_error2("Invalid hex char '%c'", s[i+1]); ++ hextmp[0] = s[i]; ++ hextmp[1] = s[i+1]; ++ hextmp[2] = '\0'; ++ if (! sscanf(hextmp, "%x", &schar)) ++ ebt_print_error2("Invalid hex char `%c'", s[i]); ++ info->pattern[sindex] = (char) schar; ++ if (s[i+2] == ' ') ++ i += 3; /* spaces included in the hex block */ ++ else ++ i += 2; ++ } else { /* the char is not part of hex data, so just copy */ ++ info->pattern[sindex] = s[i]; ++ i++; ++ } ++ if (sindex > XT_STRING_MAX_PATTERN_SIZE) ++ ebt_print_error2("STRING too long \"%s\"", s); ++ sindex++; ++ } ++ info->patlen = sindex; ++} ++ ++static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ++ unsigned int *flags, struct ebt_entry_match **match) ++{ ++ struct xt_string_info *info = (struct xt_string_info *)(*match)->data; ++ int i; ++ int input_string_length = 0; ++ char buf[3] = { 0 }; ++ ++ switch (c) { ++ case STRING_FROM: ++ ebt_check_option2(flags, OPT_STRING_FROM); ++ if (ebt_check_inverse2(optarg)) ++ ebt_print_error2("Unexpected `!' after --string-from"); ++ info->from_offset = (__u16)strtoul(optarg, NULL, 10); ++ break; ++ case STRING_TO: ++ ebt_check_option2(flags, OPT_STRING_TO); ++ if (ebt_check_inverse2(optarg)) ++ ebt_print_error2("Unexpected `!' after --string-to"); ++ info->to_offset = (__u16)strtoul(optarg, NULL, 10); ++ break; ++ case STRING_ALGO: ++ ebt_check_option2(flags, OPT_STRING_ALGO); ++ if (ebt_check_inverse2(optarg)) ++ ebt_print_error2("Unexpected `!' after --string-algo"); ++ strncpy(info->algo, optarg, XT_STRING_MAX_ALGO_NAME_SIZE); ++ break; ++ case STRING_ICASE: ++ ebt_check_option2(flags, OPT_STRING_ICASE); ++ if (ebt_check_inverse2(optarg)) ++ ebt_print_error2("Unexpected `!' after --string-icase"); ++ info->u.v1.flags |= XT_STRING_FLAG_IGNORECASE; ++ break; ++ case STRING: ++ ebt_check_option2(flags, OPT_STRING); ++ parse_string(optarg, info); ++ if (ebt_check_inverse2(optarg)) { ++ info->u.v1.flags |= XT_STRING_FLAG_INVERT; ++ } ++ break; ++ case STRING_HEX: ++ ebt_check_option2(flags, OPT_STRING_HEX); ++ parse_hex_string(optarg, info); ++ if (ebt_check_inverse2(optarg)) { ++ info->u.v1.flags |= XT_STRING_FLAG_INVERT; ++ } ++ break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match, const char *name, ++ unsigned int hookmask, unsigned int time) ++{ ++ struct xt_string_info *info = (struct xt_string_info *)match->data; ++ ++ if (info->to_offset < info->from_offset) { ++ ebt_print_error2("'to' offset should not be less than 'from' " ++ "offset"); ++ } ++} ++ ++/* Test to see if the string contains non-printable chars or quotes */ ++static unsigned short int is_hex_string(const char *str, ++ const unsigned short int len) ++{ ++ unsigned int i; ++ for (i=0; i < len; i++) { ++ if (! isprint(str[i])) { ++ /* string contains at least one non-printable char */ ++ return 1; ++ } ++ } ++ /* use hex output if the last char is a "\" */ ++ if (str[len-1] == '\\') ++ return 1; ++ return 0; ++} ++ ++/* Print string with "|" chars included as one would pass to --string-hex */ ++static void print_hex_string(const char *str, const unsigned short int len) ++{ ++ unsigned int i; ++ /* start hex block */ ++ printf("\"|"); ++ for (i=0; i < len; i++) ++ printf("%02x", (unsigned char)str[i]); ++ /* close hex block */ ++ printf("|\" "); ++} ++ ++static void print_string(const char *str, const unsigned short int len) ++{ ++ unsigned int i; ++ printf("\""); ++ for (i=0; i < len; i++) { ++ if (str[i] == '\"' || str[i] == '\\') ++ putchar('\\'); ++ printf("%c", (unsigned char) str[i]); ++ } ++ printf("\" "); /* closing quote */ ++} ++ ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_match *match) ++{ ++ const struct xt_string_info *info = ++ (const struct xt_string_info *) match->data; ++ int invert = info->u.v1.flags & XT_STRING_FLAG_INVERT; ++ ++ if (is_hex_string(info->pattern, info->patlen)) { ++ printf("--string-hex %s", invert ? "! " : ""); ++ print_hex_string(info->pattern, info->patlen); ++ } else { ++ printf("--string %s", invert ? "! " : ""); ++ print_string(info->pattern, info->patlen); ++ } ++ printf("--string-algo %s ", info->algo); ++ if (info->from_offset != 0) ++ printf("--string-from %u ", info->from_offset); ++ if (info->to_offset != 0) ++ printf("--string-to %u ", info->to_offset); ++ if (info->u.v1.flags & XT_STRING_FLAG_IGNORECASE) ++ printf("--string-icase "); ++} ++ ++static int compare(const struct ebt_entry_match *m1, ++ const struct ebt_entry_match *m2) ++{ ++ const struct xt_string_info *info1 = ++ (const struct xt_string_info *) m1->data; ++ const struct xt_string_info *info2 = ++ (const struct xt_string_info *) m2->data; ++ ++ if (info1->from_offset != info2->from_offset) ++ return 0; ++ if (info1->to_offset != info2->to_offset) ++ return 0; ++ if (info1->u.v1.flags != info2->u.v1.flags) ++ return 0; ++ if (info1->patlen != info2->patlen) ++ return 0; ++ if (strncmp (info1->algo, info2->algo, XT_STRING_MAX_ALGO_NAME_SIZE) != 0) ++ return 0; ++ if (strncmp (info1->pattern, info2->pattern, info1->patlen) != 0) ++ return 0; ++ ++ return 1; ++} ++ ++static struct ebt_u_match string_match = ++{ ++ .name = "string", ++ .revision = 1, ++ .size = sizeof(struct xt_string_info), ++ .help = print_help, ++ .init = init, ++ .parse = parse, ++ .final_check = final_check, ++ .print = print, ++ .compare = compare, ++ .extra_ops = opts, ++}; ++ ++void _init(void) ++{ ++ ebt_register_match(&string_match); ++} +diff --git a/include/ebtables.h b/include/ebtables.h +index 8f520c600b356..9bbedbb72eea5 100644 +--- a/include/ebtables.h ++++ b/include/ebtables.h +@@ -20,6 +20,7 @@ + #define EBT_TABLE_MAXNAMELEN 32 + #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN + #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN ++#define EBT_EXTENSION_MAXNAMELEN 31 + + /* verdicts >0 are "branches" */ + #define EBT_ACCEPT -1 +@@ -113,7 +114,10 @@ struct ebt_entries { + struct ebt_entry_match + { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct ebt_match *match; + } u; + /* size of data */ +@@ -127,7 +131,10 @@ struct ebt_entry_match + struct ebt_entry_watcher + { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct ebt_watcher *watcher; + } u; + /* size of data */ +@@ -141,7 +148,10 @@ struct ebt_entry_watcher + struct ebt_entry_target + { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct ebt_target *target; + } u; + /* size of data */ +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 17afa9487f5ad..c8589969bd8e0 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -144,6 +144,7 @@ struct ebt_u_entry + struct ebt_u_match + { + char name[EBT_FUNCTION_MAXNAMELEN]; ++ uint8_t revision; + /* size of the real match data */ + unsigned int size; + void (*help)(void); +diff --git a/libebtc.c b/libebtc.c +index d47424872dc51..92fd76485c723 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -272,6 +272,7 @@ void ebt_reinit_extensions() + if (!m->m) + ebt_print_memory(); + strcpy(m->m->u.name, m->name); ++ m->m->u.revision = m->revision; + m->m->match_size = EBT_ALIGN(m->size); + m->used = 0; + } +@@ -550,8 +551,10 @@ int ebt_check_rule_exists(struct ebt_u_replace *replace, + while (m_l) { + m = (struct ebt_u_match *)(m_l->m); + m_l2 = u_e->m_list; +- while (m_l2 && strcmp(m_l2->m->u.name, m->m->u.name)) ++ while (m_l2 && (strcmp(m_l2->m->u.name, m->m->u.name) || ++ m_l2->m->u.revision != m->m->u.revision)) { + m_l2 = m_l2->next; ++ } + if (!m_l2 || !m->compare(m->m, m_l2->m)) + goto letscontinue; + j++; +@@ -1209,6 +1212,7 @@ void ebt_register_match(struct ebt_u_match *m) + if (!m->m) + ebt_print_memory(); + strcpy(m->m->u.name, m->name); ++ m->m->u.revision = m->revision; + m->m->match_size = EBT_ALIGN(m->size); + m->init(m->m); + +-- +2.21.0 + diff --git a/SOURCES/0019-include-Fix-musl-libc-compatibility.patch b/SOURCES/0019-include-Fix-musl-libc-compatibility.patch new file mode 100644 index 0000000..4617054 --- /dev/null +++ b/SOURCES/0019-include-Fix-musl-libc-compatibility.patch @@ -0,0 +1,51 @@ +From fa5642bfc0585bfadef238b830058e4d6e07f4a4 Mon Sep 17 00:00:00 2001 +From: Baruch Siach +Date: Fri, 4 May 2018 12:46:52 +0300 +Subject: [PATCH] include: Fix musl libc compatibility +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Conflicting definitions of struct ethhdr between the kernel and musl +libc provides headers causes a build failure: + +In file included from .../usr/include/netinet/ether.h:8:0, + from useful_functions.c:28: +.../usr/include/netinet/if_ether.h:107:8: error: redefinition of ‘struct ethhdr’ + struct ethhdr { + ^~~~~~ +In file included from include/linux/netfilter_bridge.h:8:0, + from include/linux/netfilter_bridge/ebtables.h:17, + from include/ebtables_u.h:27, + from useful_functions.c:25: +include/linux/if_ether.h:119:8: note: originally defined here + struct ethhdr { + ^~~~~~ + +Recent enough versions kernel headers allow the libc to suppress +conflicting kernel definitions. Include the libc proivded +netinet/ether.h before kernel headers to suppress the conflicting +definition of struct ethhdr. + +Signed-off-by: Baruch Siach +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + include/ebtables_u.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index c8589969bd8e0..4824a145964ef 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -24,6 +24,7 @@ + #ifndef EBTABLES_U_H + #define EBTABLES_U_H + #include ++#include + #include + #include + +-- +2.21.0 + diff --git a/SOURCES/0020-ebtables-Fix-build-errors-and-warnings.patch b/SOURCES/0020-ebtables-Fix-build-errors-and-warnings.patch new file mode 100644 index 0000000..dd909c1 --- /dev/null +++ b/SOURCES/0020-ebtables-Fix-build-errors-and-warnings.patch @@ -0,0 +1,161 @@ +From 10b72726428476e5efe582d34aa409b53d8b1434 Mon Sep 17 00:00:00 2001 +From: Duncan Roe +Date: Tue, 15 May 2018 08:26:43 +1000 +Subject: [PATCH] ebtables: Fix build errors and warnings + +Since commit b1cdae87f25021eb835872d86d6e7206bd421c3f, make fails thusly: + +> libebtc.c: In function 'ebt_reinit_extensions': +> libebtc.c:275:11: error: 'union ' has no member named 'revision' +> m->m->u.revision = m->revision; +> ^ +> libebtc.c: In function 'ebt_check_rule_exists': +> libebtc.c:555:21: error: 'union ' has no member named 'revision' +> m_l2->m->u.revision != m->m->u.revision)) { +> ^ +> libebtc.c:555:41: error: 'union ' has no member named 'revision' +> m_l2->m->u.revision != m->m->u.revision)) { +> ^ +> libebtc.c: In function 'ebt_register_match': +> libebtc.c:1215:9: error: 'union ' has no member named 'revision' +> m->m->u.revision = m->revision; +> ^ +The cause of this failure is that the commit updated include/ebtables.h but +libebtc.c uses include/linux/netfilter_bridge/ebtables.h via +include/ebtables_u.h (gcc -E -C verifies this). + +The 2 versions of ebtables.h looked to me to be otherwise close enough, so +amended ebtables_u.h to use the newer one. + +Makefile insists on being warning-free, so cleared up warnings. Apart from +unused variables, there was also the issue that the diagnostic macro +ebt_print_error2 *returns* (i.e. makes its caller return) and returns -1. This +is unsuitable for use in functions which do not return a value, so introduced +ebt_print_error3 to do this. + +Signed-off-by: Duncan Roe +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + extensions/ebt_string.c | 25 +++++++++++-------------- + include/ebtables_u.h | 4 +++- + 2 files changed, 14 insertions(+), 15 deletions(-) + +diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c +index 793f5df312f10..9550c41096a86 100644 +--- a/extensions/ebt_string.c ++++ b/extensions/ebt_string.c +@@ -71,7 +71,7 @@ static void parse_string(const char *s, struct xt_string_info *info) + info->patlen = strnlen(s, XT_STRING_MAX_PATTERN_SIZE); + return; + } +- ebt_print_error2("STRING too long \"%s\"", s); ++ ebt_print_error3("STRING too long \"%s\"", s); + } + + static void parse_hex_string(const char *s, struct xt_string_info *info) +@@ -83,14 +83,14 @@ static void parse_hex_string(const char *s, struct xt_string_info *info) + slen = strlen(s); + + if (slen == 0) { +- ebt_print_error2("STRING must contain at least one char"); ++ ebt_print_error3("STRING must contain at least one char"); + } + + while (i < slen) { + if (s[i] == '\\' && !hex_f) { + literal_f = 1; + } else if (s[i] == '\\') { +- ebt_print_error2("Cannot include literals in hex data"); ++ ebt_print_error3("Cannot include literals in hex data"); + } else if (s[i] == '|') { + if (hex_f) + hex_f = 0; +@@ -108,28 +108,28 @@ static void parse_hex_string(const char *s, struct xt_string_info *info) + + if (literal_f) { + if (i+1 >= slen) { +- ebt_print_error2("Bad literal placement at end of string"); ++ ebt_print_error3("Bad literal placement at end of string"); + } + info->pattern[sindex] = s[i+1]; + i += 2; /* skip over literal char */ + literal_f = 0; + } else if (hex_f) { + if (i+1 >= slen) { +- ebt_print_error2("Odd number of hex digits"); ++ ebt_print_error3("Odd number of hex digits"); + } + if (i+2 >= slen) { + /* must end with a "|" */ +- ebt_print_error2("Invalid hex block"); ++ ebt_print_error3("Invalid hex block"); + } + if (! isxdigit(s[i])) /* check for valid hex char */ +- ebt_print_error2("Invalid hex char '%c'", s[i]); ++ ebt_print_error3("Invalid hex char '%c'", s[i]); + if (! isxdigit(s[i+1])) /* check for valid hex char */ +- ebt_print_error2("Invalid hex char '%c'", s[i+1]); ++ ebt_print_error3("Invalid hex char '%c'", s[i+1]); + hextmp[0] = s[i]; + hextmp[1] = s[i+1]; + hextmp[2] = '\0'; + if (! sscanf(hextmp, "%x", &schar)) +- ebt_print_error2("Invalid hex char `%c'", s[i]); ++ ebt_print_error3("Invalid hex char `%c'", s[i]); + info->pattern[sindex] = (char) schar; + if (s[i+2] == ' ') + i += 3; /* spaces included in the hex block */ +@@ -140,7 +140,7 @@ static void parse_hex_string(const char *s, struct xt_string_info *info) + i++; + } + if (sindex > XT_STRING_MAX_PATTERN_SIZE) +- ebt_print_error2("STRING too long \"%s\"", s); ++ ebt_print_error3("STRING too long \"%s\"", s); + sindex++; + } + info->patlen = sindex; +@@ -150,9 +150,6 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + unsigned int *flags, struct ebt_entry_match **match) + { + struct xt_string_info *info = (struct xt_string_info *)(*match)->data; +- int i; +- int input_string_length = 0; +- char buf[3] = { 0 }; + + switch (c) { + case STRING_FROM: +@@ -206,7 +203,7 @@ static void final_check(const struct ebt_u_entry *entry, + struct xt_string_info *info = (struct xt_string_info *)match->data; + + if (info->to_offset < info->from_offset) { +- ebt_print_error2("'to' offset should not be less than 'from' " ++ ebt_print_error3("'to' offset should not be less than 'from' " + "offset"); + } + } +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 4824a145964ef..7adc5a2f33329 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -25,7 +25,7 @@ + #define EBTABLES_U_H + #include + #include +-#include ++#include + #include + + #ifndef IPPROTO_SCTP +@@ -338,6 +338,8 @@ _ch;}) + #define ebt_print_error(format,args...) __ebt_print_error(format, ##args); + #define ebt_print_error2(format, args...) do {__ebt_print_error(format, ##args); \ + return -1;} while (0) ++#define ebt_print_error3(format, args...) do {__ebt_print_error(format, ##args); \ ++ return;} while (0) + #define ebt_check_option2(flags,mask) \ + ({ebt_check_option(flags,mask); \ + if (ebt_errormsg[0] != '\0') \ +-- +2.21.0 + diff --git a/SOURCES/0021-build-update-ebtables.h-from-kernel-and-drop-local-u.patch b/SOURCES/0021-build-update-ebtables.h-from-kernel-and-drop-local-u.patch new file mode 100644 index 0000000..31c8924 --- /dev/null +++ b/SOURCES/0021-build-update-ebtables.h-from-kernel-and-drop-local-u.patch @@ -0,0 +1,416 @@ +From b96b42e4ad9c47bf2a511905bca4e52bb4cee16d Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 6 Jun 2018 13:36:25 +0200 +Subject: [PATCH] build: update ebtables.h from kernel and drop local unused + copy + +Revert 66a97018a31eed416c6a25d051ea172e4d65be1b partly so as to use + again and import a new ebtables.h +from the kernel tree that has the "revision" field. + +With this, include/ebtables.h is (again) used by no source file, and +so can be removed. + +Signed-off-by: Jan Engelhardt +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + include/ebtables.h | 286 ---------------------- + include/ebtables_u.h | 2 +- + include/linux/netfilter_bridge/ebtables.h | 27 +- + 3 files changed, 20 insertions(+), 295 deletions(-) + delete mode 100644 include/ebtables.h + +diff --git a/include/ebtables.h b/include/ebtables.h +deleted file mode 100644 +index 9bbedbb72eea5..0000000000000 +--- a/include/ebtables.h ++++ /dev/null +@@ -1,286 +0,0 @@ +-/* +- * ebtables +- * +- * Authors: +- * Bart De Schuymer +- * +- * ebtables.c,v 2.0, April, 2002 +- * +- * This code is stongly inspired on the iptables code which is +- * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling +- */ +- +-/* Local copy of the kernel file, needed for Sparc64 support */ +-#ifndef __LINUX_BRIDGE_EFF_H +-#define __LINUX_BRIDGE_EFF_H +-#include +-#include +-#include +- +-#define EBT_TABLE_MAXNAMELEN 32 +-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN +-#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN +-#define EBT_EXTENSION_MAXNAMELEN 31 +- +-/* verdicts >0 are "branches" */ +-#define EBT_ACCEPT -1 +-#define EBT_DROP -2 +-#define EBT_CONTINUE -3 +-#define EBT_RETURN -4 +-#define NUM_STANDARD_TARGETS 4 +-/* ebtables target modules store the verdict inside an int. We can +- * reclaim a part of this int for backwards compatible extensions. +- * The 4 lsb are more than enough to store the verdict. */ +-#define EBT_VERDICT_BITS 0x0000000F +- +-struct ebt_counter +-{ +- uint64_t pcnt; +- uint64_t bcnt; +-}; +- +-struct ebt_replace +-{ +- char name[EBT_TABLE_MAXNAMELEN]; +- unsigned int valid_hooks; +- /* nr of rules in the table */ +- unsigned int nentries; +- /* total size of the entries */ +- unsigned int entries_size; +- /* start of the chains */ +-#ifdef KERNEL_64_USERSPACE_32 +- uint64_t hook_entry[NF_BR_NUMHOOKS]; +-#else +- struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; +-#endif +- /* nr of counters userspace expects back */ +- unsigned int num_counters; +- /* where the kernel will put the old counters */ +-#ifdef KERNEL_64_USERSPACE_32 +- uint64_t counters; +- uint64_t entries; +-#else +- struct ebt_counter *counters; +- char *entries; +-#endif +-}; +- +-struct ebt_entries { +- /* this field is always set to zero +- * See EBT_ENTRY_OR_ENTRIES. +- * Must be same size as ebt_entry.bitmask */ +- unsigned int distinguisher; +- /* the chain name */ +- char name[EBT_CHAIN_MAXNAMELEN]; +- /* counter offset for this chain */ +- unsigned int counter_offset; +- /* one standard (accept, drop, return) per hook */ +- int policy; +- /* nr. of entries */ +- unsigned int nentries; +- /* entry list */ +- char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +-}; +- +-/* used for the bitmask of struct ebt_entry */ +- +-/* This is a hack to make a difference between an ebt_entry struct and an +- * ebt_entries struct when traversing the entries from start to end. +- * Using this simplifies the code alot, while still being able to use +- * ebt_entries. +- * Contrary, iptables doesn't use something like ebt_entries and therefore uses +- * different techniques for naming the policy and such. So, iptables doesn't +- * need a hack like this. +- */ +-#define EBT_ENTRY_OR_ENTRIES 0x01 +-/* these are the normal masks */ +-#define EBT_NOPROTO 0x02 +-#define EBT_802_3 0x04 +-#define EBT_SOURCEMAC 0x08 +-#define EBT_DESTMAC 0x10 +-#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ +- | EBT_ENTRY_OR_ENTRIES) +- +-#define EBT_IPROTO 0x01 +-#define EBT_IIN 0x02 +-#define EBT_IOUT 0x04 +-#define EBT_ISOURCE 0x8 +-#define EBT_IDEST 0x10 +-#define EBT_ILOGICALIN 0x20 +-#define EBT_ILOGICALOUT 0x40 +-#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ +- | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) +- +-struct ebt_entry_match +-{ +- union { +- struct { +- char name[EBT_EXTENSION_MAXNAMELEN]; +- uint8_t revision; +- }; +- struct ebt_match *match; +- } u; +- /* size of data */ +- unsigned int match_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif +- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +-}; +- +-struct ebt_entry_watcher +-{ +- union { +- struct { +- char name[EBT_EXTENSION_MAXNAMELEN]; +- uint8_t revision; +- }; +- struct ebt_watcher *watcher; +- } u; +- /* size of data */ +- unsigned int watcher_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif +- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +-}; +- +-struct ebt_entry_target +-{ +- union { +- struct { +- char name[EBT_EXTENSION_MAXNAMELEN]; +- uint8_t revision; +- }; +- struct ebt_target *target; +- } u; +- /* size of data */ +- unsigned int target_size; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif +- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +-}; +- +-#define EBT_STANDARD_TARGET "standard" +-struct ebt_standard_target +-{ +- struct ebt_entry_target target; +- int verdict; +-#ifdef KERNEL_64_USERSPACE_32 +- unsigned int pad; +-#endif +-}; +- +-/* one entry */ +-struct ebt_entry { +- /* this needs to be the first field */ +- unsigned int bitmask; +- unsigned int invflags; +- uint16_t ethproto; +- /* the physical in-dev */ +- char in[IFNAMSIZ]; +- /* the logical in-dev */ +- char logical_in[IFNAMSIZ]; +- /* the physical out-dev */ +- char out[IFNAMSIZ]; +- /* the logical out-dev */ +- char logical_out[IFNAMSIZ]; +- unsigned char sourcemac[ETH_ALEN]; +- unsigned char sourcemsk[ETH_ALEN]; +- unsigned char destmac[ETH_ALEN]; +- unsigned char destmsk[ETH_ALEN]; +- /* sizeof ebt_entry + matches */ +- unsigned int watchers_offset; +- /* sizeof ebt_entry + matches + watchers */ +- unsigned int target_offset; +- /* sizeof ebt_entry + matches + watchers + target */ +- unsigned int next_offset; +- unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); +-}; +- +-/* {g,s}etsockopt numbers */ +-#define EBT_BASE_CTL 128 +- +-#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) +-#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) +-#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) +- +-#define EBT_SO_GET_INFO (EBT_BASE_CTL) +-#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) +-#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) +-#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) +-#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) +- +-/* blatently stolen from ip_tables.h +- * fn returns 0 to continue iteration */ +-#define EBT_MATCH_ITERATE(e, fn, args...) \ +-({ \ +- unsigned int __i; \ +- int __ret = 0; \ +- struct ebt_entry_match *__match; \ +- \ +- for (__i = sizeof(struct ebt_entry); \ +- __i < (e)->watchers_offset; \ +- __i += __match->match_size + \ +- sizeof(struct ebt_entry_match)) { \ +- __match = (void *)(e) + __i; \ +- \ +- __ret = fn(__match , ## args); \ +- if (__ret != 0) \ +- break; \ +- } \ +- if (__ret == 0) { \ +- if (__i != (e)->watchers_offset) \ +- __ret = -EINVAL; \ +- } \ +- __ret; \ +-}) +- +-#define EBT_WATCHER_ITERATE(e, fn, args...) \ +-({ \ +- unsigned int __i; \ +- int __ret = 0; \ +- struct ebt_entry_watcher *__watcher; \ +- \ +- for (__i = e->watchers_offset; \ +- __i < (e)->target_offset; \ +- __i += __watcher->watcher_size + \ +- sizeof(struct ebt_entry_watcher)) { \ +- __watcher = (void *)(e) + __i; \ +- \ +- __ret = fn(__watcher , ## args); \ +- if (__ret != 0) \ +- break; \ +- } \ +- if (__ret == 0) { \ +- if (__i != (e)->target_offset) \ +- __ret = -EINVAL; \ +- } \ +- __ret; \ +-}) +- +-#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ +-({ \ +- unsigned int __i; \ +- int __ret = 0; \ +- struct ebt_entry *__entry; \ +- \ +- for (__i = 0; __i < (size);) { \ +- __entry = (void *)(entries) + __i; \ +- __ret = fn(__entry , ## args); \ +- if (__ret != 0) \ +- break; \ +- if (__entry->bitmask != 0) \ +- __i += __entry->next_offset; \ +- else \ +- __i += sizeof(struct ebt_entries); \ +- } \ +- if (__ret == 0) { \ +- if (__i != (size)) \ +- __ret = -EINVAL; \ +- } \ +- __ret; \ +-}) +- +-#endif +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 7adc5a2f33329..3235bf5967055 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -25,7 +25,7 @@ + #define EBTABLES_U_H + #include + #include +-#include ++#include + #include + + #ifndef IPPROTO_SCTP +diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h +index 19a64448c648e..5be75f282cd20 100644 +--- a/include/linux/netfilter_bridge/ebtables.h ++++ b/include/linux/netfilter_bridge/ebtables.h +@@ -1,3 +1,4 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + /* + * ebtables + * +@@ -6,19 +7,20 @@ + * + * ebtables.c,v 2.0, April, 2002 + * +- * This code is stongly inspired on the iptables code which is ++ * This code is strongly inspired by the iptables code which is + * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling + */ + + #ifndef __LINUX_BRIDGE_EFF_H + #define __LINUX_BRIDGE_EFF_H ++#include + #include + #include +-#include + + #define EBT_TABLE_MAXNAMELEN 32 + #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN + #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN ++#define EBT_EXTENSION_MAXNAMELEN 31 + + /* verdicts >0 are "branches" */ + #define EBT_ACCEPT -1 +@@ -35,8 +37,8 @@ struct xt_match; + struct xt_target; + + struct ebt_counter { +- uint64_t pcnt; +- uint64_t bcnt; ++ __u64 pcnt; ++ __u64 bcnt; + }; + + struct ebt_replace { +@@ -119,7 +121,10 @@ struct ebt_entries { + + struct ebt_entry_match { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct xt_match *match; + } u; + /* size of data */ +@@ -129,7 +134,10 @@ struct ebt_entry_match { + + struct ebt_entry_watcher { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct xt_target *watcher; + } u; + /* size of data */ +@@ -139,7 +147,10 @@ struct ebt_entry_watcher { + + struct ebt_entry_target { + union { +- char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct { ++ char name[EBT_EXTENSION_MAXNAMELEN]; ++ uint8_t revision; ++ }; + struct xt_target *target; + } u; + /* size of data */ +@@ -265,4 +276,4 @@ struct ebt_entry { + __ret; \ + }) + +-#endif ++#endif /* __LINUX_BRIDGE_EFF_H */ +-- +2.21.0 + diff --git a/SOURCES/0022-extensions-fix-build-failure-on-fc28.patch b/SOURCES/0022-extensions-fix-build-failure-on-fc28.patch new file mode 100644 index 0000000..04c676f --- /dev/null +++ b/SOURCES/0022-extensions-fix-build-failure-on-fc28.patch @@ -0,0 +1,35 @@ +From d3724c422da83279eb7550019668c29bbf16592a Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 6 Jun 2018 14:21:57 +0200 +Subject: [PATCH] extensions: fix build failure on fc28 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +make fails via: +extensions/ebt_string.c: In function ‘parse’: +extensions/ebt_string.c:171:3: error: ‘strncpy’ specified bound 16 equals destination size [-Werror=stringop-truncation] + strncpy(info->algo, optarg, XT_STRING_MAX_ALGO_NAME_SIZE); + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + extensions/ebt_string.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c +index 9550c41096a86..3deff1ba83264 100644 +--- a/extensions/ebt_string.c ++++ b/extensions/ebt_string.c +@@ -168,7 +168,7 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + ebt_check_option2(flags, OPT_STRING_ALGO); + if (ebt_check_inverse2(optarg)) + ebt_print_error2("Unexpected `!' after --string-algo"); +- strncpy(info->algo, optarg, XT_STRING_MAX_ALGO_NAME_SIZE); ++ snprintf(info->algo, sizeof(info->algo), "%s", optarg); + break; + case STRING_ICASE: + ebt_check_option2(flags, OPT_STRING_ICASE); +-- +2.21.0 + diff --git a/SOURCES/0023-extensions-ebt_string-take-action-if-snprintf-discar.patch b/SOURCES/0023-extensions-ebt_string-take-action-if-snprintf-discar.patch new file mode 100644 index 0000000..cb17078 --- /dev/null +++ b/SOURCES/0023-extensions-ebt_string-take-action-if-snprintf-discar.patch @@ -0,0 +1,36 @@ +From 2a33cbf1d286443259093cfb77219fdc60cfb7df Mon Sep 17 00:00:00 2001 +From: Duncan Roe +Date: Fri, 15 Jun 2018 11:31:56 +1000 +Subject: [PATCH] extensions: ebt_string: take action if snprintf discards data + +56993546c805 ("extensions: fix build failure on fc28") eliminated a gcc +warning that strncpy could make a string w/out a NUL terminator. +snprintf guarantees NUL-termination (so fixes that possibility). But, +snprintf may discard data to make room for the NUL. This patch errors +straight away in that eventuality. + +Signed-off-by: Duncan Roe +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/ebt_string.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c +index 3deff1ba83264..7d24f8002f4d7 100644 +--- a/extensions/ebt_string.c ++++ b/extensions/ebt_string.c +@@ -168,7 +168,9 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, + ebt_check_option2(flags, OPT_STRING_ALGO); + if (ebt_check_inverse2(optarg)) + ebt_print_error2("Unexpected `!' after --string-algo"); +- snprintf(info->algo, sizeof(info->algo), "%s", optarg); ++ if (snprintf(info->algo, sizeof(info->algo), "%s", optarg) >= ++ sizeof(info->algo)) ++ ebt_print_error2("\"%s\" is truncated", info->algo); + break; + case STRING_ICASE: + ebt_check_option2(flags, OPT_STRING_ICASE); +-- +2.21.0 + diff --git a/SOURCES/0024-build-drop-install-o-g-root.patch b/SOURCES/0024-build-drop-install-o-g-root.patch new file mode 100644 index 0000000..e258ce2 --- /dev/null +++ b/SOURCES/0024-build-drop-install-o-g-root.patch @@ -0,0 +1,89 @@ +From 2dcebe667a4cbebe0c825633510c015143d5ed92 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:38 +0200 +Subject: [PATCH] build: drop install -o/-g root + +Calling /usr/bin/install with -o/-g will attempt to chown, and fail +if unsuccessful, which makes an unprivileged install with DESTDIR a +futile attempt always. + +Drop it, because /usr/bin/install chowns to the current running user +*anyway*, which means when root calls `make install`, it will do the +right thing as before. + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + Makefile | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/Makefile b/Makefile +index c1106a4e08345..79ee167e0258b 100644 +--- a/Makefile ++++ b/Makefile +@@ -157,31 +157,31 @@ tmp3:=$(shell printf $(PIPE) | sed 's/\//\\\//g') + scripts: ebtables-save ebtables.sysv ebtables-config + cat ebtables-save | sed 's/__EXEC_PATH__/$(tmp1)/g' > ebtables-save_ + mkdir -p $(DESTDIR)$(BINDIR) +- install -m 0755 -o root -g root ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save ++ install -m 0755 ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save + cat ebtables.sysv | sed 's/__EXEC_PATH__/$(tmp1)/g' | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables.sysv_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(INITDIR); fi +- if test -d $(DESTDIR)$(INITDIR); then install -m 0755 -o root -g root ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi ++ if test -d $(DESTDIR)$(INITDIR); then install -m 0755 ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi + cat ebtables-config | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables-config_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(SYSCONFIGDIR); fi +- if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 -o root -g root ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi ++ if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi + rm -f ebtables-save_ ebtables.sysv_ ebtables-config_ + + tmp4:=$(shell printf $(LOCKFILE) | sed 's/\//\\\//g') + $(MANDIR)/man8/ebtables.8: ebtables.8 + mkdir -p $(DESTDIR)$(@D) + sed -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 > ebtables.8_ +- install -m 0644 -o root -g root ebtables.8_ $(DESTDIR)$@ ++ install -m 0644 ebtables.8_ $(DESTDIR)$@ + rm -f ebtables.8_ + + $(DESTDIR)$(ETHERTYPESFILE): ethertypes + mkdir -p $(@D) +- install -m 0644 -o root -g root $< $@ ++ install -m 0644 $< $@ + + .PHONY: exec + exec: ebtables ebtables-restore + mkdir -p $(DESTDIR)$(BINDIR) +- install -m 0755 -o root -g root $(PROGNAME) $(DESTDIR)$(BINDIR)/$(PROGNAME) +- install -m 0755 -o root -g root ebtables-restore $(DESTDIR)$(BINDIR)/ebtables-restore ++ install -m 0755 $(PROGNAME) $(DESTDIR)$(BINDIR)/$(PROGNAME) ++ install -m 0755 ebtables-restore $(DESTDIR)$(BINDIR)/ebtables-restore + + .PHONY: install + install: $(MANDIR)/man8/ebtables.8 $(DESTDIR)$(ETHERTYPESFILE) exec scripts +@@ -205,18 +205,18 @@ release: + rm -f extensions/ebt_inat.c + rm -rf $(CVSDIRS) + mkdir -p include/linux/netfilter_bridge +- install -m 0644 -o root -g root \ ++ install -m 0644 \ + $(KERNEL_INCLUDES)/linux/netfilter_bridge.h include/linux/ + # To keep possible compile error complaints about undefined ETH_P_8021Q + # off my back +- install -m 0644 -o root -g root \ ++ install -m 0644 \ + $(KERNEL_INCLUDES)/linux/if_ether.h include/linux/ +- install -m 0644 -o root -g root \ ++ install -m 0644 \ + $(KERNEL_INCLUDES)/linux/types.h include/linux/ +- install -m 0644 -o root -g root \ ++ install -m 0644 \ + $(KERNEL_INCLUDES)/linux/netfilter_bridge/*.h \ + include/linux/netfilter_bridge/ +- install -m 0644 -o root -g root \ ++ install -m 0644 \ + include/ebtables.h include/linux/netfilter_bridge/ + make clean + touch * +-- +2.21.0 + diff --git a/SOURCES/0025-build-rename-sed-source-files-to-.in.patch b/SOURCES/0025-build-rename-sed-source-files-to-.in.patch new file mode 100644 index 0000000..3a64ebd --- /dev/null +++ b/SOURCES/0025-build-rename-sed-source-files-to-.in.patch @@ -0,0 +1,82 @@ +From 67613b5a7ce545683a4831bf6297f9a108538827 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:39 +0200 +Subject: [PATCH] build: rename sed source files to .in + +Prepare for autoconf-based substitution of macros in the file. + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + Makefile | 14 +++++++------- + ebtables-config => ebtables-config.in | 0 + ebtables-save => ebtables-save.in | 0 + ebtables.8 => ebtables.8.in | 0 + ebtables.sysv => ebtables.sysv.in | 0 + 5 files changed, 7 insertions(+), 7 deletions(-) + rename ebtables-config => ebtables-config.in (100%) + rename ebtables-save => ebtables-save.in (100%) + rename ebtables.8 => ebtables.8.in (100%) + rename ebtables.sysv => ebtables.sysv.in (100%) + +diff --git a/Makefile b/Makefile +index 79ee167e0258b..d0a12d6ed7325 100644 +--- a/Makefile ++++ b/Makefile +@@ -154,22 +154,22 @@ tmp1:=$(shell printf $(BINDIR) | sed 's/\//\\\//g') + tmp2:=$(shell printf $(SYSCONFIGDIR) | sed 's/\//\\\//g') + tmp3:=$(shell printf $(PIPE) | sed 's/\//\\\//g') + .PHONY: scripts +-scripts: ebtables-save ebtables.sysv ebtables-config +- cat ebtables-save | sed 's/__EXEC_PATH__/$(tmp1)/g' > ebtables-save_ ++scripts: ebtables-save.in ebtables.sysv.in ebtables-config.in ++ sed -e 's/__EXEC_PATH__/$(tmp1)/g' ebtables-save_ + mkdir -p $(DESTDIR)$(BINDIR) + install -m 0755 ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save +- cat ebtables.sysv | sed 's/__EXEC_PATH__/$(tmp1)/g' | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables.sysv_ ++ sed -e 's/__EXEC_PATH__/$(tmp1)/g' -e 's/__SYSCONFIG__/$(tmp2)/g' ebtables.sysv_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(INITDIR); fi + if test -d $(DESTDIR)$(INITDIR); then install -m 0755 ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi +- cat ebtables-config | sed 's/__SYSCONFIG__/$(tmp2)/g' > ebtables-config_ ++ sed -e 's/__SYSCONFIG__/$(tmp2)/g' ebtables-config_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(SYSCONFIGDIR); fi + if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi + rm -f ebtables-save_ ebtables.sysv_ ebtables-config_ + + tmp4:=$(shell printf $(LOCKFILE) | sed 's/\//\\\//g') +-$(MANDIR)/man8/ebtables.8: ebtables.8 ++$(MANDIR)/man8/ebtables.8: ebtables.8.in + mkdir -p $(DESTDIR)$(@D) +- sed -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 > ebtables.8_ ++ sed -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' <$< >ebtables.8_ + install -m 0644 ebtables.8_ $(DESTDIR)$@ + rm -f ebtables.8_ + +@@ -224,7 +224,7 @@ release: + touch include/* + touch include/linux/* + touch include/linux/netfilter_bridge/* +- sed -i -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 ++ sed -i -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 + sed -i -e 's/$$(VERSION)/$(PROGVERSION_)/' -e 's/$$(RELEASE)/$(PROGRELEASE)/' ebtables.spec + cd ..;tar -c $(DIR) | gzip >$(DIR).tar.gz; cd - + rm -rf include/linux +diff --git a/ebtables-config b/ebtables-config.in +similarity index 100% +rename from ebtables-config +rename to ebtables-config.in +diff --git a/ebtables-save b/ebtables-save.in +similarity index 100% +rename from ebtables-save +rename to ebtables-save.in +diff --git a/ebtables.8 b/ebtables.8.in +similarity index 100% +rename from ebtables.8 +rename to ebtables.8.in +diff --git a/ebtables.sysv b/ebtables.sysv.in +similarity index 100% +rename from ebtables.sysv +rename to ebtables.sysv.in +-- +2.21.0 + diff --git a/SOURCES/0026-build-use-autoconf-style-placeholders-in-sed-ed-file.patch b/SOURCES/0026-build-use-autoconf-style-placeholders-in-sed-ed-file.patch new file mode 100644 index 0000000..82d745b --- /dev/null +++ b/SOURCES/0026-build-use-autoconf-style-placeholders-in-sed-ed-file.patch @@ -0,0 +1,187 @@ +From 0784cbd11e40aa6c04acb89c30b9d5bb45703b33 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:40 +0200 +Subject: [PATCH] build: use autoconf-style placeholders in sed-ed files + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + Makefile | 8 ++++---- + ebtables-save.in | 2 +- + ebtables.8.in | 6 +++--- + ebtables.sysv.in | 38 +++++++++++++++++++------------------- + 4 files changed, 27 insertions(+), 27 deletions(-) + +diff --git a/Makefile b/Makefile +index d0a12d6ed7325..7c70db0267983 100644 +--- a/Makefile ++++ b/Makefile +@@ -155,13 +155,13 @@ tmp2:=$(shell printf $(SYSCONFIGDIR) | sed 's/\//\\\//g') + tmp3:=$(shell printf $(PIPE) | sed 's/\//\\\//g') + .PHONY: scripts + scripts: ebtables-save.in ebtables.sysv.in ebtables-config.in +- sed -e 's/__EXEC_PATH__/$(tmp1)/g' ebtables-save_ ++ sed -e 's/[@]sbindir@/$(tmp1)/g' ebtables-save_ + mkdir -p $(DESTDIR)$(BINDIR) + install -m 0755 ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save +- sed -e 's/__EXEC_PATH__/$(tmp1)/g' -e 's/__SYSCONFIG__/$(tmp2)/g' ebtables.sysv_ ++ sed -e 's/[@]sbindir@/$(tmp1)/g' -e 's/[@]sysconfigdir@/$(tmp2)/g' ebtables.sysv_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(INITDIR); fi + if test -d $(DESTDIR)$(INITDIR); then install -m 0755 ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi +- sed -e 's/__SYSCONFIG__/$(tmp2)/g' ebtables-config_ ++ sed -e 's/[@]sysconfigdir@/$(tmp2)/g' ebtables-config_ + if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(SYSCONFIGDIR); fi + if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi + rm -f ebtables-save_ ebtables.sysv_ ebtables-config_ +@@ -169,7 +169,7 @@ scripts: ebtables-save.in ebtables.sysv.in ebtables-config.in + tmp4:=$(shell printf $(LOCKFILE) | sed 's/\//\\\//g') + $(MANDIR)/man8/ebtables.8: ebtables.8.in + mkdir -p $(DESTDIR)$(@D) +- sed -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' <$< >ebtables.8_ ++ sed -e 's/[@]PACKAGE_VERSION@/$(PROGVERSION)/' -e 's/[@]PACKAGE_DATE@/$(PROGDATE)/' -e 's/[@]LOCKFILE@/$(tmp4)/' <$< >ebtables.8_ + install -m 0644 ebtables.8_ $(DESTDIR)$@ + rm -f ebtables.8_ + +diff --git a/ebtables-save.in b/ebtables-save.in +index 49d733b7adf5e..df141490c20b1 100644 +--- a/ebtables-save.in ++++ b/ebtables-save.in +@@ -8,7 +8,7 @@ + + use strict; + my $table; +-my $ebtables = "__EXEC_PATH__/ebtables"; ++my $ebtables = "@sbindir@/ebtables"; + my $cnt = ""; + my $version = "1.0"; + my $table_name; +diff --git a/ebtables.8.in b/ebtables.8.in +index 00c4562d20036..3e97c84da0e86 100644 +--- a/ebtables.8.in ++++ b/ebtables.8.in +@@ -1,4 +1,4 @@ +-.TH EBTABLES 8 "December 2011" ++.TH EBTABLES 8 "@PACKAGE_DATE@" + .\" + .\" Man page written by Bart De Schuymer + .\" It is based on the iptables man page. +@@ -24,7 +24,7 @@ + .\" + .\" + .SH NAME +-ebtables (v2.0.10-4) \- Ethernet bridge frame table administration ++ebtables (@PACKAGE_VERSION@) \- Ethernet bridge frame table administration + .SH SYNOPSIS + .BR "ebtables " [ -t " table ] " - [ ACDI "] chain rule specification [match extensions] [watcher extensions] target" + .br +@@ -1123,7 +1123,7 @@ arp message and the hardware address length in the arp header is 6 bytes. + .br + .SH FILES + .I /etc/ethertypes +-.I /var/lib/ebtables/lock ++.I @LOCKFILE@ + .SH ENVIRONMENT VARIABLES + .I EBTABLES_ATOMIC_FILE + .SH MAILINGLISTS +diff --git a/ebtables.sysv.in b/ebtables.sysv.in +index b6848f14257e8..bbf0e7424cb2b 100644 +--- a/ebtables.sysv.in ++++ b/ebtables.sysv.in +@@ -9,8 +9,8 @@ + # chkconfig: - 15 85 + # description: Ethernet Bridge filtering tables + # +-# config: __SYSCONFIG__/ebtables (text) +-# __SYSCONFIG__/ebtables. (binary) ++# config: @sysconfigdir@/ebtables (text) ++# @sysconfigdir@/ebtables.
(binary) + + source /etc/init.d/functions + source /etc/sysconfig/network +@@ -18,9 +18,9 @@ source /etc/sysconfig/network + # Check that networking is up. + [ ${NETWORKING} = "no" ] && exit 0 + +-[ -x __EXEC_PATH__/ebtables ] || exit 1 +-[ -x __EXEC_PATH__/ebtables-save ] || exit 1 +-[ -x __EXEC_PATH__/ebtables-restore ] || exit 1 ++[ -x @sbindir@/ebtables ] || exit 1 ++[ -x @sbindir@/ebtables-save ] || exit 1 ++[ -x @sbindir@/ebtables-restore ] || exit 1 + + RETVAL=0 + prog="ebtables" +@@ -35,17 +35,17 @@ EBTABLES_SAVE_ON_STOP="no" + EBTABLES_SAVE_ON_RESTART="no" + EBTABLES_SAVE_COUNTER="no" + +-config=__SYSCONFIG__/$prog-config ++config=@sysconfigdir@/$prog-config + [ -f "$config" ] && . "$config" + + start() { + echo -n $"Starting $desc ($prog): " + if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then +- for table in $(ls __SYSCONFIG__/ebtables.* 2>/dev/null | sed -e 's/.*ebtables\.//' -e '/save/d' ); do +- __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table --atomic-commit || RETVAL=1 ++ for table in $(ls @sysconfigdir@/ebtables.* 2>/dev/null | sed -e 's/.*ebtables\.//' -e '/save/d' ); do ++ @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table --atomic-commit || RETVAL=1 + done + else +- __EXEC_PATH__/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1 ++ @sbindir@/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1 + fi + + if [ $RETVAL -eq 0 ]; then +@@ -60,7 +60,7 @@ start() { + stop() { + echo -n $"Stopping $desc ($prog): " + for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do +- __EXEC_PATH__/ebtables -t $table --init-table || RETVAL=1 ++ @sbindir@/ebtables -t $table --init-table || RETVAL=1 + done + + if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then +@@ -86,22 +86,22 @@ restart() { + save() { + echo -n $"Saving $desc ($prog): " + if [ "$EBTABLES_TEXT_FORMAT" = "yes" ]; then +- if [ -e __SYSCONFIG__/ebtables ]; then +- chmod 0600 __SYSCONFIG__/ebtables +- mv -f __SYSCONFIG__/ebtables __SYSCONFIG__/ebtables.save ++ if [ -e @sysconfigdir@/ebtables ]; then ++ chmod 0600 @sysconfigdir@/ebtables ++ mv -f @sysconfigdir@/ebtables @sysconfigdir@/ebtables.save + fi +- __EXEC_PATH__/ebtables-save > __SYSCONFIG__/ebtables || RETVAL=1 ++ @sbindir@/ebtables-save > @sysconfigdir@/ebtables || RETVAL=1 + fi + if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then +- rm -f __SYSCONFIG__/ebtables.*.save +- for oldtable in $(ls __SYSCONFIG__/ebtables.* 2>/dev/null | grep -vF 'ebtables.save'); do ++ rm -f @sysconfigdir@/ebtables.*.save ++ for oldtable in $(ls @sysconfigdir@/ebtables.* 2>/dev/null | grep -vF 'ebtables.save'); do + chmod 0600 $oldtable + mv -f $oldtable $oldtable.save + done + for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do +- __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table --atomic-save || RETVAL=1 ++ @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table --atomic-save || RETVAL=1 + if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then +- __EXEC_PATH__/ebtables -t $table --atomic-file __SYSCONFIG__/ebtables.$table -Z || RETVAL=1 ++ @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table -Z || RETVAL=1 + fi + done + fi +@@ -134,7 +134,7 @@ case "$1" in + save + ;; + status) +- __EXEC_PATH__/ebtables-save ++ @sbindir@/ebtables-save + RETVAL=$? + ;; + *) +-- +2.21.0 + diff --git a/SOURCES/0027-extensions-use-__attribute__-constructor-for-autoreg.patch b/SOURCES/0027-extensions-use-__attribute__-constructor-for-autoreg.patch new file mode 100644 index 0000000..cdd7357 --- /dev/null +++ b/SOURCES/0027-extensions-use-__attribute__-constructor-for-autoreg.patch @@ -0,0 +1,410 @@ +From 22476c0758b930b972c5397ee3ba1bef5ccf6223 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:41 +0200 +Subject: [PATCH] extensions: use __attribute__((constructor)) for + autoregistration + +The ebtables initialization is easier, and, judging from the "static" +recipe in Makefile, that calling ebt_*_register ahead of main is +safe. + +This means that a static build won't need the pseudomain hack, +and that -nostartfiles can also go away. + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + Makefile | 34 +--------------------------------- + extensions/Makefile | 4 ++-- + extensions/ebt_802_3.c | 2 +- + extensions/ebt_among.c | 2 +- + extensions/ebt_arp.c | 2 +- + extensions/ebt_arpreply.c | 2 +- + extensions/ebt_ip.c | 2 +- + extensions/ebt_ip6.c | 2 +- + extensions/ebt_limit.c | 2 +- + extensions/ebt_log.c | 2 +- + extensions/ebt_mark.c | 2 +- + extensions/ebt_mark_m.c | 2 +- + extensions/ebt_nat.c | 2 +- + extensions/ebt_nflog.c | 2 +- + extensions/ebt_pkttype.c | 2 +- + extensions/ebt_redirect.c | 2 +- + extensions/ebt_standard.c | 2 +- + extensions/ebt_stp.c | 2 +- + extensions/ebt_string.c | 2 +- + extensions/ebt_ulog.c | 2 +- + extensions/ebt_vlan.c | 2 +- + extensions/ebtable_broute.c | 2 +- + extensions/ebtable_filter.c | 2 +- + extensions/ebtable_nat.c | 2 +- + include/ebtables_u.h | 2 ++ + 25 files changed, 27 insertions(+), 57 deletions(-) + +diff --git a/Makefile b/Makefile +index 7c70db0267983..4d7b10f4916d6 100644 +--- a/Makefile ++++ b/Makefile +@@ -116,39 +116,7 @@ daemon: ebtablesd ebtablesu + # a little scripting for a static binary, making one for ebtables-restore + # should be completely analogous + static: extensions/ebt_*.c extensions/ebtable_*.c ebtables.c communication.c ebtables-standalone.c getethertype.c libebtc.c useful_functions.c +- cp ebtables-standalone.c ebtables-standalone.c_ ; \ +- cp include/ebtables_u.h include/ebtables_u.h_ ; \ +- sed "s/ main(/ pseudomain(/" ebtables-standalone.c > ebtables-standalone.c__ ; \ +- mv ebtables-standalone.c__ ebtables-standalone.c ; \ +- printf "\nint main(int argc, char *argv[])\n{\n " >> ebtables-standalone.c ; \ +- for arg in $(EXT_FUNC) \ +- ; do \ +- sed s/_init/_$${arg}_init/ extensions/ebt_$${arg}.c > extensions/ebt_$${arg}.c_ ; \ +- mv extensions/ebt_$${arg}.c_ extensions/ebt_$${arg}.c ; \ +- printf "\t%s();\n" _$${arg}_init >> ebtables-standalone.c ; \ +- printf "extern void %s();\n" _$${arg}_init >> include/ebtables_u.h ; \ +- done ; \ +- for arg in $(EXT_TABLES) \ +- ; do \ +- sed s/_init/_t_$${arg}_init/ extensions/ebtable_$${arg}.c > extensions/ebtable_$${arg}.c_ ; \ +- mv extensions/ebtable_$${arg}.c_ extensions/ebtable_$${arg}.c ; \ +- printf "\t%s();\n" _t_$${arg}_init >> ebtables-standalone.c ; \ +- printf "extern void %s();\n" _t_$${arg}_init >> include/ebtables_u.h ; \ +- done ; \ +- printf "\n\tpseudomain(argc, argv);\n\treturn 0;\n}\n" >> ebtables-standalone.c ;\ +- $(CC) $(CFLAGS) $(LDFLAGS) $(PROGSPECS) -o $@ $^ -I$(KERNEL_INCLUDES) -Iinclude ; \ +- for arg in $(EXT_FUNC) \ +- ; do \ +- sed "s/ .*_init/ _init/" extensions/ebt_$${arg}.c > extensions/ebt_$${arg}.c_ ; \ +- mv extensions/ebt_$${arg}.c_ extensions/ebt_$${arg}.c ; \ +- done ; \ +- for arg in $(EXT_TABLES) \ +- ; do \ +- sed "s/ .*_init/ _init/" extensions/ebtable_$${arg}.c > extensions/ebtable_$${arg}.c_ ; \ +- mv extensions/ebtable_$${arg}.c_ extensions/ebtable_$${arg}.c ; \ +- done ; \ +- mv ebtables-standalone.c_ ebtables-standalone.c ; \ +- mv include/ebtables_u.h_ include/ebtables_u.h ++ $(CC) $(CFLAGS) $(LDFLAGS) $(PROGSPECS) -o $@ $^ -I$(KERNEL_INCLUDES) -Iinclude + + tmp1:=$(shell printf $(BINDIR) | sed 's/\//\\\//g') + tmp2:=$(shell printf $(SYSCONFIGDIR) | sed 's/\//\\\//g') +diff --git a/extensions/Makefile b/extensions/Makefile +index 60a70a2298357..daa11fce36e5e 100644 +--- a/extensions/Makefile ++++ b/extensions/Makefile +@@ -11,13 +11,13 @@ EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -lebt_$(T)) + EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T)) + + extensions/ebt_%.so: extensions/ebt_%.o +- $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles ++ $(CC) $(LDFLAGS) -shared -o $@ -lc $< + + extensions/libebt_%.so: extensions/ebt_%.so + mv $< $@ + + extensions/ebtable_%.so: extensions/ebtable_%.o +- $(CC) $(LDFLAGS) -shared -o $@ -lc $< -nostartfiles ++ $(CC) $(LDFLAGS) -shared -o $@ -lc $< + + extensions/libebtable_%.so: extensions/ebtable_%.so + mv $< $@ +diff --git a/extensions/ebt_802_3.c b/extensions/ebt_802_3.c +index 458484939231d..d70fd441e60db 100644 +--- a/extensions/ebt_802_3.c ++++ b/extensions/ebt_802_3.c +@@ -141,7 +141,7 @@ static struct ebt_u_match _802_3_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&_802_3_match); + } +diff --git a/extensions/ebt_among.c b/extensions/ebt_among.c +index e4fc5ac22a005..b1560e8f09e8d 100644 +--- a/extensions/ebt_among.c ++++ b/extensions/ebt_among.c +@@ -491,7 +491,7 @@ static struct ebt_u_match among_match = { + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&among_match); + } +diff --git a/extensions/ebt_arp.c b/extensions/ebt_arp.c +index b2819553ab313..84b6e900eff62 100644 +--- a/extensions/ebt_arp.c ++++ b/extensions/ebt_arp.c +@@ -362,7 +362,7 @@ static struct ebt_u_match arp_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&arp_match); + } +diff --git a/extensions/ebt_arpreply.c b/extensions/ebt_arpreply.c +index 51eda66adbff3..399868bdd9059 100644 +--- a/extensions/ebt_arpreply.c ++++ b/extensions/ebt_arpreply.c +@@ -133,7 +133,7 @@ static struct ebt_u_target arpreply_target = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_target(&arpreply_target); + } +diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c +index 1ffdb95f156df..faffade35f7f1 100644 +--- a/extensions/ebt_ip.c ++++ b/extensions/ebt_ip.c +@@ -472,7 +472,7 @@ static struct ebt_u_match ip_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&ip_match); + } +diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c +index 347797b4afe18..17a4303177284 100644 +--- a/extensions/ebt_ip6.c ++++ b/extensions/ebt_ip6.c +@@ -413,7 +413,7 @@ static struct ebt_u_match ip6_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&ip6_match); + } +diff --git a/extensions/ebt_limit.c b/extensions/ebt_limit.c +index 2cbf4dee51fb4..1fe9d84ffd137 100644 +--- a/extensions/ebt_limit.c ++++ b/extensions/ebt_limit.c +@@ -212,7 +212,7 @@ static struct ebt_u_match limit_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&limit_match); + } +diff --git a/extensions/ebt_log.c b/extensions/ebt_log.c +index 97d50919d25ca..b5d32321948c8 100644 +--- a/extensions/ebt_log.c ++++ b/extensions/ebt_log.c +@@ -217,7 +217,7 @@ static struct ebt_u_watcher log_watcher = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_watcher(&log_watcher); + } +diff --git a/extensions/ebt_mark.c b/extensions/ebt_mark.c +index 4cf1378d5085c..b4f93b5960b6a 100644 +--- a/extensions/ebt_mark.c ++++ b/extensions/ebt_mark.c +@@ -172,7 +172,7 @@ static struct ebt_u_target mark_target = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_target(&mark_target); + } +diff --git a/extensions/ebt_mark_m.c b/extensions/ebt_mark_m.c +index 7561f059c0108..b6d11a2903bbe 100644 +--- a/extensions/ebt_mark_m.c ++++ b/extensions/ebt_mark_m.c +@@ -121,7 +121,7 @@ static struct ebt_u_match mark_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&mark_match); + } +diff --git a/extensions/ebt_nat.c b/extensions/ebt_nat.c +index 00d9cd4083247..fe7e9875498e0 100644 +--- a/extensions/ebt_nat.c ++++ b/extensions/ebt_nat.c +@@ -231,7 +231,7 @@ static struct ebt_u_target dnat_target = + .extra_ops = opts_d, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_target(&snat_target); + ebt_register_target(&dnat_target); +diff --git a/extensions/ebt_nflog.c b/extensions/ebt_nflog.c +index 405673a01f893..04c547d06cee0 100644 +--- a/extensions/ebt_nflog.c ++++ b/extensions/ebt_nflog.c +@@ -166,7 +166,7 @@ static struct ebt_u_watcher nflog_watcher = { + .extra_ops = nflog_opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_watcher(&nflog_watcher); + } +diff --git a/extensions/ebt_pkttype.c b/extensions/ebt_pkttype.c +index 486c85c3c3faf..bf578fcf98f92 100644 +--- a/extensions/ebt_pkttype.c ++++ b/extensions/ebt_pkttype.c +@@ -125,7 +125,7 @@ static struct ebt_u_match pkttype_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&pkttype_match); + } +diff --git a/extensions/ebt_redirect.c b/extensions/ebt_redirect.c +index 3f8227a917583..59fe818f7b205 100644 +--- a/extensions/ebt_redirect.c ++++ b/extensions/ebt_redirect.c +@@ -108,7 +108,7 @@ static struct ebt_u_target redirect_target = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_target(&redirect_target); + } +diff --git a/extensions/ebt_standard.c b/extensions/ebt_standard.c +index 81edead71a840..f3c33086bac53 100644 +--- a/extensions/ebt_standard.c ++++ b/extensions/ebt_standard.c +@@ -84,7 +84,7 @@ static struct ebt_u_target standard = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_target(&standard); + } +diff --git a/extensions/ebt_stp.c b/extensions/ebt_stp.c +index 5c5fc3334311d..311bc63d2cb0c 100644 +--- a/extensions/ebt_stp.c ++++ b/extensions/ebt_stp.c +@@ -337,7 +337,7 @@ static struct ebt_u_match stp_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&stp_match); + } +diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c +index 7d24f8002f4d7..97fbe19eca54f 100644 +--- a/extensions/ebt_string.c ++++ b/extensions/ebt_string.c +@@ -312,7 +312,7 @@ static struct ebt_u_match string_match = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&string_match); + } +diff --git a/extensions/ebt_ulog.c b/extensions/ebt_ulog.c +index 54eec53f7069f..72a6c8b199b42 100644 +--- a/extensions/ebt_ulog.c ++++ b/extensions/ebt_ulog.c +@@ -180,7 +180,7 @@ static struct ebt_u_watcher ulog_watcher = + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_watcher(&ulog_watcher); + } +diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c +index 0a37067b5ebde..0818d48e8521b 100644 +--- a/extensions/ebt_vlan.c ++++ b/extensions/ebt_vlan.c +@@ -181,7 +181,7 @@ static struct ebt_u_match vlan_match = { + .extra_ops = opts, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_match(&vlan_match); + } +diff --git a/extensions/ebtable_broute.c b/extensions/ebtable_broute.c +index 5259355e2b01b..c106f0825a147 100644 +--- a/extensions/ebtable_broute.c ++++ b/extensions/ebtable_broute.c +@@ -23,7 +23,7 @@ ebt_u_table table = + .help = print_help, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_table(&table); + } +diff --git a/extensions/ebtable_filter.c b/extensions/ebtable_filter.c +index e41fb84ffbf20..c0bf105d75986 100644 +--- a/extensions/ebtable_filter.c ++++ b/extensions/ebtable_filter.c +@@ -29,7 +29,7 @@ static struct ebt_u_table table = + .help = print_help, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_table(&table); + } +diff --git a/extensions/ebtable_nat.c b/extensions/ebtable_nat.c +index b21c9ddaedd46..ee044823866c3 100644 +--- a/extensions/ebtable_nat.c ++++ b/extensions/ebtable_nat.c +@@ -30,7 +30,7 @@ ebt_u_table table = + .help = print_help, + }; + +-void _init(void) ++static void _INIT(void) + { + ebt_register_table(&table); + } +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 3235bf5967055..7f5968dc6f39d 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -44,6 +44,8 @@ + #define EBT_ALIGN(s) (((s) + (EBT_MIN_ALIGN-1)) & ~(EBT_MIN_ALIGN-1)) + #define ERRORMSG_MAXLEN 128 + ++#define _INIT __attribute__((constructor)) _init ++ + struct ebt_u_entries + { + int policy; +-- +2.21.0 + diff --git a/SOURCES/0028-Add-.gitignore.patch b/SOURCES/0028-Add-.gitignore.patch new file mode 100644 index 0000000..ec69317 --- /dev/null +++ b/SOURCES/0028-Add-.gitignore.patch @@ -0,0 +1,28 @@ +From 038a7384ffce9b3a134eee81a5f490391b505ee4 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:42 +0200 +Subject: [PATCH] Add .gitignore + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + .gitignore | 7 +++++++ + 1 file changed, 7 insertions(+) + create mode 100644 .gitignore + +diff --git a/.gitignore b/.gitignore +new file mode 100644 +index 0000000000000..d2fc36e763a45 +--- /dev/null ++++ b/.gitignore +@@ -0,0 +1,7 @@ ++*.o ++*.so ++/ebtables ++/ebtables-restore ++/ebtablesd ++/ebtablesu ++/static +-- +2.21.0 + diff --git a/SOURCES/0029-build-move-to-automake.patch b/SOURCES/0029-build-move-to-automake.patch new file mode 100644 index 0000000..ad21775 --- /dev/null +++ b/SOURCES/0029-build-move-to-automake.patch @@ -0,0 +1,512 @@ +From fe81d4fa47b6b69e01de7f7d41002b8e12fec284 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 27 Jun 2018 11:50:43 +0200 +Subject: [PATCH] build: move to automake + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + .gitignore | 23 +++++- + INSTALL | 99 +++++++++-------------- + Makefile | 214 -------------------------------------------------- + Makefile.am | 76 ++++++++++++++++++ + autogen.sh | 4 + + configure.ac | 23 ++++++ + m4/.gitignore | 2 + + 7 files changed, 163 insertions(+), 278 deletions(-) + delete mode 100644 Makefile + create mode 100644 Makefile.am + create mode 100755 autogen.sh + create mode 100644 configure.ac + create mode 100644 m4/.gitignore + +diff --git a/.gitignore b/.gitignore +index d2fc36e763a45..1fff83c78ba13 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -1,7 +1,28 @@ +-*.o ++*.a ++*.la ++*.lo + *.so ++*.o ++.deps/ ++.dirstamp ++.libs/ ++Makefile ++Makefile.in ++ ++/aclocal.m4 ++/autom4te.cache/ ++/build-aux/ ++/config.* ++/configure ++/libtool ++/stamp-h1 ++ + /ebtables ++/ebtables-config + /ebtables-restore ++/ebtables-save ++/ebtables.8 ++/ebtables.sysv + /ebtablesd + /ebtablesu + /static +diff --git a/INSTALL b/INSTALL +index e90d5c103bdc4..c43d95c3ed256 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -1,63 +1,36 @@ +-FOLLOW THESE SIMPLE GUIDELINES: +-------------------------------- +- +-Compiling the source code: +-%make +-Put the files in the right directories: +-%make install +- +-If you are using the CVS code or need your own kernel includes, do this +-instead (change the include directory to the appropriate one): +-%make install KERNEL_INCLUDES=/usr/src/linux/include +- +-If you want to make a static binary for ebtables, containing all the +-extensions, without shared libraries, do this (this will make a +-binary called 'static', which you can rename): +-%make static +- +-WHAT GETS INSTALLED AND WHAT OPTIONS ARE AVAILABLE? +---------------------------------------------------- +- +-- The ebtables manual gets installed in /usr/local/man/man8 +- To put the manual somewhere else, include MANDIR=<> as +- option on the command line. +- The Makefile will append /man8/ebtables.8. +-- ethertypes is by default placed in /etc/, if you +- want to change this, include ETHERTYPESPATH=<>. +-- The userspace programs ebtables ebtables-save and ebtables-restore are +- are copied by default to /usr/local/sbin/ebtables. If you want to put +- the executables somewhere else, include BINPATH=<>. +-- The ebtables initialisation file (enabling use of 'service ebtables') is +- copied to /etc/rc.d/init.d (change with option INITDIR) +-- The ebtables configuration file (ebtables-config) is copied to /etc/sysconfig +-- ebtables can use a lock file to enable concurrent execution of the ebtables +- tool. The standard location of the lock file is /var/lib/ebtables/lock. +- Include LOCKFILE=<> if you want to use another file. +- +-That's all +- +-You can also use a base directory different from the root directory (/), +-using the DESTDIR option. See the Makefile for more details. +- +-You might need to set LDFLAGS=-Wl,-no-as-needed to build ebtables correctly +-on your system. +- +-ADDITIONAL PROGRAMS: +----------------------- +--- examples/ulog/test_ulog.c -- +- +-Contains an example to receive and parse netlink messages containing +-packets seen by the ebtables ulog watcher. +- +-Compile with: +-%make test_ulog KERNEL_INCLUDES=/usr/src/linux/include +- +-Usage: +-%examples/ulog/test_ulog NETLINK_GROUP +-%ebtables -A chain --ulog-nlgroup NETLINK_GROUP +- +--- examples/perf_test/perf_test -- +- +-A test script to compare the performance for the different ways to +-construct an ebtables table. This is deprecated and should probably +-be ignored. ++Installation instructions for iptables ++====================================== ++ ++ebtables uses the well-known configure(autotools) infrastructure. ++ ++ $ ./configure ++ $ make ++ # make install ++ ++ ++Prerequisites ++============= ++ ++ * no kernel-source required ++ ++ * but obviously a compiler, glibc-devel and linux-kernel-headers ++ (/usr/include/linux) ++ ++ ++Configuring and compiling ++========================= ++ ++./configure [options] ++ ++--prefix= ++ ++ The prefix to put all installed files under. It defaults to ++ /usr/local, so the binaries will go into /usr/local/bin, sbin, ++ manpages into /usr/local/share/man, etc. ++ ++If you want to enable debugging, use ++ ++ ./configure CFLAGS="-ggdb3 -O0" CPPFLAGS="-DEBT_DEBUG" ++ ++(-O0 is used to turn off instruction reordering, which makes debugging ++much easier.) +diff --git a/Makefile b/Makefile +deleted file mode 100644 +index 4d7b10f4916d6..0000000000000 +--- a/Makefile ++++ /dev/null +@@ -1,214 +0,0 @@ +-# ebtables Makefile +- +-PROGNAME:=ebtables +-PROGRELEASE:=4 +-PROGVERSION_:=2.0.10 +-PROGVERSION:=$(PROGVERSION_)-$(PROGRELEASE) +-PROGDATE:=December\ 2011 +-LOCKFILE?=/var/lib/ebtables/lock +-LOCKDIR:=$(shell echo $(LOCKFILE) | sed 's/\(.*\)\/.*/\1/')/ +- +-# default paths +-LIBDIR:=/usr/lib +-MANDIR:=/usr/local/man +-BINDIR:=/usr/local/sbin +-ETCDIR:=/etc +-INITDIR:=/etc/rc.d/init.d +-SYSCONFIGDIR:=/etc/sysconfig +-DESTDIR:= +- +-CFLAGS:=-Wall -Wunused -Werror +-CFLAGS_SH_LIB:=-fPIC -O3 +-CC:=gcc +- +-ifeq ($(shell uname -m),sparc64) +-CFLAGS+=-DEBT_MIN_ALIGN=8 -DKERNEL_64_USERSPACE_32 +-endif +- +-include extensions/Makefile +- +-OBJECTS2:=getethertype.o communication.o libebtc.o \ +-useful_functions.o ebtables.o +- +-OBJECTS:=$(OBJECTS2) $(EXT_OBJS) $(EXT_LIBS) +- +-KERNEL_INCLUDES?=include/ +- +-ETHERTYPESPATH?=$(ETCDIR) +-ETHERTYPESFILE:=$(ETHERTYPESPATH)/ethertypes +- +-PIPE_DIR?=/tmp/$(PROGNAME)-v$(PROGVERSION) +-PIPE=$(PIPE_DIR)/ebtablesd_pipe +-EBTD_CMDLINE_MAXLN?=2048 +-EBTD_ARGC_MAX?=50 +- +-PROGSPECS:=-DPROGVERSION=\"$(PROGVERSION)\" \ +- -DPROGNAME=\"$(PROGNAME)\" \ +- -DPROGDATE=\"$(PROGDATE)\" \ +- -D_PATH_ETHERTYPES=\"$(ETHERTYPESFILE)\" \ +- -DEBTD_ARGC_MAX=$(EBTD_ARGC_MAX) \ +- -DEBTD_CMDLINE_MAXLN=$(EBTD_CMDLINE_MAXLN) \ +- -DLOCKFILE=\"$(LOCKFILE)\" \ +- -DLOCKDIR=\"$(LOCKDIR)\" +- +-# You can probably ignore this, ebtables{u,d} are normally not used +-PROGSPECSD:=-DPROGVERSION=\"$(PROGVERSION)\" \ +- -DPROGNAME=\"$(PROGNAME)\" \ +- -DPROGDATE=\"$(PROGDATE)\" \ +- -D_PATH_ETHERTYPES=\"$(ETHERTYPESFILE)\" \ +- -DEBTD_CMDLINE_MAXLN=$(EBTD_CMDLINE_MAXLN) \ +- -DEBTD_ARGC_MAX=$(EBTD_ARGC_MAX) \ +- -DEBTD_PIPE=\"$(PIPE)\" \ +- -DEBTD_PIPE_DIR=\"$(PIPE_DIR)\" +- +-# Uncomment for debugging (slower) +-#PROGSPECS+=-DEBT_DEBUG +-#PROGSPECSD+=-DEBT_DEBUG +-#CFLAGS+=-ggdb +- +-all: ebtables ebtables-restore +- +-communication.o: communication.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-libebtc.o: libebtc.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-useful_functions.o: useful_functions.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-getethertype.o: getethertype.c include/ethernetdb.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -Iinclude/ +- +-ebtables.o: ebtables.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-ebtables-standalone.o: ebtables-standalone.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c $< -o $@ -I$(KERNEL_INCLUDES) +- +-libebtc.so: $(OBJECTS2) +- $(CC) -shared $(LDFLAGS) -Wl,-soname,libebtc.so -o libebtc.so -lc $(OBJECTS2) +- +-ebtables: $(OBJECTS) ebtables-standalone.o libebtc.so +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(LDFLAGS) -o $@ ebtables-standalone.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \ +- -Wl,-rpath,$(LIBDIR) +- +-ebtablesu: ebtablesu.c +- $(CC) $(CFLAGS) $(PROGSPECSD) $< -o $@ +- +-ebtablesd.o: ebtablesd.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(PROGSPECSD) -c $< -o $@ -I$(KERNEL_INCLUDES) +- +-ebtablesd: $(OBJECTS) ebtablesd.o libebtc.so +- $(CC) $(CFLAGS) -o $@ ebtablesd.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \ +- -Wl,-rpath,$(LIBDIR) +- +-ebtables-restore.o: ebtables-restore.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(PROGSPECS) -c $< -o $@ -I$(KERNEL_INCLUDES) +- +-ebtables-restore: $(OBJECTS) ebtables-restore.o libebtc.so +- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ ebtables-restore.o -I$(KERNEL_INCLUDES) -L. -Lextensions -lebtc $(EXT_LIBSI) \ +- -Wl,-rpath,$(LIBDIR) +- +-.PHONY: daemon +-daemon: ebtablesd ebtablesu +- +-# a little scripting for a static binary, making one for ebtables-restore +-# should be completely analogous +-static: extensions/ebt_*.c extensions/ebtable_*.c ebtables.c communication.c ebtables-standalone.c getethertype.c libebtc.c useful_functions.c +- $(CC) $(CFLAGS) $(LDFLAGS) $(PROGSPECS) -o $@ $^ -I$(KERNEL_INCLUDES) -Iinclude +- +-tmp1:=$(shell printf $(BINDIR) | sed 's/\//\\\//g') +-tmp2:=$(shell printf $(SYSCONFIGDIR) | sed 's/\//\\\//g') +-tmp3:=$(shell printf $(PIPE) | sed 's/\//\\\//g') +-.PHONY: scripts +-scripts: ebtables-save.in ebtables.sysv.in ebtables-config.in +- sed -e 's/[@]sbindir@/$(tmp1)/g' ebtables-save_ +- mkdir -p $(DESTDIR)$(BINDIR) +- install -m 0755 ebtables-save_ $(DESTDIR)$(BINDIR)/ebtables-save +- sed -e 's/[@]sbindir@/$(tmp1)/g' -e 's/[@]sysconfigdir@/$(tmp2)/g' ebtables.sysv_ +- if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(INITDIR); fi +- if test -d $(DESTDIR)$(INITDIR); then install -m 0755 ebtables.sysv_ $(DESTDIR)$(INITDIR)/ebtables; fi +- sed -e 's/[@]sysconfigdir@/$(tmp2)/g' ebtables-config_ +- if [ "$(DESTDIR)" != "" ]; then mkdir -p $(DESTDIR)$(SYSCONFIGDIR); fi +- if test -d $(DESTDIR)$(SYSCONFIGDIR); then install -m 0600 ebtables-config_ $(DESTDIR)$(SYSCONFIGDIR)/ebtables-config; fi +- rm -f ebtables-save_ ebtables.sysv_ ebtables-config_ +- +-tmp4:=$(shell printf $(LOCKFILE) | sed 's/\//\\\//g') +-$(MANDIR)/man8/ebtables.8: ebtables.8.in +- mkdir -p $(DESTDIR)$(@D) +- sed -e 's/[@]PACKAGE_VERSION@/$(PROGVERSION)/' -e 's/[@]PACKAGE_DATE@/$(PROGDATE)/' -e 's/[@]LOCKFILE@/$(tmp4)/' <$< >ebtables.8_ +- install -m 0644 ebtables.8_ $(DESTDIR)$@ +- rm -f ebtables.8_ +- +-$(DESTDIR)$(ETHERTYPESFILE): ethertypes +- mkdir -p $(@D) +- install -m 0644 $< $@ +- +-.PHONY: exec +-exec: ebtables ebtables-restore +- mkdir -p $(DESTDIR)$(BINDIR) +- install -m 0755 $(PROGNAME) $(DESTDIR)$(BINDIR)/$(PROGNAME) +- install -m 0755 ebtables-restore $(DESTDIR)$(BINDIR)/ebtables-restore +- +-.PHONY: install +-install: $(MANDIR)/man8/ebtables.8 $(DESTDIR)$(ETHERTYPESFILE) exec scripts +- mkdir -p $(DESTDIR)$(LIBDIR) +- install -m 0755 extensions/*.so $(DESTDIR)$(LIBDIR) +- install -m 0755 *.so $(DESTDIR)$(LIBDIR) +- +-.PHONY: clean +-clean: +- rm -f ebtables ebtables-restore ebtablesd ebtablesu static +- rm -f *.o *~ *.so +- rm -f extensions/*.o extensions/*.c~ extensions/*.so include/*~ +- +-DIR:=$(PROGNAME)-v$(PROGVERSION) +-CVSDIRS:=CVS extensions/CVS examples/CVS examples/perf_test/CVS \ +-examples/ulog/CVS include/CVS +-# This is used to make a new userspace release, some files are altered so +-# do this on a temporary version +-.PHONY: release +-release: +- rm -f extensions/ebt_inat.c +- rm -rf $(CVSDIRS) +- mkdir -p include/linux/netfilter_bridge +- install -m 0644 \ +- $(KERNEL_INCLUDES)/linux/netfilter_bridge.h include/linux/ +-# To keep possible compile error complaints about undefined ETH_P_8021Q +-# off my back +- install -m 0644 \ +- $(KERNEL_INCLUDES)/linux/if_ether.h include/linux/ +- install -m 0644 \ +- $(KERNEL_INCLUDES)/linux/types.h include/linux/ +- install -m 0644 \ +- $(KERNEL_INCLUDES)/linux/netfilter_bridge/*.h \ +- include/linux/netfilter_bridge/ +- install -m 0644 \ +- include/ebtables.h include/linux/netfilter_bridge/ +- make clean +- touch * +- touch extensions/* +- touch include/* +- touch include/linux/* +- touch include/linux/netfilter_bridge/* +- sed -i -e 's/$$(VERSION)/$(PROGVERSION)/' -e 's/$$(DATE)/$(PROGDATE)/' -e 's/$$(LOCKFILE)/$(tmp4)/' ebtables.8 +- sed -i -e 's/$$(VERSION)/$(PROGVERSION_)/' -e 's/$$(RELEASE)/$(PROGRELEASE)/' ebtables.spec +- cd ..;tar -c $(DIR) | gzip >$(DIR).tar.gz; cd - +- rm -rf include/linux +- +-# This will make the rpm and put it in /usr/src/redhat/RPMS +-# (do this as root after make release) +-.PHONY: rpmbuild +-rpmbuild: +- cp ../$(DIR).tar.gz /usr/src/redhat/SOURCES/ +- rpmbuild --buildroot $(shell mktemp -td $(DIR)-XXXXX) -bb ebtables.spec +- +-.PHONY: test_ulog +-test_ulog: examples/ulog/test_ulog.c getethertype.o +- $(CC) $(CFLAGS) $< -o test_ulog -I$(KERNEL_INCLUDES) -lc \ +- getethertype.o +- mv test_ulog examples/ulog/ +- +-.PHONY: examples +-examples: test_ulog +diff --git a/Makefile.am b/Makefile.am +new file mode 100644 +index 0000000000000..14938fea4f252 +--- /dev/null ++++ b/Makefile.am +@@ -0,0 +1,76 @@ ++# -*- Makefile -*- ++ ++# For debugging, use ./configure CPPFLAGS=-DEBT_DEBUG CFLAGS="-O0 -ggdb3" ++ ++PROGNAME = ${PACKAGE_NAME} ++PROGVERSION = ${PACKAGE_VERSION} ++PROGDATE = December\ 2011 ++LOCKDIR = /var/lib/ebtables ++LOCKFILE = ${LOCKDIR}/lock ++INITDIR = /etc/rc.d/init.d ++initddir = ${INITDIR} ++sysconfigdir = ${sysconfdir}/sysconfig ++EBTD_CMDLINE_MAXLN = 2048 ++EBTD_ARGC_MAX = 50 ++PIPE_DIR = /tmp/${PACKAGE_NAME}-v${PROGVERSION} ++PIPE = ${PIPE_DIR}/ebtablesd_pipe ++ ++ ++ACLOCAL_AMFLAGS = -I m4 ++AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include \ ++ -DPROGVERSION=\"${PACKAGE_VERSION}\" -DPROGNAME=\"${PACKAGE_NAME}\" \ ++ -DPROGDATE=\"${PROGDATE}\" \ ++ -D_PATH_ETHERTYPES=\"${sysconfdir}/ethertypes\" \ ++ -DLOCKFILE=\"${LOCKFILE}\" -DLOCKDIR=\"${LOCKDIR}\" \ ++ -DEBTD_ARGC_MAX=${EBTD_ARGC_MAX} -DEBTD_CMDLINE_MAXLN=${EBTD_CMDLINE_MAXLN} \ ++ -DEBTD_PIPE=\"${PIPE}\" -DEBTD_PIPE_DIR=\"${PIPE_DIR}\" ++AM_CFLAGS = ${regular_CFLAGS} ++ ++sbin_PROGRAMS = ebtables ebtablesd ebtablesu ebtables-restore ++EXTRA_PROGRAMS = static examples/ulog/test_ulog ++sysconf_DATA = ethertypes ++sbin_SCRIPTS = ebtables-save ++man8_MANS = ebtables.8 ++lib_LTLIBRARIES = libebtc.la ++ ++libebtc_la_SOURCES = \ ++ communication.c ebtables.c getethertype.c \ ++ libebtc.c useful_functions.c \ ++ extensions/ebt_802_3.c extensions/ebt_among.c extensions/ebt_arp.c \ ++ extensions/ebt_arpreply.c extensions/ebt_ip.c extensions/ebt_ip6.c \ ++ extensions/ebt_limit.c extensions/ebt_log.c extensions/ebt_mark.c \ ++ extensions/ebt_mark_m.c extensions/ebt_nat.c extensions/ebt_nflog.c \ ++ extensions/ebt_pkttype.c extensions/ebt_redirect.c \ ++ extensions/ebt_standard.c extensions/ebt_stp.c extensions/ebt_string.c \ ++ extensions/ebt_ulog.c extensions/ebt_vlan.c \ ++ extensions/ebtable_broute.c extensions/ebtable_filter.c \ ++ extensions/ebtable_nat.c ++# Make sure ebtables.c can be built twice ++libebtc_la_CPPFLAGS = ${AM_CPPFLAGS} ++ebtables_SOURCES = ebtables-standalone.c ++ebtables_LDADD = libebtc.la ++ebtablesd_LDADD = libebtc.la ++ebtables_restore_LDADD = libebtc.la ++static_SOURCES = ebtables.c ++static_LDFLAGS = -static ++static_LDADD = libebtc.la ++examples_ulog_test_ulog_SOURCES = examples/ulog/test_ulog.c getethertype.c ++ ++daemon: ebtablesd ebtablesu ++exec: ebtables ebtables-restore ++ ++CLEANFILES = ebtables-save ebtables.sysv ebtables-config ebtables.8 ++ ++ebtables-save: ebtables-save.in ${top_builddir}/config.status ++ ${AM_V_GEN}sed -e 's![@]sbindir@!${sbindir}!g' <$< >$@ ++ ++ebtables.sysv: ebtables.sysv.in ${top_builddir}/config.status ++ ${AM_V_GEN}sed -e 's![@]sbindir@!${sbindir}!g' -e 's![@]sysconfigdir@!${sysconfigdir}!g' <$< >$@ ++ ++ebtables-config: ebtables-config.in ${top_builddir}/config.status ++ ${AM_V_GEN}sed -e 's![@]sysconfigdir@!${sysconfigdir}!g' <$< >$@ ++ ++ebtables.8: ebtables.8.in ${top_builddir}/config.status ++ ${AM_V_GEN}sed -e 's![@]PACKAGE_VERSION!${PACKAGE_VERSION}!g' \ ++ -e 's![@]PACKAGE_DATE@!${PROGDATE}!g' \ ++ -e 's![@]LOCKFILE@!${LOCKFILE}!g' <$< >$@ +diff --git a/autogen.sh b/autogen.sh +new file mode 100755 +index 0000000000000..a0c4395f356fd +--- /dev/null ++++ b/autogen.sh +@@ -0,0 +1,4 @@ ++#!/bin/sh -e ++ ++autoreconf -fi; ++rm -Rf autom4te*.cache; +diff --git a/configure.ac b/configure.ac +new file mode 100644 +index 0000000000000..a3bc3c93a279f +--- /dev/null ++++ b/configure.ac +@@ -0,0 +1,23 @@ ++AC_INIT([ebtables], [2.0.10.4]) ++AC_CONFIG_AUX_DIR([build-aux]) ++AC_CONFIG_HEADERS([config.h]) ++AC_CONFIG_MACRO_DIR([m4]) ++AC_PROG_INSTALL ++AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax]) ++AC_PROG_CC ++AM_PROG_CC_C_O ++AC_DISABLE_STATIC ++m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) ++AM_PROG_LIBTOOL ++ ++regular_CFLAGS="-Wall -Wunused" ++regular_CPPFLAGS="" ++case "$host" in ++ sparc64-*) ++ regular_CPPFLAGS="$regular_CPPFLAGS -DEBT_MIN_ALIGN=8 -DKERNEL_64_USERSPACE_32";; ++esac ++ ++AC_SUBST([regular_CFLAGS]) ++AC_SUBST([regular_CPPFLAGS]) ++AC_CONFIG_FILES([Makefile]) ++AC_OUTPUT +diff --git a/m4/.gitignore b/m4/.gitignore +new file mode 100644 +index 0000000000000..64d9bbcdd5ce9 +--- /dev/null ++++ b/m4/.gitignore +@@ -0,0 +1,2 @@ ++/libtool.m4 ++/lt*.m4 +-- +2.21.0 + diff --git a/SOURCES/0030-ebtablesd-avoid-build-warning.patch b/SOURCES/0030-ebtablesd-avoid-build-warning.patch new file mode 100644 index 0000000..fff76c7 --- /dev/null +++ b/SOURCES/0030-ebtablesd-avoid-build-warning.patch @@ -0,0 +1,52 @@ +From ee7071e6d7d93f10d38f4eb8c9a4c0ca8984c2d0 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 2 Jul 2018 18:06:11 +0200 +Subject: [PATCH] ebtablesd: avoid build warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ebtablesd.c:55:43: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + ebtablesd.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/ebtablesd.c b/ebtablesd.c +index 062a2d6b5afa3..02d51fa115456 100644 +--- a/ebtablesd.c ++++ b/ebtablesd.c +@@ -52,7 +52,7 @@ int main(int argc_, char *argv_[]) + char *argv[EBTD_ARGC_MAX], *args[4], name[] = "mkdir", + mkdir_option[] = "-p", mkdir_dir[] = EBTD_PIPE_DIR, + cmdline[EBTD_CMDLINE_MAXLN]; +- int readfd, base = 0, offset = 0, n = 0, ret = 0, quotemode = 0; ++ int readfd, base = 0, offset = 0, n = 0, quotemode = 0; + + /* Make sure the pipe directory exists */ + args[0] = name; +@@ -74,19 +74,16 @@ int main(int argc_, char *argv_[]) + + if (mkfifo(EBTD_PIPE, 0600) < 0 && errno != EEXIST) { + printf("Error creating FIFO " EBTD_PIPE "\n"); +- ret = -1; + goto do_exit; + } + + if ((readfd = open(EBTD_PIPE, O_RDONLY | O_NONBLOCK, 0)) == -1) { + perror("open"); +- ret = -1; + goto do_exit; + } + + if (signal(SIGPIPE, sigpipe_handler) == SIG_ERR) { + perror("signal"); +- ret = -1; + goto do_exit; + } + +-- +2.21.0 + diff --git a/SOURCES/0031-extensions-among-Fix-bitmask-check.patch b/SOURCES/0031-extensions-among-Fix-bitmask-check.patch new file mode 100644 index 0000000..602f61a --- /dev/null +++ b/SOURCES/0031-extensions-among-Fix-bitmask-check.patch @@ -0,0 +1,42 @@ +From 4237aad9c04ac6a82756545a49ae8e9bd0fe9fac Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 12 Nov 2018 17:50:27 +0100 +Subject: [PATCH] extensions: among: Fix bitmask check + +Boolean AND was applied instead of binary one, causing the exclamation +mark to be printed whenever info->bitmask was non-zero. In practice, +this leads to incorrect output if e.g. --among-src was given with an +inverted match as well as --among-dst with a non-inverted one. Output +would then list both matches as inverted. + +Signed-off-by: Phil Sutter +Signed-off-by: Florian Westphal +Signed-off-by: Phil Sutter +--- + extensions/ebt_among.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/ebt_among.c b/extensions/ebt_among.c +index b1560e8f09e8d..30c098cf69f96 100644 +--- a/extensions/ebt_among.c ++++ b/extensions/ebt_among.c +@@ -436,14 +436,14 @@ static void print(const struct ebt_u_entry *entry, + + if (info->wh_dst_ofs) { + printf("--among-dst "); +- if (info->bitmask && EBT_AMONG_DST_NEG) { ++ if (info->bitmask & EBT_AMONG_DST_NEG) { + printf("! "); + } + wormhash_printout(ebt_among_wh_dst(info)); + } + if (info->wh_src_ofs) { + printf("--among-src "); +- if (info->bitmask && EBT_AMONG_SRC_NEG) { ++ if (info->bitmask & EBT_AMONG_SRC_NEG) { + printf("! "); + } + wormhash_printout(ebt_among_wh_src(info)); +-- +2.21.0 + diff --git a/SOURCES/0032-ebtables-legacy-renaming.patch b/SOURCES/0032-ebtables-legacy-renaming.patch new file mode 100644 index 0000000..63cec1f --- /dev/null +++ b/SOURCES/0032-ebtables-legacy-renaming.patch @@ -0,0 +1,145 @@ +From 522ae2fa8b610f13ae69835959dea710f808d887 Mon Sep 17 00:00:00 2001 +From: Arturo Borrero Gonzalez +Date: Wed, 28 Nov 2018 13:47:28 +0100 +Subject: [PATCH] ebtables: legacy renaming + +The original ebtables tool is now the legacy version, let's rename it. + +A more uptodate client of the ebtables tool is provided in the iptables +tarball (ebtables-nft). The new tool was formerly known as ebtables-compat. + +The new -legacy binary has no problem if called via a symlink with the +'ebtables' name, so users can still name this binary with whatever name. + +Signed-off-by: Arturo Borrero Gonzalez +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + Makefile.am | 21 +++++++++++---------- + ebtables.8.in => ebtables-legacy.8.in | 14 +++++++++++++- + ebtables-save.in | 2 +- + include/ebtables_u.h | 2 +- + 4 files changed, 26 insertions(+), 13 deletions(-) + rename ebtables.8.in => ebtables-legacy.8.in (98%) + +diff --git a/Makefile.am b/Makefile.am +index 14938fea4f252..b16a4d6dba269 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -26,11 +26,11 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include \ + -DEBTD_PIPE=\"${PIPE}\" -DEBTD_PIPE_DIR=\"${PIPE_DIR}\" + AM_CFLAGS = ${regular_CFLAGS} + +-sbin_PROGRAMS = ebtables ebtablesd ebtablesu ebtables-restore ++sbin_PROGRAMS = ebtables-legacy ebtablesd ebtablesu ebtables-legacy-restore + EXTRA_PROGRAMS = static examples/ulog/test_ulog + sysconf_DATA = ethertypes +-sbin_SCRIPTS = ebtables-save +-man8_MANS = ebtables.8 ++sbin_SCRIPTS = ebtables-legacy-save ++man8_MANS = ebtables-legacy.8 + lib_LTLIBRARIES = libebtc.la + + libebtc_la_SOURCES = \ +@@ -47,21 +47,22 @@ libebtc_la_SOURCES = \ + extensions/ebtable_nat.c + # Make sure ebtables.c can be built twice + libebtc_la_CPPFLAGS = ${AM_CPPFLAGS} +-ebtables_SOURCES = ebtables-standalone.c +-ebtables_LDADD = libebtc.la ++ebtables_legacy_SOURCES = ebtables-standalone.c ++ebtables_legacy_LDADD = libebtc.la + ebtablesd_LDADD = libebtc.la +-ebtables_restore_LDADD = libebtc.la ++ebtables_legacy_restore_SOURCES = ebtables-restore.c ++ebtables_legacy_restore_LDADD = libebtc.la + static_SOURCES = ebtables.c + static_LDFLAGS = -static + static_LDADD = libebtc.la + examples_ulog_test_ulog_SOURCES = examples/ulog/test_ulog.c getethertype.c + + daemon: ebtablesd ebtablesu +-exec: ebtables ebtables-restore ++exec: ebtables-legacy ebtables-legacy-restore + +-CLEANFILES = ebtables-save ebtables.sysv ebtables-config ebtables.8 ++CLEANFILES = ebtables-legacy-save ebtables.sysv ebtables-config ebtables-legacy.8 + +-ebtables-save: ebtables-save.in ${top_builddir}/config.status ++ebtables-legacy-save: ebtables-save.in ${top_builddir}/config.status + ${AM_V_GEN}sed -e 's![@]sbindir@!${sbindir}!g' <$< >$@ + + ebtables.sysv: ebtables.sysv.in ${top_builddir}/config.status +@@ -70,7 +71,7 @@ ebtables.sysv: ebtables.sysv.in ${top_builddir}/config.status + ebtables-config: ebtables-config.in ${top_builddir}/config.status + ${AM_V_GEN}sed -e 's![@]sysconfigdir@!${sysconfigdir}!g' <$< >$@ + +-ebtables.8: ebtables.8.in ${top_builddir}/config.status ++ebtables-legacy.8: ebtables-legacy.8.in ${top_builddir}/config.status + ${AM_V_GEN}sed -e 's![@]PACKAGE_VERSION!${PACKAGE_VERSION}!g' \ + -e 's![@]PACKAGE_DATE@!${PROGDATE}!g' \ + -e 's![@]LOCKFILE@!${LOCKFILE}!g' <$< >$@ +diff --git a/ebtables.8.in b/ebtables-legacy.8.in +similarity index 98% +rename from ebtables.8.in +rename to ebtables-legacy.8.in +index 3e97c84da0e86..3417045fbd89d 100644 +--- a/ebtables.8.in ++++ b/ebtables-legacy.8.in +@@ -24,7 +24,7 @@ + .\" + .\" + .SH NAME +-ebtables (@PACKAGE_VERSION@) \- Ethernet bridge frame table administration ++ebtables-legacy (@PACKAGE_VERSION@) \- Ethernet bridge frame table administration (legacy) + .SH SYNOPSIS + .BR "ebtables " [ -t " table ] " - [ ACDI "] chain rule specification [match extensions] [watcher extensions] target" + .br +@@ -50,6 +50,18 @@ ebtables (@PACKAGE_VERSION@) \- Ethernet bridge frame table administration + .br + .BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-save + .br ++ ++.SH LEGACY ++This tool uses the old xtables/setsockopt framework, and is a legacy version ++of ebtables. That means that a new, more modern tool exists with the same ++functionality using the nf_tables framework and you are encouraged to migrate now. ++The new binaries (known as ebtables-nft and formerly known as ebtables-compat) ++uses the same syntax and semantics than this legacy one. ++ ++You can still use this legacy tool. You should probably get some specific ++information from your Linux distribution or vendor. ++More docs are available at https://wiki.nftables.org ++ + .SH DESCRIPTION + .B ebtables + is an application program used to set up and maintain the +diff --git a/ebtables-save.in b/ebtables-save.in +index df141490c20b1..17924a2b8df90 100644 +--- a/ebtables-save.in ++++ b/ebtables-save.in +@@ -50,7 +50,7 @@ sub process_table { + # ======================================================== + + unless (-x $ebtables) { exit -1 }; +-print "# Generated by ebtables-save v$version on " . `date`; ++print "# Generated by ebtables-save v$version (legacy) on " . `date`; + if (defined($ENV{'EBTABLES_SAVE_COUNTER'}) && $ENV{'EBTABLES_SAVE_COUNTER'} eq "yes") { + $cnt = "--Lc"; + } +diff --git a/include/ebtables_u.h b/include/ebtables_u.h +index 7f5968dc6f39d..901b28233f140 100644 +--- a/include/ebtables_u.h ++++ b/include/ebtables_u.h +@@ -395,7 +395,7 @@ extern int ebt_printstyle_mac; + #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) + /* Clear the bit in the hook_mask that tells if the rule is on a base chain */ + #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) +-#define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" ("PROGDATE")\n") ++#define PRINT_VERSION printf(PROGNAME" v"PROGVERSION" (legacy) ("PROGDATE")\n") + #ifndef PROC_SYS_MODPROBE + #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" + #endif +-- +2.21.0 + diff --git a/SOURCES/0033-ebtables-drop-.spec-file.patch b/SOURCES/0033-ebtables-drop-.spec-file.patch new file mode 100644 index 0000000..3925133 --- /dev/null +++ b/SOURCES/0033-ebtables-drop-.spec-file.patch @@ -0,0 +1,108 @@ +From df6364dbcbba11b75ede2aab6f54183939a1450b Mon Sep 17 00:00:00 2001 +From: Arturo Borrero Gonzalez +Date: Tue, 22 Jan 2019 18:41:45 +0100 +Subject: [PATCH] ebtables: drop .spec file + +This file is for packging in th RPM format. Clearly don't belong here. +Also, it is unmaintained. + +Signed-off-by: Arturo Borrero Gonzalez +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + ebtables.spec | 83 --------------------------------------------------- + 1 file changed, 83 deletions(-) + delete mode 100644 ebtables.spec + +diff --git a/ebtables.spec b/ebtables.spec +deleted file mode 100644 +index 50095db6f9470..0000000000000 +--- a/ebtables.spec ++++ /dev/null +@@ -1,83 +0,0 @@ +-# spec file originally from Dag Wieers, altered by Bart De Schuymer +- +-%define _sbindir /usr/local/sbin +-%define _mysysconfdir %{_sysconfdir}/sysconfig +- +-Summary: Ethernet Bridge frame table administration tool +-Name: ebtables +-Version: 2.0.10 +-Release: 4 +-License: GPL +-Group: System Environment/Base +-URL: http://ebtables.sourceforge.net/ +- +-Packager: Bart De Schuymer +- +-Source: http://dl.sf.net/ebtables/ebtables-v%{version}-%{release}.tar.gz +-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +- +-%description +-Ethernet bridge tables is a firewalling tool to transparantly filter network +-traffic passing a bridge. The filtering possibilities are limited to link +-layer filtering and some basic filtering on higher network layers. +- +-The ebtables tool can be used together with the other Linux filtering tools, +-like iptables. There are no incompatibility issues. +- +-%prep +-%setup -n ebtables-v%{version}-%{release} +- +-%build +-%{__make} %{?_smp_mflags} \ +- CFLAGS="%{optflags}" +- +-%install +-%{__rm} -rf %{buildroot} +-%{__install} -D -m0755 ebtables %{buildroot}%{_sbindir}/ebtables +-%{__install} -D -m0755 ebtables-restore %{buildroot}%{_sbindir}/ebtables-restore +-%{__install} -D -m0644 ethertypes %{buildroot}%{_sysconfdir}/ethertypes +-%{__install} -D -m0644 ebtables.8 %{buildroot}%{_mandir}/man8/ebtables.8 +-%{__mkdir} -p %{buildroot}%{_libdir}/ebtables/ +-%{__mkdir} -p %{buildroot}%{_sbindir} +-%{__mkdir} -p %{buildroot}%{_initrddir} +-%{__mkdir} -p %{buildroot}%{_mysysconfdir} +-%{__install} -m0755 extensions/*.so %{buildroot}%{_libdir}/ebtables/ +-%{__install} -m0755 *.so %{buildroot}%{_libdir}/ebtables/ +-export __iets=`printf %{_sbindir} | sed 's/\\//\\\\\\//g'` +-export __iets2=`printf %{_mysysconfdir} | sed 's/\\//\\\\\\//g'` +-sed -i "s/__EXEC_PATH__/$__iets/g" ebtables-save +-%{__install} -m 0755 -o root -g root ebtables-save %{buildroot}%{_sbindir}/ebtables-save +-sed -i "s/__EXEC_PATH__/$__iets/g" ebtables.sysv; sed -i "s/__SYSCONFIG__/$__iets2/g" ebtables.sysv +-%{__install} -m 0755 -o root -g root ebtables.sysv %{buildroot}%{_initrddir}/ebtables +-sed -i "s/__SYSCONFIG__/$__iets2/g" ebtables-config +-%{__install} -m 0600 -o root -g root ebtables-config %{buildroot}%{_mysysconfdir}/ebtables-config +-unset __iets +-unset __iets2 +- +-%clean +-%{__rm} -rf %{buildroot} +- +-%post +-/sbin/chkconfig --add ebtables +- +-%preun +-if [ $1 -eq 0 ]; then +- /sbin/service ebtables stop &>/dev/null || : +- /sbin/chkconfig --del ebtables +-fi +- +-%files +-%defattr(-, root, root, 0755) +-%doc ChangeLog COPYING INSTALL THANKS +-%doc %{_mandir}/man8/ebtables.8* +-%config %{_sysconfdir}/ethertypes +-%config %{_mysysconfdir}/ebtables-config +-%config %{_initrddir}/ebtables +-%{_sbindir}/ebtables +-%{_sbindir}/ebtables-save +-%{_sbindir}/ebtables-restore +-%{_libdir}/ebtables/ +- +-%changelog +-* Mon Nov 07 2005 Bart De Schuymer - 2.0.8-rc1 +-- Initial package. +-- +2.21.0 + diff --git a/SOURCES/0034-ebtables-drop-sysvinit-script.patch b/SOURCES/0034-ebtables-drop-sysvinit-script.patch new file mode 100644 index 0000000..4b0ebd2 --- /dev/null +++ b/SOURCES/0034-ebtables-drop-sysvinit-script.patch @@ -0,0 +1,204 @@ +From 2fab90f7b61fdd433b81b66a60a0124154231486 Mon Sep 17 00:00:00 2001 +From: Arturo Borrero Gonzalez +Date: Tue, 22 Jan 2019 18:41:52 +0100 +Subject: [PATCH] ebtables: drop sysvinit script + +This configuration file belongs to downstream distributions. +Also, it's unmaintained. + +Signed-off-by: Arturo Borrero Gonzalez +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + .gitignore | 1 - + Makefile.am | 5 +- + ebtables.sysv.in | 145 ----------------------------------------------- + 3 files changed, 1 insertion(+), 150 deletions(-) + delete mode 100644 ebtables.sysv.in + +diff --git a/.gitignore b/.gitignore +index 1fff83c78ba13..c1fae5463a355 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -22,7 +22,6 @@ Makefile.in + /ebtables-restore + /ebtables-save + /ebtables.8 +-/ebtables.sysv + /ebtablesd + /ebtablesu + /static +diff --git a/Makefile.am b/Makefile.am +index b16a4d6dba269..59ae595ee16de 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -60,14 +60,11 @@ examples_ulog_test_ulog_SOURCES = examples/ulog/test_ulog.c getethertype.c + daemon: ebtablesd ebtablesu + exec: ebtables-legacy ebtables-legacy-restore + +-CLEANFILES = ebtables-legacy-save ebtables.sysv ebtables-config ebtables-legacy.8 ++CLEANFILES = ebtables-legacy-save ebtables-config ebtables-legacy.8 + + ebtables-legacy-save: ebtables-save.in ${top_builddir}/config.status + ${AM_V_GEN}sed -e 's![@]sbindir@!${sbindir}!g' <$< >$@ + +-ebtables.sysv: ebtables.sysv.in ${top_builddir}/config.status +- ${AM_V_GEN}sed -e 's![@]sbindir@!${sbindir}!g' -e 's![@]sysconfigdir@!${sysconfigdir}!g' <$< >$@ +- + ebtables-config: ebtables-config.in ${top_builddir}/config.status + ${AM_V_GEN}sed -e 's![@]sysconfigdir@!${sysconfigdir}!g' <$< >$@ + +diff --git a/ebtables.sysv.in b/ebtables.sysv.in +deleted file mode 100644 +index bbf0e7424cb2b..0000000000000 +--- a/ebtables.sysv.in ++++ /dev/null +@@ -1,145 +0,0 @@ +-#!/bin/bash +-# +-# init script for the Ethernet Bridge filter tables +-# +-# Written by Dag Wieers +-# Modified by Rok Papez +-# Bart De Schuymer +-# +-# chkconfig: - 15 85 +-# description: Ethernet Bridge filtering tables +-# +-# config: @sysconfigdir@/ebtables (text) +-# @sysconfigdir@/ebtables.
(binary) +- +-source /etc/init.d/functions +-source /etc/sysconfig/network +- +-# Check that networking is up. +-[ ${NETWORKING} = "no" ] && exit 0 +- +-[ -x @sbindir@/ebtables ] || exit 1 +-[ -x @sbindir@/ebtables-save ] || exit 1 +-[ -x @sbindir@/ebtables-restore ] || exit 1 +- +-RETVAL=0 +-prog="ebtables" +-desc="Ethernet bridge filtering" +-umask 0077 +- +-#default configuration +-EBTABLES_TEXT_FORMAT="yes" +-EBTABLES_BINARY_FORMAT="yes" +-EBTABLES_MODULES_UNLOAD="yes" +-EBTABLES_SAVE_ON_STOP="no" +-EBTABLES_SAVE_ON_RESTART="no" +-EBTABLES_SAVE_COUNTER="no" +- +-config=@sysconfigdir@/$prog-config +-[ -f "$config" ] && . "$config" +- +-start() { +- echo -n $"Starting $desc ($prog): " +- if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then +- for table in $(ls @sysconfigdir@/ebtables.* 2>/dev/null | sed -e 's/.*ebtables\.//' -e '/save/d' ); do +- @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table --atomic-commit || RETVAL=1 +- done +- else +- @sbindir@/ebtables-restore < /etc/sysconfig/ebtables || RETVAL=1 +- fi +- +- if [ $RETVAL -eq 0 ]; then +- success "$prog startup" +- rm -f /var/lock/subsys/$prog +- else +- failure "$prog startup" +- fi +- echo +-} +- +-stop() { +- echo -n $"Stopping $desc ($prog): " +- for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do +- @sbindir@/ebtables -t $table --init-table || RETVAL=1 +- done +- +- if [ "$EBTABLES_MODULES_UNLOAD" = "yes" ]; then +- for mod in $(grep -E '^(ebt|ebtable)_' /proc/modules | cut -f1 -d' ') ebtables; do +- rmmod $mod 2> /dev/null +- done +- fi +- +- if [ $RETVAL -eq 0 ]; then +- success "$prog shutdown" +- rm -f /var/lock/subsys/$prog +- else +- failure "$prog shutdown" +- fi +- echo +-} +- +-restart() { +- stop +- start +-} +- +-save() { +- echo -n $"Saving $desc ($prog): " +- if [ "$EBTABLES_TEXT_FORMAT" = "yes" ]; then +- if [ -e @sysconfigdir@/ebtables ]; then +- chmod 0600 @sysconfigdir@/ebtables +- mv -f @sysconfigdir@/ebtables @sysconfigdir@/ebtables.save +- fi +- @sbindir@/ebtables-save > @sysconfigdir@/ebtables || RETVAL=1 +- fi +- if [ "$EBTABLES_BINARY_FORMAT" = "yes" ]; then +- rm -f @sysconfigdir@/ebtables.*.save +- for oldtable in $(ls @sysconfigdir@/ebtables.* 2>/dev/null | grep -vF 'ebtables.save'); do +- chmod 0600 $oldtable +- mv -f $oldtable $oldtable.save +- done +- for table in $(grep '^ebtable_' /proc/modules | sed -e 's/ebtable_\([^ ]*\).*/\1/'); do +- @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table --atomic-save || RETVAL=1 +- if [ "$EBTABLES_SAVE_COUNTER" = "no" ]; then +- @sbindir@/ebtables -t $table --atomic-file @sysconfigdir@/ebtables.$table -Z || RETVAL=1 +- fi +- done +- fi +- +- if [ $RETVAL -eq 0 ]; then +- success "$prog saved" +- else +- failure "$prog saved" +- fi +- echo +-} +- +-case "$1" in +- start) +- start +- ;; +- stop) +- [ "$EBTABLES_SAVE_ON_STOP" = "yes" ] && save +- stop +- ;; +- restart|reload) +- [ "$EBTABLES_SAVE_ON_RESTART" = "yes" ] && save +- restart +- ;; +- condrestart) +- [ -e /var/lock/subsys/$prog ] && restart +- RETVAL=$? +- ;; +- save) +- save +- ;; +- status) +- @sbindir@/ebtables-save +- RETVAL=$? +- ;; +- *) +- echo $"Usage $0 {start|stop|restart|condrestart|save|status}" +- RETVAL=1 +-esac +- +-exit $RETVAL +-- +2.21.0 + diff --git a/SOURCES/0035-Print-IPv6-prefixes-in-CIDR-notation.patch b/SOURCES/0035-Print-IPv6-prefixes-in-CIDR-notation.patch new file mode 100644 index 0000000..04742e7 --- /dev/null +++ b/SOURCES/0035-Print-IPv6-prefixes-in-CIDR-notation.patch @@ -0,0 +1,74 @@ +From 5ba6bb92b9ec3545d86d598f07643c399a47c7ad Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 12 Feb 2019 22:51:34 +0100 +Subject: [PATCH] Print IPv6 prefixes in CIDR notation + +According to RFC4291, IPv6 prefixes are represented in CIDR notation. +While the use of a "netmask" notation is not explicitly denied, its +existence merely stems from applying IPv4 standards to IPv6. This is not +necessarily correct. + +Therefore change printing of IPv6 prefixes to use CIDR notation as long +as the address mask's bits are left contiguous. + +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + useful_functions.c | 35 ++++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +diff --git a/useful_functions.c b/useful_functions.c +index 8a34f820f230b..bf4393712fa44 100644 +--- a/useful_functions.c ++++ b/useful_functions.c +@@ -416,16 +416,41 @@ char *ebt_ip6_to_numeric(const struct in6_addr *addrp) + return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); + } + ++int ebt_ip6mask_to_cidr(const struct in6_addr *k) ++{ ++ unsigned int bits = 0; ++ uint32_t a, b, c, d; ++ ++ a = ntohl(k->s6_addr32[0]); ++ b = ntohl(k->s6_addr32[1]); ++ c = ntohl(k->s6_addr32[2]); ++ d = ntohl(k->s6_addr32[3]); ++ while (a & 0x80000000U) { ++ ++bits; ++ a <<= 1; ++ a |= (b >> 31) & 1; ++ b <<= 1; ++ b |= (c >> 31) & 1; ++ c <<= 1; ++ c |= (d >> 31) & 1; ++ d <<= 1; ++ } ++ if (a != 0 || b != 0 || c != 0 || d != 0) ++ return -1; ++ return bits; ++} ++ + char *ebt_ip6_mask_to_string(const struct in6_addr *msk) + { +- /* /0000:0000:0000:0000:0000:000.000.000.000 +- * /0000:0000:0000:0000:0000:0000:0000:0000 */ ++ int l = ebt_ip6mask_to_cidr(msk); + static char buf[51+1]; +- if (msk->s6_addr32[0] == 0xFFFFFFFFL && msk->s6_addr32[1] == 0xFFFFFFFFL && +- msk->s6_addr32[2] == 0xFFFFFFFFL && msk->s6_addr32[3] == 0xFFFFFFFFL) ++ ++ if (l == 127) + *buf = '\0'; +- else ++ else if (l == -1) + sprintf(buf, "/%s", ebt_ip6_to_numeric(msk)); ++ else ++ sprintf(buf, "/%d", l); + return buf; + } + +-- +2.21.0 + diff --git a/SOURCES/0036-Adjust-.gitignore-to-renamed-files.patch b/SOURCES/0036-Adjust-.gitignore-to-renamed-files.patch new file mode 100644 index 0000000..3799f2e --- /dev/null +++ b/SOURCES/0036-Adjust-.gitignore-to-renamed-files.patch @@ -0,0 +1,36 @@ +From 822a5dcdfc473f129ea43c44175bc0da75a1be6c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 12 Mar 2019 18:13:27 +0100 +Subject: [PATCH] Adjust .gitignore to renamed files + +Fixes: 6218f812d894f ("ebtables: legacy renaming") +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + .gitignore | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/.gitignore b/.gitignore +index c1fae5463a355..9940c85762fa0 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -17,11 +17,11 @@ Makefile.in + /libtool + /stamp-h1 + +-/ebtables ++/ebtables-legacy + /ebtables-config +-/ebtables-restore +-/ebtables-save +-/ebtables.8 ++/ebtables-legacy-restore ++/ebtables-legacy-save ++/ebtables-legacy.8 + /ebtablesd + /ebtablesu + /static +-- +2.21.0 + diff --git a/SOURCES/0037-extensions-Drop-Makefile.patch b/SOURCES/0037-extensions-Drop-Makefile.patch new file mode 100644 index 0000000..f655a2a --- /dev/null +++ b/SOURCES/0037-extensions-Drop-Makefile.patch @@ -0,0 +1,56 @@ +From 38f05e8c8f760f7a6736a959a568b4267bc81978 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 19 Mar 2019 20:09:36 +0100 +Subject: [PATCH] extensions: Drop Makefile + +Sources contained in there are built from toplevel Makefile.am. This +seems like a leftover from commit 131920089dc21 ("build: move to +automake"). + +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + extensions/Makefile | 30 ------------------------------ + 1 file changed, 30 deletions(-) + delete mode 100644 extensions/Makefile + +diff --git a/extensions/Makefile b/extensions/Makefile +deleted file mode 100644 +index daa11fce36e5e..0000000000000 +--- a/extensions/Makefile ++++ /dev/null +@@ -1,30 +0,0 @@ +-#! /usr/bin/make +- +-EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \ +- pkttype stp among limit ulog nflog string +-EXT_TABLES+=filter nat broute +-EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o) +-EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o) +-EXT_LIBS+=$(foreach T,$(EXT_FUNC), extensions/libebt_$(T).so) +-EXT_LIBS+=$(foreach T,$(EXT_TABLES), extensions/libebtable_$(T).so) +-EXT_LIBSI+=$(foreach T,$(EXT_FUNC), -lebt_$(T)) +-EXT_LIBSI+=$(foreach T,$(EXT_TABLES), -lebtable_$(T)) +- +-extensions/ebt_%.so: extensions/ebt_%.o +- $(CC) $(LDFLAGS) -shared -o $@ -lc $< +- +-extensions/libebt_%.so: extensions/ebt_%.so +- mv $< $@ +- +-extensions/ebtable_%.so: extensions/ebtable_%.o +- $(CC) $(LDFLAGS) -shared -o $@ -lc $< +- +-extensions/libebtable_%.so: extensions/ebtable_%.so +- mv $< $@ +- +-extensions/ebt_%.o: extensions/ebt_%.c include/ebtables_u.h +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-extensions/ebtable_%.o: extensions/ebtable_%.c +- $(CC) $(CFLAGS) $(CFLAGS_SH_LIB) $(PROGSPECS) -c -o $@ $< -I$(KERNEL_INCLUDES) +- +-- +2.21.0 + diff --git a/SOURCES/0038-Allow-customizing-lockfile-location-at-configure-tim.patch b/SOURCES/0038-Allow-customizing-lockfile-location-at-configure-tim.patch new file mode 100644 index 0000000..4e6214f --- /dev/null +++ b/SOURCES/0038-Allow-customizing-lockfile-location-at-configure-tim.patch @@ -0,0 +1,94 @@ +From f45756c1ca3b54e8bd45b40b809bd1a8d3cedfdb Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 19 Mar 2019 20:09:37 +0100 +Subject: [PATCH] Allow customizing lockfile location at configure time + +Users may pass LOCKFILE=/some/path/to/file when calling configure to +make libebtc use that path for its lockfile. + +To simplify things, drop LOCKDIR completely and instead call dirname() +when trying to create the parent directory. + +Given that we always define LOCKFILE via compiler flag, drop the +fallback define from libebtc.c. + +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + Makefile.am | 4 +--- + configure.ac | 3 +++ + libebtc.c | 7 ++----- + 3 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 59ae595ee16de..53fcbadbca7b4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -5,8 +5,6 @@ + PROGNAME = ${PACKAGE_NAME} + PROGVERSION = ${PACKAGE_VERSION} + PROGDATE = December\ 2011 +-LOCKDIR = /var/lib/ebtables +-LOCKFILE = ${LOCKDIR}/lock + INITDIR = /etc/rc.d/init.d + initddir = ${INITDIR} + sysconfigdir = ${sysconfdir}/sysconfig +@@ -21,7 +19,7 @@ AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include \ + -DPROGVERSION=\"${PACKAGE_VERSION}\" -DPROGNAME=\"${PACKAGE_NAME}\" \ + -DPROGDATE=\"${PROGDATE}\" \ + -D_PATH_ETHERTYPES=\"${sysconfdir}/ethertypes\" \ +- -DLOCKFILE=\"${LOCKFILE}\" -DLOCKDIR=\"${LOCKDIR}\" \ ++ -DLOCKFILE=\"${LOCKFILE}\" \ + -DEBTD_ARGC_MAX=${EBTD_ARGC_MAX} -DEBTD_CMDLINE_MAXLN=${EBTD_CMDLINE_MAXLN} \ + -DEBTD_PIPE=\"${PIPE}\" -DEBTD_PIPE_DIR=\"${PIPE_DIR}\" + AM_CFLAGS = ${regular_CFLAGS} +diff --git a/configure.ac b/configure.ac +index a3bc3c93a279f..00d97734ff9a9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -10,6 +10,9 @@ AC_DISABLE_STATIC + m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) + AM_PROG_LIBTOOL + ++AC_ARG_VAR([LOCKFILE], [Custom libebtc lockfile path (default: /var/lib/ebtables/lock)]) ++AS_IF([test "x$LOCKFILE" = x], [LOCKFILE="/var/lib/ebtables/lock"]) ++ + regular_CFLAGS="-Wall -Wunused" + regular_CPPFLAGS="" + case "$host" in +diff --git a/libebtc.c b/libebtc.c +index 92fd76485c723..f2a2b500ea751 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + static void decrease_chain_jumps(struct ebt_u_replace *replace); + static int iterate_entries(struct ebt_u_replace *replace, int type); +@@ -134,10 +135,6 @@ void ebt_list_extensions() + } + } + +-#ifndef LOCKFILE +-#define LOCKDIR "/var/lib/ebtables" +-#define LOCKFILE LOCKDIR"/lock" +-#endif + int use_lockfd; + /* Returns 0 on success, -1 when the file is locked by another process + * or -2 on any other error. */ +@@ -148,7 +145,7 @@ static int lock_file() + retry: + fd = open(LOCKFILE, O_CREAT, 00600); + if (fd < 0) { +- if (try == 1 || mkdir(LOCKDIR, 00700)) ++ if (try == 1 || mkdir(dirname(LOCKFILE), 00700)) + return -2; + try = 1; + goto retry; +-- +2.21.0 + diff --git a/SOURCES/0039-extensions-Add-AUDIT-target.patch b/SOURCES/0039-extensions-Add-AUDIT-target.patch new file mode 100644 index 0000000..238cc81 --- /dev/null +++ b/SOURCES/0039-extensions-Add-AUDIT-target.patch @@ -0,0 +1,188 @@ +From 2fdf17ff85c1a3044d0e139642237bbc964ee494 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 19 Mar 2019 20:09:38 +0100 +Subject: [PATCH] extensions: Add AUDIT target + +This is a barn find from Fedora package, actually spooking around in +various places in the internet. No idea who wrote it, but it seems to be +used. So add it for the time being. + +Signed-off-by: Phil Sutter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Phil Sutter +--- + Makefile.am | 2 +- + extensions/ebt_AUDIT.c | 110 +++++++++++++++++++++++++++++ + include/linux/netfilter/xt_AUDIT.h | 30 ++++++++ + 3 files changed, 141 insertions(+), 1 deletion(-) + create mode 100644 extensions/ebt_AUDIT.c + create mode 100644 include/linux/netfilter/xt_AUDIT.h + +diff --git a/Makefile.am b/Makefile.am +index 53fcbadbca7b4..904de12773a84 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -40,7 +40,7 @@ libebtc_la_SOURCES = \ + extensions/ebt_mark_m.c extensions/ebt_nat.c extensions/ebt_nflog.c \ + extensions/ebt_pkttype.c extensions/ebt_redirect.c \ + extensions/ebt_standard.c extensions/ebt_stp.c extensions/ebt_string.c \ +- extensions/ebt_ulog.c extensions/ebt_vlan.c \ ++ extensions/ebt_ulog.c extensions/ebt_vlan.c extensions/ebt_AUDIT.c \ + extensions/ebtable_broute.c extensions/ebtable_filter.c \ + extensions/ebtable_nat.c + # Make sure ebtables.c can be built twice +diff --git a/extensions/ebt_AUDIT.c b/extensions/ebt_AUDIT.c +new file mode 100644 +index 0000000000000..c9befccca94db +--- /dev/null ++++ b/extensions/ebt_AUDIT.c +@@ -0,0 +1,110 @@ ++ ++#include ++#include ++#include ++#include ++#include "../include/ebtables_u.h" ++#include ++ ++#define AUDIT_TYPE '1' ++static struct option opts[] = ++{ ++ { "audit-type" , required_argument, 0, AUDIT_TYPE }, ++ { 0 } ++}; ++ ++static void print_help() ++{ ++ printf( ++ "AUDIT target options:\n" ++ " --audit-type TYPE : Set action type to record.\n"); ++} ++ ++static void init(struct ebt_entry_target *target) ++{ ++ struct xt_AUDIT_info *info = (struct xt_AUDIT_info *) target->data; ++ ++ info->type = 0; ++} ++ ++static int parse(int c, char **argv, int argc, ++ const struct ebt_u_entry *entry, unsigned int *flags, ++ struct ebt_entry_target **target) ++{ ++ struct xt_AUDIT_info *info = (struct xt_AUDIT_info *) (*target)->data; ++ ++ switch (c) { ++ case AUDIT_TYPE: ++ ebt_check_option2(flags, AUDIT_TYPE); ++ ++ if (!strcasecmp(optarg, "accept")) ++ info->type = XT_AUDIT_TYPE_ACCEPT; ++ else if (!strcasecmp(optarg, "drop")) ++ info->type = XT_AUDIT_TYPE_DROP; ++ else if (!strcasecmp(optarg, "reject")) ++ info->type = XT_AUDIT_TYPE_REJECT; ++ else ++ ebt_print_error2("Bad action type value `%s'", optarg); ++ ++ break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static void final_check(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target, const char *name, ++ unsigned int hookmask, unsigned int time) ++{ ++} ++ ++static void print(const struct ebt_u_entry *entry, ++ const struct ebt_entry_target *target) ++{ ++ const struct xt_AUDIT_info *info = ++ (const struct xt_AUDIT_info *) target->data; ++ ++ printf("--audit-type "); ++ ++ switch(info->type) { ++ case XT_AUDIT_TYPE_ACCEPT: ++ printf("accept"); ++ break; ++ case XT_AUDIT_TYPE_DROP: ++ printf("drop"); ++ break; ++ case XT_AUDIT_TYPE_REJECT: ++ printf("reject"); ++ break; ++ } ++} ++ ++static int compare(const struct ebt_entry_target *t1, ++ const struct ebt_entry_target *t2) ++{ ++ const struct xt_AUDIT_info *info1 = ++ (const struct xt_AUDIT_info *) t1->data; ++ const struct xt_AUDIT_info *info2 = ++ (const struct xt_AUDIT_info *) t2->data; ++ ++ return info1->type == info2->type; ++} ++ ++static struct ebt_u_target AUDIT_target = ++{ ++ .name = "AUDIT", ++ .size = sizeof(struct xt_AUDIT_info), ++ .help = print_help, ++ .init = init, ++ .parse = parse, ++ .final_check = final_check, ++ .print = print, ++ .compare = compare, ++ .extra_ops = opts, ++}; ++ ++static void _INIT(void) ++{ ++ ebt_register_target(&AUDIT_target); ++} +diff --git a/include/linux/netfilter/xt_AUDIT.h b/include/linux/netfilter/xt_AUDIT.h +new file mode 100644 +index 0000000000000..44111b242b531 +--- /dev/null ++++ b/include/linux/netfilter/xt_AUDIT.h +@@ -0,0 +1,30 @@ ++/* ++ * Header file for iptables xt_AUDIT target ++ * ++ * (C) 2010-2011 Thomas Graf ++ * (C) 2010-2011 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef _XT_AUDIT_TARGET_H ++#define _XT_AUDIT_TARGET_H ++ ++#include ++ ++enum { ++ XT_AUDIT_TYPE_ACCEPT = 0, ++ XT_AUDIT_TYPE_DROP, ++ XT_AUDIT_TYPE_REJECT, ++ __XT_AUDIT_TYPE_MAX, ++}; ++ ++#define XT_AUDIT_TYPE_MAX (__XT_AUDIT_TYPE_MAX - 1) ++ ++struct xt_AUDIT_info { ++ __u8 type; /* XT_AUDIT_TYPE_* */ ++}; ++ ++#endif /* _XT_AUDIT_TARGET_H */ +-- +2.21.0 + diff --git a/SOURCES/0040-Fix-segfault-with-missing-lockfile-directory.patch b/SOURCES/0040-Fix-segfault-with-missing-lockfile-directory.patch new file mode 100644 index 0000000..084b879 --- /dev/null +++ b/SOURCES/0040-Fix-segfault-with-missing-lockfile-directory.patch @@ -0,0 +1,40 @@ +From 97a7193e1838da9ab9631d07f6b3cedf63a5995d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 9 Apr 2019 14:21:25 +0200 +Subject: [PATCH] Fix segfault with missing lockfile directory + +Apparently, dirname() modifies the buffer passed to it. Given a +read-only location, this leads to a segfault. Use a buffer initialized +(and tailored) to the content of LOCKFILE macro at compile-time instead. + +Fixes: f45756c1ca3b5 ("Allow customizing lockfile location at configure time") +Signed-off-by: Phil Sutter +Signed-off-by: Florian Westphal +(cherry picked from commit c9348e18f3cdd52a7cb1586e03a55cefac08d849) +Signed-off-by: Phil Sutter +--- + libebtc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libebtc.c b/libebtc.c +index f2a2b500ea751..2a9ab87ac99c0 100644 +--- a/libebtc.c ++++ b/libebtc.c +@@ -140,12 +140,13 @@ int use_lockfd; + * or -2 on any other error. */ + static int lock_file() + { ++ char pathbuf[] = LOCKFILE; + int fd, try = 0; + + retry: + fd = open(LOCKFILE, O_CREAT, 00600); + if (fd < 0) { +- if (try == 1 || mkdir(dirname(LOCKFILE), 00700)) ++ if (try == 1 || mkdir(dirname(pathbuf), 00700)) + return -2; + try = 1; + goto retry; +-- +2.21.0 + diff --git a/SOURCES/ebtables-config b/SOURCES/ebtables-config new file mode 100644 index 0000000..69d9289 --- /dev/null +++ b/SOURCES/ebtables-config @@ -0,0 +1,11 @@ +# Save current firewall rules on stop. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets stopped +# (e.g. on system shutdown). +EBTABLES_SAVE_ON_STOP="no" + +# Save (and restore) rule counters. +# Value: yes|no, default: no +# Save rule counters when saving a kernel table to a file. If the +# rule counters were saved, they will be restored when restoring the table. +EBTABLES_SAVE_COUNTER="no" diff --git a/SOURCES/ebtables-helper b/SOURCES/ebtables-helper new file mode 100644 index 0000000..f1dee08 --- /dev/null +++ b/SOURCES/ebtables-helper @@ -0,0 +1,105 @@ +#!/bin/bash + +# compat for removed initscripts dependency + +success() { + echo "[ OK ]" + return 0 +} + +failure() { + echo "[FAILED]" + return 1 +} + +# internal variables +EBTABLES_CONFIG=/etc/sysconfig/ebtables-config +EBTABLES_DATA=/etc/sysconfig/ebtables +EBTABLES_TABLES="filter nat" +if ebtables --version | grep -q '(legacy)'; then + EBTABLES_TABLES+=" broute" +fi +VAR_SUBSYS_EBTABLES=/var/lock/subsys/ebtables + +# ebtables-config defaults +EBTABLES_SAVE_ON_STOP="no" +EBTABLES_SAVE_ON_RESTART="no" +EBTABLES_SAVE_COUNTER="no" + +# load config if existing +[ -f "$EBTABLES_CONFIG" ] && . "$EBTABLES_CONFIG" + +initialize() { + local ret=0 + for table in $EBTABLES_TABLES; do + ebtables -t $table --init-table || ret=1 + done + return $ret +} + +sanitize_dump() { + local drop=false + + export EBTABLES_TABLES + + cat $1 | while read line; do + case $line in + \**) + drop=false + local table="${line#\*}" + local found=false + for t in $EBTABLES_TABLES; do + if [[ $t == $table ]]; then + found=true + break + fi + done + $found || drop=true + ;; + esac + $drop || echo "$line" + done +} + +start() { + if [ -f $EBTABLES_DATA ]; then + echo -n $"ebtables: loading ruleset from $EBTABLES_DATA: " + sanitize_dump $EBTABLES_DATA | ebtables-restore + else + echo -n $"ebtables: no stored ruleset, initializing empty tables: " + initialize + fi + local ret=$? + touch $VAR_SUBSYS_EBTABLES + return $ret +} + +save() { + echo -n $"ebtables: saving active ruleset to $EBTABLES_DATA: " + export EBTABLES_SAVE_COUNTER + ebtables-save >$EBTABLES_DATA && success || failure +} + +case $1 in + start) + [ -f "$VAR_SUBSYS_EBTABLES" ] && exit 0 + start && success || failure + RETVAL=$? + ;; + stop) + [ "x$EBTABLES_SAVE_ON_STOP" = "xyes" ] && save + echo -n $"ebtables: stopping firewall: " + initialize && success || failure + RETVAL=$? + rm -f $VAR_SUBSYS_EBTABLES + ;; + save) + save + ;; + *) + echo "usage: ${0##*/} {start|stop|save}" >&2 + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/ebtables-legacy-save b/SOURCES/ebtables-legacy-save new file mode 100644 index 0000000..2d7fc4e --- /dev/null +++ b/SOURCES/ebtables-legacy-save @@ -0,0 +1,43 @@ +#!/bin/bash + +EBTABLES="/sbin/ebtables" + +[ -x "$EBTABLES" ] || exit 1 + +echo "# Generated by ebtables-save v1.0 on $(date)" + +cnt="" +[ "x$EBTABLES_SAVE_COUNTER" = "xyes" ] && cnt="--Lc" + +for table_name in $(grep -E '^ebtable_' /proc/modules | cut -f1 -d' ' | sed s/ebtable_//); do + table=$($EBTABLES -t $table_name -L $cnt) + [ $? -eq 0 ] || { echo "$table"; exit -1; } + + chain="" + rules="" + while read line; do + [ -z "$line" ] && continue + + case "$line" in + Bridge\ table:\ *) + echo "*${line:14}" + ;; + Bridge\ chain:\ *) + chain="${line:14}" + chain="${chain%%,*}" + policy="${line##*policy: }" + echo ":$chain $policy" + ;; + *) + if [ "$cnt" = "--Lc" ]; then + line=${line/, pcnt \=/ -c} + line=${line/-- bcnt \=/} + fi + rules="$rules-A $chain $line\n" + ;; + esac + done <= 9 +# RHEL-9 provides ebtables via iptables-nft, but doesn't support ebtables +# alternatives. As such avoid the Provides here so iptables-nft is chosen, not +# ebtables-legacy. +%else +Provides: ebtables +%endif + +%description legacy +Ethernet bridge tables is a firewalling tool to transparently filter network +traffic passing a bridge. The filtering possibilities are limited to link +layer filtering and some basic filtering on higher network layers. + +This tool is the userspace control for the bridge and ebtables kernel +components (built by default in Fedora kernels). + +The ebtables tool can be used together with the other Linux filtering tools, +like iptables. There are no known incompatibility issues. + +Note that it is considered legacy upstream since nftables provides the same +functionality in a much newer code-base. To aid in migration, there is +ebtables-nft utility, a drop-in replacement for the legacy one which uses +nftables internally. It is provided by iptables-nft package. + +%package services +Summary: ebtables systemd services +%{?systemd_ordering} +Obsoletes: ebtables-compat < 2.0.10-39 + +%description services +ebtables systemd services + +This package provides the systemd ebtables service that has been split +out of the base package for better integration with alternatives. + +%prep +%autosetup -p1 -n ebtables-%{version} +# Convert to UTF-8 +f=THANKS; iconv -f iso-8859-1 -t utf-8 $f -o $f.utf8 ; mv $f.utf8 $f + +%build +./autogen.sh +%configure --disable-silent-rules LOCKFILE=/run/ebtables.lock +%make_build + +%install +%make_install +install -D -m 644 %{SOURCE3} %{buildroot}%{_unitdir}/ebtables.service +install -D -m 755 %{SOURCE2} %{buildroot}%{_libexecdir}/ebtables-helper +install -D -m 600 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/ebtables-config +touch %{buildroot}%{_sysconfdir}/sysconfig/ebtables + +# install ebtables-legacy-save bash script +install -m 755 %{SOURCE1} %{buildroot}%{_sbindir}/ebtables-legacy-save + +# No use for libtool archive files +rm %{buildroot}/%{_libdir}/libebtc.la + +# Remove /etc/ethertypes (now part of setup) +rm -f %{buildroot}%{_sysconfdir}/ethertypes + +# Drop these binaries (for now at least) +rm %{buildroot}/%{_sbindir}/ebtables{d,u} + +# Prepare for Alternatives system +touch %{buildroot}%{_sbindir}/ebtables +touch %{buildroot}%{_sbindir}/ebtables-save +touch %{buildroot}%{_sbindir}/ebtables-restore +touch %{buildroot}%{_mandir}/man8/ebtables.8 + +%post legacy +pfx=%{_sbindir}/ebtables +manpfx=%{_mandir}/man8/ebtables +for sfx in "" "-restore" "-save"; do + if [ "$(readlink -e $pfx$sfx)" == $pfx$sfx ]; then + rm -f $pfx$sfx + fi +done +if [ "$(readlink -e $manpfx.8.gz)" == $manpfx.8.gz ]; then + rm -f $manpfx.8.gz +fi +%{_sbindir}/update-alternatives --install \ + $pfx ebtables $pfx-legacy 10 \ + --slave $pfx-save ebtables-save $pfx-legacy-save \ + --slave $pfx-restore ebtables-restore $pfx-legacy-restore \ + --slave $manpfx.8.gz ebtables-man $manpfx-legacy.8.gz + +%postun legacy +if [ $1 -eq 0 ]; then + %{_sbindir}/update-alternatives --remove \ + ebtables %{_sbindir}/ebtables-legacy +fi + +# When upgrading ebtables to ebtables-{legacy,services}, +# postun in ebtables thinks it is uninstalled and removes alternatives. +# Counter this with a trigger here to have it installed again. +%triggerpostun legacy -- ebtables +pfx=%{_sbindir}/ebtables +manpfx=%{_mandir}/man8/ebtables +%{_sbindir}/update-alternatives --install \ + $pfx ebtables $pfx-legacy 10 \ + --slave $pfx-save ebtables-save $pfx-legacy-save \ + --slave $pfx-restore ebtables-restore $pfx-legacy-restore \ + --slave $manpfx.8.gz ebtables-man $manpfx-legacy.8.gz + + +%post services +%systemd_post ebtables.service + +%preun services +%systemd_preun ebtables.service + +%postun services +%systemd_postun ebtables.service + +%files legacy +%license COPYING +%doc ChangeLog THANKS +%{_sbindir}/ebtables-legacy* +%{_mandir}/*/ebtables-legacy* +%{_libdir}/libebtc.so* +%ghost %{_sbindir}/ebtables +%ghost %{_sbindir}/ebtables-save +%ghost %{_sbindir}/ebtables-restore +%ghost %{_mandir}/man8/ebtables.8.gz + +%files services +%{_unitdir}/ebtables.service +%{_libexecdir}/ebtables-helper +%config(noreplace) %{_sysconfdir}/sysconfig/ebtables-config +%ghost %{_sysconfdir}/sysconfig/ebtables + +%changelog +* Tue Jan 26 2021 Eric Garver - 2.0.11-9 +- avoid Provides: ebtables for newer RHEL/ELN builds + +* Tue Jan 26 2021 Fedora Release Engineering - 2.0.11-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Thu Nov 5 2020 Florian Weimer - 2.0.11-7 +- Remove build dependency on autogen + +* Mon Jul 27 2020 Fedora Release Engineering - 2.0.11-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jan 28 2020 Fedora Release Engineering - 2.0.11-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Jan 22 2020 Tom Callaway - 2.0.11-4 +- add Requires(post): %%{_bindir}/readlink (bz1792805) + +* Mon Dec 16 2019 Phil Sutter - 2.0.11-3 +- Fix nft-variant reference in package description + +* Mon Dec 16 2019 Phil Sutter - 2.0.11-2 +- Eliminate implicit dependency on initscripts package + +* Mon Dec 2 2019 Tom Callaway - 2.0.11-1 +- update to 2.0.11 (all of Phil's awesome patches merged) + +* Wed Oct 30 2019 Phil Sutter - 2.0.10-39 +- Make services sub-package obsolete compat to fix upgrade path + +* Tue Oct 22 2019 Phil Sutter - 2.0.10-38 +- Drop compat sub-package again + +* Wed Jul 24 2019 Fedora Release Engineering - 2.0.10-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Wed Jun 26 2019 Phil Sutter - 2.0.10-36 +- Fix segfault with non-existing lock directory + +* Wed Apr 24 2019 Phil Sutter - 2.0.10-35 +- Workaround missing broute table support in ebtables-nft + +* Tue Apr 09 2019 Phil Sutter - 2.0.10-34 +- Fix lockfile location + +* Thu Apr 04 2019 Phil Sutter - 2.0.10-33 +- Fix date in previous changelog entry +- Use systemd_ordering macro + +* Thu Apr 04 2019 Phil Sutter - 2.0.10-32 +- Add upstream changes since last release +- Rename package to ebtables-legacy +- Split systemd service into services sub-package +- Rewrite systemd unit helper script for compatibility with ebtables-nft +- Drop module unloading on service stop, this causes more harm than good +- Remove save format settings, they are not effective anymore +- Remove save on restart setting, restart is merely stop && start +- Complete integration into alternatives +- Remove needless ldconfig calls + +* Thu Feb 7 2019 Tom Callaway - 2.0.10-31 +- build without as-needed everywhere (stop using Ubuntu patch) + Resolves BZ:1672683 + +* Thu Jan 31 2019 Fedora Release Engineering - 2.0.10-30 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 21 2019 David Abdurachmanov 2.0.10-29 +- Disable --as-needed to resolve segfaults + +* Sun Jul 22 2018 Peter Robinson 2.0.10-28 +- Add gcc dep, spec cleanups + +* Thu Jul 12 2018 Fedora Release Engineering - 2.0.10-27 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jul 10 2018 Phil Sutter - 2.0.10-26 +- Replace calls to ldconfig with newly introduced macro. +- Install binaries in /usr/sbin instead of /sbin. +- Make use of Alternatives system. + +* Wed Feb 07 2018 Fedora Release Engineering - 2.0.10-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Aug 02 2017 Fedora Release Engineering - 2.0.10-24 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 2.0.10-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 2.0.10-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Jul 22 2016 Thomas Woerner - 2.0.10-21 +- /etc/ethertypes has been moved into the setup package for F-25+. + (RHBZ#1329256) + +* Mon May 9 2016 Thomas Woerner - 2.0.10-20 +- add upstream --noflush option patch for ebtables-restore + +* Wed Feb 03 2016 Fedora Release Engineering - 2.0.10-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Jan 18 2016 Tom Callaway - 2.0.10-18 +- Move lock file to /run/ebtables.lock (bz 1290327) + +* Wed Jun 17 2015 Fedora Release Engineering - 2.0.10-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat Aug 16 2014 Fedora Release Engineering - 2.0.10-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jun 24 2014 Tom Callaway - 2.0.10-15 +- create and own /var/lib/ebtables (bz 1093361) + +* Sat Jun 07 2014 Fedora Release Engineering - 2.0.10-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Mar 31 2014 Tom Callaway - 2.0.10-13 +- use standard optflags and ldflags (bz 1071993) + +* Wed Feb 19 2014 Tom Callaway - 2.0.10-12 +- remove executable bit from systemd service file +- add RARP type to ethertypes (bz 1060537) + +* Wed Aug 21 2013 Tom Callaway - 2.0.10-11 +- convert to systemd + +* Sat Aug 03 2013 Fedora Release Engineering - 2.0.10-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu Mar 21 2013 Tom Callaway - 2.0.10-8 +- add audit module + +* Wed Feb 13 2013 Fedora Release Engineering - 2.0.10-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Jul 18 2012 Fedora Release Engineering - 2.0.10-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Apr 5 2012 Tom Callaway - 2.0.10-5 +- update to 2.0.10-4 (upstream numbering is goofy) +- fix missing symbol issue with extension modules (bz810006) + +* Thu Feb 16 2012 Thomas Woerner - 2.0.10-4 +- replaced ebtables-save perl script by bash script to get rid of the perl + requirement + +* Fri Jan 13 2012 Fedora Release Engineering - 2.0.10-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Aug 11 2011 Tom Callaway - 2.0.10-2 +- update to 2.0.10-2 + +* Mon Jul 11 2011 Tom Callaway - 2.0.10-1 +- update to 2.0.10-1 + +* Tue Feb 08 2011 Fedora Release Engineering - 2.0.9-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Feb 15 2010 Tom "spot" Callaway - 2.0.9-5 +- update to 2.0.9-2 + +* Fri Jan 29 2010 Thomas Woerner - 2.0.9-4 +- moved ebtables modules to /lib[64]/ebtables (rhbz#558886) + +* Fri Jan 15 2010 Thomas Woerner - 2.0.9-3 +- fixed init script to be lsb conform (rhbz#536828) +- fixed download link according to package review + +* Wed Aug 19 2009 Tom "spot" Callaway - 2.0.9-2 +- fix source0 url + +* Mon Jul 27 2009 Tom "spot" Callaway - 2.0.9-1 +- update to 2.0.9 + +* Fri Jul 24 2009 Fedora Release Engineering - 2.0.8-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Feb 24 2009 Fedora Release Engineering - 2.0.8-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Feb 19 2008 Fedora Release Engineering - 2.0.8-5 +- Autorebuild for GCC 4.3 + +* Sun Oct 28 2007 Tom "spot" Callaway 2.0.8-4 +- bump to 2.0.8-2 from upstream +- keep _libdir/ebtables, even though upstream just moved away from it. + +* Thu Aug 23 2007 Tom "spot" Callaway 2.0.8-3 +- use _libdir/ebtables to match upstream RPATH (bugzilla 248865) +- correct license tag +- use upstream init script +- enable build-id +- use cflags for all compiles +- be sane with DESTDIR + +* Mon Jul 9 2007 Tom "spot" Callaway 2.0.8-2 +- remove "Fedora Core" reference in spec + +* Mon Jul 2 2007 Tom "spot" Callaway 2.0.8-1 +- final 2.0.8 release + +* Wed Jan 17 2007 Tom "spot" Callaway 2.0.8-0.8.rc3 +- fix release order + +* Wed Jan 17 2007 Tom "spot" Callaway 2.0.8-0.1.rc3 +- bump to rc3 + +* Thu Oct 05 2006 Christian Iseli 2.0.8-0.7.rc2 + - rebuilt for unwind info generation, broken in gcc-4.1.1-21 + +* Mon Sep 18 2006 Tom "spot" Callaway 2.0.8-0.6.rc2 +- fix versioning + +* Thu Sep 14 2006 Tom "spot" Callaway 2.0.8-0.3.rc2 +- fix bugzilla 206257 + +* Tue Sep 12 2006 Tom "spot" Callaway 2.0.8-0.2.rc2 +- fix for FC-6 + +* Mon Apr 24 2006 Tom "spot" Callaway 2.0.8-0.1.rc2 +- bump to rc2 + +* Sun Apr 2 2006 Tom "spot" Callaway 2.0.8-0.5.rc1 +- learn to use "install" correctly. :/ + +* Sun Apr 2 2006 Tom "spot" Callaway 2.0.8-0.4.rc1 +- package up the shared libs too + +* Wed Mar 29 2006 Tom "spot" Callaway 2.0.8-0.3.rc1 +- use -fPIC + +* Wed Mar 29 2006 Tom "spot" Callaway 2.0.8-0.2.rc1 +- broken tagging + +* Tue Jan 10 2006 Tom "spot" Callaway 2.0.8-0.1.rc1 +- bump to 2.0.8-rc1 + +* Mon Jul 4 2005 Tom "spot" Callaway 2.0.6-7 +- buildsystem error requires artificial release bump + +* Mon Jul 4 2005 Tom "spot" Callaway 2.0.6-6 +- actually touch ghosted files + +* Fri Jul 1 2005 Tom "spot" Callaway 2.0.6-5 +- fix sysv file + +* Fri Jul 1 2005 Tom "spot" Callaway 2.0.6-4 +- remove INSTALL file +- add some text to description, correct typos +- fix %%postun +- add PreReqs +- add %%ghost config files + +* Tue May 31 2005 Tom "spot" Callaway 2.0.6-3 +- reworked for Fedora Extras +- add gcc4 fix +- move init file into SOURCE1 + +* Thu Dec 02 2004 Dag Wieers - 2.0.6-2 +- Added patch for gcc 3.4. (Nigel Smith) + +* Tue Apr 27 2004 Dag Wieers - 2.0.6-2 +- Cosmetic changes. + +* Tue Apr 27 2004 Dag Wieers - 2.0.6-1 +- Initial package. (using DAR)