diff --git a/.gitignore b/.gitignore index 4fbf74f..e765dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ SOURCES/iptables-1.8.2.tar.bz2 +SOURCES/iptables-1.8.4.tar.bz2 diff --git a/.iptables.metadata b/.iptables.metadata index d3ab801..b5d885b 100644 --- a/.iptables.metadata +++ b/.iptables.metadata @@ -1 +1,2 @@ 215c4ef4c6cd29ef0dd265b4fa5ec51a4f930c92 SOURCES/iptables-1.8.2.tar.bz2 +cd5fe776fb2b0479b3234758fc333777caa1239b SOURCES/iptables-1.8.4.tar.bz2 diff --git a/SOURCES/0001-Add-iptables-test.py-testsuite-from-v1.8.2.patch b/SOURCES/0001-Add-iptables-test.py-testsuite-from-v1.8.2.patch deleted file mode 100644 index 778357d..0000000 --- a/SOURCES/0001-Add-iptables-test.py-testsuite-from-v1.8.2.patch +++ /dev/null @@ -1,2642 +0,0 @@ -From 2297d219cc3c5150c015ce52df5c96894dd6e3d6 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 12 Jun 2019 22:12:15 +0200 -Subject: [PATCH] Add iptables-test.py testsuite from v1.8.2 - -Content gathered via: -| git co v1.8.2 -- iptables-test.py extensions/\*.t - -Signed-off-by: Phil Sutter ---- - extensions/iptables.t | 6 + - extensions/libarpt_CLASSIFY.t | 4 + - extensions/libarpt_MARK.t | 4 + - extensions/libarpt_mangle.t | 5 + - extensions/libarpt_standard.t | 14 ++ - extensions/libebt_802_3.t | 3 + - extensions/libebt_arp.t | 12 + - extensions/libebt_arpreply.t | 4 + - extensions/libebt_dnat.t | 5 + - extensions/libebt_ip.t | 13 ++ - extensions/libebt_ip6.t | 15 ++ - extensions/libebt_log.t | 6 + - extensions/libebt_mark.t | 5 + - extensions/libebt_mark_m.t | 6 + - extensions/libebt_nflog.t | 5 + - extensions/libebt_pkttype.t | 13 ++ - extensions/libebt_redirect.t | 4 + - extensions/libebt_snat.t | 4 + - extensions/libebt_standard.t | 11 + - extensions/libebt_stp.t | 13 ++ - extensions/libebt_vlan.t | 13 ++ - extensions/libip6t_DNAT.t | 16 ++ - extensions/libip6t_DNPT.t | 7 + - extensions/libip6t_HL.t | 10 + - extensions/libip6t_LOG.t | 12 + - extensions/libip6t_MASQUERADE.t | 9 + - extensions/libip6t_NETMAP.t | 4 + - extensions/libip6t_REDIRECT.t | 6 + - extensions/libip6t_REJECT.t | 11 + - extensions/libip6t_SNAT.t | 11 + - extensions/libip6t_SNPT.t | 7 + - extensions/libip6t_ah.t | 15 ++ - extensions/libip6t_dst.t | 5 + - extensions/libip6t_eui64.t | 8 + - extensions/libip6t_frag.t | 13 ++ - extensions/libip6t_hbh.t | 5 + - extensions/libip6t_hl.t | 8 + - extensions/libip6t_icmp6.t | 6 + - extensions/libip6t_ipv6header.t | 4 + - extensions/libip6t_mh.t | 6 + - extensions/libip6t_rt.t | 5 + - extensions/libip6t_srh.t | 28 +++ - extensions/libip6t_standard.t | 5 + - extensions/libipt_CLUSTERIP.t | 4 + - extensions/libipt_DNAT.t | 16 ++ - extensions/libipt_ECN.t | 5 + - extensions/libipt_LOG.t | 12 + - extensions/libipt_MASQUERADE.t | 9 + - extensions/libipt_NETMAP.t | 4 + - extensions/libipt_REDIRECT.t | 6 + - extensions/libipt_REJECT.t | 9 + - extensions/libipt_SNAT.t | 11 + - extensions/libipt_TTL.t | 10 + - extensions/libipt_ah.t | 13 ++ - extensions/libipt_icmp.t | 15 ++ - extensions/libipt_realm.t | 4 + - extensions/libipt_ttl.t | 15 ++ - extensions/libxt_AUDIT.t | 6 + - extensions/libxt_CHECKSUM.t | 4 + - extensions/libxt_CLASSIFY.t | 9 + - extensions/libxt_CONNMARK.t | 7 + - extensions/libxt_CONNSECMARK.t | 5 + - extensions/libxt_CT.t | 20 ++ - extensions/libxt_DSCP.t | 11 + - extensions/libxt_HMARK.t | 8 + - extensions/libxt_IDLETIMER.t | 4 + - extensions/libxt_LED.t | 4 + - extensions/libxt_MARK.t | 7 + - extensions/libxt_NFLOG.t | 24 ++ - extensions/libxt_NFQUEUE.t | 16 ++ - extensions/libxt_NOTRACK.t | 4 + - extensions/libxt_RATEEST.t | 2 + - extensions/libxt_SET.t | 3 + - extensions/libxt_SYNPROXY.t | 3 + - extensions/libxt_TCPMSS.t | 6 + - extensions/libxt_TCPOPTSTRIP.t | 8 + - extensions/libxt_TEE.t | 4 + - extensions/libxt_TOS.t | 16 ++ - extensions/libxt_TPROXY.t | 5 + - extensions/libxt_TRACE.t | 3 + - extensions/libxt_addrtype.t | 17 ++ - extensions/libxt_bpf.t | 2 + - extensions/libxt_cgroup.t | 8 + - extensions/libxt_cluster.t | 10 + - extensions/libxt_comment.t | 12 + - extensions/libxt_connbytes.t | 21 ++ - extensions/libxt_connlabel.t | 18 ++ - extensions/libxt_connlimit.t | 16 ++ - extensions/libxt_connmark.t | 9 + - extensions/libxt_conntrack.t | 27 +++ - extensions/libxt_cpu.t | 6 + - extensions/libxt_dccp.t | 30 +++ - extensions/libxt_dscp.t | 10 + - extensions/libxt_ecn.t | 5 + - extensions/libxt_esp.t | 8 + - extensions/libxt_hashlimit.t | 33 +++ - extensions/libxt_helper.t | 6 + - extensions/libxt_ipcomp.t | 3 + - extensions/libxt_iprange.t | 11 + - extensions/libxt_length.t | 10 + - extensions/libxt_limit.t | 6 + - extensions/libxt_mac.t | 5 + - extensions/libxt_mark.t | 7 + - extensions/libxt_multiport.t | 23 ++ - extensions/libxt_nfacct.t | 10 + - extensions/libxt_osf.t | 4 + - extensions/libxt_owner.t | 12 + - extensions/libxt_physdev.t | 14 ++ - extensions/libxt_pkttype.t | 6 + - extensions/libxt_policy.t | 8 + - extensions/libxt_quota.t | 7 + - extensions/libxt_rateest.t | 16 ++ - extensions/libxt_recent.t | 11 + - extensions/libxt_rpfilter.t | 4 + - extensions/libxt_sctp.t | 29 +++ - extensions/libxt_set.t | 4 + - extensions/libxt_socket.t | 8 + - extensions/libxt_standard.t | 11 + - extensions/libxt_state.t | 6 + - extensions/libxt_statistic.t | 8 + - extensions/libxt_string.t | 18 ++ - extensions/libxt_tcp.t | 26 +++ - extensions/libxt_tcpmss.t | 6 + - extensions/libxt_time.t | 4 + - extensions/libxt_tos.t | 13 ++ - extensions/libxt_u32.t | 2 + - extensions/libxt_udp.t | 22 ++ - iptables-test.py | 373 ++++++++++++++++++++++++++++++++ - 128 files changed, 1603 insertions(+) - create mode 100644 extensions/iptables.t - create mode 100644 extensions/libarpt_CLASSIFY.t - create mode 100644 extensions/libarpt_MARK.t - create mode 100644 extensions/libarpt_mangle.t - create mode 100644 extensions/libarpt_standard.t - create mode 100644 extensions/libebt_802_3.t - create mode 100644 extensions/libebt_arp.t - create mode 100644 extensions/libebt_arpreply.t - create mode 100644 extensions/libebt_dnat.t - create mode 100644 extensions/libebt_ip.t - create mode 100644 extensions/libebt_ip6.t - create mode 100644 extensions/libebt_log.t - create mode 100644 extensions/libebt_mark.t - create mode 100644 extensions/libebt_mark_m.t - create mode 100644 extensions/libebt_nflog.t - create mode 100644 extensions/libebt_pkttype.t - create mode 100644 extensions/libebt_redirect.t - create mode 100644 extensions/libebt_snat.t - create mode 100644 extensions/libebt_standard.t - create mode 100644 extensions/libebt_stp.t - create mode 100644 extensions/libebt_vlan.t - create mode 100644 extensions/libip6t_DNAT.t - create mode 100644 extensions/libip6t_DNPT.t - create mode 100644 extensions/libip6t_HL.t - create mode 100644 extensions/libip6t_LOG.t - create mode 100644 extensions/libip6t_MASQUERADE.t - create mode 100644 extensions/libip6t_NETMAP.t - create mode 100644 extensions/libip6t_REDIRECT.t - create mode 100644 extensions/libip6t_REJECT.t - create mode 100644 extensions/libip6t_SNAT.t - create mode 100644 extensions/libip6t_SNPT.t - create mode 100644 extensions/libip6t_ah.t - create mode 100644 extensions/libip6t_dst.t - create mode 100644 extensions/libip6t_eui64.t - create mode 100644 extensions/libip6t_frag.t - create mode 100644 extensions/libip6t_hbh.t - create mode 100644 extensions/libip6t_hl.t - create mode 100644 extensions/libip6t_icmp6.t - create mode 100644 extensions/libip6t_ipv6header.t - create mode 100644 extensions/libip6t_mh.t - create mode 100644 extensions/libip6t_rt.t - create mode 100644 extensions/libip6t_srh.t - create mode 100644 extensions/libip6t_standard.t - create mode 100644 extensions/libipt_CLUSTERIP.t - create mode 100644 extensions/libipt_DNAT.t - create mode 100644 extensions/libipt_ECN.t - create mode 100644 extensions/libipt_LOG.t - create mode 100644 extensions/libipt_MASQUERADE.t - create mode 100644 extensions/libipt_NETMAP.t - create mode 100644 extensions/libipt_REDIRECT.t - create mode 100644 extensions/libipt_REJECT.t - create mode 100644 extensions/libipt_SNAT.t - create mode 100644 extensions/libipt_TTL.t - create mode 100644 extensions/libipt_ah.t - create mode 100644 extensions/libipt_icmp.t - create mode 100644 extensions/libipt_realm.t - create mode 100644 extensions/libipt_ttl.t - create mode 100644 extensions/libxt_AUDIT.t - create mode 100644 extensions/libxt_CHECKSUM.t - create mode 100644 extensions/libxt_CLASSIFY.t - create mode 100644 extensions/libxt_CONNMARK.t - create mode 100644 extensions/libxt_CONNSECMARK.t - create mode 100644 extensions/libxt_CT.t - create mode 100644 extensions/libxt_DSCP.t - create mode 100644 extensions/libxt_HMARK.t - create mode 100644 extensions/libxt_IDLETIMER.t - create mode 100644 extensions/libxt_LED.t - create mode 100644 extensions/libxt_MARK.t - create mode 100644 extensions/libxt_NFLOG.t - create mode 100644 extensions/libxt_NFQUEUE.t - create mode 100644 extensions/libxt_NOTRACK.t - create mode 100644 extensions/libxt_RATEEST.t - create mode 100644 extensions/libxt_SET.t - create mode 100644 extensions/libxt_SYNPROXY.t - create mode 100644 extensions/libxt_TCPMSS.t - create mode 100644 extensions/libxt_TCPOPTSTRIP.t - create mode 100644 extensions/libxt_TEE.t - create mode 100644 extensions/libxt_TOS.t - create mode 100644 extensions/libxt_TPROXY.t - create mode 100644 extensions/libxt_TRACE.t - create mode 100644 extensions/libxt_addrtype.t - create mode 100644 extensions/libxt_bpf.t - create mode 100644 extensions/libxt_cgroup.t - create mode 100644 extensions/libxt_cluster.t - create mode 100644 extensions/libxt_comment.t - create mode 100644 extensions/libxt_connbytes.t - create mode 100644 extensions/libxt_connlabel.t - create mode 100644 extensions/libxt_connlimit.t - create mode 100644 extensions/libxt_connmark.t - create mode 100644 extensions/libxt_conntrack.t - create mode 100644 extensions/libxt_cpu.t - create mode 100644 extensions/libxt_dccp.t - create mode 100644 extensions/libxt_dscp.t - create mode 100644 extensions/libxt_ecn.t - create mode 100644 extensions/libxt_esp.t - create mode 100644 extensions/libxt_hashlimit.t - create mode 100644 extensions/libxt_helper.t - create mode 100644 extensions/libxt_ipcomp.t - create mode 100644 extensions/libxt_iprange.t - create mode 100644 extensions/libxt_length.t - create mode 100644 extensions/libxt_limit.t - create mode 100644 extensions/libxt_mac.t - create mode 100644 extensions/libxt_mark.t - create mode 100644 extensions/libxt_multiport.t - create mode 100644 extensions/libxt_nfacct.t - create mode 100644 extensions/libxt_osf.t - create mode 100644 extensions/libxt_owner.t - create mode 100644 extensions/libxt_physdev.t - create mode 100644 extensions/libxt_pkttype.t - create mode 100644 extensions/libxt_policy.t - create mode 100644 extensions/libxt_quota.t - create mode 100644 extensions/libxt_rateest.t - create mode 100644 extensions/libxt_recent.t - create mode 100644 extensions/libxt_rpfilter.t - create mode 100644 extensions/libxt_sctp.t - create mode 100644 extensions/libxt_set.t - create mode 100644 extensions/libxt_socket.t - create mode 100644 extensions/libxt_standard.t - create mode 100644 extensions/libxt_state.t - create mode 100644 extensions/libxt_statistic.t - create mode 100644 extensions/libxt_string.t - create mode 100644 extensions/libxt_tcp.t - create mode 100644 extensions/libxt_tcpmss.t - create mode 100644 extensions/libxt_time.t - create mode 100644 extensions/libxt_tos.t - create mode 100644 extensions/libxt_u32.t - create mode 100644 extensions/libxt_udp.t - create mode 100755 iptables-test.py - -diff --git a/extensions/iptables.t b/extensions/iptables.t -new file mode 100644 -index 0000000000000..b4b6d677abab1 ---- /dev/null -+++ b/extensions/iptables.t -@@ -0,0 +1,6 @@ -+:FORWARD -+-i alongifacename0;=;OK -+-i thisinterfaceistoolong0;;FAIL -+-i eth+ -o alongifacename+;=;OK -+! -i eth0;=;OK -+! -o eth+;=;OK -diff --git a/extensions/libarpt_CLASSIFY.t b/extensions/libarpt_CLASSIFY.t -new file mode 100644 -index 0000000000000..c30480d2b160c ---- /dev/null -+++ b/extensions/libarpt_CLASSIFY.t -@@ -0,0 +1,4 @@ -+:OUTPUT -+-o lo --destination-mac 11:22:33:44:55:66;-o lo --dst-mac 11:22:33:44:55:66;OK -+--dst-mac Broadcast ;--dst-mac ff:ff:ff:ff:ff:ff;OK -+! -o eth+ -d 1.2.3.4/24 -j CLASSIFY --set-class 0000:0000;! -o eth+ -d 1.2.3.0/24 --h-length 6 --h-type 1 -j CLASSIFY --set-class 0000:0000;OK -diff --git a/extensions/libarpt_MARK.t b/extensions/libarpt_MARK.t -new file mode 100644 -index 0000000000000..cb4c2cb630357 ---- /dev/null -+++ b/extensions/libarpt_MARK.t -@@ -0,0 +1,4 @@ -+:INPUT,OUTPUT -+-d 0.0.0.0/8 -j MARK --set-mark 0x1;-d 0.0.0.0/8 --h-length 6 --h-type 1 -j MARK --set-xmark 0x1/0xffffffff;OK -+-s ! 0.0.0.0 -j MARK --and-mark 0x17;! -s 0.0.0.0 --h-length 6 --h-type 1 -j MARK --set-xmark 0x0/0xffffffe8;OK -+-s 0.0.0.0 -j MARK --or-mark 0x17;-s 0.0.0.0 --h-length 6 --h-type 1 -j MARK --set-xmark 0x17/0x17;OK -diff --git a/extensions/libarpt_mangle.t b/extensions/libarpt_mangle.t -new file mode 100644 -index 0000000000000..1d4c3977d2a4c ---- /dev/null -+++ b/extensions/libarpt_mangle.t -@@ -0,0 +1,5 @@ -+:OUTPUT -+-s 1.2.3.4 -j mangle --mangle-ip-s 1.2.3.5;-s 1.2.3.4 --h-length 6 --h-type 1 -j mangle --mangle-ip-s 1.2.3.5;OK -+-d 1.2.3.4 -j mangle --mangle-ip-d 1.2.3.5;-d 1.2.3.4 --h-length 6 --h-type 1 -j mangle --mangle-ip-d 1.2.3.5;OK -+-d 1.2.3.4 --h-length 6 --h-type 1 -j mangle --mangle-mac-d 00:01:02:03:04:05;=;OK -+-d 1.2.3.4 -j mangle --mangle-mac-s 00:01:02:03:04:05;=;FAIL -diff --git a/extensions/libarpt_standard.t b/extensions/libarpt_standard.t -new file mode 100644 -index 0000000000000..bef682afec374 ---- /dev/null -+++ b/extensions/libarpt_standard.t -@@ -0,0 +1,14 @@ -+:INPUT -+-s 192.168.0.1;=;OK -+-s 0.0.0.0/8;=;OK -+-s ! 0.0.0.0;! -s 0.0.0.0;OK -+-d 192.168.0.1;=;OK -+! -d 0.0.0.0;=;OK -+-d 0.0.0.0/24;=;OK -+-i lo;=;OK -+! -i lo;=;OK -+-i ppp+;=;OK -+! -i ppp+;=;OK -+-i lo --destination-mac 11:22:33:44:55:66;-i lo --dst-mac 11:22:33:44:55:66;OK -+--source-mac Unicast;--src-mac 00:00:00:00:00:00/01:00:00:00:00:00;OK -+! --src-mac Multicast;! --src-mac 01:00:00:00:00:00/01:00:00:00:00:00;OK -diff --git a/extensions/libebt_802_3.t b/extensions/libebt_802_3.t -new file mode 100644 -index 0000000000000..61081bd6983a8 ---- /dev/null -+++ b/extensions/libebt_802_3.t -@@ -0,0 +1,3 @@ -+:INPUT,FORWARD,OUTPUT -+! --802_3-sap 0x0a -j CONTINUE;=;OK -+--802_3-type 0x000a -j RETURN;=;OK -diff --git a/extensions/libebt_arp.t b/extensions/libebt_arp.t -new file mode 100644 -index 0000000000000..a05ab12dc566f ---- /dev/null -+++ b/extensions/libebt_arp.t -@@ -0,0 +1,12 @@ -+:INPUT,FORWARD,OUTPUT -+-p ARP --arp-op Request;=;OK -+-p ARP ! --arp-htype 1;=;OK -+-p ARP --arp-ptype 0x2;=;OK -+-p ARP --arp-ip-src 1.2.3.4;=;OK -+-p ARP ! --arp-ip-dst 1.2.3.4;=;OK -+-p ARP ! --arp-ip-src 0.0.0.0;=;OK -+-p ARP ! --arp-ip-dst 0.0.0.0/8;=;OK -+-p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK -+-p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK -+-p ARP --arp-gratuitous;=;OK -+--arp-htype 1;=;FAIL -diff --git a/extensions/libebt_arpreply.t b/extensions/libebt_arpreply.t -new file mode 100644 -index 0000000000000..6734501a106b5 ---- /dev/null -+++ b/extensions/libebt_arpreply.t -@@ -0,0 +1,4 @@ -+:PREROUTING -+*nat -+-p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff --arpreply-target ACCEPT;=;OK -+-p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff;=;OK -diff --git a/extensions/libebt_dnat.t b/extensions/libebt_dnat.t -new file mode 100644 -index 0000000000000..9428d237850fb ---- /dev/null -+++ b/extensions/libebt_dnat.t -@@ -0,0 +1,5 @@ -+:PREROUTING -+*nat -+-i someport -j dnat --to-dst de:ad:0:be:ee:ff;-i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;OK -+-j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;=;OK -+-j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE;=;OK -diff --git a/extensions/libebt_ip.t b/extensions/libebt_ip.t -new file mode 100644 -index 0000000000000..01a91a7385fcc ---- /dev/null -+++ b/extensions/libebt_ip.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+-p ip --ip-src ! 192.168.0.0/24 -j ACCEPT;-p IPv4 ! --ip-src 192.168.0.0/24 -j ACCEPT;OK -+-p IPv4 --ip-dst 10.0.0.1;=;OK -+-p IPv4 --ip-tos 0xFF;=;OK -+-p IPv4 ! --ip-tos 0xFF;=;OK -+-p IPv4 --ip-proto tcp --ip-dport 22;=;OK -+-p IPv4 --ip-proto udp --ip-sport 1024:65535;=;OK -+-p IPv4 --ip-proto 253;=;OK -+-p IPv4 --ip-proto icmp --ip-icmp-type echo-request;=;OK -+-p IPv4 --ip-proto icmp --ip-icmp-type 1/1;=;OK -+-p ip --ip-protocol icmp --ip-icmp-type ! 1:10;-p IPv4 --ip-proto icmp ! --ip-icmp-type 1:10/0:255 -j CONTINUE;OK -+--ip-proto icmp --ip-icmp-type 1/1;=;FAIL -+! -p ip --ip-proto icmp --ip-icmp-type 1/1;=;FAIL -diff --git a/extensions/libebt_ip6.t b/extensions/libebt_ip6.t -new file mode 100644 -index 0000000000000..6b3221ea58f62 ---- /dev/null -+++ b/extensions/libebt_ip6.t -@@ -0,0 +1,15 @@ -+:INPUT,FORWARD,OUTPUT -+-p ip6 ! --ip6-src dead::beef/64 -j ACCEPT;-p IPv6 ! --ip6-src dead::/64 -j ACCEPT;OK -+-p IPv6 --ip6-dst dead:beef::/64 -j ACCEPT;=;OK -+-p IPv6 --ip6-dst f00:ba::;=;OK -+-p IPv6 --ip6-tclass 0xFF;=;OK -+-p IPv6 --ip6-proto tcp --ip6-dport 22;=;OK -+-p IPv6 --ip6-proto tcp ! --ip6-dport 22;=;OK -+-p IPv6 --ip6-proto udp --ip6-sport 1024:65535;=;OK -+-p IPv6 --ip6-proto 253;=;OK -+-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request -j CONTINUE;=;OK -+-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request;=;OK -+-p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1;-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type communication-prohibited -j CONTINUE;OK -+-p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;OK -+--ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL -+! -p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL -diff --git a/extensions/libebt_log.t b/extensions/libebt_log.t -new file mode 100644 -index 0000000000000..a0df6169112a0 ---- /dev/null -+++ b/extensions/libebt_log.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+--log;=;OK -+--log-level crit;=;OK -+--log-level 1;--log-level alert --log-prefix "";OK -+--log-level emerg --log-ip --log-arp --log-ip6;--log-level emerg --log-prefix "" --log-ip --log-arp --log-ip6 -j CONTINUE;OK -+--log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo;--log-level crit --log-prefix "foo" --log-ip --log-arp --log-ip6 -j CONTINUE;OK -diff --git a/extensions/libebt_mark.t b/extensions/libebt_mark.t -new file mode 100644 -index 0000000000000..2d8f9d7a972ad ---- /dev/null -+++ b/extensions/libebt_mark.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-j mark --mark-set 1;-j mark --mark-set 0x1 --mark-target ACCEPT;OK -+-j mark --mark-or 0xa --mark-target CONTINUE;=;OK -+-j mark --mark-and 0x1 --mark-target RETURN;=;OK -+-j mark --mark-xor 0x1 --mark-target CONTINUE;=;OK -diff --git a/extensions/libebt_mark_m.t b/extensions/libebt_mark_m.t -new file mode 100644 -index 0000000000000..9ad41704fbb82 ---- /dev/null -+++ b/extensions/libebt_mark_m.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+--mark 42;--mark 0x2a;OK -+--mark ! 42;! --mark 0x2a;OK -+--mark 42/0xff;--mark 0x2a/0xff;OK -+! --mark 0x1/0xff;=;OK -+--mark /0x2;=;OK -diff --git a/extensions/libebt_nflog.t b/extensions/libebt_nflog.t -new file mode 100644 -index 0000000000000..f867df303fa95 ---- /dev/null -+++ b/extensions/libebt_nflog.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+--nflog;=;OK -+--nflog-group 42;=;OK -+--nflog-range 42;--nflog-group 1 --nflog-range 42 -j CONTINUE;OK -+--nflog-threshold 100 --nflog-prefix foo;--nflog-prefix "foo" --nflog-group 1 --nflog-threshold 100 -j CONTINUE;OK -diff --git a/extensions/libebt_pkttype.t b/extensions/libebt_pkttype.t -new file mode 100644 -index 0000000000000..f870f5c7f05c4 ---- /dev/null -+++ b/extensions/libebt_pkttype.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+--pkttype-type host;=;OK -+! --pkttype-type host;=;OK -+--pkttype-type broadcast;=;OK -+! --pkttype-type broadcast;=;OK -+--pkttype-type multicast;=;OK -+! --pkttype-type multicast;=;OK -+--pkttype-type otherhost;=;OK -+! --pkttype-type otherhost;=;OK -+--pkttype-type outgoing;=;OK -+! --pkttype-type outgoing;=;OK -+--pkttype-type loopback;=;OK -+! --pkttype-type loopback;=;OK -diff --git a/extensions/libebt_redirect.t b/extensions/libebt_redirect.t -new file mode 100644 -index 0000000000000..23858afa3b588 ---- /dev/null -+++ b/extensions/libebt_redirect.t -@@ -0,0 +1,4 @@ -+:PREROUTING -+*nat -+-j redirect;=;OK -+-j redirect --redirect-target RETURN;=;OK -diff --git a/extensions/libebt_snat.t b/extensions/libebt_snat.t -new file mode 100644 -index 0000000000000..639b13f300c9d ---- /dev/null -+++ b/extensions/libebt_snat.t -@@ -0,0 +1,4 @@ -+:POSTROUTING -+*nat -+-o someport -j snat --to-source a:b:c:d:e:f;-o someport -j snat --to-src 0a:0b:0c:0d:0e:0f --snat-target ACCEPT;OK -+-o someport+ -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE;=;OK -diff --git a/extensions/libebt_standard.t b/extensions/libebt_standard.t -new file mode 100644 -index 0000000000000..72081fd6575a0 ---- /dev/null -+++ b/extensions/libebt_standard.t -@@ -0,0 +1,11 @@ -+:INPUT,FORWARD,OUTPUT -+-d de:ad:be:ef:00:00;=;OK -+-s 0:0:0:0:0:0;-s 00:00:00:00:00:00;OK -+-d 00:00:00:00:00:00;=;OK -+-s de:ad:be:ef:0:00 -j RETURN;-s de:ad:be:ef:00:00 -j RETURN;OK -+-d de:ad:be:ef:00:00 -j CONTINUE;=;OK -+-d de:ad:be:ef:0:00/ff:ff:ff:ff:0:0 -j DROP;-d de:ad:be:ef:00:00/ff:ff:ff:ff:00:00 -j DROP;OK -+-p ARP -j ACCEPT;=;OK -+! -p ARP -j ACCEPT;=;OK -+-p 0 -j ACCEPT;=;FAIL -+! -p 0 -j ACCEPT;=;FAIL -diff --git a/extensions/libebt_stp.t b/extensions/libebt_stp.t -new file mode 100644 -index 0000000000000..0c6b77b91454b ---- /dev/null -+++ b/extensions/libebt_stp.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+--stp-type 1;=;OK -+--stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK -+--stp-root-prio 1 -j ACCEPT;=;OK -+--stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK -+--stp-root-cost 1;=;OK -+--stp-sender-prio 1;=;OK -+--stp-sender-addr de:ad:be:ef:00:00;=;OK -+--stp-port 1;=;OK -+--stp-msg-age 1;=;OK -+--stp-max-age 1;=;OK -+--stp-hello-time 1;=;OK -+--stp-forward-delay 1;=;OK -diff --git a/extensions/libebt_vlan.t b/extensions/libebt_vlan.t -new file mode 100644 -index 0000000000000..106374cd9cb80 ---- /dev/null -+++ b/extensions/libebt_vlan.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+-p 802_1Q --vlan-id 42;=;OK -+-p 802_1Q ! --vlan-id 42;=;OK -+-p 802_1Q --vlan-prio 1;=;OK -+-p 802_1Q ! --vlan-prio 1;=;OK -+-p 802_1Q --vlan-encap ip;-p 802_1Q --vlan-encap 0800 -j CONTINUE;OK -+-p 802_1Q --vlan-encap 0800 ;=;OK -+-p 802_1Q ! --vlan-encap 0800 ;=;OK -+-p 802_1Q --vlan-encap IPv6 ! --vlan-id 1;-p 802_1Q ! --vlan-id 1 --vlan-encap 86DD -j CONTINUE;OK -+-p 802_1Q ! --vlan-id 1 --vlan-encap 86DD;=;OK -+--vlan-encap ip;=;FAIL -+--vlan-id 2;=;FAIL -+--vlan-prio 1;=;FAIL -diff --git a/extensions/libip6t_DNAT.t b/extensions/libip6t_DNAT.t -new file mode 100644 -index 0000000000000..ec7d61f418cfe ---- /dev/null -+++ b/extensions/libip6t_DNAT.t -@@ -0,0 +1,16 @@ -+:PREROUTING -+*nat -+-j DNAT --to-destination dead::beef;=;OK -+-j DNAT --to-destination dead::beef-dead::fee7;=;OK -+-j DNAT --to-destination [dead::beef]:1025-65535;;FAIL -+-j DNAT --to-destination [dead::beef] --to-destination [dead::fee7];;FAIL -+-p tcp -j DNAT --to-destination [dead::beef]:1025-65535;=;OK -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535;=;OK -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65536;;FAIL -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535 --to-destination [dead::beef-dead::fee8]:1025-65535;;FAIL -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/1000;=;OK -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/3000;=;OK -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65535;=;OK -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/0;;FAIL -+-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65536;;FAIL -+-j DNAT;;FAIL -diff --git a/extensions/libip6t_DNPT.t b/extensions/libip6t_DNPT.t -new file mode 100644 -index 0000000000000..0406dc90d2c6e ---- /dev/null -+++ b/extensions/libip6t_DNPT.t -@@ -0,0 +1,7 @@ -+:PREROUTING -+*mangle -+-j DNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK -+-j DNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL -+-j DNPT --src-pfx dead::/64;;FAIL -+-j DNPT --dst-pfx dead::/64;;FAIL -+-j DNPT;;FAIL -diff --git a/extensions/libip6t_HL.t b/extensions/libip6t_HL.t -new file mode 100644 -index 0000000000000..4e529f883b2c5 ---- /dev/null -+++ b/extensions/libip6t_HL.t -@@ -0,0 +1,10 @@ -+:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j HL --hl-set 42;=;OK -+-j HL --hl-inc 1;=;OK -+-j HL --hl-dec 1;=;OK -+-j HL --hl-set 256;;FAIL -+-j HL --hl-inc 0;;FAIL -+-j HL --hl-dec 0;;FAIL -+-j HL --hl-dec 1 --hl-inc 1;;FAIL -+-j HL --hl-set --hl-inc 1;;FAIL -diff --git a/extensions/libip6t_LOG.t b/extensions/libip6t_LOG.t -new file mode 100644 -index 0000000000000..fbf5118b2382a ---- /dev/null -+++ b/extensions/libip6t_LOG.t -@@ -0,0 +1,12 @@ -+:INPUT,FORWARD,OUTPUT -+-j LOG;-j LOG;OK -+-j LOG --log-prefix "test: ";=;OK -+-j LOG --log-prefix "test: " --log-level 1;=;OK -+# iptables displays the log-level output using the number; not the string -+-j LOG --log-prefix "test: " --log-level alert;-j LOG --log-prefix "test: " --log-level 1;OK -+-j LOG --log-prefix "test: " --log-tcp-sequence;=;OK -+-j LOG --log-prefix "test: " --log-tcp-options;=;OK -+-j LOG --log-prefix "test: " --log-ip-options;=;OK -+-j LOG --log-prefix "test: " --log-uid;=;OK -+-j LOG --log-prefix "test: " --log-level bad;;FAIL -+-j LOG --log-prefix;;FAIL -diff --git a/extensions/libip6t_MASQUERADE.t b/extensions/libip6t_MASQUERADE.t -new file mode 100644 -index 0000000000000..e25d2a04ab7b0 ---- /dev/null -+++ b/extensions/libip6t_MASQUERADE.t -@@ -0,0 +1,9 @@ -+:POSTROUTING -+*nat -+-j MASQUERADE;=;OK -+-j MASQUERADE --random;=;OK -+-j MASQUERADE --random-fully;=;OK -+-p tcp -j MASQUERADE --to-ports 1024;=;OK -+-p udp -j MASQUERADE --to-ports 1024-65535;=;OK -+-p udp -j MASQUERADE --to-ports 1024-65536;;FAIL -+-p udp -j MASQUERADE --to-ports -1;;FAIL -diff --git a/extensions/libip6t_NETMAP.t b/extensions/libip6t_NETMAP.t -new file mode 100644 -index 0000000000000..043562d261243 ---- /dev/null -+++ b/extensions/libip6t_NETMAP.t -@@ -0,0 +1,4 @@ -+:PREROUTING,INPUT,OUTPUT,POSTROUTING -+*nat -+-j NETMAP --to dead::/64;=;OK -+-j NETMAP --to dead::beef;=;OK -diff --git a/extensions/libip6t_REDIRECT.t b/extensions/libip6t_REDIRECT.t -new file mode 100644 -index 0000000000000..a0fb0ed19a5ea ---- /dev/null -+++ b/extensions/libip6t_REDIRECT.t -@@ -0,0 +1,6 @@ -+:PREROUTING,OUTPUT -+*nat -+-p tcp -j REDIRECT --to-ports 42;=;OK -+-p udp -j REDIRECT --to-ports 42-1234;=;OK -+-p tcp -j REDIRECT --to-ports 42-1234 --random;=;OK -+-j REDIRECT --to-ports 42;;FAIL -diff --git a/extensions/libip6t_REJECT.t b/extensions/libip6t_REJECT.t -new file mode 100644 -index 0000000000000..d2b337d7ebdeb ---- /dev/null -+++ b/extensions/libip6t_REJECT.t -@@ -0,0 +1,11 @@ -+:INPUT,FORWARD,OUTPUT -+-j REJECT;=;OK -+# manpage for IPv6 variant of REJECT does not show up for some reason? -+-j REJECT --reject-with icmp6-no-route;=;OK -+-j REJECT --reject-with icmp6-adm-prohibited;=;OK -+-j REJECT --reject-with icmp6-addr-unreachable;=;OK -+-j REJECT --reject-with icmp6-port-unreachable;=;OK -+-j REJECT --reject-with icmp6-policy-fail;=;OK -+-j REJECT --reject-with icmp6-reject-route;=;OK -+-p tcp -j REJECT --reject-with tcp-reset;=;OK -+-j REJECT --reject-with tcp-reset;;FAIL -diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t -new file mode 100644 -index 0000000000000..d188a6bb3d559 ---- /dev/null -+++ b/extensions/libip6t_SNAT.t -@@ -0,0 +1,11 @@ -+:POSTROUTING -+*nat -+-j SNAT --to-source dead::beef;=;OK -+-j SNAT --to-source dead::beef-dead::fee7;=;OK -+-j SNAT --to-source [dead::beef]:1025-65535;;FAIL -+-j SNAT --to-source [dead::beef] --to-source [dead::fee7];;FAIL -+-p tcp -j SNAT --to-source [dead::beef]:1025-65535;=;OK -+-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535;=;OK -+-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65536;;FAIL -+-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535 --to-source [dead::beef-dead::fee8]:1025-65535;;FAIL -+-j SNAT;;FAIL -diff --git a/extensions/libip6t_SNPT.t b/extensions/libip6t_SNPT.t -new file mode 100644 -index 0000000000000..7ed6d0c95bb35 ---- /dev/null -+++ b/extensions/libip6t_SNPT.t -@@ -0,0 +1,7 @@ -+:INPUT,POSTROUTING -+*mangle -+-j SNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK -+-j SNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL -+-j SNPT --src-pfx dead::/64;;FAIL -+-j SNPT --dst-pfx dead::/64;;FAIL -+-j SNPT;;FAIL -diff --git a/extensions/libip6t_ah.t b/extensions/libip6t_ah.t -new file mode 100644 -index 0000000000000..c1898d44cf193 ---- /dev/null -+++ b/extensions/libip6t_ah.t -@@ -0,0 +1,15 @@ -+:INPUT,FORWARD,OUTPUT -+-m ah --ahspi 0;=;OK -+-m ah --ahspi 4294967295;=;OK -+-m ah --ahspi 0:4294967295;-m ah;OK -+-m ah ! --ahspi 0;=;OK -+# ERROR: should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class 1:-1 -+# -m ah --ahres;=;OK -+# ERROR: line 7 (cannot find: ip6tables -I INPUT -m ah --ahlen 32 -+# -m ah --ahlen 32;=;OK -+-m ah --ahspi -1;;FAIL -+-m ah --ahspi 4294967296;;FAIL -+-m ah --ahspi invalid;;FAIL -+-m ah --ahspi 0:invalid;;FAIL -+-m ah --ahspi;;FAIL -+-m ah;=;OK -diff --git a/extensions/libip6t_dst.t b/extensions/libip6t_dst.t -new file mode 100644 -index 0000000000000..0b0013b57fc0b ---- /dev/null -+++ b/extensions/libip6t_dst.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-m dst --dst-len 0;=;OK -+-m dst --dst-opts 149:92,12:12,123:12;=;OK -+-m dst ! --dst-len 42;=;OK -+-m dst --dst-len 42 --dst-opts 149:92,12:12,123:12;=;OK -diff --git a/extensions/libip6t_eui64.t b/extensions/libip6t_eui64.t -new file mode 100644 -index 0000000000000..e5aaaacef48bf ---- /dev/null -+++ b/extensions/libip6t_eui64.t -@@ -0,0 +1,8 @@ -+:PREROUTING -+*raw -+-m eui64;=;OK -+:INPUT,FORWARD -+*filter -+-m eui64;=;OK -+:OUTPUT -+-m eui64;;FAIL -diff --git a/extensions/libip6t_frag.t b/extensions/libip6t_frag.t -new file mode 100644 -index 0000000000000..299fa03f8845b ---- /dev/null -+++ b/extensions/libip6t_frag.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+-m frag --fragid 1:42;=;OK -+-m frag --fraglen 42;=;OK -+-m frag --fragres;=;OK -+-m frag --fragfirst;=;OK -+-m frag --fragmore;=;OK -+-m frag --fraglast;=;OK -+-m frag ! --fragid 1 ! --fraglen 42 --fragres --fragfirst;=;OK -+-m frag --fragfirst --fragmore;=;OK -+-m frag --fragfirst --fraglast;=;OK -+-m frag --fraglast --fragmore;;FAIL -+-d ff02::fb/128 -p udp -m udp --dport 5353 -m frag --fragmore;=;OK -+-d fe80::/64 -p udp --dport 546 -m frag --fraglast;-d fe80::/64 -p udp -m udp --dport 546 -m frag --fraglast;OK -diff --git a/extensions/libip6t_hbh.t b/extensions/libip6t_hbh.t -new file mode 100644 -index 0000000000000..4b58f25a1301a ---- /dev/null -+++ b/extensions/libip6t_hbh.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-m hbh;=;OK -+-m hbh --hbh-len 42;=;OK -+-m hbh ! --hbh-len 42;=;OK -+-m hbh --hbh-len 42 --hbh-opts 1:2,23:42,4:6,8:10,42,23,4:5;=;OK -diff --git a/extensions/libip6t_hl.t b/extensions/libip6t_hl.t -new file mode 100644 -index 0000000000000..b02816afb827b ---- /dev/null -+++ b/extensions/libip6t_hl.t -@@ -0,0 +1,8 @@ -+:INPUT,FORWARD,OUTPUT -+-m hl;;FAIL -+-m hl --hl-eq 42;=;OK -+-m hl ! --hl-eq 42;=;OK -+-m hl --hl-lt 42;=;OK -+-m hl --hl-gt 42;=;OK -+-m hl --hl-gt 42 --hl-eq 42;;FAIL -+-m hl --hl-gt;;FAIL -diff --git a/extensions/libip6t_icmp6.t b/extensions/libip6t_icmp6.t -new file mode 100644 -index 0000000000000..028cfc16ede24 ---- /dev/null -+++ b/extensions/libip6t_icmp6.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m icmpv6;;FAIL -+-p ipv6-icmp -m icmp6 --icmpv6-type 1/0;=;OK -+-p ipv6-icmp -m icmp6 --icmpv6-type 2;=;OK -+# cannot use option twice: -+-p ipv6-icmp -m icmp6 --icmpv6-type no-route --icmpv6-type packet-too-big;;FAIL -diff --git a/extensions/libip6t_ipv6header.t b/extensions/libip6t_ipv6header.t -new file mode 100644 -index 0000000000000..67fa47998ee09 ---- /dev/null -+++ b/extensions/libip6t_ipv6header.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-m ipv6header --header hop-by-hop;=;OK -+-m ipv6header --header hop-by-hop --soft;=;OK -+-m ipv6header --header ipv6-nonxt;=;OK -diff --git a/extensions/libip6t_mh.t b/extensions/libip6t_mh.t -new file mode 100644 -index 0000000000000..6b76d13d0a00f ---- /dev/null -+++ b/extensions/libip6t_mh.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m mh;;FAIL -+-p mobility-header -m mh;=;OK -+-p mobility-header -m mh --mh-type 1;=;OK -+-p mobility-header -m mh ! --mh-type 4;=;OK -+-p mobility-header -m mh --mh-type 4:123;=;OK -diff --git a/extensions/libip6t_rt.t b/extensions/libip6t_rt.t -new file mode 100644 -index 0000000000000..3c7b2d981324a ---- /dev/null -+++ b/extensions/libip6t_rt.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-m rt --rt-type 0 --rt-segsleft 1:23 --rt-len 42 --rt-0-res;=;OK -+-m rt --rt-type 0 ! --rt-segsleft 1:23 ! --rt-len 42 --rt-0-res;=;OK -+-m rt ! --rt-type 1 ! --rt-segsleft 12:23 ! --rt-len 42;=;OK -+-m rt;=;OK -diff --git a/extensions/libip6t_srh.t b/extensions/libip6t_srh.t -new file mode 100644 -index 0000000000000..07b540319233e ---- /dev/null -+++ b/extensions/libip6t_srh.t -@@ -0,0 +1,28 @@ -+:INPUT,FORWARD,OUTPUT -+-m srh --srh-next-hdr 17;=;OK -+-m srh --srh-hdr-len-eq 8;=;OK -+-m srh --srh-hdr-len-gt 8;=;OK -+-m srh --srh-hdr-len-lt 8;=;OK -+-m srh --srh-segs-left-eq 1;=;OK -+-m srh --srh-segs-left-gt 1;=;OK -+-m srh --srh-segs-left-lt 1;=;OK -+-m srh --srh-last-entry-eq 4;=;OK -+-m srh --srh-last-entry-gt 4;=;OK -+-m srh --srh-last-entry-lt 4;=;OK -+-m srh --srh-tag 0;=;OK -+-m srh ! --srh-next-hdr 17;=;OK -+-m srh ! --srh-hdr-len-eq 8;=;OK -+-m srh ! --srh-hdr-len-gt 8;=;OK -+-m srh ! --srh-hdr-len-lt 8;=;OK -+-m srh ! --srh-segs-left-eq 1;=;OK -+-m srh ! --srh-segs-left-gt 1;=;OK -+-m srh ! --srh-segs-left-lt 1;=;OK -+-m srh ! --srh-last-entry-eq 4;=;OK -+-m srh ! --srh-last-entry-gt 4;=;OK -+-m srh ! --srh-last-entry-lt 4;=;OK -+-m srh ! --srh-tag 0;=;OK -+-m srh --srh-next-hdr 17 --srh-segs-left-eq 1 --srh-last-entry-eq 4 --srh-tag 0;=;OK -+-m srh ! --srh-next-hdr 17 ! --srh-segs-left-eq 0 --srh-tag 0;=;OK -+-m srh --srh-psid A::/64 --srh-nsid B:: --srh-lsid C::/0;;OK -+-m srh ! --srh-psid A::/64 ! --srh-nsid B:: ! --srh-lsid C::/0;;OK -+-m srh;=;OK -diff --git a/extensions/libip6t_standard.t b/extensions/libip6t_standard.t -new file mode 100644 -index 0000000000000..a528af10ea152 ---- /dev/null -+++ b/extensions/libip6t_standard.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-s ::/128;=;OK -+! -d ::;! -d ::/128;OK -+! -s ::;! -s ::/128;OK -+-s ::/64;=;OK -diff --git a/extensions/libipt_CLUSTERIP.t b/extensions/libipt_CLUSTERIP.t -new file mode 100644 -index 0000000000000..5af555e005c1d ---- /dev/null -+++ b/extensions/libipt_CLUSTERIP.t -@@ -0,0 +1,4 @@ -+:INPUT -+-d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 0 --hash-init 1;=;FAIL -+-d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 1 --hash-init 1;=;OK -+-d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 2 --hash-init 1;=;OK -diff --git a/extensions/libipt_DNAT.t b/extensions/libipt_DNAT.t -new file mode 100644 -index 0000000000000..1c4413b9b3bb5 ---- /dev/null -+++ b/extensions/libipt_DNAT.t -@@ -0,0 +1,16 @@ -+:PREROUTING -+*nat -+-j DNAT --to-destination 1.1.1.1;=;OK -+-j DNAT --to-destination 1.1.1.1-1.1.1.10;=;OK -+-j DNAT --to-destination 1.1.1.1:1025-65535;;FAIL -+-j DNAT --to-destination 1.1.1.1 --to-destination 2.2.2.2;;FAIL -+-p tcp -j DNAT --to-destination 1.1.1.1:1025-65535;=;OK -+-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65535;=;OK -+-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65536;;FAIL -+-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65535 --to-destination 2.2.2.2-2.2.2.20:1025-65535;;FAIL -+-p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/1000;=;OK -+-p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/3000;=;OK -+-p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/65535;=;OK -+-p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/0;;FAIL -+-p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/65536;;FAIL -+-j DNAT;;FAIL -diff --git a/extensions/libipt_ECN.t b/extensions/libipt_ECN.t -new file mode 100644 -index 0000000000000..2e09205212e7f ---- /dev/null -+++ b/extensions/libipt_ECN.t -@@ -0,0 +1,5 @@ -+:PREROUTING,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j ECN;;FAIL -+-p tcp -j ECN;;FAIL -+-p tcp -j ECN --ecn-tcp-remove;=;OK -diff --git a/extensions/libipt_LOG.t b/extensions/libipt_LOG.t -new file mode 100644 -index 0000000000000..fbf5118b2382a ---- /dev/null -+++ b/extensions/libipt_LOG.t -@@ -0,0 +1,12 @@ -+:INPUT,FORWARD,OUTPUT -+-j LOG;-j LOG;OK -+-j LOG --log-prefix "test: ";=;OK -+-j LOG --log-prefix "test: " --log-level 1;=;OK -+# iptables displays the log-level output using the number; not the string -+-j LOG --log-prefix "test: " --log-level alert;-j LOG --log-prefix "test: " --log-level 1;OK -+-j LOG --log-prefix "test: " --log-tcp-sequence;=;OK -+-j LOG --log-prefix "test: " --log-tcp-options;=;OK -+-j LOG --log-prefix "test: " --log-ip-options;=;OK -+-j LOG --log-prefix "test: " --log-uid;=;OK -+-j LOG --log-prefix "test: " --log-level bad;;FAIL -+-j LOG --log-prefix;;FAIL -diff --git a/extensions/libipt_MASQUERADE.t b/extensions/libipt_MASQUERADE.t -new file mode 100644 -index 0000000000000..e25d2a04ab7b0 ---- /dev/null -+++ b/extensions/libipt_MASQUERADE.t -@@ -0,0 +1,9 @@ -+:POSTROUTING -+*nat -+-j MASQUERADE;=;OK -+-j MASQUERADE --random;=;OK -+-j MASQUERADE --random-fully;=;OK -+-p tcp -j MASQUERADE --to-ports 1024;=;OK -+-p udp -j MASQUERADE --to-ports 1024-65535;=;OK -+-p udp -j MASQUERADE --to-ports 1024-65536;;FAIL -+-p udp -j MASQUERADE --to-ports -1;;FAIL -diff --git a/extensions/libipt_NETMAP.t b/extensions/libipt_NETMAP.t -new file mode 100644 -index 0000000000000..31924b985cd6f ---- /dev/null -+++ b/extensions/libipt_NETMAP.t -@@ -0,0 +1,4 @@ -+:PREROUTING,INPUT,OUTPUT,POSTROUTING -+*nat -+-j NETMAP --to 1.2.3.0/24;=;OK -+-j NETMAP --to 1.2.3.4;=;OK -diff --git a/extensions/libipt_REDIRECT.t b/extensions/libipt_REDIRECT.t -new file mode 100644 -index 0000000000000..a0fb0ed19a5ea ---- /dev/null -+++ b/extensions/libipt_REDIRECT.t -@@ -0,0 +1,6 @@ -+:PREROUTING,OUTPUT -+*nat -+-p tcp -j REDIRECT --to-ports 42;=;OK -+-p udp -j REDIRECT --to-ports 42-1234;=;OK -+-p tcp -j REDIRECT --to-ports 42-1234 --random;=;OK -+-j REDIRECT --to-ports 42;;FAIL -diff --git a/extensions/libipt_REJECT.t b/extensions/libipt_REJECT.t -new file mode 100644 -index 0000000000000..5b26b1076b5b2 ---- /dev/null -+++ b/extensions/libipt_REJECT.t -@@ -0,0 +1,9 @@ -+:INPUT,FORWARD,OUTPUT -+-j REJECT;=;OK -+-j REJECT --reject-with icmp-net-unreachable;=;OK -+-j REJECT --reject-with icmp-host-unreachable;=;OK -+-j REJECT --reject-with icmp-port-unreachable;=;OK -+-j REJECT --reject-with icmp-proto-unreachable;=;OK -+-j REJECT --reject-with icmp-net-prohibited;=;OK -+-j REJECT --reject-with icmp-host-prohibited;=;OK -+-j REJECT --reject-with icmp-admin-prohibited;=;OK -diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t -new file mode 100644 -index 0000000000000..186e1cb82c3f3 ---- /dev/null -+++ b/extensions/libipt_SNAT.t -@@ -0,0 +1,11 @@ -+:POSTROUTING -+*nat -+-j SNAT --to-source 1.1.1.1;=;OK -+-j SNAT --to-source 1.1.1.1-1.1.1.10;=;OK -+-j SNAT --to-source 1.1.1.1:1025-65535;;FAIL -+-j SNAT --to-source 1.1.1.1 --to-source 2.2.2.2;;FAIL -+-p tcp -j SNAT --to-source 1.1.1.1:1025-65535;=;OK -+-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535;=;OK -+-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65536;;FAIL -+-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535 --to-source 2.2.2.2-2.2.2.20:1025-65535;;FAIL -+-j SNAT;;FAIL -diff --git a/extensions/libipt_TTL.t b/extensions/libipt_TTL.t -new file mode 100644 -index 0000000000000..36809792a4b92 ---- /dev/null -+++ b/extensions/libipt_TTL.t -@@ -0,0 +1,10 @@ -+:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j TTL --ttl-set 42;=;OK -+-j TTL --ttl-inc 1;=;OK -+-j TTL --ttl-dec 1;=;OK -+-j TTL --ttl-set 256;;FAIL -+-j TTL --ttl-inc 0;;FAIL -+-j TTL --ttl-dec 0;;FAIL -+-j TTL --ttl-dec 1 --ttl-inc 1;;FAIL -+-j TTL --ttl-set --ttl-inc 1;;FAIL -diff --git a/extensions/libipt_ah.t b/extensions/libipt_ah.t -new file mode 100644 -index 0000000000000..cd853865638e8 ---- /dev/null -+++ b/extensions/libipt_ah.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+-p ah -m ah --ahspi 0;=;OK -+-p ah -m ah --ahspi 4294967295;=;OK -+-p ah -m ah --ahspi 0:4294967295;-p ah -m ah;OK -+-p ah -m ah ! --ahspi 0;=;OK -+-p ah -m ah --ahspi -1;;FAIL -+-p ah -m ah --ahspi 4294967296;;FAIL -+-p ah -m ah --ahspi invalid;;FAIL -+-p ah -m ah --ahspi 0:invalid;;FAIL -+-m ah --ahspi 0;;FAIL -+-m ah --ahspi;;FAIL -+-m ah;;FAIL -+-p ah -m ah;=;OK -diff --git a/extensions/libipt_icmp.t b/extensions/libipt_icmp.t -new file mode 100644 -index 0000000000000..f4ba65c27f032 ---- /dev/null -+++ b/extensions/libipt_icmp.t -@@ -0,0 +1,15 @@ -+:INPUT,FORWARD,OUTPUT -+-p icmp -m icmp --icmp-type any;=;OK -+# output uses the number, better use the name? -+# ERROR: cannot find: iptables -I INPUT -p icmp -m icmp --icmp-type echo-reply -+# -p icmp -m icmp --icmp-type echo-reply;=;OK -+# output uses the number, better use the name? -+# ERROR: annot find: iptables -I INPUT -p icmp -m icmp --icmp-type destination-unreachable -+# -p icmp -m icmp --icmp-type destination-unreachable;=;OK -+# it does not acccept name/name, should we accept this? -+# ERROR: cannot load: iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable -+# -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable;=;OK -+-m icmp;;FAIL -+# we accept "iptables -I INPUT -p tcp -m tcp", why not this below? -+# ERROR: cannot load: iptables -A INPUT -p icmp -m icmp -+# -p icmp -m icmp;=;OK -diff --git a/extensions/libipt_realm.t b/extensions/libipt_realm.t -new file mode 100644 -index 0000000000000..ca66640766983 ---- /dev/null -+++ b/extensions/libipt_realm.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-m realm --realm 0x1/0x2a;=;OK -+-m realm --realm 0x2a;=;OK -+-m realm;;FAIL -diff --git a/extensions/libipt_ttl.t b/extensions/libipt_ttl.t -new file mode 100644 -index 0000000000000..ebe5b3a21a268 ---- /dev/null -+++ b/extensions/libipt_ttl.t -@@ -0,0 +1,15 @@ -+:INPUT,FORWARD,OUTPUT -+-m ttl --ttl-eq 0;=;OK -+-m ttl --ttl-eq 255;=;OK -+-m ttl ! --ttl-eq 0;=;OK -+-m ttl ! --ttl-eq 255;=;OK -+-m ttl --ttl-gt 0;=;OK -+# not possible have anything greater than 255, TTL is 8-bit long -+# ERROR: should fail: iptables -A INPUT -m ttl --ttl-gt 255 -+## -m ttl --ttl-gt 255;;FAIL -+# not possible have anything below 0 -+# ERROR: should fail: iptables -A INPUT -m ttl --ttl-lt 0 -+## -m ttl --ttl-lt 0;;FAIL -+-m ttl --ttl-eq 256;;FAIL -+-m ttl --ttl-eq -1;;FAIL -+-m ttl;;FAIL -diff --git a/extensions/libxt_AUDIT.t b/extensions/libxt_AUDIT.t -new file mode 100644 -index 0000000000000..97575b0eb1ce8 ---- /dev/null -+++ b/extensions/libxt_AUDIT.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-j AUDIT --type accept;=;OK -+-j AUDIT --type drop;=;OK -+-j AUDIT --type reject;=;OK -+-j AUDIT;;FAIL -+-j AUDIT --type wrong;;FAIL -diff --git a/extensions/libxt_CHECKSUM.t b/extensions/libxt_CHECKSUM.t -new file mode 100644 -index 0000000000000..9451ad86489b2 ---- /dev/null -+++ b/extensions/libxt_CHECKSUM.t -@@ -0,0 +1,4 @@ -+:PREROUTING,FORWARD,POSTROUTING -+*mangle -+-j CHECKSUM --checksum-fill;=;OK -+-j CHECKSUM;;FAIL -diff --git a/extensions/libxt_CLASSIFY.t b/extensions/libxt_CLASSIFY.t -new file mode 100644 -index 0000000000000..7b3ddbf75039e ---- /dev/null -+++ b/extensions/libxt_CLASSIFY.t -@@ -0,0 +1,9 @@ -+:FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j CLASSIFY --set-class 0000:ffff;=;OK -+# maximum handle accepted by tc is 0xffff -+# ERROR : should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class 0000:ffffffff -+# -j CLASSIFY --set-class 0000:ffffffff;;FAIL -+# ERROR: should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class 1:-1 -+# -j CLASSIFY --set-class 1:-1;;FAIL -+-j CLASSIFY;;FAIL -diff --git a/extensions/libxt_CONNMARK.t b/extensions/libxt_CONNMARK.t -new file mode 100644 -index 0000000000000..79a838fefaa14 ---- /dev/null -+++ b/extensions/libxt_CONNMARK.t -@@ -0,0 +1,7 @@ -+:PREROUTING,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j CONNMARK --restore-mark;=;OK -+-j CONNMARK --save-mark;=;OK -+-j CONNMARK --save-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --save-mark;OK -+-j CONNMARK --restore-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --restore-mark;OK -+-j CONNMARK;;FAIL -diff --git a/extensions/libxt_CONNSECMARK.t b/extensions/libxt_CONNSECMARK.t -new file mode 100644 -index 0000000000000..2751b255cd273 ---- /dev/null -+++ b/extensions/libxt_CONNSECMARK.t -@@ -0,0 +1,5 @@ -+:PREROUTING,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j CONNSECMARK --restore;=;OK -+-j CONNSECMARK --save;=;OK -+-j CONNSECMARK;;FAIL -diff --git a/extensions/libxt_CT.t b/extensions/libxt_CT.t -new file mode 100644 -index 0000000000000..3c28534e8169e ---- /dev/null -+++ b/extensions/libxt_CT.t -@@ -0,0 +1,20 @@ -+:PREROUTING,OUTPUT -+*raw -+-j CT --notrack;=;OK -+-j CT --ctevents new,related,destroy,reply,assured,protoinfo,helper,mark;=;OK -+-j CT --expevents new;=;OK -+# ERROR: cannot find: iptables -I PREROUTING -t raw -j CT --zone 0 -+# -j CT --zone 0;=;OK -+-j CT --zone 65535;=;OK -+-j CT --zone 65536;;FAIL -+-j CT --zone -1;;FAIL -+# ERROR: should fail: iptables -A PREROUTING -t raw -j CT -+# -j CT;;FAIL -+@nfct timeout add test inet tcp ESTABLISHED 100 -+# cannot load: iptables -A PREROUTING -t raw -j CT --timeout test -+# -j CT --timeout test;=;OK -+@nfct timeout del test -+@nfct helper add rpc inet tcp -+# cannot load: iptables -A PREROUTING -t raw -j CT --helper rpc -+# -j CT --helper rpc;=;OK -+@nfct helper del rpc -diff --git a/extensions/libxt_DSCP.t b/extensions/libxt_DSCP.t -new file mode 100644 -index 0000000000000..fcc55986dbcd7 ---- /dev/null -+++ b/extensions/libxt_DSCP.t -@@ -0,0 +1,11 @@ -+:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j DSCP --set-dscp 0;=;OK -+-j DSCP --set-dscp 0x3f;=;OK -+-j DSCP --set-dscp -1;;FAIL -+-j DSCP --set-dscp 0x40;;FAIL -+-j DSCP --set-dscp 0x3f --set-dscp-class CS0;;FAIL -+-j DSCP --set-dscp-class CS0;-j DSCP --set-dscp 0x00;OK -+-j DSCP --set-dscp-class BE;-j DSCP --set-dscp 0x00;OK -+-j DSCP --set-dscp-class EF;-j DSCP --set-dscp 0x2e;OK -+-j DSCP;;FAIL -diff --git a/extensions/libxt_HMARK.t b/extensions/libxt_HMARK.t -new file mode 100644 -index 0000000000000..3bcf1dada5d02 ---- /dev/null -+++ b/extensions/libxt_HMARK.t -@@ -0,0 +1,8 @@ -+:INPUT,FORWARD,OUTPUT -+-j HMARK;;FAIL -+-j HMARK --hmark-src-prefix 32 --hmark-rnd 0x00000004 --hmark-mod 42;=;OK -+-j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-sport-mask 0xffff --hmark-dport-mask 0xffff --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK -+-j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-spi-mask 0x00000004 --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK -+-j HMARK --hmark-src-prefix 1 --hmark-dst-prefix 2 --hmark-sport-mask 0x0003 --hmark-dport-mask 0x0004 --hmark-proto-mask 0x05 --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK -+# cannot mix in spi mask: -+-j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-sport-mask 0xffff --hmark-dport-mask 0xffff --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct --hmark-spi-mask 4;;FAIL -diff --git a/extensions/libxt_IDLETIMER.t b/extensions/libxt_IDLETIMER.t -new file mode 100644 -index 0000000000000..6afd92c1a1c88 ---- /dev/null -+++ b/extensions/libxt_IDLETIMER.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-j IDLETIMER --timeout;;FAIL -+-j IDLETIMER --timeout 42;;FAIL -+-j IDLETIMER --timeout 42 --label foo;=;OK -diff --git a/extensions/libxt_LED.t b/extensions/libxt_LED.t -new file mode 100644 -index 0000000000000..1f6705f464b1d ---- /dev/null -+++ b/extensions/libxt_LED.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-j LED;;FAIL -+-j LED --led-trigger-id "foo";=;OK -+-j LED --led-trigger-id "foo" --led-delay 42 --led-always-blink;=;OK -diff --git a/extensions/libxt_MARK.t b/extensions/libxt_MARK.t -new file mode 100644 -index 0000000000000..9d1aa7d7d58a4 ---- /dev/null -+++ b/extensions/libxt_MARK.t -@@ -0,0 +1,7 @@ -+:INPUT,FORWARD,OUTPUT -+-j MARK --set-xmark 0xfeedcafe/0xfeedcafe;=;OK -+-j MARK --set-xmark 0;=;OK -+-j MARK --set-xmark 4294967295;-j MARK --set-xmark 0xffffffff;OK -+-j MARK --set-xmark 4294967296;;FAIL -+-j MARK --set-xmark -1;;FAIL -+-j MARK;;FAIL -diff --git a/extensions/libxt_NFLOG.t b/extensions/libxt_NFLOG.t -new file mode 100644 -index 0000000000000..933fa22160e59 ---- /dev/null -+++ b/extensions/libxt_NFLOG.t -@@ -0,0 +1,24 @@ -+:INPUT,FORWARD,OUTPUT -+-j NFLOG --nflog-group 1;=;OK -+-j NFLOG --nflog-group 65535;=;OK -+-j NFLOG --nflog-group 65536;;FAIL -+-j NFLOG --nflog-group 0;-j NFLOG;OK -+-j NFLOG --nflog-range 1;=;OK -+-j NFLOG --nflog-range 4294967295;=;OK -+-j NFLOG --nflog-range 4294967296;;FAIL -+-j NFLOG --nflog-range -1;;FAIL -+-j NFLOG --nflog-size 0;=;OK -+-j NFLOG --nflog-size 1;=;OK -+-j NFLOG --nflog-size 4294967295;=;OK -+-j NFLOG --nflog-size 4294967296;;FAIL -+-j NFLOG --nflog-size -1;;FAIL -+# ERROR: cannot find: iptables -I INPUT -j NFLOG --nflog-prefix xxxxxx [...] -+# -j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK -+# ERROR: should fail: iptables -A INPUT -j NFLOG --nflog-prefix xxxxxxx [...] -+# -j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;;FAIL -+-j NFLOG --nflog-threshold 1;=;OK -+# ERROR: line 13 (should fail: iptables -A INPUT -j NFLOG --nflog-threshold 0 -+# -j NFLOG --nflog-threshold 0;;FAIL -+-j NFLOG --nflog-threshold 65535;=;OK -+-j NFLOG --nflog-threshold 65536;;FAIL -+-j NFLOG;=;OK -diff --git a/extensions/libxt_NFQUEUE.t b/extensions/libxt_NFQUEUE.t -new file mode 100644 -index 0000000000000..b51b19fd435f7 ---- /dev/null -+++ b/extensions/libxt_NFQUEUE.t -@@ -0,0 +1,16 @@ -+:INPUT,FORWARD,OUTPUT -+-j NFQUEUE;=;OK -+-j NFQUEUE --queue-num 0;=;OK -+-j NFQUEUE --queue-num 65535;=;OK -+-j NFQUEUE --queue-num 65536;;FAIL -+-j NFQUEUE --queue-num -1;;FAIL -+# it says "NFQUEUE: number of total queues is 0", overflow in NFQUEUE_parse_v1? -+# ERROR: cannot load: iptables -A INPUT -j NFQUEUE --queue-balance 0:65535 -+# -j NFQUEUE --queue-balance 0:65535;=;OK -+-j NFQUEUE --queue-balance 0:65536;;FAIL -+-j NFQUEUE --queue-balance -1:65535;;FAIL -+-j NFQUEUE --queue-num 10 --queue-bypass;=;OK -+-j NFQUEUE --queue-balance 0:6 --queue-cpu-fanout --queue-bypass;-j NFQUEUE --queue-balance 0:6 --queue-bypass --queue-cpu-fanout;OK -+-j NFQUEUE --queue-bypass --queue-balance 0:6 --queue-cpu-fanout;-j NFQUEUE --queue-balance 0:6 --queue-bypass --queue-cpu-fanout;OK -+-j NFQUEUE --queue-balance 0:6 --queue-bypass;=;OK -+-j NFQUEUE --queue-bypass;-j NFQUEUE --queue-num 0 --queue-bypass;OK -diff --git a/extensions/libxt_NOTRACK.t b/extensions/libxt_NOTRACK.t -new file mode 100644 -index 0000000000000..585be82d56ecb ---- /dev/null -+++ b/extensions/libxt_NOTRACK.t -@@ -0,0 +1,4 @@ -+:PREROUTING,OUTPUT -+*raw -+# ERROR: cannot find: iptables -I PREROUTING -t raw -j NOTRACK -+#-j NOTRACK;=;OK -diff --git a/extensions/libxt_RATEEST.t b/extensions/libxt_RATEEST.t -new file mode 100644 -index 0000000000000..c2b6bb34e7aa2 ---- /dev/null -+++ b/extensions/libxt_RATEEST.t -@@ -0,0 +1,2 @@ -+:INPUT,FORWARD,OUTPUT -+-j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms;=;OK -diff --git a/extensions/libxt_SET.t b/extensions/libxt_SET.t -new file mode 100644 -index 0000000000000..30c27ca319176 ---- /dev/null -+++ b/extensions/libxt_SET.t -@@ -0,0 +1,3 @@ -+:INPUT,FORWARD,OUTPUT -+# fails: foo does not exist -+-j SET --add-set foo src,dst;;FAIL -diff --git a/extensions/libxt_SYNPROXY.t b/extensions/libxt_SYNPROXY.t -new file mode 100644 -index 0000000000000..dd8b0e769f568 ---- /dev/null -+++ b/extensions/libxt_SYNPROXY.t -@@ -0,0 +1,3 @@ -+:INPUT,FORWARD -+-j SYNPROXY --sack-perm --timestamp --mss 1460 --wscale 9;;FAIL -+-p tcp -m tcp --dport 42 -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 9 --mss 1460;=;OK -diff --git a/extensions/libxt_TCPMSS.t b/extensions/libxt_TCPMSS.t -new file mode 100644 -index 0000000000000..553a3452e4876 ---- /dev/null -+++ b/extensions/libxt_TCPMSS.t -@@ -0,0 +1,6 @@ -+:FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j TCPMSS;;FAIL -+-p tcp -j TCPMSS --set-mss 42;;FAIL -+-p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --set-mss 42;=;OK -+-p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j TCPMSS --clamp-mss-to-pmtu;=;OK -diff --git a/extensions/libxt_TCPOPTSTRIP.t b/extensions/libxt_TCPOPTSTRIP.t -new file mode 100644 -index 0000000000000..b5c7a109e5b91 ---- /dev/null -+++ b/extensions/libxt_TCPOPTSTRIP.t -@@ -0,0 +1,8 @@ -+:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j TCPOPTSTRIP;;FAIL -+-p tcp -j TCPOPTSTRIP;=;OK -+-p tcp -j TCPOPTSTRIP --strip-options 2,3,4,5,6,7;=;OK -+-p tcp -j TCPOPTSTRIP --strip-options 0;;FAIL -+-p tcp -j TCPOPTSTRIP --strip-options 1;;FAIL -+-p tcp -j TCPOPTSTRIP --strip-options 1,2;;FAIL -diff --git a/extensions/libxt_TEE.t b/extensions/libxt_TEE.t -new file mode 100644 -index 0000000000000..ce8b103e0dc24 ---- /dev/null -+++ b/extensions/libxt_TEE.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-j TEE --gateway 1.1.1.1;=;OK -+-j TEE ! --gateway 1.1.1.1;;FAIL -+-j TEE;;FAIL -diff --git a/extensions/libxt_TOS.t b/extensions/libxt_TOS.t -new file mode 100644 -index 0000000000000..ae8531cc582e2 ---- /dev/null -+++ b/extensions/libxt_TOS.t -@@ -0,0 +1,16 @@ -+:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-j TOS --set-tos 0x1f;=;OK -+-j TOS --set-tos 0x1f/0x1f;=;OK -+# maximum TOS is 0x1f (5 bits) -+# ERROR: should fail: iptables -A PREROUTING -t mangle -j TOS --set-tos 0xff -+# -j TOS --set-tos 0xff;;FAIL -+-j TOS --set-tos Minimize-Delay;-j TOS --set-tos 0x10;OK -+-j TOS --set-tos Maximize-Throughput;-j TOS --set-tos 0x08;OK -+-j TOS --set-tos Maximize-Reliability;-j TOS --set-tos 0x04;OK -+-j TOS --set-tos Minimize-Cost;-j TOS --set-tos 0x02;OK -+-j TOS --set-tos Normal-Service;-j TOS --set-tos 0x00;OK -+-j TOS --and-tos 0x12;-j TOS --set-tos 0x00/0xed;OK -+-j TOS --or-tos 0x12;-j TOS --set-tos 0x12/0x12;OK -+-j TOS --xor-tos 0x12;-j TOS --set-tos 0x12/0x00;OK -+-j TOS;;FAIL -diff --git a/extensions/libxt_TPROXY.t b/extensions/libxt_TPROXY.t -new file mode 100644 -index 0000000000000..12f82b1fae76a ---- /dev/null -+++ b/extensions/libxt_TPROXY.t -@@ -0,0 +1,5 @@ -+:PREROUTING -+*mangle -+-j TPROXY --on-port 12345 --on-ip 10.0.0.1 --tproxy-mark 0x23/0xff;;FAIL -+-p udp -j TPROXY --on-port 12345 --on-ip 10.0.0.1 --tproxy-mark 0x23/0xff;=;OK -+-p tcp -m tcp --dport 2342 -j TPROXY --on-port 12345 --on-ip 10.0.0.1 --tproxy-mark 0x23/0xff;=;OK -diff --git a/extensions/libxt_TRACE.t b/extensions/libxt_TRACE.t -new file mode 100644 -index 0000000000000..cadb7330174e5 ---- /dev/null -+++ b/extensions/libxt_TRACE.t -@@ -0,0 +1,3 @@ -+:PREROUTING,OUTPUT -+*raw -+-j TRACE;=;OK -diff --git a/extensions/libxt_addrtype.t b/extensions/libxt_addrtype.t -new file mode 100644 -index 0000000000000..390a63f0fa232 ---- /dev/null -+++ b/extensions/libxt_addrtype.t -@@ -0,0 +1,17 @@ -+:INPUT,FORWARD,OUTPUT -+-m addrtype;;FAIL -+-m addrtype --src-type wrong;;FAIL -+-m addrtype --src-type UNSPEC;=;OK -+-m addrtype --dst-type UNSPEC;=;OK -+-m addrtype --src-type LOCAL --dst-type LOCAL;=;OK -+-m addrtype --dst-type UNSPEC;=;OK -+-m addrtype --limit-iface-in;;FAIL -+-m addrtype --limit-iface-out;;FAIL -+-m addrtype --limit-iface-in --limit-iface-out;;FAIL -+-m addrtype --src-type LOCAL --limit-iface-in --limit-iface-out;;FAIL -+:INPUT -+-m addrtype --src-type LOCAL --limit-iface-in;=;OK -+-m addrtype --dst-type LOCAL --limit-iface-in;=;OK -+:OUTPUT -+-m addrtype --src-type LOCAL --limit-iface-out;=;OK -+-m addrtype --dst-type LOCAL --limit-iface-out;=;OK -diff --git a/extensions/libxt_bpf.t b/extensions/libxt_bpf.t -new file mode 100644 -index 0000000000000..80361ad52e713 ---- /dev/null -+++ b/extensions/libxt_bpf.t -@@ -0,0 +1,2 @@ -+:INPUT,FORWARD,OUTPUT -+-m bpf --bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0";=;OK -diff --git a/extensions/libxt_cgroup.t b/extensions/libxt_cgroup.t -new file mode 100644 -index 0000000000000..72c8e37708e95 ---- /dev/null -+++ b/extensions/libxt_cgroup.t -@@ -0,0 +1,8 @@ -+:INPUT,OUTPUT,POSTROUTING -+*mangle -+-m cgroup --cgroup 1;=;OK -+-m cgroup ! --cgroup 1;=;OK -+-m cgroup --path "/";=;OK -+-m cgroup ! --path "/";=;OK -+-m cgroup --cgroup 1 --path "/";;FAIL -+-m cgroup ;;FAIL -diff --git a/extensions/libxt_cluster.t b/extensions/libxt_cluster.t -new file mode 100644 -index 0000000000000..ac608244833f2 ---- /dev/null -+++ b/extensions/libxt_cluster.t -@@ -0,0 +1,10 @@ -+:PREROUTING,FORWARD,POSTROUTING -+*mangle -+-m cluster;;FAIL -+-m cluster --cluster-total-nodes 3;;FAIL -+-m cluster --cluster-total-nodes 2 --cluster-local-node 2;;FAIL -+-m cluster --cluster-total-nodes 2 --cluster-local-node 3 --cluster-hash-seed;;FAIL -+# -+# outputs --cluster-local-nodemask instead of --cluster-local-node -+# -+-m cluster --cluster-total-nodes 2 --cluster-local-node 2 --cluster-hash-seed 0xfeedcafe;-m cluster --cluster-local-nodemask 0x00000002 --cluster-total-nodes 2 --cluster-hash-seed 0xfeedcafe;OK -diff --git a/extensions/libxt_comment.t b/extensions/libxt_comment.t -new file mode 100644 -index 0000000000000..f12cd66841e7f ---- /dev/null -+++ b/extensions/libxt_comment.t -@@ -0,0 +1,12 @@ -+:INPUT,FORWARD,OUTPUT -+-m comment;;FAIL -+-m comment --comment;;FAIL -+# -+# it fails with 256 characters -+# -+# should fail: iptables -A INPUT -m comment --comment xxxxxxxxxxxxxxxxx [....] -+# -m comment --comment xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;;FAIL -+# -+# success with 255 characters -+# -+-m comment --comment xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK -diff --git a/extensions/libxt_connbytes.t b/extensions/libxt_connbytes.t -new file mode 100644 -index 0000000000000..6b24e266c1a04 ---- /dev/null -+++ b/extensions/libxt_connbytes.t -@@ -0,0 +1,21 @@ -+:INPUT,FORWARD,OUTPUT -+-m connbytes --connbytes 0:1000 --connbytes-mode packets --connbytes-dir original;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode packets --connbytes-dir reply;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode packets --connbytes-dir both;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode bytes --connbytes-dir original;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode bytes --connbytes-dir reply;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode bytes --connbytes-dir both;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode avgpkt --connbytes-dir original;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode avgpkt --connbytes-dir reply;=;OK -+-m connbytes --connbytes 0:1000 --connbytes-mode avgpkt --connbytes-dir both;=;OK -+-m connbytes --connbytes -1:0 --connbytes-mode packets --connbytes-dir original;;FAIL -+-m connbytes --connbytes 0:-1 --connbytes-mode packets --connbytes-dir original;;FAIL -+# ERROR: cannot find: iptables -I INPUT -m connbytes --connbytes 0:18446744073709551615 --connbytes-mode avgpkt --connbytes-dir both -+# -m connbytes --connbytes 0:18446744073709551615 --connbytes-mode avgpkt --connbytes-dir both;=;OK -+-m connbytes --connbytes 0:18446744073709551616 --connbytes-mode avgpkt --connbytes-dir both;;FAIL -+-m connbytes --connbytes 0:1000 --connbytes-mode wrong --connbytes-dir both;;FAIL -+-m connbytes --connbytes 0:1000 --connbytes-dir original;;FAIL -+-m connbytes --connbytes 0:1000 --connbytes-mode packets;;FAIL -+-m connbytes --connbytes-dir original;;FAIL -+-m connbytes --connbytes 0:1000;;FAIL -+-m connbytes;;FAIL -diff --git a/extensions/libxt_connlabel.t b/extensions/libxt_connlabel.t -new file mode 100644 -index 0000000000000..aad1032b5a8bb ---- /dev/null -+++ b/extensions/libxt_connlabel.t -@@ -0,0 +1,18 @@ -+:INPUT,FORWARD,OUTPUT -+# Backup the connlabel.conf, then add some label maps for test -+@[ -f /etc/xtables/connlabel.conf ] && mv /etc/xtables/connlabel.conf /tmp/connlabel.conf.bak -+@mkdir -p /etc/xtables -+@echo "40 bit40" > /etc/xtables/connlabel.conf -+@echo "41 bit41" >> /etc/xtables/connlabel.conf -+@echo "128 bit128" >> /etc/xtables/connlabel.conf -+-m connlabel --label "bit40";=;OK -+-m connlabel ! --label "bit40";=;OK -+-m connlabel --label "bit41" --set;=;OK -+-m connlabel ! --label "bit41" --set;=;OK -+-m connlabel --label "bit128";;FAIL -+@echo > /etc/xtables/connlabel.conf -+-m connlabel --label "abc";;FAIL -+@rm -f /etc/xtables/connlabel.conf -+-m connlabel --label "abc";;FAIL -+# Restore the original connlabel.conf -+@[ -f /tmp/connlabel.conf.bak ] && mv /tmp/connlabel.conf.bak /etc/xtables/connlabel.conf -diff --git a/extensions/libxt_connlimit.t b/extensions/libxt_connlimit.t -new file mode 100644 -index 0000000000000..c7ea61e95fbc8 ---- /dev/null -+++ b/extensions/libxt_connlimit.t -@@ -0,0 +1,16 @@ -+:INPUT,FORWARD,OUTPUT -+-m connlimit --connlimit-upto 0;=;OK -+-m connlimit --connlimit-upto 4294967295;=;OK -+-m connlimit --connlimit-upto 4294967296;;FAIL -+-m connlimit --connlimit-upto -1;;FAIL -+-m connlimit --connlimit-above 0;=;OK -+-m connlimit --connlimit-above 4294967295;=;OK -+-m connlimit --connlimit-above 4294967296;;FAIL -+-m connlimit --connlimit-above -1;;FAIL -+-m connlimit --connlimit-upto 1 --conlimit-above 1;;FAIL -+-m connlimit --connlimit-above 10 --connlimit-saddr;-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-saddr;OK -+-m connlimit --connlimit-above 10 --connlimit-daddr;-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-daddr;OK -+-m connlimit --connlimit-above 10 --connlimit-saddr --connlimit-daddr;;FAIL -+-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-saddr;=;OK -+-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-daddr;=;OK -+-m connlimit;;FAIL -diff --git a/extensions/libxt_connmark.t b/extensions/libxt_connmark.t -new file mode 100644 -index 0000000000000..4dd7d9af265a5 ---- /dev/null -+++ b/extensions/libxt_connmark.t -@@ -0,0 +1,9 @@ -+:PREROUTING,FORWARD,OUTPUT,POSTROUTING -+*mangle -+-m connmark --mark 0xffffffff;=;OK -+-m connmark --mark 0xffffffff/0xffffffff;-m connmark --mark 0xffffffff;OK -+-m connmark --mark 0xffffffff/0;=;OK -+-m connmark --mark 0/0xffffffff;-m connmark --mark 0;OK -+-m connmark --mark -1;;FAIL -+-m connmark --mark 0xfffffffff;;FAIL -+-m connmark;;FAIL -diff --git a/extensions/libxt_conntrack.t b/extensions/libxt_conntrack.t -new file mode 100644 -index 0000000000000..db53147532afd ---- /dev/null -+++ b/extensions/libxt_conntrack.t -@@ -0,0 +1,27 @@ -+:INPUT,FORWARD,OUTPUT -+-m conntrack --ctstate NEW;=;OK -+-m conntrack --ctstate NEW,ESTABLISHED;=;OK -+-m conntrack --ctstate NEW,RELATED,ESTABLISHED;=;OK -+-m conntrack --ctstate INVALID;=;OK -+-m conntrack --ctstate UNTRACKED;=;OK -+-m conntrack --ctstate SNAT,DNAT;=;OK -+-m conntrack --ctstate wrong;;FAIL -+# should we convert this to output "tcp" instead of 6? -+-m conntrack --ctproto tcp;-m conntrack --ctproto 6;OK -+-m conntrack --ctorigsrc 1.1.1.1;=;OK -+-m conntrack --ctorigdst 1.1.1.1;=;OK -+-m conntrack --ctreplsrc 1.1.1.1;=;OK -+-m conntrack --ctrepldst 1.1.1.1;=;OK -+-m conntrack --ctexpire 0;=;OK -+-m conntrack --ctexpire 4294967295;=;OK -+-m conntrack --ctexpire 0:4294967295;=;OK -+-m conntrack --ctexpire 42949672956;;FAIL -+-m conntrack --ctexpire -1;;FAIL -+-m conntrack --ctdir ORIGINAL;=;OK -+-m conntrack --ctdir REPLY;=;OK -+-m conntrack --ctstatus NONE;=;OK -+-m conntrack --ctstatus CONFIRMED;=;OK -+-m conntrack --ctstatus ASSURED;=;OK -+-m conntrack --ctstatus EXPECTED;=;OK -+-m conntrack --ctstatus SEEN_REPLY;=;OK -+-m conntrack;;FAIL -diff --git a/extensions/libxt_cpu.t b/extensions/libxt_cpu.t -new file mode 100644 -index 0000000000000..f5adb45db7424 ---- /dev/null -+++ b/extensions/libxt_cpu.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m cpu --cpu 0;=;OK -+-m cpu ! --cpu 0;=;OK -+-m cpu --cpu 4294967295;=;OK -+-m cpu --cpu 4294967296;;FAIL -+-m cpu;;FAIL -diff --git a/extensions/libxt_dccp.t b/extensions/libxt_dccp.t -new file mode 100644 -index 0000000000000..f60b480fb6fc7 ---- /dev/null -+++ b/extensions/libxt_dccp.t -@@ -0,0 +1,30 @@ -+:INPUT,FORWARD,OUTPUT -+-p dccp -m dccp --sport 1;=;OK -+-p dccp -m dccp --sport 65535;=;OK -+-p dccp -m dccp --dport 1;=;OK -+-p dccp -m dccp --dport 65535;=;OK -+-p dccp -m dccp --sport 1:1023;=;OK -+-p dccp -m dccp --sport 1024:65535;=;OK -+-p dccp -m dccp --sport 1024:;-p dccp -m dccp --sport 1024:65535;OK -+-p dccp -m dccp ! --sport 1;=;OK -+-p dccp -m dccp ! --sport 65535;=;OK -+-p dccp -m dccp ! --dport 1;=;OK -+-p dccp -m dccp ! --dport 65535;=;OK -+-p dccp -m dccp --sport 1 --dport 65535;=;OK -+-p dccp -m dccp --sport 65535 --dport 1;=;OK -+-p dccp -m dccp ! --sport 1 --dport 65535;=;OK -+-p dccp -m dccp ! --sport 65535 --dport 1;=;OK -+# ERROR: should fail: iptables -A INPUT -p dccp -m dccp --sport 65536 -+# -p dccp -m dccp --sport 65536;;FAIL -+-p dccp -m dccp --sport -1;;FAIL -+-p dccp -m dccp --dport -1;;FAIL -+-p dccp -m dccp --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,RESET,SYNC,SYNCACK,INVALID;=;OK -+-p dccp -m dccp ! --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,RESET,SYNC,SYNCACK,INVALID;=;OK -+# DCCP option 0 is valid, see http://tools.ietf.org/html/rfc4340#page-29 -+# ERROR: cannot load: iptables -A INPUT -p dccp -m dccp --dccp-option 0 -+#-p dccp -m dccp --dccp-option 0;=;OK -+-p dccp -m dccp --dccp-option 255;=;OK -+-p dccp -m dccp --dccp-option 256;;FAIL -+-p dccp -m dccp --dccp-option -1;;FAIL -+# should we accept this below? -+-p dccp -m dccp;=;OK -diff --git a/extensions/libxt_dscp.t b/extensions/libxt_dscp.t -new file mode 100644 -index 0000000000000..38d7f04e18698 ---- /dev/null -+++ b/extensions/libxt_dscp.t -@@ -0,0 +1,10 @@ -+:INPUT,FORWARD,OUTPUT -+-m dscp --dscp 0;=;OK -+-m dscp --dscp 0x3f;=;OK -+-m dscp --dscp -1;;FAIL -+-m dscp --dscp 0x40;;FAIL -+-m dscp --dscp 0x3f --dscp-class CS0;;FAIL -+-m dscp --dscp-class CS0;-m dscp --dscp 0x00;OK -+-m dscp --dscp-class BE;-m dscp --dscp 0x00;OK -+-m dscp --dscp-class EF;-m dscp --dscp 0x2e;OK -+-m dscp;;FAIL -diff --git a/extensions/libxt_ecn.t b/extensions/libxt_ecn.t -new file mode 100644 -index 0000000000000..b32aea306dcae ---- /dev/null -+++ b/extensions/libxt_ecn.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD,OUTPUT -+-m ecn --ecn-tcp-cwr;;FAIL -+-p tcp -m ecn --ecn-tcp-cwr;=;OK -+-p tcp -m ecn --ecn-tcp-ece --ecn-tcp-cwr --ecn-ip-ect 2;=;OK -+-p tcp -m ecn ! --ecn-tcp-ece ! --ecn-tcp-cwr ! --ecn-ip-ect 2;=;OK -diff --git a/extensions/libxt_esp.t b/extensions/libxt_esp.t -new file mode 100644 -index 0000000000000..92c5779f860f1 ---- /dev/null -+++ b/extensions/libxt_esp.t -@@ -0,0 +1,8 @@ -+:INPUT,FORWARD,OUTPUT -+-p esp -m esp --espspi 0;=;OK -+-p esp -m esp --espspi :32;-p esp -m esp --espspi 0:32;OK -+-p esp -m esp --espspi 0:4294967295;-p esp -m esp;OK -+-p esp -m esp ! --espspi 0:4294967294;=;OK -+-p esp -m esp --espspi -1;;FAIL -+-p esp -m esp;=;OK -+-m esp;;FAIL -diff --git a/extensions/libxt_hashlimit.t b/extensions/libxt_hashlimit.t -new file mode 100644 -index 0000000000000..ccd0d1e6a2a1a ---- /dev/null -+++ b/extensions/libxt_hashlimit.t -@@ -0,0 +1,33 @@ -+:INPUT,FORWARD,OUTPUT -+-m hashlimit --hashlimit-above 1/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-above 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-above 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+# kernel says "xt_hashlimit: overflow, try lower: 864000000/5" -+-m hashlimit --hashlimit-above 1/day --hashlimit-burst 5 --hashlimit-name mini1;;FAIL -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-upto 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-upto 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-upto 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+# kernel says "xt_hashlimit: overflow, try lower: 864000000/5" -+-m hashlimit --hashlimit-upto 1/day --hashlimit-burst 5 --hashlimit-name mini1;;FAIL -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name mini1 --hashlimit-htable-max 2000 --hashlimit-htable-expire 2000;=;OK -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name mini1 --hashlimit-htable-max 2000 --hashlimit-htable-gcinterval 60000 --hashlimit-htable-expire 2000;=;OK -+-m hashlimit --hashlimit-upto 1/sec --hashlimit-name mini1;-m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 5 --hashlimit-name mini1;OK -+-m hashlimit --hashlimit-upto 4kb/s --hashlimit-burst 400kb --hashlimit-name mini5;=;OK -+-m hashlimit --hashlimit-upto 10mb/s --hashlimit-name mini6;=;OK -+-m hashlimit --hashlimit-upto 123456b/s --hashlimit-burst 1mb --hashlimit-name mini7;=;OK -+# should work, it says "iptables v1.4.15: burst cannot be smaller than 96b" -+# ERROR: cannot load: iptables -A INPUT -m hashlimit --hashlimit-upto 96b/s --hashlimit-burst 5 --hashlimit-name mini1 -+# -m hashlimit --hashlimit-upto 96b/s --hashlimit-burst 5 --hashlimit-name mini1;=;OK -+-m hashlimit --hashlimit-name mini1;;FAIL -+-m hashlimit --hashlimit-upto 1/sec;;FAIL -+-m hashlimit;;FAIL -+-m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name syn-flood;=;OK -+-m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name rate1 --hashlimit-rate-match;=;OK -+-m hashlimit --hashlimit-upto 40mb/s --hashlimit-mode srcip --hashlimit-name rate2 --hashlimit-rate-match;=;OK -+-m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name rate3 --hashlimit-rate-match --hashlimit-rate-interval 10;=;OK -+-m hashlimit --hashlimit-upto 40mb/s --hashlimit-mode srcip --hashlimit-name rate4 --hashlimit-rate-match --hashlimit-rate-interval 10;=;OK -diff --git a/extensions/libxt_helper.t b/extensions/libxt_helper.t -new file mode 100644 -index 0000000000000..8c8420ac5693a ---- /dev/null -+++ b/extensions/libxt_helper.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m helper --helper ftp;=;OK -+# should be OK? -+# ERROR: should fail: iptables -A INPUT -m helper --helper wrong -+# -m helper --helper wrong;;FAIL -+-m helper;;FAIL -diff --git a/extensions/libxt_ipcomp.t b/extensions/libxt_ipcomp.t -new file mode 100644 -index 0000000000000..8546ba9ce416f ---- /dev/null -+++ b/extensions/libxt_ipcomp.t -@@ -0,0 +1,3 @@ -+:INPUT,OUTPUT -+-p ipcomp -m ipcomp --ipcompspi 18 -j DROP;=;OK -+-p ipcomp -m ipcomp ! --ipcompspi 18 -j ACCEPT;=;OK -diff --git a/extensions/libxt_iprange.t b/extensions/libxt_iprange.t -new file mode 100644 -index 0000000000000..6fd98be656028 ---- /dev/null -+++ b/extensions/libxt_iprange.t -@@ -0,0 +1,11 @@ -+:INPUT,FORWARD,OUTPUT -+-m iprange --src-range 1.1.1.1-1.1.1.10;=;OK -+-m iprange ! --src-range 1.1.1.1-1.1.1.10;=;OK -+-m iprange --dst-range 1.1.1.1-1.1.1.10;=;OK -+-m iprange ! --dst-range 1.1.1.1-1.1.1.10;=;OK -+# it shows -A INPUT -m iprange --src-range 1.1.1.1-1.1.1.1, should we support this? -+# ERROR: should fail: iptables -A INPUT -m iprange --src-range 1.1.1.1 -+# -m iprange --src-range 1.1.1.1;;FAIL -+# ERROR: should fail: iptables -A INPUT -m iprange --dst-range 1.1.1.1 -+#-m iprange --dst-range 1.1.1.1;;FAIL -+-m iprange;;FAIL -diff --git a/extensions/libxt_length.t b/extensions/libxt_length.t -new file mode 100644 -index 0000000000000..0b6624ee069f6 ---- /dev/null -+++ b/extensions/libxt_length.t -@@ -0,0 +1,10 @@ -+:INPUT,FORWARD,OUTPUT -+-m length --length 1;=;OK -+-m length --length :2;-m length --length 0:2;OK -+-m length --length 0:3;=;OK -+-m length --length 4:;=;OK -+-m length --length 0:65535;=;OK -+-m length ! --length 0:65535;=;OK -+-m length --length 0:65536;;FAIL -+-m length --length -1:65535;;FAIL -+-m length;;FAIL -diff --git a/extensions/libxt_limit.t b/extensions/libxt_limit.t -new file mode 100644 -index 0000000000000..b0af6538a9c05 ---- /dev/null -+++ b/extensions/libxt_limit.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m limit --limit 1/sec;=;OK -+-m limit --limit 1/min;=;OK -+-m limit --limit 1000/hour;=;OK -+-m limit --limit 1000/day;=;OK -+-m limit --limit 1/sec --limit-burst 1;=;OK -diff --git a/extensions/libxt_mac.t b/extensions/libxt_mac.t -new file mode 100644 -index 0000000000000..a5ec81d80e23d ---- /dev/null -+++ b/extensions/libxt_mac.t -@@ -0,0 +1,5 @@ -+:INPUT,FORWARD -+-m mac --mac-source 42:01:02:03:04:05;=;OK -+-m mac --mac-source 42:01:02:03:04;=;FAIL -+-m mac --mac-source 42:01:02:03:04:05:06;=;FAIL -+-m mac;;FAIL -diff --git a/extensions/libxt_mark.t b/extensions/libxt_mark.t -new file mode 100644 -index 0000000000000..7c005379f6d64 ---- /dev/null -+++ b/extensions/libxt_mark.t -@@ -0,0 +1,7 @@ -+:INPUT,FORWARD,OUTPUT -+-m mark --mark 0xfeedcafe/0xfeedcafe;=;OK -+-m mark --mark 0;=;OK -+-m mark --mark 4294967295;-m mark --mark 0xffffffff;OK -+-m mark --mark 4294967296;;FAIL -+-m mark --mark -1;;FAIL -+-m mark;;FAIL -diff --git a/extensions/libxt_multiport.t b/extensions/libxt_multiport.t -new file mode 100644 -index 0000000000000..e9b80a4ee376b ---- /dev/null -+++ b/extensions/libxt_multiport.t -@@ -0,0 +1,23 @@ -+:INPUT,FORWARD,OUTPUT -+-p tcp -m multiport --sports 53,1024:65535;=;OK -+-p tcp -m multiport --dports 53,1024:65535;=;OK -+-p udp -m multiport --sports 53,1024:65535;=;OK -+-p udp -m multiport --dports 53,1024:65535;=;OK -+-p udp -m multiport --ports 53,1024:65535;=;OK -+-p udp -m multiport --ports 53,1024:65535;=;OK -+-p sctp -m multiport --sports 53,1024:65535;=;OK -+-p sctp -m multiport --dports 53,1024:65535;=;OK -+-p dccp -m multiport --sports 53,1024:65535;=;OK -+-p dccp -m multiport --dports 53,1024:65535;=;OK -+-p udplite -m multiport --sports 53,1024:65535;=;OK -+-p udplite -m multiport --dports 53,1024:65535;=;OK -+-p tcp -m multiport --sports 1024:65536;;FAIL -+-p udp -m multiport --sports 1024:65536;;FAIL -+-p tcp -m multiport --ports 1024:65536;;FAIL -+-p udp -m multiport --ports 1024:65536;;FAIL -+-p tcp -m multiport --ports 1,2,3,4,6,7,8,9,10,11,12,13,14,15;=;OK -+# fix manpage, it says "up to 15 ports supported" -+# ERROR: should fail: iptables -A INPUT -p tcp -m multiport --ports 1,2,3,4,6,7,8,9,10,11,12,13,14,15,16 -+# -p tcp -m multiport --ports 1,2,3,4,6,7,8,9,10,11,12,13,14,15,16;;FAIL -+-p tcp --multiport;;FAIL -+-m multiport;;FAIL -diff --git a/extensions/libxt_nfacct.t b/extensions/libxt_nfacct.t -new file mode 100644 -index 0000000000000..3419b4cebfebf ---- /dev/null -+++ b/extensions/libxt_nfacct.t -@@ -0,0 +1,10 @@ -+:INPUT,FORWARD,OUTPUT -+@nfacct add test -+# -+# extra space in iptables-save output, fix it -+# -+# ERROR: cannot load: iptables -A INPUT -m nfacct --nfacct-name test -+#-m nfacct --nfacct-name test;=;OK -+-m nfacct --nfacct-name wrong;;FAIL -+-m nfacct;;FAIL -+@nfacct del test -diff --git a/extensions/libxt_osf.t b/extensions/libxt_osf.t -new file mode 100644 -index 0000000000000..ede6d32c7cc4c ---- /dev/null -+++ b/extensions/libxt_osf.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD -+-m osf --genre linux --ttl 0 --log 0;;FAIL -+-p tcp -m osf --genre linux --ttl 0 --log 0;=;OK -+-p tcp -m osf --genre linux --ttl 3 --log 0;;FAIL -diff --git a/extensions/libxt_owner.t b/extensions/libxt_owner.t -new file mode 100644 -index 0000000000000..aec30b655e9a5 ---- /dev/null -+++ b/extensions/libxt_owner.t -@@ -0,0 +1,12 @@ -+:OUTPUT,POSTROUTING -+*mangle -+-m owner --uid-owner root;-m owner --uid-owner 0;OK -+-m owner --uid-owner 0-10;=;OK -+-m owner --gid-owner root;-m owner --gid-owner 0;OK -+-m owner --gid-owner 0-10;=;OK -+-m owner --uid-owner root --gid-owner root;-m owner --uid-owner 0 --gid-owner 0;OK -+-m owner --uid-owner 0-10 --gid-owner 0-10;=;OK -+-m owner ! --uid-owner root;-m owner ! --uid-owner 0;OK -+-m owner --socket-exists;=;OK -+:INPUT -+-m owner --uid-owner root;;FAIL -diff --git a/extensions/libxt_physdev.t b/extensions/libxt_physdev.t -new file mode 100644 -index 0000000000000..1fab7e1920d25 ---- /dev/null -+++ b/extensions/libxt_physdev.t -@@ -0,0 +1,14 @@ -+:INPUT,FORWARD -+-m physdev --physdev-in lo;=;OK -+-m physdev --physdev-is-in --physdev-in lo;=;OK -+:OUTPUT,FORWARD -+# xt_physdev: using --physdev-out in the OUTPUT, FORWARD and POSTROUTING chains for non-bridged traffic is not supported anymore. -+# ERROR: should fail: iptables -A FORWARD -m physdev --physdev-out lo -+#-m physdev --physdev-out lo;;FAIL -+# ERROR: cannot load: iptables -A OUTPUT -m physdev --physdev-is-out --physdev-out lo -+#-m physdev --physdev-is-out --physdev-out lo;=;OK -+:FORWARD -+-m physdev --physdev-in lo --physdev-is-bridged;=;OK -+:POSTROUTING -+*mangle -+-m physdev --physdev-out lo --physdev-is-bridged;=;OK -diff --git a/extensions/libxt_pkttype.t b/extensions/libxt_pkttype.t -new file mode 100644 -index 0000000000000..d93baeaf24ec3 ---- /dev/null -+++ b/extensions/libxt_pkttype.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m pkttype --pkt-type unicast;=;OK -+-m pkttype --pkt-type broadcast;=;OK -+-m pkttype --pkt-type multicast;=;OK -+-m pkttype --pkt-type wrong;;FAIL -+-m pkttype;;FAIL -diff --git a/extensions/libxt_policy.t b/extensions/libxt_policy.t -new file mode 100644 -index 0000000000000..6524122bcf793 ---- /dev/null -+++ b/extensions/libxt_policy.t -@@ -0,0 +1,8 @@ -+:INPUT,FORWARD -+-m policy --dir in --pol ipsec;=;OK -+-m policy --dir in --pol ipsec --proto ipcomp;=;OK -+-m policy --dir in --pol ipsec --strict;;FAIL -+-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto ipcomp;=;OK -+-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto esp --mode tunnel --tunnel-dst 10.0.0.0/8 --tunnel-src 10.0.0.0/8 --next --reqid 2;=;OK -+-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto esp --tunnel-dst 10.0.0.0/8;;FAIL -+-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto ipcomp --mode tunnel --tunnel-dst 10.0.0.0/8 --tunnel-src 10.0.0.0/8 --next --reqid 2;=;OK -diff --git a/extensions/libxt_quota.t b/extensions/libxt_quota.t -new file mode 100644 -index 0000000000000..c568427974f84 ---- /dev/null -+++ b/extensions/libxt_quota.t -@@ -0,0 +1,7 @@ -+:INPUT,FORWARD,OUTPUT -+-m quota --quota 0;=;OK -+-m quota ! --quota 0;=;OK -+-m quota --quota 18446744073709551615;=;OK -+-m quota ! --quota 18446744073709551615;=;OK -+-m quota --quota 18446744073709551616;;FAIL -+-m quota;;FAIL -diff --git a/extensions/libxt_rateest.t b/extensions/libxt_rateest.t -new file mode 100644 -index 0000000000000..c5158614f46a3 ---- /dev/null -+++ b/extensions/libxt_rateest.t -@@ -0,0 +1,16 @@ -+:INPUT,FORWARD,OUTPUT -+%iptables -I INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms -+-m rateest --rateest RE1 --rateest-lt --rateest-bps 8bit;=;OK -+-m rateest --rateest RE1 --rateest-eq --rateest-pps 5;=;OK -+-m rateest --rateest RE1 --rateest-gt --rateest-bps 5kbit;-m rateest --rateest RE1 --rateest-gt --rateest-bps 5000bit;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-bps1 8bit --rateest-lt --rateest-bps2 16bit;=;OK -+%iptables -I INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms -+-m rateest --rateest1 RE1 --rateest-lt --rateest-bps --rateest2 RE2;=;OK -+-m rateest --rateest-delta --rateest1 RE1 --rateest-pps1 0 --rateest-lt --rateest-pps2 42 --rateest2 RE2;=;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-bps1 8bit --rateest-eq --rateest-bps2 16bit;=;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-bps1 8bit --rateest-gt --rateest-bps2 16bit;=;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-lt --rateest-pps2 9;=;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-eq --rateest-pps2 9;=;OK -+-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-gt --rateest-pps2 9;=;OK -+%iptables -D INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms -+%iptables -D INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms -diff --git a/extensions/libxt_recent.t b/extensions/libxt_recent.t -new file mode 100644 -index 0000000000000..9a83918ea5835 ---- /dev/null -+++ b/extensions/libxt_recent.t -@@ -0,0 +1,11 @@ -+:INPUT,FORWARD,OUTPUT -+-m recent --set;=;OK -+-m recent --rcheck --hitcount 8 --name foo --mask 255.255.255.255 --rsource;=;OK -+-m recent --rcheck --hitcount 12 --name foo --mask 255.255.255.255 --rsource;=;OK -+-m recent --update --rttl;=;OK -+-m recent --set --rttl;;FAIL -+-m recent --rcheck --hitcount 999 --name foo --mask 255.255.255.255 --rsource;;FAIL -+# nonsensical, but all should load successfully: -+-m recent --rcheck --hitcount 3 --name foo --mask 255.255.255.255 --rsource -m recent --rcheck --hitcount 4 --name foo --mask 255.255.255.255 --rsource;=;OK -+-m recent --rcheck --hitcount 4 --name foo --mask 255.255.255.255 --rsource -m recent --rcheck --hitcount 4 --name foo --mask 255.255.255.255 --rsource;=;OK -+-m recent --rcheck --hitcount 8 --name foo --mask 255.255.255.255 --rsource -m recent --rcheck --hitcount 12 --name foo --mask 255.255.255.255 --rsource;=;OK -diff --git a/extensions/libxt_rpfilter.t b/extensions/libxt_rpfilter.t -new file mode 100644 -index 0000000000000..390268f35bce0 ---- /dev/null -+++ b/extensions/libxt_rpfilter.t -@@ -0,0 +1,4 @@ -+:PREROUTING -+*mangle -+-m rpfilter;=;OK -+-m rpfilter --loose --validmark --accept-local --invert;=;OK -diff --git a/extensions/libxt_sctp.t b/extensions/libxt_sctp.t -new file mode 100644 -index 0000000000000..4016e4fb1880e ---- /dev/null -+++ b/extensions/libxt_sctp.t -@@ -0,0 +1,29 @@ -+:INPUT,FORWARD,OUTPUT -+-p sctp -m sctp --sport 1;=;OK -+-p sctp -m sctp --sport 65535;=;OK -+-p sctp -m sctp --sport 1:65535;=;OK -+-p sctp -m sctp --sport -1;;FAIL -+-p sctp -m sctp --sport 65536;;FAIL -+-p sctp -m sctp --dport 1;=;OK -+-p sctp -m sctp --dport 1:65535;=;OK -+-p sctp -m sctp --dport 65535;=;OK -+-p sctp -m sctp --dport -1;;FAIL -+-p sctp -m sctp --dport 65536;;FAIL -+-p sctp -m sctp --chunk-types all DATA;=;OK -+-p sctp -m sctp --chunk-types all INIT;=;OK -+-p sctp -m sctp --chunk-types all INIT_ACK;=;OK -+-p sctp -m sctp --chunk-types all SACK;=;OK -+-p sctp -m sctp --chunk-types all HEARTBEAT;=;OK -+-p sctp -m sctp --chunk-types all HEARTBEAT_ACK;=;OK -+-p sctp -m sctp --chunk-types all ABORT;=;OK -+-p sctp -m sctp --chunk-types all SHUTDOWN;=;OK -+-p sctp -m sctp --chunk-types all SHUTDOWN_ACK;=;OK -+-p sctp -m sctp --chunk-types all ERROR;=;OK -+-p sctp -m sctp --chunk-types all COOKIE_ECHO;=;OK -+-p sctp -m sctp --chunk-types all COOKIE_ACK;=;OK -+-p sctp -m sctp --chunk-types all ECN_ECNE;=;OK -+-p sctp -m sctp --chunk-types all ECN_CWR;=;OK -+-p sctp -m sctp --chunk-types all ASCONF;=;OK -+-p sctp -m sctp --chunk-types all ASCONF_ACK;=;OK -+-p sctp -m sctp --chunk-types all FORWARD_TSN;=;OK -+-p sctp -m sctp --chunk-types all SHUTDOWN_COMPLETE;=;OK -diff --git a/extensions/libxt_set.t b/extensions/libxt_set.t -new file mode 100644 -index 0000000000000..dd9e9f175b5f8 ---- /dev/null -+++ b/extensions/libxt_set.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-m set --match-set foo;;FAIL -+# fails: foo does not exist -+-m set --match-set foo src,dst;;FAIL -diff --git a/extensions/libxt_socket.t b/extensions/libxt_socket.t -new file mode 100644 -index 0000000000000..fe4eb3e4ba2d2 ---- /dev/null -+++ b/extensions/libxt_socket.t -@@ -0,0 +1,8 @@ -+:PREROUTING,INPUT -+*mangle -+-m socket;=;OK -+-m socket --transparent --nowildcard;=;OK -+-m socket --transparent --nowildcard --restore-skmark;=;OK -+-m socket --transparent --restore-skmark;=;OK -+-m socket --nowildcard --restore-skmark;=;OK -+-m socket --restore-skmark;=;OK -diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t -new file mode 100644 -index 0000000000000..4313f7b7bac9d ---- /dev/null -+++ b/extensions/libxt_standard.t -@@ -0,0 +1,11 @@ -+:INPUT,FORWARD,OUTPUT -+-s 127.0.0.1/32 -d 0.0.0.0/8 -j DROP;=;OK -+! -s 0.0.0.0 -j ACCEPT;! -s 0.0.0.0/32 -j ACCEPT;OK -+! -d 0.0.0.0/32 -j ACCEPT;=;OK -+-s 0.0.0.0/24 -j RETURN;=;OK -+-p tcp -j ACCEPT;=;OK -+! -p udp -j ACCEPT;=;OK -+-j DROP;=;OK -+-j ACCEPT;=;OK -+-j RETURN;=;OK -+! -p 0 -j ACCEPT;=;FAIL -diff --git a/extensions/libxt_state.t b/extensions/libxt_state.t -new file mode 100644 -index 0000000000000..8e4bce3f96e34 ---- /dev/null -+++ b/extensions/libxt_state.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m state --state INVALID;=;OK -+-m state --state NEW,RELATED;=;OK -+-m state --state UNTRACKED;=;OK -+-m state wrong;;FAIL -+-m state;;FAIL -diff --git a/extensions/libxt_statistic.t b/extensions/libxt_statistic.t -new file mode 100644 -index 0000000000000..bb6673dae5e4a ---- /dev/null -+++ b/extensions/libxt_statistic.t -@@ -0,0 +1,8 @@ -+:INPUT,FORWARD,OUTPUT -+-m statistic;;FAIL -+-m statistic --mode random ! --probability 0.50000000000;=;OK -+-m statistic --mode random ! --probability 1.1;;FAIL -+-m statistic --probability 1;;FAIL -+-m statistic --mode nth ! --every 5 --packet 2;=;OK -+-m statistic --mode nth ! --every 5;;FAIL -+-m statistic --mode nth ! --every 5 --packet 5;;FAIL -diff --git a/extensions/libxt_string.t b/extensions/libxt_string.t -new file mode 100644 -index 0000000000000..d68f099d966c6 ---- /dev/null -+++ b/extensions/libxt_string.t -@@ -0,0 +1,18 @@ -+:INPUT,FORWARD,OUTPUT -+# ERROR: cannot find: iptables -I INPUT -m string --algo bm --string "test" -+# -m string --algo bm --string "test";=;OK -+# ERROR: cannot find: iptables -I INPUT -m string --algo kmp --string "test") -+# -m string --algo kmp --string "test";=;OK -+# ERROR: cannot find: iptables -I INPUT -m string --algo kmp ! --string "test" -+# -m string --algo kmp ! --string "test";=;OK -+# cannot find: iptables -I INPUT -m string --algo bm --string "xxxxxxxxxxx" ....] -+# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK -+# ERROR: cannot load: iptables -A INPUT -m string --algo bm --string "xxxx" -+# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK -+# ERROR: cannot load: iptables -A INPUT -m string --algo bm --hexstring "|0a0a0a0a|" -+# -m string --algo bm --hexstring "|0a0a0a0a|";=;OK -+# ERROR: cannot find: iptables -I INPUT -m string --algo bm --from 0 --to 65535 --string "test" -+# -m string --algo bm --from 0 --to 65535 --string "test";=;OK -+-m string --algo wrong;;FAIL -+-m string --algo bm;;FAIL -+-m string;;FAIL -diff --git a/extensions/libxt_tcp.t b/extensions/libxt_tcp.t -new file mode 100644 -index 0000000000000..b0e8006e51869 ---- /dev/null -+++ b/extensions/libxt_tcp.t -@@ -0,0 +1,26 @@ -+:INPUT,FORWARD,OUTPUT -+-p tcp -m tcp --sport 1;=;OK -+-p tcp -m tcp --sport 65535;=;OK -+-p tcp -m tcp --dport 1;=;OK -+-p tcp -m tcp --dport 65535;=;OK -+-p tcp -m tcp --sport 1:1023;=;OK -+-p tcp -m tcp --sport 1024:65535;=;OK -+-p tcp -m tcp --sport 1024:;-p tcp -m tcp --sport 1024:65535;OK -+-p tcp -m tcp ! --sport 1;=;OK -+-p tcp -m tcp ! --sport 65535;=;OK -+-p tcp -m tcp ! --dport 1;=;OK -+-p tcp -m tcp ! --dport 65535;=;OK -+-p tcp -m tcp --sport 1 --dport 65535;=;OK -+-p tcp -m tcp --sport 65535 --dport 1;=;OK -+-p tcp -m tcp ! --sport 1 --dport 65535;=;OK -+-p tcp -m tcp ! --sport 65535 --dport 1;=;OK -+-p tcp -m tcp --sport 65536;;FAIL -+-p tcp -m tcp --sport -1;;FAIL -+-p tcp -m tcp --dport -1;;FAIL -+-p tcp -m tcp --syn;-p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN;OK -+-p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN;=;OK -+-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK -+-p tcp -m tcp ! --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK -+-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG RST;=;OK -+# should we accept this below? -+-p tcp -m tcp;=;OK -diff --git a/extensions/libxt_tcpmss.t b/extensions/libxt_tcpmss.t -new file mode 100644 -index 0000000000000..2b415957ffd00 ---- /dev/null -+++ b/extensions/libxt_tcpmss.t -@@ -0,0 +1,6 @@ -+:INPUT,FORWARD,OUTPUT -+-m tcpmss --mss 42;;FAIL -+-p tcp -m tcpmss --mss 42;=;OK -+-p tcp -m tcpmss --mss 42:12345;=;OK -+-p tcp -m tcpmss --mss 42:65536;;FAIL -+-p tcp -m tcpmss --mss 65535:1000;;FAIL -diff --git a/extensions/libxt_time.t b/extensions/libxt_time.t -new file mode 100644 -index 0000000000000..673af09b21fe2 ---- /dev/null -+++ b/extensions/libxt_time.t -@@ -0,0 +1,4 @@ -+:INPUT,FORWARD,OUTPUT -+-m time --timestart 01:02:03 --timestop 04:05:06 --monthdays 1,2,3,4,5 --weekdays Mon,Fri,Sun --datestart 2001-02-03T04:05:06 --datestop 2012-09-08T09:06:05 --kerneltz;=;OK -+-m time --timestart 01:02:03 --timestop 04:05:06 --monthdays 1,2,3,4,5 --weekdays Mon,Fri,Sun --datestart 2001-02-03T04:05:06 --datestop 2012-09-08T09:06:05;=;OK -+-m time --timestart 02:00:00 --timestop 03:00:00 --datestart 1970-01-01T02:00:00 --datestop 1970-01-01T03:00:00;=;OK -diff --git a/extensions/libxt_tos.t b/extensions/libxt_tos.t -new file mode 100644 -index 0000000000000..ccbe80099bdd9 ---- /dev/null -+++ b/extensions/libxt_tos.t -@@ -0,0 +1,13 @@ -+:INPUT,FORWARD,OUTPUT -+-m tos --tos Minimize-Delay;-m tos --tos 0x10/0x3f;OK -+-m tos --tos Maximize-Throughput;-m tos --tos 0x08/0x3f;OK -+-m tos --tos Maximize-Reliability;-m tos --tos 0x04/0x3f;OK -+-m tos --tos Minimize-Cost;-m tos --tos 0x02/0x3f;OK -+-m tos --tos Normal-Service;-m tos --tos 0x00/0x3f;OK -+-m tos --tos 0xff;=;OK -+-m tos ! --tos 0xff;=;OK -+-m tos --tos 0x00;=;OK -+-m tos --tos 0x0f;=;OK -+-m tos --tos 0x0f/0x0f;=;OK -+-m tos --tos wrong;;FAIL -+-m tos;;FAIL -diff --git a/extensions/libxt_u32.t b/extensions/libxt_u32.t -new file mode 100644 -index 0000000000000..0d9be47a10e84 ---- /dev/null -+++ b/extensions/libxt_u32.t -@@ -0,0 +1,2 @@ -+:INPUT,FORWARD,OUTPUT -+-m u32 --u32 "0x0=0x0&&0x0=0x1";=;OK -diff --git a/extensions/libxt_udp.t b/extensions/libxt_udp.t -new file mode 100644 -index 0000000000000..1b4d3dd625759 ---- /dev/null -+++ b/extensions/libxt_udp.t -@@ -0,0 +1,22 @@ -+:INPUT,OUTPUT,FORWARD -+-p udp -m udp --sport 1;=;OK -+-p udp -m udp --sport 65535;=;OK -+-p udp -m udp --dport 1;=;OK -+-p udp -m udp --dport 65535;=;OK -+-p udp -m udp --sport 1:1023;=;OK -+-p udp -m udp --sport 1024:65535;=;OK -+-p udp -m udp --sport 1024:;-p udp -m udp --sport 1024:65535;OK -+-p udp -m udp ! --sport 1;=;OK -+-p udp -m udp ! --sport 65535;=;OK -+-p udp -m udp ! --dport 1;=;OK -+-p udp -m udp ! --dport 65535;=;OK -+-p udp -m udp --sport 1 --dport 65535;=;OK -+-p udp -m udp --sport 65535 --dport 1;=;OK -+-p udp -m udp ! --sport 1 --dport 65535;=;OK -+-p udp -m udp ! --sport 65535 --dport 1;=;OK -+# ERRROR: should fail: iptables -A INPUT -p udp -m udp --sport 65536 -+# -p udp -m udp --sport 65536;;FAIL -+-p udp -m udp --sport -1;;FAIL -+-p udp -m udp --dport -1;;FAIL -+# should we accept this below? -+-p udp -m udp;=;OK -diff --git a/iptables-test.py b/iptables-test.py -new file mode 100755 -index 0000000000000..532dee7c9000f ---- /dev/null -+++ b/iptables-test.py -@@ -0,0 +1,373 @@ -+#!/usr/bin/python -+# -+# (C) 2012-2013 by Pablo Neira Ayuso -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This software has been sponsored by Sophos Astaro -+# -+ -+import sys -+import os -+import subprocess -+import argparse -+ -+IPTABLES = "iptables" -+IP6TABLES = "ip6tables" -+ARPTABLES = "arptables" -+EBTABLES = "ebtables" -+ -+IPTABLES_SAVE = "iptables-save" -+IP6TABLES_SAVE = "ip6tables-save" -+ARPTABLES_SAVE = "arptables-save" -+EBTABLES_SAVE = "ebtables-save" -+#IPTABLES_SAVE = ['xtables-save','-4'] -+#IP6TABLES_SAVE = ['xtables-save','-6'] -+ -+EXTENSIONS_PATH = "extensions" -+LOGFILE="/tmp/iptables-test.log" -+log_file = None -+ -+ -+class Colors: -+ HEADER = '\033[95m' -+ BLUE = '\033[94m' -+ GREEN = '\033[92m' -+ YELLOW = '\033[93m' -+ RED = '\033[91m' -+ ENDC = '\033[0m' -+ -+ -+def print_error(reason, filename=None, lineno=None): -+ ''' -+ Prints an error with nice colors, indicating file and line number. -+ ''' -+ print (filename + ": " + Colors.RED + "ERROR" + -+ Colors.ENDC + ": line %d (%s)" % (lineno, reason)) -+ -+ -+def delete_rule(iptables, rule, filename, lineno): -+ ''' -+ Removes an iptables rule -+ ''' -+ cmd = iptables + " -D " + rule -+ ret = execute_cmd(cmd, filename, lineno) -+ if ret == 1: -+ reason = "cannot delete: " + iptables + " -I " + rule -+ print_error(reason, filename, lineno) -+ return -1 -+ -+ return 0 -+ -+ -+def run_test(iptables, rule, rule_save, res, filename, lineno, netns): -+ ''' -+ Executes an unit test. Returns the output of delete_rule(). -+ -+ Parameters: -+ :param iptables: string with the iptables command to execute -+ :param rule: string with iptables arguments for the rule to test -+ :param rule_save: string to find the rule in the output of iptables -save -+ :param res: expected result of the rule. Valid values: "OK", "FAIL" -+ :param filename: name of the file tested (used for print_error purposes) -+ :param lineno: line number being tested (used for print_error purposes) -+ ''' -+ ret = 0 -+ -+ cmd = iptables + " -A " + rule -+ if netns: -+ cmd = "ip netns exec ____iptables-container-test " + EXECUTEABLE + " " + cmd -+ -+ ret = execute_cmd(cmd, filename, lineno) -+ -+ # -+ # report failed test -+ # -+ if ret: -+ if res == "OK": -+ reason = "cannot load: " + cmd -+ print_error(reason, filename, lineno) -+ return -1 -+ else: -+ # do not report this error -+ return 0 -+ else: -+ if res == "FAIL": -+ reason = "should fail: " + cmd -+ print_error(reason, filename, lineno) -+ delete_rule(iptables, rule, filename, lineno) -+ return -1 -+ -+ matching = 0 -+ splitted = iptables.split(" ") -+ if len(splitted) == 2: -+ if splitted[1] == '-4': -+ command = IPTABLES_SAVE -+ elif splitted[1] == '-6': -+ command = IP6TABLES_SAVE -+ elif len(splitted) == 1: -+ if splitted[0] == IPTABLES: -+ command = IPTABLES_SAVE -+ elif splitted[0] == IP6TABLES: -+ command = IP6TABLES_SAVE -+ elif splitted[0] == ARPTABLES: -+ command = ARPTABLES_SAVE -+ elif splitted[0] == EBTABLES: -+ command = EBTABLES_SAVE -+ -+ path = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE -+ command = path + " " + command -+ -+ if netns: -+ command = "ip netns exec ____iptables-container-test " + command -+ -+ args = splitted[1:] -+ proc = subprocess.Popen(command, shell=True, -+ stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ out, err = proc.communicate() -+ -+ # -+ # check for segfaults -+ # -+ if proc.returncode == -11: -+ reason = "iptables-save segfaults: " + cmd -+ print_error(reason, filename, lineno) -+ delete_rule(iptables, rule, filename, lineno) -+ return -1 -+ -+ # find the rule -+ matching = out.find(rule_save) -+ if matching < 0: -+ reason = "cannot find: " + iptables + " -I " + rule -+ print_error(reason, filename, lineno) -+ delete_rule(iptables, rule, filename, lineno) -+ return -1 -+ -+ # Test "ip netns del NETNS" path with rules in place -+ if netns: -+ return 0 -+ -+ return delete_rule(iptables, rule, filename, lineno) -+ -+def execute_cmd(cmd, filename, lineno): -+ ''' -+ Executes a command, checking for segfaults and returning the command exit -+ code. -+ -+ :param cmd: string with the command to be executed -+ :param filename: name of the file tested (used for print_error purposes) -+ :param lineno: line number being tested (used for print_error purposes) -+ ''' -+ global log_file -+ if cmd.startswith('iptables ') or cmd.startswith('ip6tables ') or cmd.startswith('ebtables ') or cmd.startswith('arptables '): -+ cmd = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE + " " + cmd -+ -+ print >> log_file, "command: %s" % cmd -+ ret = subprocess.call(cmd, shell=True, universal_newlines=True, -+ stderr=subprocess.STDOUT, stdout=log_file) -+ log_file.flush() -+ -+ # generic check for segfaults -+ if ret == -11: -+ reason = "command segfaults: " + cmd -+ print_error(reason, filename, lineno) -+ return ret -+ -+ -+def run_test_file(filename, netns): -+ ''' -+ Runs a test file -+ -+ :param filename: name of the file with the test rules -+ ''' -+ # -+ # if this is not a test file, skip. -+ # -+ if not filename.endswith(".t"): -+ return 0, 0 -+ -+ if "libipt_" in filename: -+ iptables = IPTABLES -+ elif "libip6t_" in filename: -+ iptables = IP6TABLES -+ elif "libxt_" in filename: -+ iptables = IPTABLES -+ elif "libarpt_" in filename: -+ # only supported with nf_tables backend -+ if EXECUTEABLE != "xtables-nft-multi": -+ return 0, 0 -+ iptables = ARPTABLES -+ elif "libebt_" in filename: -+ # only supported with nf_tables backend -+ if EXECUTEABLE != "xtables-nft-multi": -+ return 0, 0 -+ iptables = EBTABLES -+ else: -+ # default to iptables if not known prefix -+ iptables = IPTABLES -+ -+ f = open(filename) -+ -+ tests = 0 -+ passed = 0 -+ table = "" -+ total_test_passed = True -+ -+ if netns: -+ execute_cmd("ip netns add ____iptables-container-test", filename, 0) -+ -+ for lineno, line in enumerate(f): -+ if line[0] == "#": -+ continue -+ -+ if line[0] == ":": -+ chain_array = line.rstrip()[1:].split(",") -+ continue -+ -+ # external non-iptables invocation, executed as is. -+ if line[0] == "@": -+ external_cmd = line.rstrip()[1:] -+ if netns: -+ external_cmd = "ip netns exec ____iptables-container-test " + external_cmd -+ execute_cmd(external_cmd, filename, lineno) -+ continue -+ -+ # external iptables invocation, executed as is. -+ if line[0] == "%": -+ external_cmd = line.rstrip()[1:] -+ if netns: -+ external_cmd = "ip netns exec ____iptables-container-test " + EXECUTEABLE + " " + external_cmd -+ execute_cmd(external_cmd, filename, lineno) -+ continue -+ -+ if line[0] == "*": -+ table = line.rstrip()[1:] -+ continue -+ -+ if len(chain_array) == 0: -+ print "broken test, missing chain, leaving" -+ sys.exit() -+ -+ test_passed = True -+ tests += 1 -+ -+ for chain in chain_array: -+ item = line.split(";") -+ if table == "": -+ rule = chain + " " + item[0] -+ else: -+ rule = chain + " -t " + table + " " + item[0] -+ -+ if item[1] == "=": -+ rule_save = chain + " " + item[0] -+ else: -+ rule_save = chain + " " + item[1] -+ -+ res = item[2].rstrip() -+ ret = run_test(iptables, rule, rule_save, -+ res, filename, lineno + 1, netns) -+ -+ if ret < 0: -+ test_passed = False -+ total_test_passed = False -+ break -+ -+ if test_passed: -+ passed += 1 -+ -+ if netns: -+ execute_cmd("ip netns del ____iptables-container-test", filename, 0) -+ if total_test_passed: -+ print filename + ": " + Colors.GREEN + "OK" + Colors.ENDC -+ -+ f.close() -+ return tests, passed -+ -+ -+def show_missing(): -+ ''' -+ Show the list of missing test files -+ ''' -+ file_list = os.listdir(EXTENSIONS_PATH) -+ testfiles = [i for i in file_list if i.endswith('.t')] -+ libfiles = [i for i in file_list -+ if i.startswith('lib') and i.endswith('.c')] -+ -+ def test_name(x): -+ return x[0:-2] + '.t' -+ missing = [test_name(i) for i in libfiles -+ if not test_name(i) in testfiles] -+ -+ print '\n'.join(missing) -+ -+ -+# -+# main -+# -+def main(): -+ parser = argparse.ArgumentParser(description='Run iptables tests') -+ parser.add_argument('filename', nargs='?', -+ metavar='path/to/file.t', -+ help='Run only this test') -+ parser.add_argument('-l', '--legacy', action='store_true', -+ help='Test iptables-legacy') -+ parser.add_argument('-m', '--missing', action='store_true', -+ help='Check for missing tests') -+ parser.add_argument('-n', '--nftables', action='store_true', -+ help='Test iptables-over-nftables') -+ parser.add_argument('-N', '--netns', action='store_true', -+ help='Test netnamespace path') -+ args = parser.parse_args() -+ -+ # -+ # show list of missing test files -+ # -+ if args.missing: -+ show_missing() -+ return -+ -+ global EXECUTEABLE -+ EXECUTEABLE = "xtables-legacy-multi" -+ if args.nftables: -+ EXECUTEABLE = "xtables-nft-multi" -+ -+ if os.getuid() != 0: -+ print "You need to be root to run this, sorry" -+ return -+ -+ os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH)) -+ os.putenv("PATH", "%s/iptables:%s" % (os.path.abspath(os.path.curdir), os.getenv("PATH"))) -+ -+ test_files = 0 -+ tests = 0 -+ passed = 0 -+ -+ # setup global var log file -+ global log_file -+ try: -+ log_file = open(LOGFILE, 'w') -+ except IOError: -+ print "Couldn't open log file %s" % LOGFILE -+ return -+ -+ file_list = [os.path.join(EXTENSIONS_PATH, i) -+ for i in os.listdir(EXTENSIONS_PATH)] -+ if args.filename: -+ file_list = [args.filename] -+ for filename in file_list: -+ file_tests, file_passed = run_test_file(filename, args.netns) -+ if file_tests: -+ tests += file_tests -+ passed += file_passed -+ test_files += 1 -+ -+ print ("%d test files, %d unit tests, %d passed" % -+ (test_files, tests, passed)) -+ -+ -+if __name__ == '__main__': -+ main() --- -2.21.0 - diff --git a/SOURCES/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch b/SOURCES/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch new file mode 100644 index 0000000..ef6490b --- /dev/null +++ b/SOURCES/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch @@ -0,0 +1,35 @@ +From a69b9119bde58b372acb1c3914ee90f2ed48afb8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Sep 2018 11:39:50 +0200 +Subject: [PATCH] iptables-apply: Use mktemp instead of tempfile + +Signed-off-by: Phil Sutter +--- + iptables/iptables-apply | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/iptables-apply b/iptables/iptables-apply +index 819ca4a459c42..a685b6bbcd7dc 100755 +--- a/iptables/iptables-apply ++++ b/iptables/iptables-apply +@@ -111,7 +111,7 @@ if [[ ! -r "$FILE" ]]; then + exit 2 + fi + +-COMMANDS=(tempfile "$SAVE" "$RESTORE") ++COMMANDS=(mktemp "$SAVE" "$RESTORE") + + for cmd in "${COMMANDS[@]}"; do + if ! command -v $cmd >/dev/null; then +@@ -122,7 +122,7 @@ done + + umask 0700 + +-TMPFILE=$(tempfile -p iptap) ++TMPFILE=$(mktemp) + trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \ + FPE USR1 SEGV USR2 PIPE ALRM TERM + +-- +2.24.0 + diff --git a/SOURCES/0002-iptables-apply-Use-mktemp-instead-of-tempfile.patch b/SOURCES/0002-iptables-apply-Use-mktemp-instead-of-tempfile.patch deleted file mode 100644 index 640bffc..0000000 --- a/SOURCES/0002-iptables-apply-Use-mktemp-instead-of-tempfile.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7fe7c604d819d0b827f2abce253280b38a374cf1 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 17 Sep 2018 11:39:50 +0200 -Subject: [PATCH] iptables-apply: Use mktemp instead of tempfile - -Signed-off-by: Phil Sutter ---- - iptables/iptables-apply | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/iptables/iptables-apply b/iptables/iptables-apply -index 819ca4a459c42..a685b6bbcd7dc 100755 ---- a/iptables/iptables-apply -+++ b/iptables/iptables-apply -@@ -111,7 +111,7 @@ if [[ ! -r "$FILE" ]]; then - exit 2 - fi - --COMMANDS=(tempfile "$SAVE" "$RESTORE") -+COMMANDS=(mktemp "$SAVE" "$RESTORE") - - for cmd in "${COMMANDS[@]}"; do - if ! command -v $cmd >/dev/null; then -@@ -122,7 +122,7 @@ done - - umask 0700 - --TMPFILE=$(tempfile -p iptap) -+TMPFILE=$(mktemp) - trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \ - FPE USR1 SEGV USR2 PIPE ALRM TERM - --- -2.21.0 - diff --git a/SOURCES/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch b/SOURCES/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch new file mode 100644 index 0000000..4910448 --- /dev/null +++ b/SOURCES/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch @@ -0,0 +1,59 @@ +From 25af0fd3a7edd9a9aa5ed7ed63188456ee6389ef Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 4 Dec 2019 09:56:06 +0100 +Subject: [PATCH] xtables-restore: Fix parser feed from line buffer + +When called with --noflush, xtables-restore would trip over chain lines: +Parser uses strtok() to separate chain name, policy and counters which +inserts nul-chars into the source string. Therefore strlen() can't be +used anymore to find end of line. Fix this by caching line length before +calling xtables_restore_parse_line(). + +Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit a103fbfadf4c17b8b12caa57eef72deaaa71a18c) +Signed-off-by: Phil Sutter +--- + .../testcases/ipt-restore/0010-noflush-new-chain_0 | 10 ++++++++++ + iptables/xtables-restore.c | 4 +++- + 2 files changed, 13 insertions(+), 1 deletion(-) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 +new file mode 100755 +index 0000000000000..739e684a21183 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 +@@ -0,0 +1,10 @@ ++#!/bin/sh -e ++ ++# assert input feed from buffer doesn't trip over ++# added nul-chars from parsing chain line. ++ ++$XT_MULTI iptables-restore --noflush <error.lineno = ++line; + DEBUGP("%s: buffered line %d: '%s'\n", __func__, line, ptr); + xtables_restore_parse_line(h, p, &state, ptr); +- ptr += strlen(ptr) + 1; ++ ptr += len + 1; + } + if (*buffer) { + h->error.lineno = ++line; +-- +2.24.0 + diff --git a/SOURCES/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch b/SOURCES/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch new file mode 100644 index 0000000..0af13d3 --- /dev/null +++ b/SOURCES/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch @@ -0,0 +1,31 @@ +From 5ee8338b9f1b5c02efca1a33185cf648cdf1aa20 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 11:40:26 +0100 +Subject: [PATCH] xtables-restore: Avoid access of uninitialized data + +When flushing, 'buffer' is not written to prior to checking its first +byte's value. Therefore it needs to be initialized upon declaration. + +Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") +(cherry picked from commit 48be21bf39f9af35d53af0e211cbd50dcfd12d08) +Signed-off-by: Phil Sutter +--- + iptables/xtables-restore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index dd907e0b8ddd5..63cc15cee9621 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -281,7 +281,7 @@ void xtables_restore_parse(struct nft_handle *h, + const struct nft_xt_restore_parse *p) + { + struct nft_xt_restore_state state = {}; +- char preload_buffer[PREBUFSIZ] = {}, buffer[10240], *ptr; ++ char preload_buffer[PREBUFSIZ] = {}, buffer[10240] = {}, *ptr; + + if (!h->noflush) { + nft_fake_cache(h); +-- +2.24.0 + diff --git a/SOURCES/0004-arptables-nft-use-generic-expression-parsing-functio.patch b/SOURCES/0004-arptables-nft-use-generic-expression-parsing-functio.patch deleted file mode 100644 index e48e653..0000000 --- a/SOURCES/0004-arptables-nft-use-generic-expression-parsing-functio.patch +++ /dev/null @@ -1,190 +0,0 @@ -From abf79e364e9ef2dc355eb52d07d160b1f6c0f8c4 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Sun, 18 Nov 2018 12:31:33 +0100 -Subject: [PATCH] arptables-nft: use generic expression parsing function - -since commit d9c6a5d0977a6d8bbe772dbc31a2c4f58eec1708 -("xtables: merge {ip,arp}tables_command_state structs") arptables -uses the shared representation. - -With only minor changes (e.g., use generic counters in command_state), -in print/save functions we can use the shared nftnl expression parser -too. - -arptables-legacy prints (-L) the jump target first, i.e.: --j MARK -d 0.0.0.0/8 --h-length 6 ... - -... so keep that here too. - -Signed-off-by: Florian Westphal -(cherry picked from commit aa5d3c5b16e94036ac0dc6d44194db7b009ced53) -Signed-off-by: Phil Sutter ---- - extensions/libarpt_standard.t | 4 +- - iptables/nft-arp.c | 92 ++++------------------------------- - 2 files changed, 12 insertions(+), 84 deletions(-) - -diff --git a/extensions/libarpt_standard.t b/extensions/libarpt_standard.t -index bef682afec374..195865929c8d3 100644 ---- a/extensions/libarpt_standard.t -+++ b/extensions/libarpt_standard.t -@@ -5,8 +5,8 @@ - -d 192.168.0.1;=;OK - ! -d 0.0.0.0;=;OK - -d 0.0.0.0/24;=;OK ---i lo;=;OK --! -i lo;=;OK -+-i lo -j DROP;-i lo --h-length 6 --h-type 1 -j DROP;OK -+! -i lo -j ACCEPT;! -i lo --h-length 6 --h-type 1 -j ACCEPT;OK - -i ppp+;=;OK - ! -i ppp+;=;OK - -i lo --destination-mac 11:22:33:44:55:66;-i lo --dst-mac 11:22:33:44:55:66;OK -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index 1a98996f94bda..37850bd328b71 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -412,56 +412,6 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, - } - } - --static void nft_arp_rule_to_cs(const struct nftnl_rule *r, -- struct iptables_command_state *cs) --{ -- struct nftnl_expr_iter *iter; -- struct nftnl_expr *expr; -- int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY); -- struct nft_xt_ctx ctx = { -- .cs = cs, -- .family = family, -- }; -- -- iter = nftnl_expr_iter_create(r); -- if (iter == NULL) -- return; -- -- ctx.iter = iter; -- expr = nftnl_expr_iter_next(iter); -- while (expr != NULL) { -- const char *name = -- nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); -- -- if (strcmp(name, "counter") == 0) -- nft_parse_counter(expr, &ctx.cs->arp.counters); -- else if (strcmp(name, "payload") == 0) -- nft_parse_payload(&ctx, expr); -- else if (strcmp(name, "meta") == 0) -- nft_parse_meta(&ctx, expr); -- else if (strcmp(name, "bitwise") == 0) -- nft_parse_bitwise(&ctx, expr); -- else if (strcmp(name, "cmp") == 0) -- nft_parse_cmp(&ctx, expr); -- else if (strcmp(name, "immediate") == 0) -- nft_parse_immediate(&ctx, expr); -- else if (strcmp(name, "target") == 0) -- nft_parse_target(&ctx, expr); -- -- expr = nftnl_expr_iter_next(iter); -- } -- -- nftnl_expr_iter_destroy(iter); -- -- if (cs->jumpto != NULL) -- return; -- -- if (cs->target != NULL && cs->target->name != NULL) -- cs->target = xtables_find_target(cs->target->name, XTF_TRY_LOAD); -- else -- cs->jumpto = ""; --} -- - static void nft_arp_print_header(unsigned int format, const char *chain, - const char *pol, - const struct xt_counters *counters, -@@ -627,14 +577,6 @@ after_devdst: - } - } - --static void nft_arp_save_counters(const void *data) --{ -- const struct iptables_command_state *cs = data; -- -- printf("[%llu:%llu] ", (unsigned long long)cs->arp.counters.pcnt, -- (unsigned long long)cs->arp.counters.bcnt); --} -- - static void - nft_arp_save_rule(const void *data, unsigned int format) - { -@@ -643,17 +585,7 @@ nft_arp_save_rule(const void *data, unsigned int format) - format |= FMT_NUMERIC; - - nft_arp_print_rule_details(&cs->arp, format); -- -- if (cs->jumpto != NULL && strcmp(cs->jumpto, "") != 0) { -- printf("-j %s", cs->jumpto); -- } else if (cs->target) { -- printf("-j %s", cs->target->name); -- if (cs->target->save != NULL) -- cs->target->save(&cs->arp, cs->target->t); -- } -- -- if (!(format & FMT_NONEWLINE)) -- fputc('\n', stdout); -+ save_matches_and_target(cs, false, &cs->arp, format); - } - - static void -@@ -664,22 +596,18 @@ nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format) - if (format & FMT_LINENUMBERS) - printf("%u ", num); - -- nft_arp_rule_to_cs(r, &cs); -+ nft_rule_to_iptables_command_state(r, &cs); - -+ if (cs.jumpto) -+ printf("-j %s ", cs.jumpto); - nft_arp_print_rule_details(&cs.arp, format); -- -- if (cs.jumpto != NULL && strcmp(cs.jumpto, "") != 0) { -- printf("-j %s", cs.jumpto); -- } else if (cs.target) { -- printf("-j %s", cs.target->name); -- cs.target->print(&cs.arp, cs.target->t, format & FMT_NUMERIC); -- } -+ print_matches_and_target(&cs, format); - - if (!(format & FMT_NOCOUNTS)) { - printf(", pcnt="); -- xtables_print_num(cs.arp.counters.pcnt, format); -+ xtables_print_num(cs.counters.pcnt, format); - printf("-- bcnt="); -- xtables_print_num(cs.arp.counters.bcnt, format); -+ xtables_print_num(cs.counters.bcnt, format); - } - - if (!(format & FMT_NONEWLINE)) -@@ -720,7 +648,7 @@ static bool nft_arp_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r, - struct iptables_command_state this = {}; - - /* Delete by matching rule case */ -- nft_arp_rule_to_cs(r, &this); -+ nft_rule_to_iptables_command_state(r, &this); - - if (!nft_arp_is_same(&cs->arp, &this.arp)) - return false; -@@ -751,10 +679,10 @@ struct nft_family_ops nft_family_ops_arp = { - .print_header = nft_arp_print_header, - .print_rule = nft_arp_print_rule, - .save_rule = nft_arp_save_rule, -- .save_counters = nft_arp_save_counters, -+ .save_counters = save_counters, - .save_chain = nft_arp_save_chain, - .post_parse = NULL, -- .rule_to_cs = nft_arp_rule_to_cs, -+ .rule_to_cs = nft_rule_to_iptables_command_state, - .clear_cs = nft_clear_iptables_command_state, - .rule_find = nft_arp_rule_find, - .parse_target = nft_ipv46_parse_target, --- -2.21.0 - diff --git a/SOURCES/0004-extensions-time-Avoid-undefined-shift.patch b/SOURCES/0004-extensions-time-Avoid-undefined-shift.patch new file mode 100644 index 0000000..ad67a3d --- /dev/null +++ b/SOURCES/0004-extensions-time-Avoid-undefined-shift.patch @@ -0,0 +1,31 @@ +From bda4f46d1a474e5cc13712a0302adcf723e3cc5c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:15:01 +0100 +Subject: [PATCH] extensions: time: Avoid undefined shift + +Value 1 is signed by default and left-shifting by 31 is undefined for +those. Fix this by marking the value as unsigned. + +Fixes: ad326ef9f734a ("Add the libxt_time iptables match") +(cherry picked from commit 98b221002960040bf3505811c06025b6b9b6984b) +Signed-off-by: Phil Sutter +--- + extensions/libxt_time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c +index 5a8cc5de13031..d001f5b7f448f 100644 +--- a/extensions/libxt_time.c ++++ b/extensions/libxt_time.c +@@ -330,7 +330,7 @@ static void time_print_monthdays(uint32_t mask, bool human_readable) + + printf(" "); + for (i = 1; i <= 31; ++i) +- if (mask & (1 << i)) { ++ if (mask & (1u << i)) { + if (nbdays++ > 0) + printf(","); + printf("%u", i); +-- +2.24.0 + diff --git a/SOURCES/0005-extensions-cluster-Avoid-undefined-shift.patch b/SOURCES/0005-extensions-cluster-Avoid-undefined-shift.patch new file mode 100644 index 0000000..576db90 --- /dev/null +++ b/SOURCES/0005-extensions-cluster-Avoid-undefined-shift.patch @@ -0,0 +1,31 @@ +From 45aacdc1bbb3a889d9820c1fb587dc8df3cae763 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:36:31 +0100 +Subject: [PATCH] extensions: cluster: Avoid undefined shift + +Value 1 is signed by default and left-shifting by 31 is undefined for +those. Fix this by marking the value as unsigned. + +Fixes: 64a0e09894e52 ("extensions: libxt_cluster: Add translation to nft") +(cherry picked from commit 28c16371cdad16707674450b59919e3d97185694) +Signed-off-by: Phil Sutter +--- + extensions/libxt_cluster.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_cluster.c b/extensions/libxt_cluster.c +index c9c35ee22e3df..d164bf6960166 100644 +--- a/extensions/libxt_cluster.c ++++ b/extensions/libxt_cluster.c +@@ -156,7 +156,7 @@ static int cluster_xlate(struct xt_xlate *xl, + xt_xlate_add(xl, "%s %u seed 0x%08x ", jhash_st, + info->total_nodes, info->hash_seed); + for (node = 0; node < 32; node++) { +- if (info->node_mask & (1 << node)) { ++ if (info->node_mask & (1u << node)) { + if (needs_set == 0) { + xt_xlate_add(xl, "{ "); + needs_set = 1; +-- +2.24.0 + diff --git a/SOURCES/0005-xtables-Don-t-use-native-nftables-comments.patch b/SOURCES/0005-xtables-Don-t-use-native-nftables-comments.patch deleted file mode 100644 index e990de2..0000000 --- a/SOURCES/0005-xtables-Don-t-use-native-nftables-comments.patch +++ /dev/null @@ -1,143 +0,0 @@ -From b7556207b12decbe4e79bf218ec5bff073a04ad2 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 27 Nov 2018 20:07:11 +0100 -Subject: [PATCH] xtables: Don't use native nftables comments - -The problem with converting libxt_comment into nftables comment is that -rules change when parsing from kernel due to comment match being moved -to the end of the match list. And since match ordering matters, the rule -may not be found anymore when checking or deleting. Apart from that, -iptables-nft didn't support multiple comments per rule anymore. This is -a compatibility issue without technical reason. - -Leave conversion from nftables comment to libxt_comment in place so we -don't break running systems during an update. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit ccf154d7420c07b6e6febc1c3b8b31d2bd1adbe6) -Signed-off-by: Phil Sutter ---- - extensions/libxt_comment.t | 2 ++ - iptables/nft-ipv4.c | 14 +++----------- - iptables/nft-ipv6.c | 14 +++----------- - iptables/nft.c | 27 --------------------------- - iptables/nft.h | 1 - - 5 files changed, 8 insertions(+), 50 deletions(-) - -diff --git a/extensions/libxt_comment.t b/extensions/libxt_comment.t -index f12cd66841e7f..f0c8fb999401b 100644 ---- a/extensions/libxt_comment.t -+++ b/extensions/libxt_comment.t -@@ -1,6 +1,8 @@ - :INPUT,FORWARD,OUTPUT - -m comment;;FAIL - -m comment --comment;;FAIL -+-p tcp -m tcp --dport 22 -m comment --comment foo;=;OK -+-p tcp -m comment --comment foo -m tcp --dport 22;=;OK - # - # it fails with 256 characters - # -diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c -index ffb439b4a1128..4497eb9b9347c 100644 ---- a/iptables/nft-ipv4.c -+++ b/iptables/nft-ipv4.c -@@ -77,17 +77,9 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data) - add_compat(r, cs->fw.ip.proto, cs->fw.ip.invflags & XT_INV_PROTO); - - for (matchp = cs->matches; matchp; matchp = matchp->next) { -- /* Use nft built-in comments support instead of comment match */ -- if (strcmp(matchp->match->name, "comment") == 0) { -- ret = add_comment(r, (char *)matchp->match->m->data); -- if (ret < 0) -- goto try_match; -- } else { --try_match: -- ret = add_match(r, matchp->match->m); -- if (ret < 0) -- return ret; -- } -+ ret = add_match(r, matchp->match->m); -+ if (ret < 0) -+ return ret; - } - - /* Counters need to me added before the target, otherwise they are -diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c -index 7bacee4ab3a21..cacb1c9e141f2 100644 ---- a/iptables/nft-ipv6.c -+++ b/iptables/nft-ipv6.c -@@ -66,17 +66,9 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data) - add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags & XT_INV_PROTO); - - for (matchp = cs->matches; matchp; matchp = matchp->next) { -- /* Use nft built-in comments support instead of comment match */ -- if (strcmp(matchp->match->name, "comment") == 0) { -- ret = add_comment(r, (char *)matchp->match->m->data); -- if (ret < 0) -- goto try_match; -- } else { --try_match: -- ret = add_match(r, matchp->match->m); -- if (ret < 0) -- return ret; -- } -+ ret = add_match(r, matchp->match->m); -+ if (ret < 0) -+ return ret; - } - - /* Counters need to me added before the target, otherwise they are -diff --git a/iptables/nft.c b/iptables/nft.c -index e8538d38e0109..6863d851e44c2 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1107,33 +1107,6 @@ enum udata_type { - }; - #define UDATA_TYPE_MAX (__UDATA_TYPE_MAX - 1) - --int add_comment(struct nftnl_rule *r, const char *comment) --{ -- struct nftnl_udata_buf *udata; -- uint32_t len; -- -- if (nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len)) -- return -EALREADY; -- -- udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN); -- if (!udata) -- return -ENOMEM; -- -- if (strnlen(comment, 255) == 255) -- return -ENOSPC; -- -- if (!nftnl_udata_put_strz(udata, UDATA_TYPE_COMMENT, comment)) -- return -ENOMEM; -- -- nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, -- nftnl_udata_buf_data(udata), -- nftnl_udata_buf_len(udata)); -- -- nftnl_udata_buf_free(udata); -- -- return 0; --} -- - static int parse_udata_cb(const struct nftnl_udata *attr, void *data) - { - unsigned char *value = nftnl_udata_get(attr); -diff --git a/iptables/nft.h b/iptables/nft.h -index 9b4ba5f9a63eb..052105fc6f3cd 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -116,7 +116,6 @@ int add_match(struct nftnl_rule *r, struct xt_entry_match *m); - int add_target(struct nftnl_rule *r, struct xt_entry_target *t); - int add_jumpto(struct nftnl_rule *r, const char *name, int verdict); - int add_action(struct nftnl_rule *r, struct iptables_command_state *cs, bool goto_set); --int add_comment(struct nftnl_rule *r, const char *comment); - char *get_comment(const void *data, uint32_t data_len); - - enum nft_rule_print { --- -2.21.0 - diff --git a/SOURCES/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch b/SOURCES/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch new file mode 100644 index 0000000..6b03afa --- /dev/null +++ b/SOURCES/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch @@ -0,0 +1,32 @@ +From d3641eaed9ad19b74f3bababb3db53af0004488b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:57:18 +0100 +Subject: [PATCH] libxtables: Avoid buffer overrun in + xtables_compatible_revision() + +The function is exported and accepts arbitrary strings as input. Calling +strcpy() without length checks is not OK. + +(cherry picked from commit f7d3dbb82e7ed94ccbf10cf70a3c7b3f3aaef1a1) +Signed-off-by: Phil Sutter +--- + libxtables/xtables.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 895f6988eaf57..777c2b08e9896 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -856,7 +856,8 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt) + + xtables_load_ko(xtables_modprobe_program, true); + +- strcpy(rev.name, name); ++ strncpy(rev.name, name, XT_EXTENSION_MAXNAMELEN - 1); ++ rev.name[XT_EXTENSION_MAXNAMELEN - 1] = '\0'; + rev.revision = revision; + + max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); +-- +2.24.0 + diff --git a/SOURCES/0006-xtables-Introduce-per-table-chain-caches.patch b/SOURCES/0006-xtables-Introduce-per-table-chain-caches.patch deleted file mode 100644 index 96b32c3..0000000 --- a/SOURCES/0006-xtables-Introduce-per-table-chain-caches.patch +++ /dev/null @@ -1,592 +0,0 @@ -From a09e8ae2a1e2ff589af839ad3460493fc04306d7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 15 Nov 2018 14:53:02 +0100 -Subject: [PATCH] xtables: Introduce per table chain caches - -Being able to omit the previously obligatory table name check when -iterating over the chain cache might help restore performance with large -rulesets in xtables-save and -restore. - -There is one subtle quirk in the code: flush_chain_cache() did free the -global chain cache if not called with a table name but didn't if a table -name was given even if it emptied the chain cache. In other places, -chain_cache being non-NULL prevented a cache update from happening, so -this patch establishes the same behaviour (for each individual chain -cache) since otherwise unexpected cache updates lead to weird problems. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit c58ecf9f8bcb7619a27ef8ffaddf847a562475a5) -Signed-off-by: Phil Sutter ---- - iptables/nft-shared.h | 3 +- - iptables/nft.c | 160 +++++++++++++++++-------------------- - iptables/nft.h | 10 ++- - iptables/xtables-restore.c | 16 ++-- - iptables/xtables-save.c | 12 +-- - 5 files changed, 95 insertions(+), 106 deletions(-) - -diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h -index e3ecdb4d23df3..9a61d8d2863e3 100644 ---- a/iptables/nft-shared.h -+++ b/iptables/nft-shared.h -@@ -251,7 +251,8 @@ struct nftnl_chain_list; - - struct nft_xt_restore_cb { - void (*table_new)(struct nft_handle *h, const char *table); -- struct nftnl_chain_list *(*chain_list)(struct nft_handle *h); -+ struct nftnl_chain_list *(*chain_list)(struct nft_handle *h, -+ const char *table); - void (*chain_del)(struct nftnl_chain_list *clist, const char *curtable, - const char *chain); - int (*chain_user_flush)(struct nft_handle *h, -diff --git a/iptables/nft.c b/iptables/nft.c -index 6863d851e44c2..36529048a0ca6 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -673,15 +673,17 @@ nft_chain_builtin_find(struct builtin_table *t, const char *chain) - static void nft_chain_builtin_init(struct nft_handle *h, - struct builtin_table *table) - { -- struct nftnl_chain_list *list = nft_chain_list_get(h); -+ struct nftnl_chain_list *list = nft_chain_list_get(h, table->name); - struct nftnl_chain *c; - int i; - -+ if (!list) -+ return; -+ - /* Initialize built-in chains if they don't exist yet */ - for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) { - -- c = nft_chain_list_find(list, table->name, -- table->chains[i].name); -+ c = nft_chain_list_find(list, table->chains[i].name); - if (c != NULL) - continue; - -@@ -782,27 +784,33 @@ static void flush_rule_cache(struct nft_handle *h, const char *tablename) - - static int __flush_chain_cache(struct nftnl_chain *c, void *data) - { -- const char *tablename = data; -- -- if (!strcmp(nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), tablename)) { -- nftnl_chain_list_del(c); -- nftnl_chain_free(c); -- } -+ nftnl_chain_list_del(c); -+ nftnl_chain_free(c); - - return 0; - } - - static void flush_chain_cache(struct nft_handle *h, const char *tablename) - { -- if (!h->chain_cache) -- return; -+ int i; - -- if (tablename) { -- nftnl_chain_list_foreach(h->chain_cache, __flush_chain_cache, -- (void *)tablename); -- } else { -- nftnl_chain_list_free(h->chain_cache); -- h->chain_cache = NULL; -+ for (i = 0; i < NFT_TABLE_MAX; i++) { -+ if (h->tables[i].name == NULL) -+ continue; -+ -+ if (tablename && strcmp(h->tables[i].name, tablename)) -+ continue; -+ -+ if (h->tables[i].chain_cache) { -+ if (tablename) { -+ nftnl_chain_list_foreach(h->tables[i].chain_cache, -+ __flush_chain_cache, NULL); -+ break; -+ } else { -+ nftnl_chain_list_free(h->tables[i].chain_cache); -+ h->tables[i].chain_cache = NULL; -+ } -+ } - } - } - -@@ -1244,8 +1252,9 @@ nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type, - - static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) - { -+ struct nft_handle *h = data; -+ struct builtin_table *t; - struct nftnl_chain *c; -- struct nftnl_chain_list *list = data; - - c = nftnl_chain_alloc(); - if (c == NULL) -@@ -1254,7 +1263,18 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) - if (nftnl_chain_nlmsg_parse(nlh, c) < 0) - goto out; - -- nftnl_chain_list_add_tail(c, list); -+ t = nft_table_builtin_find(h, -+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE)); -+ if (!t) -+ goto out; -+ -+ if (!t->chain_cache) { -+ t->chain_cache = nftnl_chain_list_alloc(); -+ if (!t->chain_cache) -+ goto out; -+ } -+ -+ nftnl_chain_list_add_tail(c, t->chain_cache); - - return MNL_CB_OK; - out: -@@ -1263,35 +1283,34 @@ err: - return MNL_CB_OK; - } - --struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h) -+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -+ const char *table) - { - char buf[16536]; - struct nlmsghdr *nlh; -- struct nftnl_chain_list *list; -+ struct builtin_table *t; - int ret; - -- if (h->chain_cache) -- return h->chain_cache; --retry: -- list = nftnl_chain_list_alloc(); -- if (list == NULL) { -- errno = ENOMEM; -+ t = nft_table_builtin_find(h, table); -+ if (!t) - return NULL; -- } - -+ if (t->chain_cache) -+ return t->chain_cache; -+retry: - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, - NLM_F_DUMP, h->seq); - -- ret = mnl_talk(h, nlh, nftnl_chain_list_cb, list); -+ ret = mnl_talk(h, nlh, nftnl_chain_list_cb, h); - if (ret < 0 && errno == EINTR) { - assert(nft_restart(h) >= 0); -- nftnl_chain_list_free(list); - goto retry; - } - -- h->chain_cache = list; -+ if (!t->chain_cache) -+ t->chain_cache = nftnl_chain_list_alloc(); - -- return list; -+ return t->chain_cache; - } - - static const char *policy_name[NF_ACCEPT+1] = { -@@ -1299,8 +1318,7 @@ static const char *policy_name[NF_ACCEPT+1] = { - [NF_ACCEPT] = "ACCEPT", - }; - --int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, -- const char *table) -+int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) - { - struct nftnl_chain_list_iter *iter; - struct nft_family_ops *ops; -@@ -1314,13 +1332,8 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *chain_table = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *policy = NULL; - -- if (strcmp(table, chain_table) != 0) -- goto next; -- - if (nft_chain_builtin(c)) { - uint32_t pol = NF_ACCEPT; - -@@ -1331,7 +1344,7 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, - - if (ops->save_chain) - ops->save_chain(c, policy); --next: -+ - c = nftnl_chain_list_iter_next(iter); - } - -@@ -1502,7 +1515,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, - - nft_fn = nft_rule_flush; - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); - if (list == NULL) { - ret = 1; - goto err; -@@ -1516,21 +1529,16 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *table_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - -- if (strcmp(table, table_name) != 0) -- goto next; -- - if (chain != NULL && strcmp(chain, chain_name) != 0) - goto next; - - if (verbose) - fprintf(stdout, "Flushing chain `%s'\n", chain_name); - -- __nft_rule_flush(h, table_name, chain_name); -+ __nft_rule_flush(h, table, chain_name); - - if (chain != NULL) - break; -@@ -1546,6 +1554,7 @@ err: - - int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) - { -+ struct nftnl_chain_list *list; - struct nftnl_chain *c; - int ret; - -@@ -1564,9 +1573,9 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl - - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); - -- nft_chain_list_get(h); -- -- nftnl_chain_list_add(c, h->chain_cache); -+ list = nft_chain_list_get(h, table); -+ if (list) -+ nftnl_chain_list_add(c, list); - - /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; -@@ -1588,7 +1597,7 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, - - nft_fn = nft_chain_user_del; - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); - if (list == NULL) - goto err; - -@@ -1598,8 +1607,6 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *table_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - -@@ -1607,9 +1614,6 @@ int nft_chain_user_del(struct nft_handle *h, const char *chain, - if (nft_chain_builtin(c)) - goto next; - -- if (strcmp(table, table_name) != 0) -- goto next; -- - if (chain != NULL && strcmp(chain, chain_name) != 0) - goto next; - -@@ -1644,8 +1648,7 @@ err: - } - - struct nftnl_chain * --nft_chain_list_find(struct nftnl_chain_list *list, -- const char *table, const char *chain) -+nft_chain_list_find(struct nftnl_chain_list *list, const char *chain) - { - struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; -@@ -1656,14 +1659,9 @@ nft_chain_list_find(struct nftnl_chain_list *list, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *table_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - -- if (strcmp(table, table_name) != 0) -- goto next; -- - if (strcmp(chain, chain_name) != 0) - goto next; - -@@ -1681,11 +1679,11 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain) - { - struct nftnl_chain_list *list; - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); - if (list == NULL) - return NULL; - -- return nft_chain_list_find(list, table, chain); -+ return nft_chain_list_find(list, chain); - } - - bool nft_chain_exists(struct nft_handle *h, -@@ -2297,7 +2295,9 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - return 1; - } - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); -+ if (!list) -+ goto err; /* XXX: return 0 instead? */ - - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) -@@ -2308,8 +2308,6 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *chain_table = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - uint32_t policy = -@@ -2326,8 +2324,6 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) - basechain = true; - -- if (strcmp(table, chain_table) != 0) -- goto next; - if (chain) { - if (strcmp(chain, chain_name) != 0) - goto next; -@@ -2442,7 +2438,9 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - return 0; - } - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); -+ if (!list) -+ goto err; /* XXX: correct? */ - - /* Dump policies and custom chains first */ - if (!rulenum) -@@ -2460,13 +2458,9 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *chain_table = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - -- if (strcmp(table, chain_table) != 0) -- goto next; - if (chain && strcmp(chain, chain_name) != 0) - goto next; - -@@ -3045,7 +3039,7 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, - struct nftnl_chain *c; - int ret = 0; - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, table); - if (list == NULL) - goto err; - -@@ -3057,11 +3051,6 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, - while (c != NULL) { - const char *chain_name = - nftnl_chain_get(c, NFTNL_CHAIN_NAME); -- const char *chain_table = -- nftnl_chain_get(c, NFTNL_CHAIN_TABLE); -- -- if (strcmp(table, chain_table) != 0) -- goto next; - - if (chain != NULL && strcmp(chain, chain_name) != 0) - goto next; -@@ -3202,7 +3191,7 @@ static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename - struct nftnl_chain *chain; - int ret = 0; - -- list = nft_chain_list_get(h); -+ list = nft_chain_list_get(h, tablename); - if (list == NULL) - return -1; - -@@ -3212,12 +3201,7 @@ static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename - - chain = nftnl_chain_list_iter_next(iter); - while (chain != NULL) { -- const char *chain_table; -- -- chain_table = nftnl_chain_get_str(chain, NFTNL_CHAIN_TABLE); -- -- if (strcmp(chain_table, tablename) || -- !nft_chain_builtin(chain)) -+ if (!nft_chain_builtin(chain)) - goto next; - - ret = nft_is_chain_compatible(h, chain); -diff --git a/iptables/nft.h b/iptables/nft.h -index 052105fc6f3cd..6229221bd51f7 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -25,6 +25,7 @@ struct builtin_table { - const char *name; - struct builtin_chain chains[NF_INET_NUMHOOKS]; - bool initialized; -+ struct nftnl_chain_list *chain_cache; - }; - - struct nft_handle { -@@ -38,7 +39,6 @@ struct nft_handle { - struct list_head err_list; - struct nft_family_ops *ops; - struct builtin_table *tables; -- struct nftnl_chain_list *chain_cache; - struct nftnl_rule_list *rule_cache; - bool restore; - int8_t config_done; -@@ -78,9 +78,11 @@ struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *t - struct nftnl_chain; - - int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters); --struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h); --struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain); --int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table); -+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -+ const char *table); -+struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, -+ const char *chain); -+int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list); - int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table); - int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose); - int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list, -diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c -index f529774054215..a46a92955a01a 100644 ---- a/iptables/xtables-restore.c -+++ b/iptables/xtables-restore.c -@@ -56,11 +56,12 @@ static void print_usage(const char *name, const char *version) - " [ --ipv6 ]\n", name); - } - --static struct nftnl_chain_list *get_chain_list(struct nft_handle *h) -+static struct nftnl_chain_list *get_chain_list(struct nft_handle *h, -+ const char *table) - { - struct nftnl_chain_list *chain_list; - -- chain_list = nft_chain_list_get(h); -+ chain_list = nft_chain_list_get(h, table); - if (chain_list == NULL) - xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n"); - -@@ -72,7 +73,7 @@ static void chain_delete(struct nftnl_chain_list *clist, const char *curtable, - { - struct nftnl_chain *chain_obj; - -- chain_obj = nft_chain_list_find(clist, curtable, chain); -+ chain_obj = nft_chain_list_find(clist, chain); - /* This chain has been found, delete from list. Later - * on, unvisited chains will be purged out. - */ -@@ -112,9 +113,6 @@ void xtables_restore_parse(struct nft_handle *h, - - line = 0; - -- if (cb->chain_list) -- chain_list = cb->chain_list(h); -- - /* Grab standard input. */ - while (fgets(buffer, sizeof(buffer), p->in)) { - int ret = 0; -@@ -165,6 +163,9 @@ void xtables_restore_parse(struct nft_handle *h, - if (p->tablename && (strcmp(p->tablename, table) != 0)) - continue; - -+ if (cb->chain_list) -+ chain_list = cb->chain_list(h, table); -+ - if (noflush == 0) { - DEBUGP("Cleaning all chains of table '%s'\n", - table); -@@ -197,8 +198,7 @@ void xtables_restore_parse(struct nft_handle *h, - if (cb->chain_del) - cb->chain_del(chain_list, curtable->name, - chain); -- } else if (nft_chain_list_find(chain_list, -- curtable->name, chain)) { -+ } else if (nft_chain_list_find(chain_list, chain)) { - chain_exists = true; - /* Apparently -n still flushes existing user - * defined chains that are redefined. Otherwise, -diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c -index bed3ee0318995..d121d50e180ff 100644 ---- a/iptables/xtables-save.c -+++ b/iptables/xtables-save.c -@@ -73,7 +73,9 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters) - return 0; - } - -- chain_list = nft_chain_list_get(h); -+ chain_list = nft_chain_list_get(h, tablename); -+ if (!chain_list) -+ return 0; - - time_t now = time(NULL); - -@@ -83,7 +85,7 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters) - - /* Dump out chain names first, - * thereby preventing dependency conflicts */ -- nft_chain_save(h, chain_list, tablename); -+ nft_chain_save(h, chain_list); - nft_rule_save(h, tablename, counters ? 0 : FMT_NOCOUNTS); - - now = time(NULL); -@@ -257,7 +259,7 @@ static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters - return 0; - } - -- chain_list = nft_chain_list_get(h); -+ chain_list = nft_chain_list_get(h, tablename); - - if (first) { - now = time(NULL); -@@ -272,7 +274,7 @@ static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters - - /* Dump out chain names first, - * thereby preventing dependency conflicts */ -- nft_chain_save(h, chain_list, tablename); -+ nft_chain_save(h, chain_list); - nft_rule_save(h, tablename, format); - printf("\n"); - return 0; -@@ -399,7 +401,7 @@ int xtables_arp_save_main(int argc, char **argv) - } - - printf("*filter\n"); -- nft_chain_save(&h, nft_chain_list_get(&h), "filter"); -+ nft_chain_save(&h, nft_chain_list_get(&h, "filter")); - nft_rule_save(&h, "filter", show_counters ? 0 : FMT_NOCOUNTS); - printf("\n"); - nft_fini(&h); --- -2.21.0 - diff --git a/SOURCES/0007-nft-add-type-field-to-builtin_table.patch b/SOURCES/0007-nft-add-type-field-to-builtin_table.patch deleted file mode 100644 index da765c3..0000000 --- a/SOURCES/0007-nft-add-type-field-to-builtin_table.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 312897725486bf4a3014076f3659cc1d8ce294ce Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Sat, 17 Nov 2018 18:10:15 +0100 -Subject: [PATCH] nft: add type field to builtin_table - -Use enum nft_table_type to set the new type field in the structure that -define tables. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 9847abe6fbb91621f6494df8243ff96f04efdc4a) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 8 ++++++++ - iptables/nft.h | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 36529048a0ca6..f0a60e1f568af 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -379,6 +379,7 @@ static int batch_rule_add(struct nft_handle *h, enum obj_update_type type, - struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - [NFT_TABLE_RAW] = { - .name = "raw", -+ .type = NFT_TABLE_RAW, - .chains = { - { - .name = "PREROUTING", -@@ -396,6 +397,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - }, - [NFT_TABLE_MANGLE] = { - .name = "mangle", -+ .type = NFT_TABLE_MANGLE, - .chains = { - { - .name = "PREROUTING", -@@ -431,6 +433,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - }, - [NFT_TABLE_FILTER] = { - .name = "filter", -+ .type = NFT_TABLE_FILTER, - .chains = { - { - .name = "INPUT", -@@ -454,6 +457,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - }, - [NFT_TABLE_SECURITY] = { - .name = "security", -+ .type = NFT_TABLE_SECURITY, - .chains = { - { - .name = "INPUT", -@@ -477,6 +481,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - }, - [NFT_TABLE_NAT] = { - .name = "nat", -+ .type = NFT_TABLE_NAT, - .chains = { - { - .name = "PREROUTING", -@@ -511,6 +516,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - struct builtin_table xtables_arp[NFT_TABLE_MAX] = { - [NFT_TABLE_FILTER] = { - .name = "filter", -+ .type = NFT_TABLE_FILTER, - .chains = { - { - .name = "INPUT", -@@ -533,6 +539,7 @@ struct builtin_table xtables_arp[NFT_TABLE_MAX] = { - struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { - [NFT_TABLE_FILTER] = { - .name = "filter", -+ .type = NFT_TABLE_FILTER, - .chains = { - { - .name = "INPUT", -@@ -556,6 +563,7 @@ struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { - }, - [NFT_TABLE_NAT] = { - .name = "nat", -+ .type = NFT_TABLE_NAT, - .chains = { - { - .name = "PREROUTING", -diff --git a/iptables/nft.h b/iptables/nft.h -index 6229221bd51f7..85c894e80e02e 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -23,6 +23,7 @@ struct builtin_chain { - - struct builtin_table { - const char *name; -+ enum nft_table_type type; - struct builtin_chain chains[NF_INET_NUMHOOKS]; - bool initialized; - struct nftnl_chain_list *chain_cache; --- -2.21.0 - diff --git a/SOURCES/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch b/SOURCES/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch new file mode 100644 index 0000000..5ef2d9e --- /dev/null +++ b/SOURCES/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch @@ -0,0 +1,40 @@ +From 5fe54ca701a38e283faf840903e9ed20eba8a6f4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 16:01:29 +0100 +Subject: [PATCH] xtables-translate: Guard strcpy() call in xlate_ifname() + +The function potentially fed overlong strings to strcpy(). Given that +everything needed to avoid this is there, reorder code a bit to prevent +those inputs, too. + +Fixes: 0ddd663e9c167 ("iptables-translate: add in/out ifname wildcard match translation to nft") +(cherry picked from commit 2861bdbbf062071487a49103513d129ce40e2652) +Signed-off-by: Phil Sutter +--- + iptables/xtables-translate.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index a42c60a3b64c6..77a186b905d73 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -32,14 +32,13 @@ + void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, + bool invert) + { ++ int ifaclen = strlen(ifname); + char iface[IFNAMSIZ]; +- int ifaclen; + +- if (ifname[0] == '\0') ++ if (ifaclen < 1 || ifaclen >= IFNAMSIZ) + return; + + strcpy(iface, ifname); +- ifaclen = strlen(iface); + if (iface[ifaclen - 1] == '+') + iface[ifaclen - 1] = '*'; + +-- +2.24.0 + diff --git a/SOURCES/0008-extensions-among-Check-call-to-fstat.patch b/SOURCES/0008-extensions-among-Check-call-to-fstat.patch new file mode 100644 index 0000000..8d6bd90 --- /dev/null +++ b/SOURCES/0008-extensions-among-Check-call-to-fstat.patch @@ -0,0 +1,41 @@ +From 3a4d59e5cb35cf2395cfd8004dd16d45dd889e11 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 16:35:51 +0100 +Subject: [PATCH] extensions: among: Check call to fstat() + +If this fails, a bogus length value may be passed to mmap(). + +Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support") +(cherry picked from commit 25b38bcbf2fdc019f438805c7d1ecd877af9c968) +Signed-off-by: Phil Sutter +--- + extensions/libebt_among.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index 2e87db3bc06fa..715d559f432c2 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -6,6 +6,7 @@ + * August, 2003 + */ + ++#include + #include + #include + #include +@@ -137,7 +138,10 @@ static int bramong_parse(int c, char **argv, int invert, + if ((fd = open(optarg, O_RDONLY)) == -1) + xtables_error(PARAMETER_PROBLEM, + "Couldn't open file '%s'", optarg); +- fstat(fd, &stats); ++ if (fstat(fd, &stats) < 0) ++ xtables_error(PARAMETER_PROBLEM, ++ "fstat(%s) failed: '%s'", ++ optarg, strerror(errno)); + flen = stats.st_size; + /* use mmap because the file will probably be big */ + optarg = mmap(0, flen, PROT_READ | PROT_WRITE, +-- +2.24.0 + diff --git a/SOURCES/0008-nft-move-chain_cache-back-to-struct-nft_handle.patch b/SOURCES/0008-nft-move-chain_cache-back-to-struct-nft_handle.patch deleted file mode 100644 index 75f8802..0000000 --- a/SOURCES/0008-nft-move-chain_cache-back-to-struct-nft_handle.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 48455efdfbee0df02c724a594cf8af8c440ded7d Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Sat, 17 Nov 2018 18:16:45 +0100 -Subject: [PATCH] nft: move chain_cache back to struct nft_handle - -Place this back into the structure that stores the state information. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 1847d9db753825b0bd1cd450b549f4e39f7bcc31) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 26 +++++++++++++------------- - iptables/nft.h | 4 +++- - 2 files changed, 16 insertions(+), 14 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index f0a60e1f568af..fdb4ead55a873 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -809,14 +809,14 @@ static void flush_chain_cache(struct nft_handle *h, const char *tablename) - if (tablename && strcmp(h->tables[i].name, tablename)) - continue; - -- if (h->tables[i].chain_cache) { -+ if (h->table[i].chain_cache) { - if (tablename) { -- nftnl_chain_list_foreach(h->tables[i].chain_cache, -+ nftnl_chain_list_foreach(h->table[i].chain_cache, - __flush_chain_cache, NULL); - break; - } else { -- nftnl_chain_list_free(h->tables[i].chain_cache); -- h->tables[i].chain_cache = NULL; -+ nftnl_chain_list_free(h->table[i].chain_cache); -+ h->table[i].chain_cache = NULL; - } - } - } -@@ -1276,13 +1276,13 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) - if (!t) - goto out; - -- if (!t->chain_cache) { -- t->chain_cache = nftnl_chain_list_alloc(); -- if (!t->chain_cache) -+ if (!h->table[t->type].chain_cache) { -+ h->table[t->type].chain_cache = nftnl_chain_list_alloc(); -+ if (!h->table[t->type].chain_cache) - goto out; - } - -- nftnl_chain_list_add_tail(c, t->chain_cache); -+ nftnl_chain_list_add_tail(c, h->table[t->type].chain_cache); - - return MNL_CB_OK; - out: -@@ -1303,8 +1303,8 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - if (!t) - return NULL; - -- if (t->chain_cache) -- return t->chain_cache; -+ if (h->table[t->type].chain_cache) -+ return h->table[t->type].chain_cache; - retry: - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, - NLM_F_DUMP, h->seq); -@@ -1315,10 +1315,10 @@ retry: - goto retry; - } - -- if (!t->chain_cache) -- t->chain_cache = nftnl_chain_list_alloc(); -+ if (!h->table[t->type].chain_cache) -+ h->table[t->type].chain_cache = nftnl_chain_list_alloc(); - -- return t->chain_cache; -+ return h->table[t->type].chain_cache; - } - - static const char *policy_name[NF_ACCEPT+1] = { -diff --git a/iptables/nft.h b/iptables/nft.h -index 85c894e80e02e..1c028206221c4 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -26,7 +26,6 @@ struct builtin_table { - enum nft_table_type type; - struct builtin_chain chains[NF_INET_NUMHOOKS]; - bool initialized; -- struct nftnl_chain_list *chain_cache; - }; - - struct nft_handle { -@@ -40,6 +39,9 @@ struct nft_handle { - struct list_head err_list; - struct nft_family_ops *ops; - struct builtin_table *tables; -+ struct { -+ struct nftnl_chain_list *chain_cache; -+ } table[NFT_TABLE_MAX]; - struct nftnl_rule_list *rule_cache; - bool restore; - int8_t config_done; --- -2.21.0 - diff --git a/SOURCES/0009-nft-move-initialize-to-struct-nft_handle.patch b/SOURCES/0009-nft-move-initialize-to-struct-nft_handle.patch deleted file mode 100644 index 9bacf4d..0000000 --- a/SOURCES/0009-nft-move-initialize-to-struct-nft_handle.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 6186853420f23e500e0b9a234cc446697cca16a7 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Sat, 17 Nov 2018 18:38:30 +0100 -Subject: [PATCH] nft: move initialize to struct nft_handle - -Move this to the structure that stores, stateful information. Introduce -nft_table_initialized() and use it. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 5016d1eb84f951d84f5a0c18f994f40677ad0643) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 14 ++++++++++---- - iptables/nft.h | 2 +- - 2 files changed, 11 insertions(+), 5 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index fdb4ead55a873..9b479307a2fbc 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -587,13 +587,19 @@ struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { - }, - }; - -+static bool nft_table_initialized(const struct nft_handle *h, -+ enum nft_table_type type) -+{ -+ return h->table[type].initialized; -+} -+ - static int nft_table_builtin_add(struct nft_handle *h, - struct builtin_table *_t) - { - struct nftnl_table *t; - int ret; - -- if (_t->initialized) -+ if (nft_table_initialized(h, _t->type)) - return 0; - - t = nftnl_table_alloc(); -@@ -707,7 +713,7 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table) - if (t == NULL) - return -1; - -- if (t->initialized) -+ if (nft_table_initialized(h, t->type)) - return 0; - - if (nft_table_builtin_add(h, t) < 0) -@@ -715,7 +721,7 @@ static int nft_xt_builtin_init(struct nft_handle *h, const char *table) - - nft_chain_builtin_init(h, t); - -- t->initialized = true; -+ h->table[t->type].initialized = true; - - return 0; - } -@@ -1875,7 +1881,7 @@ static int __nft_table_flush(struct nft_handle *h, const char *table) - - _t = nft_table_builtin_find(h, table); - assert(_t); -- _t->initialized = false; -+ h->table[_t->type].initialized = false; - - flush_chain_cache(h, table); - flush_rule_cache(h, table); -diff --git a/iptables/nft.h b/iptables/nft.h -index 1c028206221c4..b9ba66b110042 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -25,7 +25,6 @@ struct builtin_table { - const char *name; - enum nft_table_type type; - struct builtin_chain chains[NF_INET_NUMHOOKS]; -- bool initialized; - }; - - struct nft_handle { -@@ -41,6 +40,7 @@ struct nft_handle { - struct builtin_table *tables; - struct { - struct nftnl_chain_list *chain_cache; -+ bool initialized; - } table[NFT_TABLE_MAX]; - struct nftnl_rule_list *rule_cache; - bool restore; --- -2.21.0 - diff --git a/SOURCES/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch b/SOURCES/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch new file mode 100644 index 0000000..1842162 --- /dev/null +++ b/SOURCES/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch @@ -0,0 +1,43 @@ +From fe1ac5eaa8ae482c9112aed6b89f9f2e529f4516 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 10 Dec 2019 12:27:13 +0100 +Subject: [PATCH] uapi: netfilter: Avoid undefined left-shift in xt_sctp.h + +This is a backport of kernel commit 164166558aace ("netfilter: uapi: +Avoid undefined left-shift in xt_sctp.h"). + +Signed-off-by: Phil Sutter +--- + include/linux/netfilter/xt_sctp.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h +index a501e6196905d..5b28525a2482a 100644 +--- a/include/linux/netfilter/xt_sctp.h ++++ b/include/linux/netfilter/xt_sctp.h +@@ -40,19 +40,19 @@ struct xt_sctp_info { + #define SCTP_CHUNKMAP_SET(chunkmap, type) \ + do { \ + (chunkmap)[type / bytes(__u32)] |= \ +- 1 << (type % bytes(__u32)); \ ++ 1u << (type % bytes(__u32)); \ + } while (0) + + #define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ + do { \ + (chunkmap)[type / bytes(__u32)] &= \ +- ~(1 << (type % bytes(__u32))); \ ++ ~(1u << (type % bytes(__u32))); \ + } while (0) + + #define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ + ({ \ + ((chunkmap)[type / bytes (__u32)] & \ +- (1 << (type % bytes (__u32)))) ? 1: 0; \ ++ (1u << (type % bytes (__u32)))) ? 1: 0; \ + }) + + #define SCTP_CHUNKMAP_RESET(chunkmap) \ +-- +2.24.0 + diff --git a/SOURCES/0010-xtables-constify-struct-builtin_table-and-struct-bui.patch b/SOURCES/0010-xtables-constify-struct-builtin_table-and-struct-bui.patch deleted file mode 100644 index 1118c3c..0000000 --- a/SOURCES/0010-xtables-constify-struct-builtin_table-and-struct-bui.patch +++ /dev/null @@ -1,287 +0,0 @@ -From e73749ba27388068af05e78ed6cb03b1824182c0 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Sat, 17 Nov 2018 18:25:58 +0100 -Subject: [PATCH] xtables: constify struct builtin_table and struct - builtin_chain - -These definitions should be const, propagate this to all existing users. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 3c7ea26c85b95a4c62355c359030d6bbdf2f8df0) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 42 ++++++++++++++++++------------------ - iptables/nft.h | 14 ++++++------ - iptables/xtables-restore.c | 4 ++-- - iptables/xtables-save.c | 2 +- - iptables/xtables-translate.c | 2 +- - 5 files changed, 32 insertions(+), 32 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 9b479307a2fbc..7b6fb2b10686d 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -376,7 +376,7 @@ static int batch_rule_add(struct nft_handle *h, enum obj_update_type type, - return batch_add(h, type, r); - } - --struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { -+const struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - [NFT_TABLE_RAW] = { - .name = "raw", - .type = NFT_TABLE_RAW, -@@ -513,7 +513,7 @@ struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { - - #include - --struct builtin_table xtables_arp[NFT_TABLE_MAX] = { -+const struct builtin_table xtables_arp[NFT_TABLE_MAX] = { - [NFT_TABLE_FILTER] = { - .name = "filter", - .type = NFT_TABLE_FILTER, -@@ -536,7 +536,7 @@ struct builtin_table xtables_arp[NFT_TABLE_MAX] = { - - #include - --struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { -+const struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { - [NFT_TABLE_FILTER] = { - .name = "filter", - .type = NFT_TABLE_FILTER, -@@ -594,7 +594,7 @@ static bool nft_table_initialized(const struct nft_handle *h, - } - - static int nft_table_builtin_add(struct nft_handle *h, -- struct builtin_table *_t) -+ const struct builtin_table *_t) - { - struct nftnl_table *t; - int ret; -@@ -614,8 +614,8 @@ static int nft_table_builtin_add(struct nft_handle *h, - } - - static struct nftnl_chain * --nft_chain_builtin_alloc(struct builtin_table *table, -- struct builtin_chain *chain, int policy) -+nft_chain_builtin_alloc(const struct builtin_table *table, -+ const struct builtin_chain *chain, int policy) - { - struct nftnl_chain *c; - -@@ -634,8 +634,8 @@ nft_chain_builtin_alloc(struct builtin_table *table, - } - - static void nft_chain_builtin_add(struct nft_handle *h, -- struct builtin_table *table, -- struct builtin_chain *chain) -+ const struct builtin_table *table, -+ const struct builtin_chain *chain) - { - struct nftnl_chain *c; - -@@ -647,7 +647,7 @@ static void nft_chain_builtin_add(struct nft_handle *h, - } - - /* find if built-in table already exists */ --struct builtin_table * -+const struct builtin_table * - nft_table_builtin_find(struct nft_handle *h, const char *table) - { - int i; -@@ -668,8 +668,8 @@ nft_table_builtin_find(struct nft_handle *h, const char *table) - } - - /* find if built-in chain already exists */ --struct builtin_chain * --nft_chain_builtin_find(struct builtin_table *t, const char *chain) -+const struct builtin_chain * -+nft_chain_builtin_find(const struct builtin_table *t, const char *chain) - { - int i; - bool found = false; -@@ -685,7 +685,7 @@ nft_chain_builtin_find(struct builtin_table *t, const char *chain) - } - - static void nft_chain_builtin_init(struct nft_handle *h, -- struct builtin_table *table) -+ const struct builtin_table *table) - { - struct nftnl_chain_list *list = nft_chain_list_get(h, table->name); - struct nftnl_chain *c; -@@ -707,7 +707,7 @@ static void nft_chain_builtin_init(struct nft_handle *h, - - static int nft_xt_builtin_init(struct nft_handle *h, const char *table) - { -- struct builtin_table *t; -+ const struct builtin_table *t; - - t = nft_table_builtin_find(h, table); - if (t == NULL) -@@ -750,7 +750,7 @@ static int nft_restart(struct nft_handle *h) - return 0; - } - --int nft_init(struct nft_handle *h, struct builtin_table *t) -+int nft_init(struct nft_handle *h, const struct builtin_table *t) - { - h->nl = mnl_socket_open(NETLINK_NETFILTER); - if (h->nl == NULL) -@@ -852,8 +852,8 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h, - const struct xt_counters *counters) - { - struct nftnl_chain *c; -- struct builtin_table *_t; -- struct builtin_chain *_c; -+ const struct builtin_table *_t; -+ const struct builtin_chain *_c; - - _t = nft_table_builtin_find(h, table); - if (!_t) { -@@ -1267,7 +1267,7 @@ nft_rule_print_save(const struct nftnl_rule *r, enum nft_rule_print type, - static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) - { - struct nft_handle *h = data; -- struct builtin_table *t; -+ const struct builtin_table *t; - struct nftnl_chain *c; - - c = nftnl_chain_alloc(); -@@ -1302,7 +1302,7 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - { - char buf[16536]; - struct nlmsghdr *nlh; -- struct builtin_table *t; -+ const struct builtin_table *t; - int ret; - - t = nft_table_builtin_find(h, table); -@@ -1703,7 +1703,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain) - bool nft_chain_exists(struct nft_handle *h, - const char *table, const char *chain) - { -- struct builtin_table *t = nft_table_builtin_find(h, table); -+ const struct builtin_table *t = nft_table_builtin_find(h, table); - - /* xtables does not support custom tables */ - if (!t) -@@ -1868,7 +1868,7 @@ int nft_for_each_table(struct nft_handle *h, - - static int __nft_table_flush(struct nft_handle *h, const char *table) - { -- struct builtin_table *_t; -+ const struct builtin_table *_t; - struct nftnl_table *t; - - t = nftnl_table_alloc(); -@@ -3166,7 +3166,7 @@ static int nft_is_chain_compatible(const struct nft_handle *h, - const struct nftnl_chain *chain) - { - const char *table, *name, *type, *cur_table; -- struct builtin_chain *chains; -+ const struct builtin_chain *chains; - int i, j, prio; - enum nf_inet_hooks hook; - -diff --git a/iptables/nft.h b/iptables/nft.h -index b9ba66b110042..bf60ab3943659 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -37,7 +37,7 @@ struct nft_handle { - struct nftnl_batch *batch; - struct list_head err_list; - struct nft_family_ops *ops; -- struct builtin_table *tables; -+ const struct builtin_table *tables; - struct { - struct nftnl_chain_list *chain_cache; - bool initialized; -@@ -52,14 +52,14 @@ struct nft_handle { - } error; - }; - --extern struct builtin_table xtables_ipv4[NFT_TABLE_MAX]; --extern struct builtin_table xtables_arp[NFT_TABLE_MAX]; --extern struct builtin_table xtables_bridge[NFT_TABLE_MAX]; -+extern const struct builtin_table xtables_ipv4[NFT_TABLE_MAX]; -+extern const struct builtin_table xtables_arp[NFT_TABLE_MAX]; -+extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX]; - - int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, - int (*cb)(const struct nlmsghdr *nlh, void *data), - void *data); --int nft_init(struct nft_handle *h, struct builtin_table *t); -+int nft_init(struct nft_handle *h, const struct builtin_table *t); - void nft_fini(struct nft_handle *h); - - /* -@@ -73,7 +73,7 @@ bool nft_table_find(struct nft_handle *h, const char *tablename); - int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list); - int nft_table_flush(struct nft_handle *h, const char *table); - void nft_table_new(struct nft_handle *h, const char *table); --struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table); -+const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table); - - /* - * Operations with chains. -@@ -92,7 +92,7 @@ int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list, - const char *chain, const char *table); - int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname); - int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose); --struct builtin_chain *nft_chain_builtin_find(struct builtin_table *t, const char *chain); -+const struct builtin_chain *nft_chain_builtin_find(const struct builtin_table *t, const char *chain); - bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain); - - /* -diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c -index a46a92955a01a..642876d6c70ac 100644 ---- a/iptables/xtables-restore.c -+++ b/iptables/xtables-restore.c -@@ -105,9 +105,9 @@ void xtables_restore_parse(struct nft_handle *h, - struct nft_xt_restore_cb *cb, - int argc, char *argv[]) - { -+ const struct builtin_table *curtable = NULL; - char buffer[10240]; - int in_table = 0; -- struct builtin_table *curtable = NULL; - const struct xtc_ops *ops = &xtc_ops; - struct nftnl_chain_list *chain_list = NULL; - -@@ -359,7 +359,7 @@ void xtables_restore_parse(struct nft_handle *h, - static int - xtables_restore_main(int family, const char *progname, int argc, char *argv[]) - { -- struct builtin_table *tables; -+ const struct builtin_table *tables; - struct nft_handle h = { - .family = family, - .restore = true, -diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c -index d121d50e180ff..414a864b6196b 100644 ---- a/iptables/xtables-save.c -+++ b/iptables/xtables-save.c -@@ -122,7 +122,7 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) - static int - xtables_save_main(int family, const char *progname, int argc, char *argv[]) - { -- struct builtin_table *tables; -+ const struct builtin_table *tables; - const char *tablename = NULL; - bool dump = false; - struct nft_handle h = { -diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c -index 849c53f30e155..e1d2a7d6cce88 100644 ---- a/iptables/xtables-translate.c -+++ b/iptables/xtables-translate.c -@@ -426,7 +426,7 @@ static int xtables_xlate_main_common(struct nft_handle *h, - int family, - const char *progname) - { -- struct builtin_table *tables; -+ const struct builtin_table *tables; - int ret; - - xtables_globals.program_name = progname; --- -2.21.0 - diff --git a/SOURCES/0011-nft-Simplify-nftnl_rule_list_chain_save.patch b/SOURCES/0011-nft-Simplify-nftnl_rule_list_chain_save.patch deleted file mode 100644 index 3604d25..0000000 --- a/SOURCES/0011-nft-Simplify-nftnl_rule_list_chain_save.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 014b6acbb382f42dd20577fa1ff6e013526a57d5 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:02 +0100 -Subject: [PATCH] nft: Simplify nftnl_rule_list_chain_save() - -Since there are per table chain caches, The chain list passed to that -function is comprised of chains belonging to the right table only. -Therefore the table name check can safely be skipped. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 71f9e474d467dd59582d7a3920eded9613b99000) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 7b6fb2b10686d..9d20eb0eac2db 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2381,8 +2381,7 @@ list_save(struct nftnl_rule *r, unsigned int num, unsigned int format) - - static int - nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain, -- const char *table, struct nftnl_chain_list *list, -- int counters) -+ struct nftnl_chain_list *list, int counters) - { - struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; -@@ -2393,15 +2392,12 @@ nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain, - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *chain_table = -- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - uint32_t policy = - nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - -- if (strcmp(table, chain_table) != 0 || -- (chain && strcmp(chain, chain_name) != 0)) -+ if (chain && strcmp(chain, chain_name) != 0) - goto next; - - /* this is a base chain */ -@@ -2458,7 +2454,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - - /* Dump policies and custom chains first */ - if (!rulenum) -- nftnl_rule_list_chain_save(h, chain, table, list, counters); -+ nftnl_rule_list_chain_save(h, chain, list, counters); - - /* Now dump out rules in this table */ - iter = nftnl_chain_list_iter_create(list); --- -2.21.0 - diff --git a/SOURCES/0012-nft-Review-unclear-return-points.patch b/SOURCES/0012-nft-Review-unclear-return-points.patch deleted file mode 100644 index 395f42d..0000000 --- a/SOURCES/0012-nft-Review-unclear-return-points.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d54baa487a93f54d192de82704e1fba9675fcadc Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:03 +0100 -Subject: [PATCH] nft: Review unclear return points - -When converting to per table chain caches, these two error returns were -marked for review but apparently forgotten. Make sure error condition is -propagated when returning at those points. - -Fixes: c58ecf9f8bcb7 ("xtables: Introduce per table chain caches") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 7e09582a57440f13796bdd5bd70466ef0913345b) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 9d20eb0eac2db..1fca1f17147f6 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2311,7 +2311,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - - list = nft_chain_list_get(h, table); - if (!list) -- goto err; /* XXX: return 0 instead? */ -+ return 0; - - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) -@@ -2450,7 +2450,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - - list = nft_chain_list_get(h, table); - if (!list) -- goto err; /* XXX: correct? */ -+ goto err; - - /* Dump policies and custom chains first */ - if (!rulenum) --- -2.21.0 - diff --git a/SOURCES/0013-xtables-restore-Review-chain-handling.patch b/SOURCES/0013-xtables-restore-Review-chain-handling.patch deleted file mode 100644 index 826c3a8..0000000 --- a/SOURCES/0013-xtables-restore-Review-chain-handling.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 757b84e866dc1f288c54ad5ca9868b1765da3948 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:04 +0100 -Subject: [PATCH] xtables-restore: Review chain handling - -There is no need to "delete" (actually, remove from cache) a chain if -noflush wasn't given: While handling the corresponding table line, -'table_flush' callback has already taken care of that. - -This .chain_del indirection is not required since d1eb4d587297 -("iptables-compat: chains are purge out already from table flush"). - -Streamlining the code further, move syntax checks to the top. If these -concede, there are three cases to distinguish: - -A) Given chain name matches a builtin one in current table, so assume it - exists already and just set policy and counters. - -B) Noflush was given and the (custom) chain exists already, flush it. - -C) Custom chain was either flushed (noflush not given) or didn't exist - before, create it. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 9523b2e9dee3d9b4439214092c496542ce9f434e) -Signed-off-by: Phil Sutter ---- - iptables/nft-shared.h | 2 -- - iptables/xtables-restore.c | 68 +++++++++++--------------------------- - 2 files changed, 19 insertions(+), 51 deletions(-) - -diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h -index 9a61d8d2863e3..17fff984ba312 100644 ---- a/iptables/nft-shared.h -+++ b/iptables/nft-shared.h -@@ -253,8 +253,6 @@ struct nft_xt_restore_cb { - void (*table_new)(struct nft_handle *h, const char *table); - struct nftnl_chain_list *(*chain_list)(struct nft_handle *h, - const char *table); -- void (*chain_del)(struct nftnl_chain_list *clist, const char *curtable, -- const char *chain); - int (*chain_user_flush)(struct nft_handle *h, - struct nftnl_chain_list *clist, - const char *table, const char *chain); -diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c -index 642876d6c70ac..4e00ed86be06d 100644 ---- a/iptables/xtables-restore.c -+++ b/iptables/xtables-restore.c -@@ -68,21 +68,6 @@ static struct nftnl_chain_list *get_chain_list(struct nft_handle *h, - return chain_list; - } - --static void chain_delete(struct nftnl_chain_list *clist, const char *curtable, -- const char *chain) --{ -- struct nftnl_chain *chain_obj; -- -- chain_obj = nft_chain_list_find(clist, chain); -- /* This chain has been found, delete from list. Later -- * on, unvisited chains will be purged out. -- */ -- if (chain_obj != NULL) { -- nftnl_chain_list_del(chain_obj); -- nftnl_chain_free(chain_obj); -- } --} -- - struct nft_xt_restore_cb restore_cb = { - .chain_list = get_chain_list, - .commit = nft_commit, -@@ -90,7 +75,6 @@ struct nft_xt_restore_cb restore_cb = { - .table_new = nft_table_new, - .table_flush = nft_table_flush, - .chain_user_flush = nft_chain_user_flush, -- .chain_del = chain_delete, - .do_command = do_commandx, - .chain_set = nft_chain_set, - .chain_user_add = nft_chain_user_add, -@@ -183,7 +167,6 @@ void xtables_restore_parse(struct nft_handle *h, - /* New chain. */ - char *policy, *chain = NULL; - struct xt_counters count = {}; -- bool chain_exists = false; - - chain = strtok(buffer+1, " \t\n"); - DEBUGP("line %u, chain '%s'\n", line, chain); -@@ -194,21 +177,6 @@ void xtables_restore_parse(struct nft_handle *h, - exit(1); - } - -- if (noflush == 0) { -- if (cb->chain_del) -- cb->chain_del(chain_list, curtable->name, -- chain); -- } else if (nft_chain_list_find(chain_list, chain)) { -- chain_exists = true; -- /* Apparently -n still flushes existing user -- * defined chains that are redefined. Otherwise, -- * leave them as is. -- */ -- if (cb->chain_user_flush) -- cb->chain_user_flush(h, chain_list, -- curtable->name, chain); -- } -- - if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) - xtables_error(PARAMETER_PROBLEM, - "Invalid chain name `%s' " -@@ -246,24 +214,28 @@ void xtables_restore_parse(struct nft_handle *h, - } - DEBUGP("Setting policy of chain %s to %s\n", - chain, policy); -- ret = 1; - -- } else { -- if (!chain_exists && -- cb->chain_user_add && -- cb->chain_user_add(h, chain, -- curtable->name) < 0) { -- if (errno == EEXIST) -- continue; -+ } else if (noflush && -+ nftnl_chain_list_lookup_byname(chain_list, chain)) { -+ /* Apparently -n still flushes existing user -+ * defined chains that are redefined. Otherwise, -+ * leave them as is. -+ */ -+ if (cb->chain_user_flush) -+ cb->chain_user_flush(h, chain_list, -+ curtable->name, chain); -+ } else if (cb->chain_user_add && -+ cb->chain_user_add(h, chain, -+ curtable->name) < 0) { -+ if (errno == EEXIST) -+ continue; - -- xtables_error(PARAMETER_PROBLEM, -- "cannot create chain " -- "'%s' (%s)\n", chain, -- strerror(errno)); -- } -- continue; -+ xtables_error(PARAMETER_PROBLEM, -+ "cannot create chain " -+ "'%s' (%s)\n", chain, -+ strerror(errno)); - } -- -+ ret = 1; - } else if (in_table) { - int a; - char *pcnt = NULL; -@@ -496,7 +468,6 @@ struct nft_xt_restore_cb ebt_restore_cb = { - .table_new = nft_table_new, - .table_flush = nft_table_flush, - .chain_user_flush = nft_chain_user_flush, -- .chain_del = chain_delete, - .do_command = do_commandeb, - .chain_set = nft_chain_set, - .chain_user_add = nft_chain_user_add, -@@ -542,7 +513,6 @@ struct nft_xt_restore_cb arp_restore_cb = { - .table_new = nft_table_new, - .table_flush = nft_table_flush, - .chain_user_flush = nft_chain_user_flush, -- .chain_del = chain_delete, - .do_command = do_commandarp, - .chain_set = nft_chain_set, - .chain_user_add = nft_chain_user_add, --- -2.21.0 - diff --git a/SOURCES/0014-nft-Review-is_-_compatible-routines.patch b/SOURCES/0014-nft-Review-is_-_compatible-routines.patch deleted file mode 100644 index b35c248..0000000 --- a/SOURCES/0014-nft-Review-is_-_compatible-routines.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 109b8f2d637b5e4b1a6ff6994297203834e4e77a Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:05 +0100 -Subject: [PATCH] nft: Review is_*_compatible() routines - -- Call to nft_table_builtin_find() in nft_is_table_compatible() is not - needed, as it is repeated in the latter call to nft_chain_list_get() - by nft_are_chains_compatible(). - -- Turn nft_is_chain_compatible(), nft_is_rule_compatible() and - nft_is_expr_compatible() into callbacks for use with respective - foreach functions. - -- nft_are_chains_compatible() is not needed anymore due to foreach - function use. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit e774b15299c271a4c7570899591cf1b7960477ea) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 153 ++++++++++++++++++------------------------------- - 1 file changed, 55 insertions(+), 98 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 1fca1f17147f6..5032c718b33a9 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -3115,7 +3115,7 @@ static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = { - }; - - --static int nft_is_expr_compatible(const struct nftnl_expr *expr) -+static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data) - { - const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME); - int i; -@@ -3130,138 +3130,95 @@ static int nft_is_expr_compatible(const struct nftnl_expr *expr) - nftnl_expr_get_u32(expr, NFTNL_EXPR_LIMIT_FLAGS) == 0) - return 0; - -- return 1; -+ return -1; - } - --static bool nft_is_rule_compatible(struct nftnl_rule *rule) --{ -- struct nftnl_expr_iter *iter; -- struct nftnl_expr *expr; -- bool compatible = false; -- -- iter = nftnl_expr_iter_create(rule); -- if (iter == NULL) -- return false; -+struct nft_is_rule_compatible_data { -+ const char *tablename; -+}; - -- expr = nftnl_expr_iter_next(iter); -- while (expr != NULL) { -- if (nft_is_expr_compatible(expr) == 0) { -- expr = nftnl_expr_iter_next(iter); -- continue; -- } -+static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data) -+{ -+ const char *table = nftnl_rule_get_str(rule, NFTNL_RULE_TABLE); -+ struct nft_is_rule_compatible_data *d = data; - -- compatible = true; -- break; -- } -+ /* ignore rules belonging to a different table */ -+ if (strcmp(table, d->tablename)) -+ return 0; - -- nftnl_expr_iter_destroy(iter); -- return compatible; -+ return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL); - } - --static int nft_is_chain_compatible(const struct nft_handle *h, -- const struct nftnl_chain *chain) -+static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) - { -- const char *table, *name, *type, *cur_table; -- const struct builtin_chain *chains; -- int i, j, prio; -+ const struct builtin_chain *chains = NULL, *chain = NULL; -+ const char *table, *name, *type; -+ struct nft_handle *h = data; - enum nf_inet_hooks hook; -+ int i, prio; - -- table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE); -- name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME); -- type = nftnl_chain_get(chain, NFTNL_CHAIN_TYPE); -- prio = nftnl_chain_get_u32(chain, NFTNL_CHAIN_PRIO); -- hook = nftnl_chain_get_u32(chain, NFTNL_CHAIN_HOOKNUM); -+ if (!nft_chain_builtin(c)) -+ return 0; - -+ /* find chain's table in builtin tables */ -+ table = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); - for (i = 0; i < NFT_TABLE_MAX; i++) { -- cur_table = h->tables[i].name; -- chains = h->tables[i].chains; -+ const char *cur_table = h->tables[i].name; - -- if (!cur_table || strcmp(table, cur_table) != 0) -+ if (!cur_table || strcmp(cur_table, table)) - continue; - -- for (j = 0; j < NF_INET_NUMHOOKS && chains[j].name; j++) { -- if (strcmp(name, chains[j].name) != 0) -- continue; -- -- if (strcmp(type, chains[j].type) == 0 && -- prio == chains[j].prio && -- hook == chains[j].hook) -- return 0; -- break; -- } -+ chains = h->tables[i].chains; -+ break; - } -- -- return 1; --} -- --static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename) --{ -- struct nftnl_chain_list *list; -- struct nftnl_chain_list_iter *iter; -- struct nftnl_chain *chain; -- int ret = 0; -- -- list = nft_chain_list_get(h, tablename); -- if (list == NULL) -- return -1; -- -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -+ if (!chains) - return -1; - -- chain = nftnl_chain_list_iter_next(iter); -- while (chain != NULL) { -- if (!nft_chain_builtin(chain)) -- goto next; -+ /* find chain in builtin chain list */ -+ name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -+ for (i = 0; i < NF_INET_NUMHOOKS && chains[i].name; i++) { -+ if (strcmp(name, chains[i].name)) -+ continue; - -- ret = nft_is_chain_compatible(h, chain); -- if (ret != 0) -- break; --next: -- chain = nftnl_chain_list_iter_next(iter); -+ chain = &chains[i]; -+ break; - } -+ if (!chain) -+ return -1; - -- nftnl_chain_list_iter_destroy(iter); -+ /* compare properties */ -+ type = nftnl_chain_get_str(c, NFTNL_CHAIN_TYPE); -+ prio = nftnl_chain_get_u32(c, NFTNL_CHAIN_PRIO); -+ hook = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM); -+ if (strcmp(type, chain->type) || -+ prio != chain->prio || -+ hook != chain->hook) -+ return -1; - -- return ret; -+ return 0; - } - - bool nft_is_table_compatible(struct nft_handle *h, const char *tablename) - { -+ struct nft_is_rule_compatible_data rcd = { -+ .tablename = tablename -+ }; -+ struct nftnl_chain_list *clist; - struct nftnl_rule_list *list; -- struct nftnl_rule_list_iter *iter; -- struct nftnl_rule *rule; -- int ret = 0; - -- if (!nft_table_builtin_find(h, tablename)) -+ clist = nft_chain_list_get(h, tablename); -+ if (clist == NULL) - return false; - -- ret = nft_are_chains_compatible(h, tablename); -- if (ret != 0) -+ if (nftnl_chain_list_foreach(clist, nft_is_chain_compatible, h)) - return false; - - list = nft_rule_list_get(h); - if (list == NULL) - return true; - -- iter = nftnl_rule_list_iter_create(list); -- if (iter == NULL) -- return true; -- -- rule = nftnl_rule_list_iter_next(iter); -- while (rule != NULL) { -- const char *table = nftnl_rule_get_str(rule, NFTNL_RULE_TABLE); -- -- if (strcmp(table, tablename)) -- goto next_rule; -- -- ret = nft_is_rule_compatible(rule); -- if (ret != 0) -- break; --next_rule: -- rule = nftnl_rule_list_iter_next(iter); -- } -+ if (nftnl_rule_list_foreach(list, nft_is_rule_compatible, &rcd)) -+ return false; - -- nftnl_rule_list_iter_destroy(iter); -- return ret == 0; -+ return true; - } --- -2.21.0 - diff --git a/SOURCES/0015-nft-Reduce-__nft_rule_del-signature.patch b/SOURCES/0015-nft-Reduce-__nft_rule_del-signature.patch deleted file mode 100644 index b044125..0000000 --- a/SOURCES/0015-nft-Reduce-__nft_rule_del-signature.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0e260c69746ea4ff101b6f66bf40de8426cfccbd Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:06 +0100 -Subject: [PATCH] nft: Reduce __nft_rule_del() signature - -The function does not use passed struct nftnl_rule_list, so remove it -from its parameters. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 9975b6da9f926994bcea8ae788e47aab4b5b235e) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 5032c718b33a9..befd9f4dd9026 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1946,8 +1946,7 @@ void nft_table_new(struct nft_handle *h, const char *table) - nft_xt_builtin_init(h, table); - } - --static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule_list *list, -- struct nftnl_rule *r) -+static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r) - { - int ret; - -@@ -2046,7 +2045,7 @@ int nft_rule_delete(struct nft_handle *h, const char *chain, - - r = nft_rule_find(h, list, chain, table, data, -1); - if (r != NULL) { -- ret =__nft_rule_del(h, list, r); -+ ret =__nft_rule_del(h, r); - if (ret < 0) - errno = ENOMEM; - if (verbose) -@@ -2151,7 +2150,7 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, - r = nft_rule_find(h, list, chain, table, NULL, rulenum); - if (r != NULL) { - DEBUGP("deleting rule by number %d\n", rulenum); -- ret = __nft_rule_del(h, list, r); -+ ret = __nft_rule_del(h, r); - if (ret < 0) - errno = ENOMEM; - } else --- -2.21.0 - diff --git a/SOURCES/0016-nft-Reduce-indenting-level-in-flush_chain_cache.patch b/SOURCES/0016-nft-Reduce-indenting-level-in-flush_chain_cache.patch deleted file mode 100644 index ddcd2fb..0000000 --- a/SOURCES/0016-nft-Reduce-indenting-level-in-flush_chain_cache.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 3614b4bee283ea6d08207ccc5e2efa3ebfad321c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:07 +0100 -Subject: [PATCH] nft: Reduce indenting level in flush_chain_cache() - -Instead of doing all in one go, make two separate decisions: - -1) If table has no chain cache, either continue or return depending on - whether we're flushing for a specific table. - -2) With chain cache present, flushing strategy once more depends on - whether we're flushing for a specific table: If given, just remove - all rules and return. If not, free the cache and set to NULL (so that - it will be repopulated later), then continue the loop. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit d4b0d248cc057e39608c7c1c1203dd3f1ea96645) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 22 +++++++++++++--------- - 1 file changed, 13 insertions(+), 9 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index befd9f4dd9026..997d7bc58fd00 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -815,16 +815,20 @@ static void flush_chain_cache(struct nft_handle *h, const char *tablename) - if (tablename && strcmp(h->tables[i].name, tablename)) - continue; - -- if (h->table[i].chain_cache) { -- if (tablename) { -- nftnl_chain_list_foreach(h->table[i].chain_cache, -- __flush_chain_cache, NULL); -- break; -- } else { -- nftnl_chain_list_free(h->table[i].chain_cache); -- h->table[i].chain_cache = NULL; -- } -+ if (!h->table[i].chain_cache) { -+ if (tablename) -+ return; -+ continue; - } -+ -+ if (tablename) { -+ nftnl_chain_list_foreach(h->table[i].chain_cache, -+ __flush_chain_cache, NULL); -+ return; -+ } -+ -+ nftnl_chain_list_free(h->table[i].chain_cache); -+ h->table[i].chain_cache = NULL; - } - } - --- -2.21.0 - diff --git a/SOURCES/0017-nft-Simplify-per-table-chain-cache-update.patch b/SOURCES/0017-nft-Simplify-per-table-chain-cache-update.patch deleted file mode 100644 index ff29396..0000000 --- a/SOURCES/0017-nft-Simplify-per-table-chain-cache-update.patch +++ /dev/null @@ -1,86 +0,0 @@ -From eafa37433c920c6613bd351017d31cfd6e4cc397 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:08 +0100 -Subject: [PATCH] nft: Simplify per table chain cache update - -Previously, each table's chain cache was potentially unallocated until -nftnl_chain_list_cb() saw a chain for it. This means such callback had to -check the chain_cache pointer for each chain belonging to that table. - -In addition to the above, nft_chain_list_get() had to cover for the -possibility that a given table didn't have any chains at all in kernel, -so check requested table's chain cache once more and allocate it if -NULL. - -Instead, simply iterate over all tables and preallocate their chain -caches prior to requesting the chain list from kernel. The only caveat -is to flush the chain cache completely before retrying in case of EINTR. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 402dac2190e6011d4f4ad81c2992b7126b3d79d9) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 997d7bc58fd00..7d08a0884adde 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1286,12 +1286,6 @@ static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data) - if (!t) - goto out; - -- if (!h->table[t->type].chain_cache) { -- h->table[t->type].chain_cache = nftnl_chain_list_alloc(); -- if (!h->table[t->type].chain_cache) -- goto out; -- } -- - nftnl_chain_list_add_tail(c, h->table[t->type].chain_cache); - - return MNL_CB_OK; -@@ -1307,7 +1301,7 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - char buf[16536]; - struct nlmsghdr *nlh; - const struct builtin_table *t; -- int ret; -+ int i, ret; - - t = nft_table_builtin_find(h, table); - if (!t) -@@ -1316,18 +1310,27 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - if (h->table[t->type].chain_cache) - return h->table[t->type].chain_cache; - retry: -+ for (i = 0; i < NFT_TABLE_MAX; i++) { -+ enum nft_table_type type = h->tables[i].type; -+ -+ if (!h->tables[i].name) -+ continue; -+ -+ h->table[type].chain_cache = nftnl_chain_list_alloc(); -+ if (!h->table[type].chain_cache) -+ return NULL; -+ } -+ - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, - NLM_F_DUMP, h->seq); - - ret = mnl_talk(h, nlh, nftnl_chain_list_cb, h); - if (ret < 0 && errno == EINTR) { - assert(nft_restart(h) >= 0); -+ flush_chain_cache(h, NULL); - goto retry; - } - -- if (!h->table[t->type].chain_cache) -- h->table[t->type].chain_cache = nftnl_chain_list_alloc(); -- - return h->table[t->type].chain_cache; - } - --- -2.21.0 - diff --git a/SOURCES/0018-nft-Simplify-nft_rule_insert-a-bit.patch b/SOURCES/0018-nft-Simplify-nft_rule_insert-a-bit.patch deleted file mode 100644 index 38240fe..0000000 --- a/SOURCES/0018-nft-Simplify-nft_rule_insert-a-bit.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8ae498f20e89ae11f8cbde9a16e0e5397a274a8c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:09 +0100 -Subject: [PATCH] nft: Simplify nft_rule_insert() a bit - -Fetch rule list right on top instead of in each branch separately. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 88bd4f28878bc7d41daa23098d68bf1bf6f5cea2) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 7d08a0884adde..469448f42cd6d 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2091,8 +2091,8 @@ nft_rule_add(struct nft_handle *h, const char *chain, - int nft_rule_insert(struct nft_handle *h, const char *chain, - const char *table, void *data, int rulenum, bool verbose) - { -+ struct nftnl_rule_list *list = nft_rule_list_get(h); - struct nftnl_rule *r, *new_rule; -- struct nftnl_rule_list *list; - uint64_t handle = 0; - - /* If built-in chains don't exist for this table, create them */ -@@ -2102,7 +2102,6 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - nft_fn = nft_rule_insert; - - if (rulenum > 0) { -- list = nft_rule_list_get(h); - if (list == NULL) - goto err; - -@@ -2123,8 +2122,6 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - - handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE); - DEBUGP("adding after rule handle %"PRIu64"\n", handle); -- } else { -- nft_rule_list_get(h); - } - - new_rule = nft_rule_add(h, chain, table, data, handle, verbose); --- -2.21.0 - diff --git a/SOURCES/0019-nft-Introduce-fetch_chain_cache.patch b/SOURCES/0019-nft-Introduce-fetch_chain_cache.patch deleted file mode 100644 index 17868d1..0000000 --- a/SOURCES/0019-nft-Introduce-fetch_chain_cache.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0e72e49c0f220a9223de85574b878114bf8ceff3 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:10 +0100 -Subject: [PATCH] nft: Introduce fetch_chain_cache() - -Move chain cache population from nft_chain_list_get() into a dedicated -function. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 8bae620abf9ac81794acca43d305ca74f15a13ff) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 469448f42cd6d..b425577798679 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1295,20 +1295,12 @@ err: - return MNL_CB_OK; - } - --struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -- const char *table) -+static int fetch_chain_cache(struct nft_handle *h) - { - char buf[16536]; - struct nlmsghdr *nlh; -- const struct builtin_table *t; - int i, ret; - -- t = nft_table_builtin_find(h, table); -- if (!t) -- return NULL; -- -- if (h->table[t->type].chain_cache) -- return h->table[t->type].chain_cache; - retry: - for (i = 0; i < NFT_TABLE_MAX; i++) { - enum nft_table_type type = h->tables[i].type; -@@ -1318,7 +1310,7 @@ retry: - - h->table[type].chain_cache = nftnl_chain_list_alloc(); - if (!h->table[type].chain_cache) -- return NULL; -+ return -1; - } - - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family, -@@ -1331,6 +1323,21 @@ retry: - goto retry; - } - -+ return ret; -+} -+ -+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -+ const char *table) -+{ -+ const struct builtin_table *t; -+ -+ t = nft_table_builtin_find(h, table); -+ if (!t) -+ return NULL; -+ -+ if (!h->table[t->type].chain_cache) -+ fetch_chain_cache(h); -+ - return h->table[t->type].chain_cache; - } - --- -2.21.0 - diff --git a/SOURCES/0020-nft-Move-nft_rule_list_get-above-nft_chain_list_get.patch b/SOURCES/0020-nft-Move-nft_rule_list_get-above-nft_chain_list_get.patch deleted file mode 100644 index 5fbb973..0000000 --- a/SOURCES/0020-nft-Move-nft_rule_list_get-above-nft_chain_list_get.patch +++ /dev/null @@ -1,149 +0,0 @@ -From e3624bf4de451c53a3b42e1b83adab3051c03500 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:11 +0100 -Subject: [PATCH] nft: Move nft_rule_list_get() above nft_chain_list_get() - -Later when introducing per chain rule caches, nft_rule_list_get() will -be removed. But nftnl_rule_list_cb() which it uses will be reused to -update each chain's rule cache from inside nftnl_chain_list_get(), so -move both into position. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit eb13831f1c41c0efa626ab85d4448fb8ce4c87a2) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 110 ++++++++++++++++++++++++------------------------- - 1 file changed, 55 insertions(+), 55 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index b425577798679..1840561f2e531 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1326,61 +1326,6 @@ retry: - return ret; - } - --struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -- const char *table) --{ -- const struct builtin_table *t; -- -- t = nft_table_builtin_find(h, table); -- if (!t) -- return NULL; -- -- if (!h->table[t->type].chain_cache) -- fetch_chain_cache(h); -- -- return h->table[t->type].chain_cache; --} -- --static const char *policy_name[NF_ACCEPT+1] = { -- [NF_DROP] = "DROP", -- [NF_ACCEPT] = "ACCEPT", --}; -- --int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) --{ -- struct nftnl_chain_list_iter *iter; -- struct nft_family_ops *ops; -- struct nftnl_chain *c; -- -- ops = nft_family_ops_lookup(h->family); -- -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- return 0; -- -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *policy = NULL; -- -- if (nft_chain_builtin(c)) { -- uint32_t pol = NF_ACCEPT; -- -- if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) -- pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -- policy = policy_name[pol]; -- } -- -- if (ops->save_chain) -- ops->save_chain(c, policy); -- -- c = nftnl_chain_list_iter_next(iter); -- } -- -- nftnl_chain_list_iter_destroy(iter); -- -- return 1; --} -- - static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data) - { - struct nftnl_rule *r; -@@ -1437,6 +1382,61 @@ retry: - return list; - } - -+struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -+ const char *table) -+{ -+ const struct builtin_table *t; -+ -+ t = nft_table_builtin_find(h, table); -+ if (!t) -+ return NULL; -+ -+ if (!h->table[t->type].chain_cache) -+ fetch_chain_cache(h); -+ -+ return h->table[t->type].chain_cache; -+} -+ -+static const char *policy_name[NF_ACCEPT+1] = { -+ [NF_DROP] = "DROP", -+ [NF_ACCEPT] = "ACCEPT", -+}; -+ -+int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) -+{ -+ struct nftnl_chain_list_iter *iter; -+ struct nft_family_ops *ops; -+ struct nftnl_chain *c; -+ -+ ops = nft_family_ops_lookup(h->family); -+ -+ iter = nftnl_chain_list_iter_create(list); -+ if (iter == NULL) -+ return 0; -+ -+ c = nftnl_chain_list_iter_next(iter); -+ while (c != NULL) { -+ const char *policy = NULL; -+ -+ if (nft_chain_builtin(c)) { -+ uint32_t pol = NF_ACCEPT; -+ -+ if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) -+ pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -+ policy = policy_name[pol]; -+ } -+ -+ if (ops->save_chain) -+ ops->save_chain(c, policy); -+ -+ c = nftnl_chain_list_iter_next(iter); -+ } -+ -+ nftnl_chain_list_iter_destroy(iter); -+ -+ return 1; -+} -+ - int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) - { - struct nftnl_rule_list *list; --- -2.21.0 - diff --git a/SOURCES/0021-xtables-Implement-per-chain-rule-cache.patch b/SOURCES/0021-xtables-Implement-per-chain-rule-cache.patch deleted file mode 100644 index c12a69a..0000000 --- a/SOURCES/0021-xtables-Implement-per-chain-rule-cache.patch +++ /dev/null @@ -1,802 +0,0 @@ -From 56521a8270d740184510f660492e2c9f8588afbf Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:12 +0100 -Subject: [PATCH] xtables: Implement per chain rule cache - -Use recently introduced support for rules inside chains in libnftnl to -introduce a rule cache per chain instead of a global one. - -A tricky bit is to decide if cache should be updated or not. Previously, -the global rule cache was populated just once and then reused unless -being flushed completely (via call to flush_rule_cache() with -NULL-pointer table argument). Resemble this behaviour by introducing a -boolean indicating cache status and fetch rules for all chains when -updating the chain cache in nft_chain_list_get(). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 947c51c95edbbf08d6b3c105177ac5cfa238aade) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 386 +++++++++++++++++++++---------------------------- - iptables/nft.h | 2 +- - 2 files changed, 166 insertions(+), 222 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 1840561f2e531..842ed2b805bee 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -772,28 +772,15 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t) - - static int __flush_rule_cache(struct nftnl_rule *r, void *data) - { -- const char *tablename = data; -- -- if (!strcmp(nftnl_rule_get_str(r, NFTNL_RULE_TABLE), tablename)) { -- nftnl_rule_list_del(r); -- nftnl_rule_free(r); -- } -+ nftnl_rule_list_del(r); -+ nftnl_rule_free(r); - - return 0; - } - --static void flush_rule_cache(struct nft_handle *h, const char *tablename) -+static void flush_rule_cache(struct nftnl_chain *c) - { -- if (!h->rule_cache) -- return; -- -- if (tablename) { -- nftnl_rule_list_foreach(h->rule_cache, __flush_rule_cache, -- (void *)tablename); -- } else { -- nftnl_rule_list_free(h->rule_cache); -- h->rule_cache = NULL; -- } -+ nftnl_rule_foreach(c, __flush_rule_cache, NULL); - } - - static int __flush_chain_cache(struct nftnl_chain *c, void *data) -@@ -830,12 +817,12 @@ static void flush_chain_cache(struct nft_handle *h, const char *tablename) - nftnl_chain_list_free(h->table[i].chain_cache); - h->table[i].chain_cache = NULL; - } -+ h->have_cache = false; - } - - void nft_fini(struct nft_handle *h) - { - flush_chain_cache(h, NULL); -- flush_rule_cache(h, NULL); - mnl_socket_close(h->nl); - } - -@@ -1195,12 +1182,14 @@ err: - return NULL; - } - --static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h); -+static struct nftnl_chain * -+nft_chain_find(struct nft_handle *h, const char *table, const char *chain); - - int - nft_rule_append(struct nft_handle *h, const char *chain, const char *table, - void *data, uint64_t handle, bool verbose) - { -+ struct nftnl_chain *c; - struct nftnl_rule *r; - int type; - -@@ -1228,10 +1217,9 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, - if (verbose) - h->ops->print_rule(r, 0, FMT_PRINT_RULE); - -- if (!nft_rule_list_get(h)) -- return 0; -- -- nftnl_rule_list_add_tail(r, h->rule_cache); -+ c = nft_chain_find(h, table, chain); -+ if (c) -+ nftnl_chain_rule_add_tail(r, c); - - return 1; - } -@@ -1328,58 +1316,75 @@ retry: - - static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data) - { -+ struct nftnl_chain *c = data; - struct nftnl_rule *r; -- struct nftnl_rule_list *list = data; - - r = nftnl_rule_alloc(); - if (r == NULL) -- goto err; -- -- if (nftnl_rule_nlmsg_parse(nlh, r) < 0) -- goto out; -+ return MNL_CB_OK; - -- nftnl_rule_list_add_tail(r, list); -+ if (nftnl_rule_nlmsg_parse(nlh, r) < 0) { -+ nftnl_rule_free(r); -+ return MNL_CB_OK; -+ } - -- return MNL_CB_OK; --out: -- nftnl_rule_free(r); -- nftnl_rule_list_free(list); --err: -+ nftnl_chain_rule_add_tail(r, c); - return MNL_CB_OK; - } - --static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h) -+static int nft_rule_list_update(struct nftnl_chain *c, void *data) - { -+ struct nft_handle *h = data; - char buf[16536]; - struct nlmsghdr *nlh; -- struct nftnl_rule_list *list; -+ struct nftnl_rule *rule; - int ret; - -- if (h->rule_cache) -- return h->rule_cache; -+ rule = nftnl_rule_alloc(); -+ if (!rule) -+ return -1; - --retry: -- list = nftnl_rule_list_alloc(); -- if (list == NULL) -- return 0; -+ nftnl_rule_set_str(rule, NFTNL_RULE_TABLE, -+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE)); -+ nftnl_rule_set_str(rule, NFTNL_RULE_CHAIN, -+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); - -+retry: - nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family, - NLM_F_DUMP, h->seq); -+ nftnl_rule_nlmsg_build_payload(nlh, rule); - -- ret = mnl_talk(h, nlh, nftnl_rule_list_cb, list); -+ ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c); - if (ret < 0) { -+ flush_rule_cache(c); -+ - if (errno == EINTR) { - assert(nft_restart(h) >= 0); -- nftnl_rule_list_free(list); - goto retry; - } -- -- nftnl_rule_list_free(list); -- return NULL; -+ nftnl_rule_free(rule); -+ return -1; - } - -- h->rule_cache = list; -- return list; -+ nftnl_rule_free(rule); -+ return 0; -+} -+ -+static int fetch_rule_cache(struct nft_handle *h) -+{ -+ int i; -+ -+ for (i = 0; i < NFT_TABLE_MAX; i++) { -+ enum nft_table_type type = h->tables[i].type; -+ -+ if (!h->tables[i].name) -+ continue; -+ -+ if (nftnl_chain_list_foreach(h->table[type].chain_cache, -+ nft_rule_list_update, h)) -+ return -1; -+ } -+ return 0; - } - - struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, -@@ -1391,8 +1396,11 @@ struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - if (!t) - return NULL; - -- if (!h->table[t->type].chain_cache) -+ if (!h->have_cache) { - fetch_chain_cache(h); -+ fetch_rule_cache(h); -+ h->have_cache = true; -+ } - - return h->table[t->type].chain_cache; - } -@@ -1437,38 +1445,54 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) - return 1; - } - --int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) -+static int nft_chain_save_rules(struct nft_handle *h, -+ struct nftnl_chain *c, unsigned int format) - { -- struct nftnl_rule_list *list; -- struct nftnl_rule_list_iter *iter; -+ struct nftnl_rule_iter *iter; - struct nftnl_rule *r; - -- list = nft_rule_list_get(h); -- if (list == NULL) -- return 0; -- -- iter = nftnl_rule_list_iter_create(list); -+ iter = nftnl_rule_iter_create(c); - if (iter == NULL) -- return 0; -+ return 1; - -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - while (r != NULL) { -- const char *rule_table = -- nftnl_rule_get_str(r, NFTNL_RULE_TABLE); -+ nft_rule_print_save(r, NFT_RULE_APPEND, format); -+ r = nftnl_rule_iter_next(iter); -+ } - -- if (strcmp(table, rule_table) != 0) -- goto next; -+ nftnl_rule_iter_destroy(iter); -+ return 0; -+} - -- nft_rule_print_save(r, NFT_RULE_APPEND, format); -+int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) -+{ -+ struct nftnl_chain_list_iter *iter; -+ struct nftnl_chain_list *list; -+ struct nftnl_chain *c; -+ int ret = 0; - --next: -- r = nftnl_rule_list_iter_next(iter); -+ list = nft_chain_list_get(h, table); -+ if (!list) -+ return 0; -+ -+ iter = nftnl_chain_list_iter_create(list); -+ if (!iter) -+ return 0; -+ -+ c = nftnl_chain_list_iter_next(iter); -+ while (c) { -+ ret = nft_chain_save_rules(h, c, format); -+ if (ret != 0) -+ break; -+ -+ c = nftnl_chain_list_iter_next(iter); - } - -- nftnl_rule_list_iter_destroy(iter); -+ nftnl_chain_list_iter_destroy(iter); - - /* the core expects 1 for success and 0 for error */ -- return 1; -+ return ret == 0 ? 1 : 0; - } - - static void -@@ -1567,6 +1591,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, - fprintf(stdout, "Flushing chain `%s'\n", chain_name); - - __nft_rule_flush(h, table, chain_name); -+ flush_rule_cache(c); - - if (chain != NULL) - break; -@@ -1574,7 +1599,6 @@ next: - c = nftnl_chain_list_iter_next(iter); - } - nftnl_chain_list_iter_destroy(iter); -- flush_rule_cache(h, table); - err: - /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; -@@ -1898,7 +1922,6 @@ static int __nft_table_flush(struct nft_handle *h, const char *table) - h->table[_t->type].initialized = false; - - flush_chain_cache(h, table); -- flush_rule_cache(h, table); - - return 0; - } -@@ -1939,12 +1962,6 @@ next: - t = nftnl_table_list_iter_next(iter); - } - -- if (!h->rule_cache) { -- h->rule_cache = nftnl_rule_list_alloc(); -- if (h->rule_cache == NULL) -- return -1; -- } -- - err_table_iter: - nftnl_table_list_iter_destroy(iter); - err_table_list: -@@ -1975,31 +1992,19 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r) - } - - static struct nftnl_rule * --nft_rule_find(struct nft_handle *h, struct nftnl_rule_list *list, -- const char *chain, const char *table, void *data, int rulenum) -+nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulenum) - { - struct nftnl_rule *r; -- struct nftnl_rule_list_iter *iter; -+ struct nftnl_rule_iter *iter; - int rule_ctr = 0; - bool found = false; - -- iter = nftnl_rule_list_iter_create(list); -+ iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return 0; - -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - while (r != NULL) { -- const char *rule_table = -- nftnl_rule_get_str(r, NFTNL_RULE_TABLE); -- const char *rule_chain = -- nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); -- -- if (strcmp(table, rule_table) != 0 || -- strcmp(chain, rule_chain) != 0) { -- DEBUGP("different chain / table\n"); -- goto next; -- } -- - if (rulenum >= 0) { - /* Delete by rule number case */ - if (rule_ctr == rulenum) { -@@ -2012,11 +2017,10 @@ nft_rule_find(struct nft_handle *h, struct nftnl_rule_list *list, - break; - } - rule_ctr++; --next: -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - } - -- nftnl_rule_list_iter_destroy(iter); -+ nftnl_rule_iter_destroy(iter); - - return found ? r : NULL; - } -@@ -2024,16 +2028,16 @@ next: - int nft_rule_check(struct nft_handle *h, const char *chain, - const char *table, void *data, bool verbose) - { -- struct nftnl_rule_list *list; -+ struct nftnl_chain *c; - struct nftnl_rule *r; - - nft_fn = nft_rule_check; - -- list = nft_rule_list_get(h); -- if (list == NULL) -+ c = nft_chain_find(h, table, chain); -+ if (!c) - return 0; - -- r = nft_rule_find(h, list, chain, table, data, -1); -+ r = nft_rule_find(h, c, data, -1); - if (r == NULL) { - errno = ENOENT; - return 0; -@@ -2048,16 +2052,18 @@ int nft_rule_delete(struct nft_handle *h, const char *chain, - const char *table, void *data, bool verbose) - { - int ret = 0; -+ struct nftnl_chain *c; - struct nftnl_rule *r; -- struct nftnl_rule_list *list; - - nft_fn = nft_rule_delete; - -- list = nft_rule_list_get(h); -- if (list == NULL) -+ c = nft_chain_find(h, table, chain); -+ if (!c) { -+ errno = ENOENT; - return 0; -+ } - -- r = nft_rule_find(h, list, chain, table, data, -1); -+ r = nft_rule_find(h, c, data, -1); - if (r != NULL) { - ret =__nft_rule_del(h, r); - if (ret < 0) -@@ -2098,8 +2104,8 @@ nft_rule_add(struct nft_handle *h, const char *chain, - int nft_rule_insert(struct nft_handle *h, const char *chain, - const char *table, void *data, int rulenum, bool verbose) - { -- struct nftnl_rule_list *list = nft_rule_list_get(h); - struct nftnl_rule *r, *new_rule; -+ struct nftnl_chain *c; - uint64_t handle = 0; - - /* If built-in chains don't exist for this table, create them */ -@@ -2108,17 +2114,19 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - - nft_fn = nft_rule_insert; - -- if (rulenum > 0) { -- if (list == NULL) -- goto err; -+ c = nft_chain_find(h, table, chain); -+ if (!c) { -+ errno = ENOENT; -+ goto err; -+ } - -- r = nft_rule_find(h, list, chain, table, data, rulenum); -+ if (rulenum > 0) { -+ r = nft_rule_find(h, c, data, rulenum); - if (r == NULL) { - /* special case: iptables allows to insert into - * rule_count + 1 position. - */ -- r = nft_rule_find(h, list, chain, table, data, -- rulenum - 1); -+ r = nft_rule_find(h, c, data, rulenum - 1); - if (r != NULL) - return nft_rule_append(h, chain, table, data, - 0, verbose); -@@ -2136,9 +2144,9 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - goto err; - - if (handle) -- nftnl_rule_list_insert_at(new_rule, r); -+ nftnl_chain_rule_insert_at(new_rule, r); - else -- nftnl_rule_list_add(new_rule, h->rule_cache); -+ nftnl_chain_rule_add(new_rule, c); - - return 1; - err: -@@ -2149,16 +2157,18 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain, - const char *table, int rulenum, bool verbose) - { - int ret = 0; -+ struct nftnl_chain *c; - struct nftnl_rule *r; -- struct nftnl_rule_list *list; - - nft_fn = nft_rule_delete_num; - -- list = nft_rule_list_get(h); -- if (list == NULL) -+ c = nft_chain_find(h, table, chain); -+ if (!c) { -+ errno = ENOENT; - return 0; -+ } - -- r = nft_rule_find(h, list, chain, table, NULL, rulenum); -+ r = nft_rule_find(h, c, NULL, rulenum); - if (r != NULL) { - DEBUGP("deleting rule by number %d\n", rulenum); - ret = __nft_rule_del(h, r); -@@ -2174,16 +2184,18 @@ int nft_rule_replace(struct nft_handle *h, const char *chain, - const char *table, void *data, int rulenum, bool verbose) - { - int ret = 0; -+ struct nftnl_chain *c; - struct nftnl_rule *r; -- struct nftnl_rule_list *list; - - nft_fn = nft_rule_replace; - -- list = nft_rule_list_get(h); -- if (list == NULL) -+ c = nft_chain_find(h, table, chain); -+ if (!c) { -+ errno = ENOENT; - return 0; -+ } - -- r = nft_rule_find(h, list, chain, table, data, rulenum); -+ r = nft_rule_find(h, c, data, rulenum); - if (r != NULL) { - DEBUGP("replacing rule with handle=%llu\n", - (unsigned long long) -@@ -2201,35 +2213,21 @@ int nft_rule_replace(struct nft_handle *h, const char *chain, - } - - static int --__nft_rule_list(struct nft_handle *h, const char *chain, const char *table, -+__nft_rule_list(struct nft_handle *h, struct nftnl_chain *c, - int rulenum, unsigned int format, - void (*cb)(struct nftnl_rule *r, unsigned int num, - unsigned int format)) - { -- struct nftnl_rule_list *list; -- struct nftnl_rule_list_iter *iter; -+ struct nftnl_rule_iter *iter; - struct nftnl_rule *r; - int rule_ctr = 0; - -- list = nft_rule_list_get(h); -- if (list == NULL) -- return 0; -- -- iter = nftnl_rule_list_iter_create(list); -+ iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return 0; - -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - while (r != NULL) { -- const char *rule_table = -- nftnl_rule_get_str(r, NFTNL_RULE_TABLE); -- const char *rule_chain = -- nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); -- -- if (strcmp(table, rule_table) != 0 || -- strcmp(chain, rule_chain) != 0) -- goto next; -- - rule_ctr++; - - if (rulenum > 0 && rule_ctr != rulenum) { -@@ -2242,46 +2240,30 @@ __nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - break; - - next: -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - } - -- nftnl_rule_list_iter_destroy(iter); -+ nftnl_rule_iter_destroy(iter); - return 1; - } - --static int nft_rule_count(struct nft_handle *h, -- const char *chain, const char *table) -+static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c) - { -- struct nftnl_rule_list_iter *iter; -- struct nftnl_rule_list *list; -+ struct nftnl_rule_iter *iter; - struct nftnl_rule *r; - int rule_ctr = 0; - -- list = nft_rule_list_get(h); -- if (list == NULL) -- return 0; -- -- iter = nftnl_rule_list_iter_create(list); -+ iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return 0; - -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - while (r != NULL) { -- const char *rule_table = -- nftnl_rule_get_str(r, NFTNL_RULE_TABLE); -- const char *rule_chain = -- nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); -- -- if (strcmp(table, rule_table) != 0 || -- strcmp(chain, rule_chain) != 0) -- goto next; -- - rule_ctr++; --next: -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - } - -- nftnl_rule_list_iter_destroy(iter); -+ nftnl_rule_iter_destroy(iter); - return rule_ctr; - } - -@@ -2314,8 +2296,11 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - } - - if (chain && rulenum) { -- __nft_rule_list(h, chain, table, -- rulenum, format, ops->print_rule); -+ c = nft_chain_find(h, table, chain); -+ if (!c) -+ return 0; -+ -+ __nft_rule_list(h, c, rulenum, format, ops->print_rule); - return 1; - } - -@@ -2358,12 +2343,11 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - if (found) - printf("\n"); - -- entries = nft_rule_count(h, chain_name, table); -+ entries = nft_rule_count(h, c); - ops->print_header(format, chain_name, policy_name[policy], - &ctrs, basechain, refs - entries, entries); - -- __nft_rule_list(h, chain_name, table, -- rulenum, format, ops->print_rule); -+ __nft_rule_list(h, c, rulenum, format, ops->print_rule); - - found = true; - -@@ -2484,8 +2468,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - if (chain && strcmp(chain, chain_name) != 0) - goto next; - -- ret = __nft_rule_list(h, chain_name, table, rulenum, -- format, list_save); -+ ret = __nft_rule_list(h, c, rulenum, format, list_save); - - /* we printed the chain we wanted, stop processing. */ - if (chain) -@@ -2503,17 +2486,17 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, - const char *table, int rulenum) - { - struct iptables_command_state cs = {}; -- struct nftnl_rule_list *list; -+ struct nftnl_chain *c; - struct nftnl_rule *r; - int ret = 0; - - nft_fn = nft_rule_delete; - -- list = nft_rule_list_get(h); -- if (list == NULL) -+ c = nft_chain_find(h, table, chain); -+ if (!c) - return 0; - -- r = nft_rule_find(h, list, chain, table, NULL, rulenum); -+ r = nft_rule_find(h, c, NULL, rulenum); - if (r == NULL) { - errno = ENOENT; - ret = 1; -@@ -2982,38 +2965,19 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, - static void nft_chain_zero_rule_counters(struct nft_handle *h, - struct nftnl_chain *c) - { -- struct nftnl_rule_list_iter *iter; -- struct nftnl_rule_list *list; -- const char *table_name; -- const char *chain_name; -+ struct nftnl_rule_iter *iter; - struct nftnl_rule *r; - -- list = nft_rule_list_get(h); -- if (list == NULL) -- return; -- iter = nftnl_rule_list_iter_create(list); -+ iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return; - -- table_name = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); -- chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - while (r != NULL) { - struct nftnl_expr_iter *ei; -- const char *table_chain; -- const char *rule_chain; - struct nftnl_expr *e; - bool zero_needed; - -- table_chain = nftnl_rule_get_str(r, NFTNL_RULE_TABLE); -- if (strcmp(table_chain, table_name)) -- goto next; -- -- rule_chain = nftnl_rule_get_str(r, NFTNL_RULE_CHAIN); -- if (strcmp(rule_chain, chain_name)) -- goto next; -- - ei = nftnl_expr_iter_create(r); - if (!ei) - break; -@@ -3044,11 +3008,10 @@ static void nft_chain_zero_rule_counters(struct nft_handle *h, - nftnl_rule_unset(r, NFTNL_RULE_POSITION); - batch_rule_add(h, NFT_COMPAT_RULE_REPLACE, r); - } --next: -- r = nftnl_rule_list_iter_next(iter); -+ r = nftnl_rule_iter_next(iter); - } - -- nftnl_rule_list_iter_destroy(iter); -+ nftnl_rule_iter_destroy(iter); - } - - int nft_chain_zero_counters(struct nft_handle *h, const char *chain, -@@ -3143,19 +3106,8 @@ static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data) - return -1; - } - --struct nft_is_rule_compatible_data { -- const char *tablename; --}; -- - static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data) - { -- const char *table = nftnl_rule_get_str(rule, NFTNL_RULE_TABLE); -- struct nft_is_rule_compatible_data *d = data; -- -- /* ignore rules belonging to a different table */ -- if (strcmp(table, d->tablename)) -- return 0; -- - return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL); - } - -@@ -3167,6 +3119,9 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) - enum nf_inet_hooks hook; - int i, prio; - -+ if (nftnl_rule_foreach(c, nft_is_rule_compatible, NULL)) -+ return -1; -+ - if (!nft_chain_builtin(c)) - return 0; - -@@ -3210,11 +3165,7 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) - - bool nft_is_table_compatible(struct nft_handle *h, const char *tablename) - { -- struct nft_is_rule_compatible_data rcd = { -- .tablename = tablename -- }; - struct nftnl_chain_list *clist; -- struct nftnl_rule_list *list; - - clist = nft_chain_list_get(h, tablename); - if (clist == NULL) -@@ -3223,12 +3174,5 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename) - if (nftnl_chain_list_foreach(clist, nft_is_chain_compatible, h)) - return false; - -- list = nft_rule_list_get(h); -- if (list == NULL) -- return true; -- -- if (nftnl_rule_list_foreach(list, nft_is_rule_compatible, &rcd)) -- return false; -- - return true; - } -diff --git a/iptables/nft.h b/iptables/nft.h -index bf60ab3943659..6568257feddc7 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -42,7 +42,7 @@ struct nft_handle { - struct nftnl_chain_list *chain_cache; - bool initialized; - } table[NFT_TABLE_MAX]; -- struct nftnl_rule_list *rule_cache; -+ bool have_cache; - bool restore; - int8_t config_done; - --- -2.21.0 - diff --git a/SOURCES/0022-nft-Drop-nft_chain_list_find.patch b/SOURCES/0022-nft-Drop-nft_chain_list_find.patch deleted file mode 100644 index 0fca0cc..0000000 --- a/SOURCES/0022-nft-Drop-nft_chain_list_find.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 4255a54501f8588b4bd346cd36379cccd6e0abc7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:13 +0100 -Subject: [PATCH] nft: Drop nft_chain_list_find() - -Replace the function by nftnl_chain_list_lookup_byname() as provided by -libnftnl. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 63dc7a0d86a1b86b10c5e04dd910497b9d8fcfaf) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 31 ++----------------------------- - iptables/nft.h | 2 -- - 2 files changed, 2 insertions(+), 31 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 842ed2b805bee..883fb3db2c671 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -697,7 +697,7 @@ static void nft_chain_builtin_init(struct nft_handle *h, - /* Initialize built-in chains if they don't exist yet */ - for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) { - -- c = nft_chain_list_find(list, table->chains[i].name); -+ c = nftnl_chain_list_lookup_byname(list, table->chains[i].name); - if (c != NULL) - continue; - -@@ -1699,33 +1699,6 @@ err: - return ret == 0 ? 1 : 0; - } - --struct nftnl_chain * --nft_chain_list_find(struct nftnl_chain_list *list, const char *chain) --{ -- struct nftnl_chain_list_iter *iter; -- struct nftnl_chain *c; -- -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- return NULL; -- -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- -- if (strcmp(chain, chain_name) != 0) -- goto next; -- -- nftnl_chain_list_iter_destroy(iter); -- return c; --next: -- c = nftnl_chain_list_iter_next(iter); -- } -- nftnl_chain_list_iter_destroy(iter); -- return NULL; --} -- - static struct nftnl_chain * - nft_chain_find(struct nft_handle *h, const char *table, const char *chain) - { -@@ -1735,7 +1708,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain) - if (list == NULL) - return NULL; - -- return nft_chain_list_find(list, chain); -+ return nftnl_chain_list_lookup_byname(list, chain); - } - - bool nft_chain_exists(struct nft_handle *h, -diff --git a/iptables/nft.h b/iptables/nft.h -index 6568257feddc7..dfdffd69342db 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -83,8 +83,6 @@ struct nftnl_chain; - int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters); - struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h, - const char *table); --struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, -- const char *chain); - int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list); - int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table); - int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose); --- -2.21.0 - diff --git a/SOURCES/0023-xtables-Optimize-flushing-a-specific-chain.patch b/SOURCES/0023-xtables-Optimize-flushing-a-specific-chain.patch deleted file mode 100644 index 172140d..0000000 --- a/SOURCES/0023-xtables-Optimize-flushing-a-specific-chain.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0497d24ecbc4414274bbfa33762de90b28c57be9 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:14 +0100 -Subject: [PATCH] xtables: Optimize flushing a specific chain - -If a chain name is given to nft_rule_flush(), make use of -nftnl_chain_list_lookup_byname(). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 196841c9597eff536b59655b60df088ee1929904) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 30 +++++++++++++++++------------- - 1 file changed, 17 insertions(+), 13 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 883fb3db2c671..a23acbcc9b100 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1496,10 +1496,14 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) - } - - static void --__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain) -+__nft_rule_flush(struct nft_handle *h, const char *table, -+ const char *chain, bool verbose) - { - struct nftnl_rule *r; - -+ if (verbose) -+ fprintf(stdout, "Flushing chain `%s'\n", chain); -+ - r = nftnl_rule_alloc(); - if (r == NULL) - return; -@@ -1533,7 +1537,7 @@ static int __nft_chain_user_flush(struct nftnl_chain *c, void *data) - return 0; - - if (!nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) -- __nft_rule_flush(h, table, chain); -+ __nft_rule_flush(h, table, chain, false); - - return 0; - } -@@ -1573,6 +1577,16 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, - goto err; - } - -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); -+ if (!c) -+ return 0; -+ -+ __nft_rule_flush(h, table, chain, verbose); -+ flush_rule_cache(c); -+ return 1; -+ } -+ - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) { - ret = 1; -@@ -1584,18 +1598,8 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, - const char *chain_name = - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - -- if (chain != NULL && strcmp(chain, chain_name) != 0) -- goto next; -- -- if (verbose) -- fprintf(stdout, "Flushing chain `%s'\n", chain_name); -- -- __nft_rule_flush(h, table, chain_name); -+ __nft_rule_flush(h, table, chain_name, verbose); - flush_rule_cache(c); -- -- if (chain != NULL) -- break; --next: - c = nftnl_chain_list_iter_next(iter); - } - nftnl_chain_list_iter_destroy(iter); --- -2.21.0 - diff --git a/SOURCES/0024-xtables-Optimize-nft_chain_zero_counters.patch b/SOURCES/0024-xtables-Optimize-nft_chain_zero_counters.patch deleted file mode 100644 index 850d8a3..0000000 --- a/SOURCES/0024-xtables-Optimize-nft_chain_zero_counters.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 25eff54c9a82ad816f7a4c274d39daf2e1aaf3a7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:15 +0100 -Subject: [PATCH] xtables: Optimize nft_chain_zero_counters() - -If a chain name was given, make use of nftnl_chain_list_lookup_byname(). -Streamline nft_chain_zero_rule_counters() to be suitable for calling -from nftnl_chain_list_foreach(). - -There is an unrelated optimization in here, too: Add batch job -NFT_COMPAT_CHAIN_ZERO only if it is a base chain. Since user-defined -chains don't have counters, there is no need to do anything for them. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit a6ce0c65d3a390bfff16e834c18650beedecf40c) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 72 +++++++++++++++++++++++++------------------------- - 1 file changed, 36 insertions(+), 36 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index a23acbcc9b100..9951bf3212197 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2939,15 +2939,36 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, - return h->config_done; - } - --static void nft_chain_zero_rule_counters(struct nft_handle *h, -- struct nftnl_chain *c) -+struct chain_zero_data { -+ struct nft_handle *handle; -+ bool verbose; -+}; -+ -+static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data) - { -+ struct chain_zero_data *d = data; -+ struct nft_handle *h = d->handle; - struct nftnl_rule_iter *iter; - struct nftnl_rule *r; -+ int ret = 0; -+ -+ if (d->verbose) -+ fprintf(stdout, "Zeroing chain `%s'\n", -+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); -+ -+ if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { -+ /* zero base chain counters. */ -+ nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); -+ nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); -+ nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); -+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c); -+ if (ret) -+ return -1; -+ } - - iter = nftnl_rule_iter_create(c); - if (iter == NULL) -- return; -+ return -1; - - r = nftnl_rule_iter_next(iter); - while (r != NULL) { -@@ -2989,13 +3010,17 @@ static void nft_chain_zero_rule_counters(struct nft_handle *h, - } - - nftnl_rule_iter_destroy(iter); -+ return 0; - } - - int nft_chain_zero_counters(struct nft_handle *h, const char *chain, - const char *table, bool verbose) - { - struct nftnl_chain_list *list; -- struct nftnl_chain_list_iter *iter; -+ struct chain_zero_data d = { -+ .handle = h, -+ .verbose = verbose, -+ }; - struct nftnl_chain *c; - int ret = 0; - -@@ -3003,41 +3028,16 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, - if (list == NULL) - goto err; - -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- goto err; -- -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get(c, NFTNL_CHAIN_NAME); -- -- if (chain != NULL && strcmp(chain, chain_name) != 0) -- goto next; -- -- if (verbose) -- fprintf(stdout, "Zeroing chain `%s'\n", chain_name); -- -- if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { -- /* zero base chain counters. */ -- nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); -- nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); -- } -- -- nft_chain_zero_rule_counters(h, c); -- -- nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); -- -- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c); -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); -+ if (!c) -+ return 0; - -- if (chain != NULL) -- break; --next: -- c = nftnl_chain_list_iter_next(iter); -+ ret = __nft_chain_zero_counters(c, &d); -+ goto err; - } - -- nftnl_chain_list_iter_destroy(iter); -- -+ ret = nftnl_chain_list_foreach(list, __nft_chain_zero_counters, &d); - err: - /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; --- -2.21.0 - diff --git a/SOURCES/0025-tests-Extend-verbose-output-and-return-code-tests.patch b/SOURCES/0025-tests-Extend-verbose-output-and-return-code-tests.patch deleted file mode 100644 index ab0c60e..0000000 --- a/SOURCES/0025-tests-Extend-verbose-output-and-return-code-tests.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 9cc2fc0be5adc8f828fc8fd62951f7773148b7f0 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:16 +0100 -Subject: [PATCH] tests: Extend verbose output and return code tests - -Recent changes to chain flush and zero routines incorporate proper error -propagation so trying to flush or zero a non-existent chain results in -an error. This is consistent with iptables-legacy, extend tests to make -sure it stays this way. - -Also extend verbose output test to make these recent changes didn't mess -it up. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit e80f7fe56e4c64e05da426418bc2fae7ca221c49) -Signed-off-by: Phil Sutter ---- - .../shell/testcases/iptables/0002-verbose-output_0 | 13 +++++++++---- - .../shell/testcases/iptables/0004-return-codes_0 | 6 ++++++ - 2 files changed, 15 insertions(+), 4 deletions(-) - -diff --git a/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 b/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 -index 2e8059536ea7b..b1ef91f61f481 100755 ---- a/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 -+++ b/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 -@@ -29,23 +29,28 @@ Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) - - diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -n -L) - -+[[ -z $($XT_MULTI iptables -v -N foobar) ]] || exit 1 -+ - diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -D FORWARD $RULE1) - diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -D FORWARD $RULE2) - - EXPECT="Flushing chain \`INPUT' - Flushing chain \`FORWARD' --Flushing chain \`OUTPUT'" -+Flushing chain \`OUTPUT' -+Flushing chain \`foobar'" - - diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -F) - - EXPECT="Zeroing chain \`INPUT' - Zeroing chain \`FORWARD' --Zeroing chain \`OUTPUT'" -+Zeroing chain \`OUTPUT' -+Zeroing chain \`foobar'" - - diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -Z) - - diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI iptables -v -F OUTPUT) - diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI iptables -v -Z OUTPUT) -+diff -u <(echo "Flushing chain \`foobar'") <($XT_MULTI iptables -v -F foobar) -+diff -u <(echo "Zeroing chain \`foobar'") <($XT_MULTI iptables -v -Z foobar) - --$XT_MULTI iptables -N foo --diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI iptables -v -X foo) -+diff -u <(echo "Deleting chain \`foobar'") <($XT_MULTI iptables -v -X foobar) -diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 -index 5b6e1f6f1bc7a..9d2493992bd69 100755 ---- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 -+++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 -@@ -23,6 +23,12 @@ cmd 1 iptables -N foo - # iptables-nft allows this - bug or feature? - #cmd 2 iptables -N "invalid name" - -+# test chain flushing/zeroing -+cmd 0 iptables -F foo -+cmd 0 iptables -Z foo -+cmd 1 iptables -F bar -+cmd 1 iptables -Z bar -+ - # test chain rename - cmd 0 iptables -E foo bar - cmd 1 iptables -E foo bar --- -2.21.0 - diff --git a/SOURCES/0026-xtables-Optimize-user-defined-chain-deletion.patch b/SOURCES/0026-xtables-Optimize-user-defined-chain-deletion.patch deleted file mode 100644 index 4f47354..0000000 --- a/SOURCES/0026-xtables-Optimize-user-defined-chain-deletion.patch +++ /dev/null @@ -1,134 +0,0 @@ -From c9db6c26efce63e052b1a35ba1f4d529c2294c93 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:17 +0100 -Subject: [PATCH] xtables: Optimize user-defined chain deletion - -Make use of nftnl_chain_list_lookup_byname() if a chain name was given. -Move the actual chain deleting code into a callback suitable for passing -to nftnl_chain_list_foreach(). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 0b950ed4549308ef23ffc7561567df86c90cfed9) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 89 ++++++++++++++++++++++++++------------------------ - 1 file changed, 46 insertions(+), 43 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 9951bf3212197..162d91e82115b 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1642,63 +1642,66 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl - #define NLM_F_NONREC 0x100 /* Do not delete recursively */ - #endif - -+struct chain_user_del_data { -+ struct nft_handle *handle; -+ bool verbose; -+ int builtin_err; -+}; -+ -+static int __nft_chain_user_del(struct nftnl_chain *c, void *data) -+{ -+ struct chain_user_del_data *d = data; -+ struct nft_handle *h = d->handle; -+ int ret; -+ -+ /* don't delete built-in chain */ -+ if (nft_chain_builtin(c)) -+ return d->builtin_err; -+ -+ if (d->verbose) -+ fprintf(stdout, "Deleting chain `%s'\n", -+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); -+ -+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); -+ if (ret) -+ return -1; -+ -+ nftnl_chain_list_del(c); -+ return 0; -+} -+ - int nft_chain_user_del(struct nft_handle *h, const char *chain, - const char *table, bool verbose) - { -+ struct chain_user_del_data d = { -+ .handle = h, -+ .verbose = verbose, -+ }; - struct nftnl_chain_list *list; -- struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; - int ret = 0; -- int deleted_ctr = 0; - - nft_fn = nft_chain_user_del; - - list = nft_chain_list_get(h, table); - if (list == NULL) -- goto err; -- -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- goto err; -- -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- -- /* don't delete built-in chain */ -- if (nft_chain_builtin(c)) -- goto next; -- -- if (chain != NULL && strcmp(chain, chain_name) != 0) -- goto next; -- -- if (verbose) -- fprintf(stdout, "Deleting chain `%s'\n", chain); -- -- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); -- -- if (ret < 0) -- break; -- -- deleted_ctr++; -- nftnl_chain_list_del(c); -- -- if (chain != NULL) -- break; --next: -- c = nftnl_chain_list_iter_next(iter); -- } -- -- nftnl_chain_list_iter_destroy(iter); --err: -+ return 0; - -- /* chain not found */ -- if (chain != NULL && deleted_ctr == 0) { -- ret = -1; -- errno = ENOENT; -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); -+ if (!c) { -+ errno = ENOENT; -+ return 0; -+ } -+ d.builtin_err = -2; -+ ret = __nft_chain_user_del(c, &d); -+ if (ret == -2) -+ errno = EINVAL; -+ goto out; - } - -+ ret = nftnl_chain_list_foreach(list, __nft_chain_user_del, &d); -+out: - /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; - } --- -2.21.0 - diff --git a/SOURCES/0027-xtables-Optimize-list-command-with-given-chain.patch b/SOURCES/0027-xtables-Optimize-list-command-with-given-chain.patch deleted file mode 100644 index 88c160f..0000000 --- a/SOURCES/0027-xtables-Optimize-list-command-with-given-chain.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 8b38ab8ead7829569ab6a3c9fa7a193d568b707a Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:18 +0100 -Subject: [PATCH] xtables: Optimize list command with given chain - -Make use of nftnl_chain_list_lookup_byname() even if not listing a -specific rule. Introduce __nft_print_header() to consolidate chain value -extraction for printing with ops->print_header(). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 11cbd7291f37fbfd5ebe6ffa1730f7d198ed2ac0) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 78 +++++++++++++++++++++----------------------------- - 1 file changed, 32 insertions(+), 46 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 162d91e82115b..e1c997836cb97 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2247,6 +2247,24 @@ static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c) - return rule_ctr; - } - -+static void __nft_print_header(struct nft_handle *h, -+ const struct nft_family_ops *ops, -+ struct nftnl_chain *c, unsigned int format) -+{ -+ const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -+ uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -+ bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM); -+ uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); -+ uint32_t entries = nft_rule_count(h, c); -+ struct xt_counters ctrs = { -+ .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), -+ .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), -+ }; -+ -+ ops->print_header(format, chain_name, policy_name[policy], -+ &ctrs, basechain, refs - entries, entries); -+} -+ - int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - int rulenum, unsigned int format) - { -@@ -2275,75 +2293,43 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - return 0; - } - -- if (chain && rulenum) { -- c = nft_chain_find(h, table, chain); -+ list = nft_chain_list_get(h, table); -+ if (!list) -+ return 0; -+ -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); - if (!c) - return 0; - -+ if (!rulenum) { -+ if (ops->print_table_header) -+ ops->print_table_header(table); -+ __nft_print_header(h, ops, c, format); -+ } - __nft_rule_list(h, c, rulenum, format, ops->print_rule); - return 1; - } - -- list = nft_chain_list_get(h, table); -- if (!list) -- return 0; -- - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) -- goto err; -+ return 0; - -- if (!chain && ops->print_table_header) -+ if (ops->print_table_header) - ops->print_table_header(table); - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- uint32_t policy = -- nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -- uint32_t refs = -- nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); -- struct xt_counters ctrs = { -- .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), -- .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), -- }; -- bool basechain = false; -- uint32_t entries; -- -- if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) -- basechain = true; -- -- if (chain) { -- if (strcmp(chain, chain_name) != 0) -- goto next; -- else if (ops->print_table_header) -- ops->print_table_header(table); -- } -- - if (found) - printf("\n"); - -- entries = nft_rule_count(h, c); -- ops->print_header(format, chain_name, policy_name[policy], -- &ctrs, basechain, refs - entries, entries); -- -+ __nft_print_header(h, ops, c, format); - __nft_rule_list(h, c, rulenum, format, ops->print_rule); - - found = true; -- -- /* we printed the chain we wanted, stop processing. */ -- if (chain) -- break; -- --next: - c = nftnl_chain_list_iter_next(iter); - } -- - nftnl_chain_list_iter_destroy(iter); --err: -- if (chain && !found) -- return 0; -- - return 1; - } - --- -2.21.0 - diff --git a/SOURCES/0028-xtables-Optimize-list-rules-command-with-given-chain.patch b/SOURCES/0028-xtables-Optimize-list-rules-command-with-given-chain.patch deleted file mode 100644 index 50971b9..0000000 --- a/SOURCES/0028-xtables-Optimize-list-rules-command-with-given-chain.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 23ef58d88034cdd5c972b9392944a772cccd61f9 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:19 +0100 -Subject: [PATCH] xtables: Optimize list rules command with given chain - -If a chain name was given, make use of nftnl_chain_list_lookup_byname(). - -Likewise in nftnl_rule_list_chain_save(), but introduce -__nftnl_rule_list_chain_save() suitable for passing to -nftnl_chain_list_foreach(). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 6b1871914e4f3717c7e6324727b80cf1d5d985b1) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 93 +++++++++++++++++++++++--------------------------- - 1 file changed, 43 insertions(+), 50 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index e1c997836cb97..e0455eabda77a 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2339,46 +2339,44 @@ list_save(struct nftnl_rule *r, unsigned int num, unsigned int format) - nft_rule_print_save(r, NFT_RULE_APPEND, format); - } - -+static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data) -+{ -+ const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -+ uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -+ int *counters = data; -+ -+ if (!nft_chain_builtin(c)) { -+ printf("-N %s\n", chain_name); -+ return 0; -+ } -+ -+ /* this is a base chain */ -+ -+ printf("-P %s %s", chain_name, policy_name[policy]); -+ if (*counters) -+ printf(" -c %"PRIu64" %"PRIu64, -+ nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), -+ nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES)); -+ printf("\n"); -+ return 0; -+} -+ - static int - nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain, - struct nftnl_chain_list *list, int counters) - { -- struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; - -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- return 0; -- -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- uint32_t policy = -- nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -- -- if (chain && strcmp(chain, chain_name) != 0) -- goto next; -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); -+ if (!c) -+ return 0; - -- /* this is a base chain */ -- if (nft_chain_builtin(c)) { -- printf("-P %s %s", chain_name, policy_name[policy]); -- -- if (counters) { -- printf(" -c %"PRIu64" %"PRIu64"\n", -- nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), -- nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES)); -- } else -- printf("\n"); -- } else { -- printf("-N %s\n", chain_name); -- } --next: -- c = nftnl_chain_list_iter_next(iter); -+ __nftnl_rule_list_chain_save(c, &counters); -+ return 1; - } - -- nftnl_chain_list_iter_destroy(iter); -- -+ nftnl_chain_list_foreach(list, __nftnl_rule_list_chain_save, &counters); - return 1; - } - -@@ -2410,41 +2408,36 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - - list = nft_chain_list_get(h, table); - if (!list) -- goto err; -+ return 0; - - /* Dump policies and custom chains first */ - if (!rulenum) - nftnl_rule_list_chain_save(h, chain, list, counters); - -- /* Now dump out rules in this table */ -- iter = nftnl_chain_list_iter_create(list); -- if (iter == NULL) -- goto err; -- - if (counters < 0) - format = FMT_C_COUNTS; - else if (counters == 0) - format = FMT_NOCOUNTS; - -- c = nftnl_chain_list_iter_next(iter); -- while (c != NULL) { -- const char *chain_name = -- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -+ if (chain) { -+ c = nftnl_chain_list_lookup_byname(list, chain); -+ if (!c) -+ return 0; - -- if (chain && strcmp(chain, chain_name) != 0) -- goto next; -+ return __nft_rule_list(h, c, rulenum, format, list_save); -+ } - -- ret = __nft_rule_list(h, c, rulenum, format, list_save); -+ /* Now dump out rules in this table */ -+ iter = nftnl_chain_list_iter_create(list); -+ if (iter == NULL) -+ return 0; - -- /* we printed the chain we wanted, stop processing. */ -- if (chain) -- break; --next: -+ c = nftnl_chain_list_iter_next(iter); -+ while (c != NULL) { -+ ret = __nft_rule_list(h, c, rulenum, format, list_save); - c = nftnl_chain_list_iter_next(iter); - } -- - nftnl_chain_list_iter_destroy(iter); --err: - return ret; - } - --- -2.21.0 - diff --git a/SOURCES/0029-nft-Make-use-of-nftnl_rule_lookup_byindex.patch b/SOURCES/0029-nft-Make-use-of-nftnl_rule_lookup_byindex.patch deleted file mode 100644 index 43af7dd..0000000 --- a/SOURCES/0029-nft-Make-use-of-nftnl_rule_lookup_byindex.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 4af07f53926f4bf65caa3804adbadb726e3dc301 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 20 Dec 2018 16:09:20 +0100 -Subject: [PATCH] nft: Make use of nftnl_rule_lookup_byindex() - -Use the function where suitable to potentially speedup rule cache lookup -by rule number. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 039b04896521026d1cb52d60dbacb6ee5226c02d) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 31 ++++++++++++++++++------------- - 1 file changed, 18 insertions(+), 13 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index e0455eabda77a..1fd3837f2d334 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1976,27 +1976,21 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen - { - struct nftnl_rule *r; - struct nftnl_rule_iter *iter; -- int rule_ctr = 0; - bool found = false; - -+ if (rulenum >= 0) -+ /* Delete by rule number case */ -+ return nftnl_rule_lookup_byindex(c, rulenum); -+ - iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return 0; - - r = nftnl_rule_iter_next(iter); - while (r != NULL) { -- if (rulenum >= 0) { -- /* Delete by rule number case */ -- if (rule_ctr == rulenum) { -- found = true; -- break; -- } -- } else { -- found = h->ops->rule_find(h->ops, r, data); -- if (found) -- break; -- } -- rule_ctr++; -+ found = h->ops->rule_find(h->ops, r, data); -+ if (found) -+ break; - r = nftnl_rule_iter_next(iter); - } - -@@ -2202,6 +2196,17 @@ __nft_rule_list(struct nft_handle *h, struct nftnl_chain *c, - struct nftnl_rule *r; - int rule_ctr = 0; - -+ if (rulenum > 0) { -+ r = nftnl_rule_lookup_byindex(c, rulenum - 1); -+ if (!r) -+ /* iptables-legacy returns 0 when listing for -+ * valid chain but invalid rule number -+ */ -+ return 1; -+ cb(r, rulenum, format); -+ return 1; -+ } -+ - iter = nftnl_rule_iter_create(c); - if (iter == NULL) - return 0; --- -2.21.0 - diff --git a/SOURCES/0030-nft-Simplify-nft_is_chain_compatible.patch b/SOURCES/0030-nft-Simplify-nft_is_chain_compatible.patch deleted file mode 100644 index cfd7001..0000000 --- a/SOURCES/0030-nft-Simplify-nft_is_chain_compatible.patch +++ /dev/null @@ -1,80 +0,0 @@ -From b8d3fdae853c391312b2a0be533fd4a91bf80e8e Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sun, 30 Dec 2018 20:06:08 +0100 -Subject: [PATCH] nft: Simplify nft_is_chain_compatible() - -Make use of nft_{table,chain}_builtin_find() instead of open-coding the -list traversal. Since code is pretty obvious now, drop the comments -added earlier. - -Fixes: e774b15299c27 ("nft: Review is_*_compatible() routines") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit fae77a24634365b18687a5f09357dbf4aaee2bc0) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 34 +++++++++------------------------- - 1 file changed, 9 insertions(+), 25 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 1fd3837f2d334..25e538b7e35d7 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -3077,11 +3077,12 @@ static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data) - - static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) - { -- const struct builtin_chain *chains = NULL, *chain = NULL; -- const char *table, *name, *type; -+ const struct builtin_table *table; -+ const struct builtin_chain *chain; -+ const char *tname, *cname, *type; - struct nft_handle *h = data; - enum nf_inet_hooks hook; -- int i, prio; -+ int prio; - - if (nftnl_rule_foreach(c, nft_is_rule_compatible, NULL)) - return -1; -@@ -3089,33 +3090,16 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) - if (!nft_chain_builtin(c)) - return 0; - -- /* find chain's table in builtin tables */ -- table = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); -- for (i = 0; i < NFT_TABLE_MAX; i++) { -- const char *cur_table = h->tables[i].name; -- -- if (!cur_table || strcmp(cur_table, table)) -- continue; -- -- chains = h->tables[i].chains; -- break; -- } -- if (!chains) -+ tname = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE); -+ table = nft_table_builtin_find(h, tname); -+ if (!table) - return -1; - -- /* find chain in builtin chain list */ -- name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- for (i = 0; i < NF_INET_NUMHOOKS && chains[i].name; i++) { -- if (strcmp(name, chains[i].name)) -- continue; -- -- chain = &chains[i]; -- break; -- } -+ cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -+ chain = nft_chain_builtin_find(table, cname); - if (!chain) - return -1; - -- /* compare properties */ - type = nftnl_chain_get_str(c, NFTNL_CHAIN_TYPE); - prio = nftnl_chain_get_u32(c, NFTNL_CHAIN_PRIO); - hook = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM); --- -2.21.0 - diff --git a/SOURCES/0031-nft-Simplify-flush_chain_cache.patch b/SOURCES/0031-nft-Simplify-flush_chain_cache.patch deleted file mode 100644 index 9df21bb..0000000 --- a/SOURCES/0031-nft-Simplify-flush_chain_cache.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 1ad5112b216c46fdf799fa7c8fbf6508f0f4afc9 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sun, 30 Dec 2018 20:06:09 +0100 -Subject: [PATCH] nft: Simplify flush_chain_cache() - -With all the checks for 'tablename' being non-NULL, this code was rather -stupid and really hard to read. And the fix is indeed quite simple: If a -table name was given, use nft_table_builtin_find() and just flush its -chain cache. Otherwise iterate over all builtin tables without any -conditionals for 'tablename'. - -Fixes: d4b0d248cc057 ("nft: Reduce indenting level in flush_chain_cache()") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 4441b7da7995ed87741164ef39e99f1065eb9637) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 24 +++++++++++------------- - 1 file changed, 11 insertions(+), 13 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 25e538b7e35d7..dafb879ebd6f0 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -793,27 +793,25 @@ static int __flush_chain_cache(struct nftnl_chain *c, void *data) - - static void flush_chain_cache(struct nft_handle *h, const char *tablename) - { -+ const struct builtin_table *table; - int i; - -+ if (tablename) { -+ table = nft_table_builtin_find(h, tablename); -+ if (!table || !h->table[table->type].chain_cache) -+ return; -+ nftnl_chain_list_foreach(h->table[table->type].chain_cache, -+ __flush_chain_cache, NULL); -+ return; -+ } -+ - for (i = 0; i < NFT_TABLE_MAX; i++) { - if (h->tables[i].name == NULL) - continue; - -- if (tablename && strcmp(h->tables[i].name, tablename)) -+ if (!h->table[i].chain_cache) - continue; - -- if (!h->table[i].chain_cache) { -- if (tablename) -- return; -- continue; -- } -- -- if (tablename) { -- nftnl_chain_list_foreach(h->table[i].chain_cache, -- __flush_chain_cache, NULL); -- return; -- } -- - nftnl_chain_list_free(h->table[i].chain_cache); - h->table[i].chain_cache = NULL; - } --- -2.21.0 - diff --git a/SOURCES/0032-xtables-Set-errno-in-nft_rule_check-if-chain-not-fou.patch b/SOURCES/0032-xtables-Set-errno-in-nft_rule_check-if-chain-not-fou.patch deleted file mode 100644 index 7031d52..0000000 --- a/SOURCES/0032-xtables-Set-errno-in-nft_rule_check-if-chain-not-fou.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 276b4dba9aa9d52cafe8df2546050d4591ac5b01 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sun, 30 Dec 2018 20:06:10 +0100 -Subject: [PATCH] xtables: Set errno in nft_rule_check() if chain not found - -With this, the explicit check for chain existence can be removed from -xtables.c since all related commands do this now. - -Note that this effectively changes the error message printed by -iptables-nft when given a non-existing chain, but the new error -message(s) conform with those printed by legacy iptables. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 41358d474357a39d616302c03cd7f943e19969a2) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 12 +++++++----- - iptables/xtables.c | 4 ---- - 2 files changed, 7 insertions(+), 9 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index dafb879ebd6f0..1ce1ecdd276be 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2007,17 +2007,19 @@ int nft_rule_check(struct nft_handle *h, const char *chain, - - c = nft_chain_find(h, table, chain); - if (!c) -- return 0; -+ goto fail_enoent; - - r = nft_rule_find(h, c, data, -1); -- if (r == NULL) { -- errno = ENOENT; -- return 0; -- } -+ if (r == NULL) -+ goto fail_enoent; -+ - if (verbose) - h->ops->print_rule(r, 0, FMT_PRINT_RULE); - - return 1; -+fail_enoent: -+ errno = ENOENT; -+ return 0; - } - - int nft_rule_delete(struct nft_handle *h, const char *chain, -diff --git a/iptables/xtables.c b/iptables/xtables.c -index 24a6e234bcf4b..da11e8cc159a0 100644 ---- a/iptables/xtables.c -+++ b/iptables/xtables.c -@@ -1064,10 +1064,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], - p->chain); - } - -- if (!p->xlate && !nft_chain_exists(h, p->table, p->chain)) -- xtables_error(OTHER_PROBLEM, -- "Chain '%s' does not exist", p->chain); -- - if (!p->xlate && !cs->target && strlen(cs->jumpto) > 0 && - !nft_chain_exists(h, p->table, cs->jumpto)) - xtables_error(PARAMETER_PROBLEM, --- -2.21.0 - diff --git a/SOURCES/0033-xtables-Speed-up-chain-deletion-in-large-rulesets.patch b/SOURCES/0033-xtables-Speed-up-chain-deletion-in-large-rulesets.patch deleted file mode 100644 index a6373e7..0000000 --- a/SOURCES/0033-xtables-Speed-up-chain-deletion-in-large-rulesets.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 27bc424993e8138e26d7db1d7f902baaf269dd7c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 12 Dec 2018 20:04:12 +0100 -Subject: [PATCH] xtables: Speed up chain deletion in large rulesets - -Kernel prefers to identify chain by handle if it was given which causes -manual traversal of the chain list. In contrast, chain lookup by name in -kernel makes use of a hash table so is considerably faster. Force this -code path by removing the cached chain's handle when removing it. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit a5f517a41d72794fae3d1332e6e0e413a5cd16c1) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 1ce1ecdd276be..9c0ad9a2d054f 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1660,6 +1660,8 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data) - fprintf(stdout, "Deleting chain `%s'\n", - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); - -+ /* XXX This triggers a fast lookup from the kernel. */ -+ nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); - if (ret) - return -1; --- -2.21.0 - diff --git a/SOURCES/0034-arptables-nft-Fix-listing-rules-without-target.patch b/SOURCES/0034-arptables-nft-Fix-listing-rules-without-target.patch deleted file mode 100644 index 56f8f1b..0000000 --- a/SOURCES/0034-arptables-nft-Fix-listing-rules-without-target.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 922b572f262469c9332ea9a7f18808033129b017 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:50 +0100 -Subject: [PATCH] arptables-nft: Fix listing rules without target - -Don't try to print cs.jumpto if it is an empty string, otherwise listing -(and verbose output) contains '-j' flag without argument. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 043bf38bc9ee020bbf1a9789773050d47f83b807) -Signed-off-by: Phil Sutter ---- - iptables/nft-arp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index 37850bd328b71..56021223bdbe6 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -598,7 +598,7 @@ nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format) - - nft_rule_to_iptables_command_state(r, &cs); - -- if (cs.jumpto) -+ if (strlen(cs.jumpto)) - printf("-j %s ", cs.jumpto); - nft_arp_print_rule_details(&cs.arp, format); - print_matches_and_target(&cs, format); --- -2.21.0 - diff --git a/SOURCES/0035-arptables-nft-Fix-MARK-target-parsing-and-printing.patch b/SOURCES/0035-arptables-nft-Fix-MARK-target-parsing-and-printing.patch deleted file mode 100644 index 68c76c7..0000000 --- a/SOURCES/0035-arptables-nft-Fix-MARK-target-parsing-and-printing.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 0b6b93e52f2a862c23206f9ad9fc48aadc06fbd2 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:51 +0100 -Subject: [PATCH] arptables-nft: Fix MARK target parsing and printing - -Legacy arptables parses mark values in hex no matter if prefixed with -'0x' or not. Sadly, this is not easily achievable with guided option -parser. Hence fall back to the old 'parse' callback. The introduced -target definition is valid only for revision 2, but that's consistent -with legacy arptables. - -When printing, use --set-mark option instead of --set-xmark. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit f7fa88020f3bc4ec646ce2a48731a1f5fa2aa0a9) -Signed-off-by: Phil Sutter ---- - extensions/libxt_MARK.c | 95 +++++++++++++++++++ - .../arptables/0001-arptables-save-restore_0 | 2 +- - 2 files changed, 96 insertions(+), 1 deletion(-) - -diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c -index 43aa977924b12..b765af6c35304 100644 ---- a/extensions/libxt_MARK.c -+++ b/extensions/libxt_MARK.c -@@ -1,3 +1,4 @@ -+#include - #include - #include - #include -@@ -245,6 +246,87 @@ static void mark_tg_save(const void *ip, const struct xt_entry_target *target) - printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask); - } - -+static void mark_tg_arp_save(const void *ip, const struct xt_entry_target *target) -+{ -+ const struct xt_mark_tginfo2 *info = (const void *)target->data; -+ -+ if (info->mark == 0) -+ printf(" --and-mark %x", (unsigned int)(uint32_t)~info->mask); -+ else if (info->mark == info->mask) -+ printf(" --or-mark %x", info->mark); -+ else -+ printf(" --set-mark %x", info->mark); -+} -+ -+static void mark_tg_arp_print(const void *ip, -+ const struct xt_entry_target *target, int numeric) -+{ -+ mark_tg_arp_save(ip, target); -+} -+ -+#define MARK_OPT 1 -+#define AND_MARK_OPT 2 -+#define OR_MARK_OPT 3 -+ -+static struct option mark_tg_arp_opts[] = { -+ { .name = "set-mark", .has_arg = required_argument, .flag = 0, .val = MARK_OPT }, -+ { .name = "and-mark", .has_arg = required_argument, .flag = 0, .val = AND_MARK_OPT }, -+ { .name = "or-mark", .has_arg = required_argument, .flag = 0, .val = OR_MARK_OPT }, -+ { .name = NULL} -+}; -+ -+static int -+mark_tg_arp_parse(int c, char **argv, int invert, unsigned int *flags, -+ const void *entry, struct xt_entry_target **target) -+{ -+ struct xt_mark_tginfo2 *info = -+ (struct xt_mark_tginfo2 *)(*target)->data; -+ int i; -+ -+ switch (c) { -+ case MARK_OPT: -+ if (sscanf(argv[optind-1], "%x", &i) != 1) { -+ xtables_error(PARAMETER_PROBLEM, -+ "Bad mark value `%s'", optarg); -+ return 0; -+ } -+ info->mark = i; -+ if (*flags) -+ xtables_error(PARAMETER_PROBLEM, -+ "MARK: Can't specify --set-mark twice"); -+ *flags = 1; -+ break; -+ case AND_MARK_OPT: -+ if (sscanf(argv[optind-1], "%x", &i) != 1) { -+ xtables_error(PARAMETER_PROBLEM, -+ "Bad mark value `%s'", optarg); -+ return 0; -+ } -+ info->mark = 0; -+ info->mask = ~i; -+ if (*flags) -+ xtables_error(PARAMETER_PROBLEM, -+ "MARK: Can't specify --and-mark twice"); -+ *flags = 1; -+ break; -+ case OR_MARK_OPT: -+ if (sscanf(argv[optind-1], "%x", &i) != 1) { -+ xtables_error(PARAMETER_PROBLEM, -+ "Bad mark value `%s'", optarg); -+ return 0; -+ } -+ info->mark = info->mask = i; -+ if (*flags) -+ xtables_error(PARAMETER_PROBLEM, -+ "MARK: Can't specify --or-mark twice"); -+ *flags = 1; -+ break; -+ default: -+ return 0; -+ } -+ return 1; -+} -+ - static int mark_tg_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) - { -@@ -335,6 +417,19 @@ static struct xtables_target mark_tg_reg[] = { - .x6_options = mark_tg_opts, - .xlate = mark_tg_xlate, - }, -+ { -+ .version = XTABLES_VERSION, -+ .name = "MARK", -+ .revision = 2, -+ .family = NFPROTO_ARP, -+ .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), -+ .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), -+ .help = mark_tg_help, -+ .print = mark_tg_arp_print, -+ .save = mark_tg_arp_save, -+ .parse = mark_tg_arp_parse, -+ .extra_opts = mark_tg_arp_opts, -+ }, - }; - - void _init(void) -diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -index 73b3b0cf88e18..f8629551b0ba9 100755 ---- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -+++ b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -@@ -47,7 +47,7 @@ DUMP='*filter - -A OUTPUT -o eth432 --h-length 6 --opcode 1 --h-type 1 -j CLASSIFY --set-class feed:babe - -A foo -i lo --h-length 6 --h-type 1 -j ACCEPT - -A foo --h-length 6 --h-type 1 -j ACCEPT ---A foo --h-length 6 --h-type 1 -j MARK --set-xmark 0x3039/0xffffffff -+-A foo --h-length 6 --h-type 1 -j MARK --set-mark 12345 - -A foo --h-length 6 --opcode 1 --h-type 1 -j ACCEPT - -A foo --h-length 6 --h-type 1 --proto-type 0x800 -j ACCEPT - -A foo -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 -j ACCEPT --- -2.21.0 - diff --git a/SOURCES/0036-arptables-nft-Fix-CLASSIFY-target-printing.patch b/SOURCES/0036-arptables-nft-Fix-CLASSIFY-target-printing.patch deleted file mode 100644 index a2a9671..0000000 --- a/SOURCES/0036-arptables-nft-Fix-CLASSIFY-target-printing.patch +++ /dev/null @@ -1,99 +0,0 @@ -From fabed9f23311cdf42180613123309307b5c6add5 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:52 +0100 -Subject: [PATCH] arptables-nft: Fix CLASSIFY target printing - -In legacy arptables, CLASSIFY target is not printed with fixed hex -number lengths. Counter this by introducing a dedicated target -definition for NFPROTO_ARP only having own print/save callbacks. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 756bea26a3dad89c467c703725ce6d3c6b29c871) -Signed-off-by: Phil Sutter ---- - extensions/libxt_CLASSIFY.c | 59 +++++++++++++++++++++++++++++-------- - 1 file changed, 46 insertions(+), 13 deletions(-) - -diff --git a/extensions/libxt_CLASSIFY.c b/extensions/libxt_CLASSIFY.c -index f90082dc7c50e..75aaf0c41b61a 100644 ---- a/extensions/libxt_CLASSIFY.c -+++ b/extensions/libxt_CLASSIFY.c -@@ -73,6 +73,24 @@ CLASSIFY_save(const void *ip, const struct xt_entry_target *target) - TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority)); - } - -+static void -+CLASSIFY_arp_save(const void *ip, const struct xt_entry_target *target) -+{ -+ const struct xt_classify_target_info *clinfo = -+ (const struct xt_classify_target_info *)target->data; -+ -+ printf(" --set-class %x:%x", -+ TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority)); -+} -+ -+static void -+CLASSIFY_arp_print(const void *ip, -+ const struct xt_entry_target *target, -+ int numeric) -+{ -+ CLASSIFY_arp_save(ip, target); -+} -+ - static int CLASSIFY_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) - { -@@ -98,21 +116,36 @@ static int CLASSIFY_xlate(struct xt_xlate *xl, - return 1; - } - --static struct xtables_target classify_target = { -- .family = NFPROTO_UNSPEC, -- .name = "CLASSIFY", -- .version = XTABLES_VERSION, -- .size = XT_ALIGN(sizeof(struct xt_classify_target_info)), -- .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)), -- .help = CLASSIFY_help, -- .print = CLASSIFY_print, -- .save = CLASSIFY_save, -- .x6_parse = CLASSIFY_parse, -- .x6_options = CLASSIFY_opts, -- .xlate = CLASSIFY_xlate, -+static struct xtables_target classify_tg_reg[] = { -+ { -+ .family = NFPROTO_UNSPEC, -+ .name = "CLASSIFY", -+ .version = XTABLES_VERSION, -+ .size = XT_ALIGN(sizeof(struct xt_classify_target_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)), -+ .help = CLASSIFY_help, -+ .print = CLASSIFY_print, -+ .save = CLASSIFY_save, -+ .x6_parse = CLASSIFY_parse, -+ .x6_options = CLASSIFY_opts, -+ .xlate = CLASSIFY_xlate, -+ }, -+ { -+ .family = NFPROTO_ARP, -+ .name = "CLASSIFY", -+ .version = XTABLES_VERSION, -+ .size = XT_ALIGN(sizeof(struct xt_classify_target_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)), -+ .help = CLASSIFY_help, -+ .print = CLASSIFY_arp_print, -+ .save = CLASSIFY_arp_save, -+ .x6_parse = CLASSIFY_parse, -+ .x6_options = CLASSIFY_opts, -+ .xlate = CLASSIFY_xlate, -+ } - }; - - void _init(void) - { -- xtables_register_target(&classify_target); -+ xtables_register_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg)); - } --- -2.21.0 - diff --git a/SOURCES/0037-arptables-nft-Remove-space-between-cnt-and-value.patch b/SOURCES/0037-arptables-nft-Remove-space-between-cnt-and-value.patch deleted file mode 100644 index b60ec8f..0000000 --- a/SOURCES/0037-arptables-nft-Remove-space-between-cnt-and-value.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 44e633b17e257f1915c4b33d9249f2e45f0a39cc Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:53 +0100 -Subject: [PATCH] arptables-nft: Remove space between *cnt= and value - -When printing rule counters, call xtables_print_num() with FMT_NOTABLE -bit set to avoid spaces between equal sign and value. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 9421327926a529ec8300d37f3be8a6cfab701786) -Signed-off-by: Phil Sutter ---- - iptables/nft-arp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index 56021223bdbe6..f357fc4a43c4c 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -605,9 +605,9 @@ nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format) - - if (!(format & FMT_NOCOUNTS)) { - printf(", pcnt="); -- xtables_print_num(cs.counters.pcnt, format); -+ xtables_print_num(cs.counters.pcnt, format | FMT_NOTABLE); - printf("-- bcnt="); -- xtables_print_num(cs.counters.bcnt, format); -+ xtables_print_num(cs.counters.bcnt, format | FMT_NOTABLE); - } - - if (!(format & FMT_NONEWLINE)) --- -2.21.0 - diff --git a/SOURCES/0038-arptables-nft-save-Fix-position-of-j-option.patch b/SOURCES/0038-arptables-nft-save-Fix-position-of-j-option.patch deleted file mode 100644 index d812306..0000000 --- a/SOURCES/0038-arptables-nft-save-Fix-position-of-j-option.patch +++ /dev/null @@ -1,296 +0,0 @@ -From f521f424e5ab298d0dd2146677ea4f0170a9dfd0 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:54 +0100 -Subject: [PATCH] arptables-nft-save: Fix position of -j option - -Legacy arptables-save (just like arptables itself) prints verdict as -first option, then matches and finally any target options. - -To achieve this without introducing double/trailing spaces everywhere, -integrate target ('-j') option printing into -nft_arp_print_rule_details() and make it print separating whitespace -before each option. - -In nft_arp_save_rule(), replace the call to save_matches_and_target() by -by a direct call to cs->target->save() since the former prints '-j' -option itself. Since there are no match extensions in arptables, any -other code from that function is not needed. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 2c3f7a2cd6fd8325b3a84e280cce945c6c20b87f) -Signed-off-by: Phil Sutter ---- - iptables/nft-arp.c | 65 +++++++++++-------- - .../arptables/0001-arptables-save-restore_0 | 32 ++++----- - .../0002-arptables-restore-defaults_0 | 6 +- - 3 files changed, 58 insertions(+), 45 deletions(-) - -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index f357fc4a43c4c..2cbdf23214049 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -434,14 +434,21 @@ static void nft_arp_print_header(unsigned int format, const char *chain, - } - } - --static void nft_arp_print_rule_details(const struct arpt_entry *fw, -+static void nft_arp_print_rule_details(const struct iptables_command_state *cs, - unsigned int format) - { -+ const struct arpt_entry *fw = &cs->arp; - char buf[BUFSIZ]; - char iface[IFNAMSIZ+2]; -+ const char *sep = ""; - int print_iface = 0; - int i; - -+ if (strlen(cs->jumpto)) { -+ printf("%s-j %s", sep, cs->jumpto); -+ sep = " "; -+ } -+ - iface[0] = '\0'; - - if (fw->arp.iniface[0] != '\0') { -@@ -453,9 +460,11 @@ static void nft_arp_print_rule_details(const struct arpt_entry *fw, - if (format & FMT_NUMERIC) strcat(iface, "*"); - else strcat(iface, "any"); - } -- if (print_iface) -- printf("%s-i %s ", fw->arp.invflags & ARPT_INV_VIA_IN ? -+ if (print_iface) { -+ printf("%s%s-i %s", sep, fw->arp.invflags & ARPT_INV_VIA_IN ? - "! " : "", iface); -+ sep = " "; -+ } - - print_iface = 0; - iface[0] = '\0'; -@@ -469,12 +478,14 @@ static void nft_arp_print_rule_details(const struct arpt_entry *fw, - if (format & FMT_NUMERIC) strcat(iface, "*"); - else strcat(iface, "any"); - } -- if (print_iface) -- printf("%s-o %s ", fw->arp.invflags & ARPT_INV_VIA_OUT ? -+ if (print_iface) { -+ printf("%s%s-o %s", sep, fw->arp.invflags & ARPT_INV_VIA_OUT ? - "! " : "", iface); -+ sep = " "; -+ } - - if (fw->arp.smsk.s_addr != 0L) { -- printf("%s", fw->arp.invflags & ARPT_INV_SRCIP -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCIP - ? "! " : ""); - if (format & FMT_NUMERIC) - sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src))); -@@ -482,7 +493,8 @@ static void nft_arp_print_rule_details(const struct arpt_entry *fw, - sprintf(buf, "%s", addr_to_anyname(&(fw->arp.src))); - strncat(buf, mask_to_dotted(&(fw->arp.smsk)), - sizeof(buf) - strlen(buf) - 1); -- printf("-s %s ", buf); -+ printf("-s %s", buf); -+ sep = " "; - } - - for (i = 0; i < ARPT_DEV_ADDR_LEN_MAX; i++) -@@ -490,16 +502,16 @@ static void nft_arp_print_rule_details(const struct arpt_entry *fw, - break; - if (i == ARPT_DEV_ADDR_LEN_MAX) - goto after_devsrc; -- printf("%s", fw->arp.invflags & ARPT_INV_SRCDEVADDR -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCDEVADDR - ? "! " : ""); - printf("--src-mac "); - print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr, - (unsigned char *)fw->arp.src_devaddr.mask, ETH_ALEN); -- printf(" "); -+ sep = " "; - after_devsrc: - - if (fw->arp.tmsk.s_addr != 0L) { -- printf("%s", fw->arp.invflags & ARPT_INV_TGTIP -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTIP - ? "! " : ""); - if (format & FMT_NUMERIC) - sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt))); -@@ -507,7 +519,8 @@ after_devsrc: - sprintf(buf, "%s", addr_to_anyname(&(fw->arp.tgt))); - strncat(buf, mask_to_dotted(&(fw->arp.tmsk)), - sizeof(buf) - strlen(buf) - 1); -- printf("-d %s ", buf); -+ printf("-d %s", buf); -+ sep = " "; - } - - for (i = 0; i arp.invflags & ARPT_INV_TGTDEVADDR -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTDEVADDR - ? "! " : ""); - printf("--dst-mac "); - print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr, - (unsigned char *)fw->arp.tgt_devaddr.mask, ETH_ALEN); -- printf(" "); -+ sep = " "; - - after_devdst: - - if (fw->arp.arhln_mask != 0) { -- printf("%s", fw->arp.invflags & ARPT_INV_ARPHLN -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN - ? "! " : ""); - printf("--h-length %d", fw->arp.arhln); - if (fw->arp.arhln_mask != 255) - printf("/%d", fw->arp.arhln_mask); -- printf(" "); -+ sep = " "; - } - - if (fw->arp.arpop_mask != 0) { - int tmp = ntohs(fw->arp.arpop); - -- printf("%s", fw->arp.invflags & ARPT_INV_ARPOP -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPOP - ? "! " : ""); - if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC)) - printf("--opcode %s", opcodes[tmp-1]); -@@ -545,13 +558,13 @@ after_devdst: - - if (fw->arp.arpop_mask != 65535) - printf("/%d", ntohs(fw->arp.arpop_mask)); -- printf(" "); -+ sep = " "; - } - - if (fw->arp.arhrd_mask != 0) { - uint16_t tmp = ntohs(fw->arp.arhrd); - -- printf("%s", fw->arp.invflags & ARPT_INV_ARPHRD -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD - ? "! " : ""); - if (tmp == 1 && !(format & FMT_NUMERIC)) - printf("--h-type %s", "Ethernet"); -@@ -559,13 +572,13 @@ after_devdst: - printf("--h-type %u", tmp); - if (fw->arp.arhrd_mask != 65535) - printf("/%d", ntohs(fw->arp.arhrd_mask)); -- printf(" "); -+ sep = " "; - } - - if (fw->arp.arpro_mask != 0) { - int tmp = ntohs(fw->arp.arpro); - -- printf("%s", fw->arp.invflags & ARPT_INV_ARPPRO -+ printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPPRO - ? "! " : ""); - if (tmp == 0x0800 && !(format & FMT_NUMERIC)) - printf("--proto-type %s", "IPv4"); -@@ -573,7 +586,7 @@ after_devdst: - printf("--proto-type 0x%x", tmp); - if (fw->arp.arpro_mask != 65535) - printf("/%x", ntohs(fw->arp.arpro_mask)); -- printf(" "); -+ sep = " "; - } - } - -@@ -584,8 +597,10 @@ nft_arp_save_rule(const void *data, unsigned int format) - - format |= FMT_NUMERIC; - -- nft_arp_print_rule_details(&cs->arp, format); -- save_matches_and_target(cs, false, &cs->arp, format); -+ nft_arp_print_rule_details(cs, format); -+ if (cs->target && cs->target->save) -+ cs->target->save(&cs->fw, cs->target->t); -+ printf("\n"); - } - - static void -@@ -598,9 +613,7 @@ nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format) - - nft_rule_to_iptables_command_state(r, &cs); - -- if (strlen(cs.jumpto)) -- printf("-j %s ", cs.jumpto); -- nft_arp_print_rule_details(&cs.arp, format); -+ nft_arp_print_rule_details(&cs, format); - print_matches_and_target(&cs, format); - - if (!(format & FMT_NOCOUNTS)) { -diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -index f8629551b0ba9..0664e3b38d5e8 100755 ---- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -+++ b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -@@ -35,22 +35,22 @@ DUMP='*filter - :INPUT ACCEPT - :OUTPUT DROP - :foo - ---A INPUT -s 10.0.0.0/8 --h-length 6 --h-type 1 -j ACCEPT ---A INPUT -d 192.168.123.1 --h-length 6 --h-type 1 -j ACCEPT ---A INPUT --src-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -j ACCEPT ---A INPUT --dst-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -j ACCEPT ---A INPUT --h-length 6 --h-type 1 -j foo ---A INPUT --h-length 6 --h-type 1 ---A OUTPUT -o lo --h-length 6 --h-type 1 -j ACCEPT ---A OUTPUT -o eth134 --h-length 6 --h-type 1 -j mangle --mangle-ip-s 10.0.0.1 ---A OUTPUT -o eth432 --h-length 6 --h-type 1 -j CLASSIFY --set-class feed:babe ---A OUTPUT -o eth432 --h-length 6 --opcode 1 --h-type 1 -j CLASSIFY --set-class feed:babe ---A foo -i lo --h-length 6 --h-type 1 -j ACCEPT ---A foo --h-length 6 --h-type 1 -j ACCEPT ---A foo --h-length 6 --h-type 1 -j MARK --set-mark 12345 ---A foo --h-length 6 --opcode 1 --h-type 1 -j ACCEPT ---A foo --h-length 6 --h-type 1 --proto-type 0x800 -j ACCEPT ---A foo -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 -j ACCEPT -+-A INPUT -j ACCEPT -s 10.0.0.0/8 --h-length 6 --h-type 1 -+-A INPUT -j ACCEPT -d 192.168.123.1 --h-length 6 --h-type 1 -+-A INPUT -j ACCEPT --src-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -+-A INPUT -j ACCEPT --dst-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -+-A INPUT -j foo --h-length 6 --h-type 1 -+-A INPUT --h-length 6 --h-type 1 -+-A OUTPUT -j ACCEPT -o lo --h-length 6 --h-type 1 -+-A OUTPUT -j mangle -o eth134 --h-length 6 --h-type 1 --mangle-ip-s 10.0.0.1 -+-A OUTPUT -j CLASSIFY -o eth432 --h-length 6 --h-type 1 --set-class feed:babe -+-A OUTPUT -j CLASSIFY -o eth432 --h-length 6 --opcode 1 --h-type 1 --set-class feed:babe -+-A foo -j ACCEPT -i lo --h-length 6 --h-type 1 -+-A foo -j ACCEPT --h-length 6 --h-type 1 -+-A foo -j MARK --h-length 6 --h-type 1 --set-mark 12345 -+-A foo -j ACCEPT --h-length 6 --opcode 1 --h-type 1 -+-A foo -j ACCEPT --h-length 6 --h-type 1 --proto-type 0x800 -+-A foo -j ACCEPT -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 - ' - - diff -u <(echo -e "$DUMP") <($XT_MULTI arptables-save) -diff --git a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -index ee17da0023b82..d742c3d506305 100755 ---- a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -+++ b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -@@ -11,7 +11,7 @@ set -e - DUMP='*filter - :OUTPUT ACCEPT - -A OUTPUT -j mangle --mangle-ip-s 10.0.0.1 ---A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-d 10.0.0.2 -+-A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-d 10.0.0.2 - ' - - # note how mangle-ip-s is unset in second rule -@@ -19,8 +19,8 @@ DUMP='*filter - EXPECT='*filter - :INPUT ACCEPT - :OUTPUT ACCEPT ---A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-s 10.0.0.1 ---A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-d 10.0.0.2 -+-A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-s 10.0.0.1 -+-A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-d 10.0.0.2 - ' - - $XT_MULTI arptables -F --- -2.21.0 - diff --git a/SOURCES/0039-arptables-nft-Don-t-print-default-h-len-h-type-value.patch b/SOURCES/0039-arptables-nft-Don-t-print-default-h-len-h-type-value.patch deleted file mode 100644 index 83234ca..0000000 --- a/SOURCES/0039-arptables-nft-Don-t-print-default-h-len-h-type-value.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 3013545255719fcda031c227570c498c4fc7cc35 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:55 +0100 -Subject: [PATCH] arptables-nft: Don't print default h-len/h-type values - -Default values for --h-len and --h-type being printed for rules where -user didn't provide them is unexpected and confusing. The drawback is -the opposite: If user provided either of them with their default value, -they are later omitted when listing rules. Though since unlike legacy -arptables we can't distinguish between not specified and specified with -default value, we can't fix both - so choose to optimize for the more -likely case. - -Fixes: 5aecb2d8bfdda ("arptables: pre-init hlen and ethertype") -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 84331e3ed3f8eb9d53c00c221113ad16b209968a) -Signed-off-by: Phil Sutter ---- - iptables/nft-arp.c | 4 +-- - .../arptables/0001-arptables-save-restore_0 | 32 +++++++++---------- - .../0002-arptables-restore-defaults_0 | 6 ++-- - 3 files changed, 21 insertions(+), 21 deletions(-) - -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index 2cbdf23214049..37b0985377bef 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -537,7 +537,7 @@ after_devsrc: - - after_devdst: - -- if (fw->arp.arhln_mask != 0) { -+ if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) { - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN - ? "! " : ""); - printf("--h-length %d", fw->arp.arhln); -@@ -561,7 +561,7 @@ after_devdst: - sep = " "; - } - -- if (fw->arp.arhrd_mask != 0) { -+ if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) { - uint16_t tmp = ntohs(fw->arp.arhrd); - - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD -diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -index 0664e3b38d5e8..e10f61cc8f95b 100755 ---- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -+++ b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 -@@ -35,22 +35,22 @@ DUMP='*filter - :INPUT ACCEPT - :OUTPUT DROP - :foo - ---A INPUT -j ACCEPT -s 10.0.0.0/8 --h-length 6 --h-type 1 ---A INPUT -j ACCEPT -d 192.168.123.1 --h-length 6 --h-type 1 ---A INPUT -j ACCEPT --src-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 ---A INPUT -j ACCEPT --dst-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 ---A INPUT -j foo --h-length 6 --h-type 1 ---A INPUT --h-length 6 --h-type 1 ---A OUTPUT -j ACCEPT -o lo --h-length 6 --h-type 1 ---A OUTPUT -j mangle -o eth134 --h-length 6 --h-type 1 --mangle-ip-s 10.0.0.1 ---A OUTPUT -j CLASSIFY -o eth432 --h-length 6 --h-type 1 --set-class feed:babe ---A OUTPUT -j CLASSIFY -o eth432 --h-length 6 --opcode 1 --h-type 1 --set-class feed:babe ---A foo -j ACCEPT -i lo --h-length 6 --h-type 1 ---A foo -j ACCEPT --h-length 6 --h-type 1 ---A foo -j MARK --h-length 6 --h-type 1 --set-mark 12345 ---A foo -j ACCEPT --h-length 6 --opcode 1 --h-type 1 ---A foo -j ACCEPT --h-length 6 --h-type 1 --proto-type 0x800 ---A foo -j ACCEPT -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 -+-A INPUT -j ACCEPT -s 10.0.0.0/8 -+-A INPUT -j ACCEPT -d 192.168.123.1 -+-A INPUT -j ACCEPT --src-mac fe:ed:ba:be:00:01 -+-A INPUT -j ACCEPT --dst-mac fe:ed:ba:be:00:01 -+-A INPUT -j foo -+-A INPUT -+-A OUTPUT -j ACCEPT -o lo -+-A OUTPUT -j mangle -o eth134 --mangle-ip-s 10.0.0.1 -+-A OUTPUT -j CLASSIFY -o eth432 --set-class feed:babe -+-A OUTPUT -j CLASSIFY -o eth432 --opcode 1 --set-class feed:babe -+-A foo -j ACCEPT -i lo -+-A foo -j ACCEPT -+-A foo -j MARK --set-mark 12345 -+-A foo -j ACCEPT --opcode 1 -+-A foo -j ACCEPT --proto-type 0x800 -+-A foo -j ACCEPT -i lo --opcode 1 --proto-type 0x800 - ' - - diff -u <(echo -e "$DUMP") <($XT_MULTI arptables-save) -diff --git a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -index d742c3d506305..b2ed95e87bb40 100755 ---- a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -+++ b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 -@@ -11,7 +11,7 @@ set -e - DUMP='*filter - :OUTPUT ACCEPT - -A OUTPUT -j mangle --mangle-ip-s 10.0.0.1 ---A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-d 10.0.0.2 -+-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2 - ' - - # note how mangle-ip-s is unset in second rule -@@ -19,8 +19,8 @@ DUMP='*filter - EXPECT='*filter - :INPUT ACCEPT - :OUTPUT ACCEPT ---A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-s 10.0.0.1 ---A OUTPUT -j mangle --h-length 6 --h-type 1 --mangle-ip-d 10.0.0.2 -+-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1 -+-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2 - ' - - $XT_MULTI arptables -F --- -2.21.0 - diff --git a/SOURCES/0040-tests-shell-Add-arptables-nft-verbose-output-test.patch b/SOURCES/0040-tests-shell-Add-arptables-nft-verbose-output-test.patch deleted file mode 100644 index 1543610..0000000 --- a/SOURCES/0040-tests-shell-Add-arptables-nft-verbose-output-test.patch +++ /dev/null @@ -1,90 +0,0 @@ -From bf2b28732579e44bf4c77869be586ee7d73bdabb Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 31 Jan 2019 16:12:56 +0100 -Subject: [PATCH] tests: shell: Add arptables-nft verbose output test - -With arptables-nft output being in a very good state now, add a test to -ensure it stays that way. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 3d8f261c565a024c13d627b18a0fcafc76de8f2c) -Signed-off-by: Phil Sutter ---- - .../arptables/0003-arptables-verbose-output_0 | 64 +++++++++++++++++++ - 1 file changed, 64 insertions(+) - create mode 100755 iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 - -diff --git a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 -new file mode 100755 -index 0000000000000..35126fa7d717c ---- /dev/null -+++ b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 -@@ -0,0 +1,64 @@ -+#!/bin/bash -+ -+set -e -+set -x -+ -+# there is no legacy backend to test -+[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } -+ -+$XT_MULTI arptables -N foo -+ -+# check verbose output matches expectations -+ -+RULE1='-i eth23 -j ACCEPT' -+VOUT1='-j ACCEPT -i eth23 -o *' -+ -+RULE2='-i eth23' -+VOUT2='-i eth23 -o *' -+ -+RULE3='-i eth23 -j MARK --set-mark 42' -+VOUT3='-j MARK -i eth23 -o * --set-mark 42' -+ -+RULE4='-o eth23 -j CLASSIFY --set-class 23:42' -+VOUT4='-j CLASSIFY -i * -o eth23 --set-class 23:42' -+ -+RULE5='-o eth23 -j foo' -+VOUT5='-j foo -i * -o eth23' -+ -+RULE6='-o eth23 -j mangle --mangle-ip-s 10.0.0.1' -+VOUT6='-j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1' -+ -+diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI arptables -v -A INPUT $RULE1) -+diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI arptables -v -A INPUT $RULE2) -+diff -u -Z <(echo -e "$VOUT3") <($XT_MULTI arptables -v -A INPUT $RULE3) -+diff -u -Z <(echo -e "$VOUT4") <($XT_MULTI arptables -v -A OUTPUT $RULE4) -+diff -u -Z <(echo -e "$VOUT5") <($XT_MULTI arptables -v -A OUTPUT $RULE5) -+diff -u -Z <(echo -e "$VOUT6") <($XT_MULTI arptables -v -A foo $RULE6) -+ -+EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes) -+-j ACCEPT -i eth23 -o *, pcnt=0 -- bcnt=0 -+-i eth23 -o *, pcnt=0 -- bcnt=0 -+-j MARK -i eth23 -o * --set-mark 42, pcnt=0 -- bcnt=0 -+ -+Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) -+-j CLASSIFY -i * -o eth23 --set-class 23:42, pcnt=0 -- bcnt=0 -+-j foo -i * -o eth23, pcnt=0 -- bcnt=0 -+ -+Chain foo (1 references) -+-j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1, pcnt=0 -- bcnt=0' -+ -+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables -v -n -L) -+ -+EXPECT='*filter -+:INPUT ACCEPT -+:OUTPUT ACCEPT -+:foo - -+-A INPUT -j ACCEPT -i eth23 -+-A INPUT -i eth23 -+-A INPUT -j MARK -i eth23 --set-mark 42 -+-A OUTPUT -j CLASSIFY -o eth23 --set-class 23:42 -+-A OUTPUT -j foo -o eth23 -+-A foo -j mangle -o eth23 --mangle-ip-s 10.0.0.1 -+' -+ -+diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables-save) --- -2.21.0 - diff --git a/SOURCES/0041-arptables-nft-Set-h-type-h-length-masks-by-default-t.patch b/SOURCES/0041-arptables-nft-Set-h-type-h-length-masks-by-default-t.patch deleted file mode 100644 index dd26985..0000000 --- a/SOURCES/0041-arptables-nft-Set-h-type-h-length-masks-by-default-t.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2fb13e8bdc9649c3910c6c1341dc4dd483767c0c Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 1 Feb 2019 17:06:18 +0100 -Subject: [PATCH] arptables-nft: Set h-type/h-length masks by default, too - -These masks are not used in nftables backend, but mangle extension -checks arhln_mask value to make sure --h-length was given (which is -implicitly the case). - -Fixes: 5aecb2d8bfdda ("arptables: pre-init hlen and ethertype") -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit a1da179b0ff3783badca352a42808f4398dd1a98) -Signed-off-by: Phil Sutter ---- - iptables/xtables-arp.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c -index 819e7e6c94034..2dce1a52f16fd 100644 ---- a/iptables/xtables-arp.c -+++ b/iptables/xtables-arp.c -@@ -909,8 +909,12 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, - { - struct iptables_command_state cs = { - .jumpto = "", -- .arp.arp.arhln = 6, -- .arp.arp.arhrd = htons(ARPHRD_ETHER), -+ .arp.arp = { -+ .arhln = 6, -+ .arhln_mask = 255, -+ .arhrd = htons(ARPHRD_ETHER), -+ .arhrd_mask = 65535, -+ }, - }; - int invert = 0; - unsigned int nsaddrs = 0, ndaddrs = 0; --- -2.21.0 - diff --git a/SOURCES/0042-nft-Add-new-builtin-chains-to-cache-immediately.patch b/SOURCES/0042-nft-Add-new-builtin-chains-to-cache-immediately.patch deleted file mode 100644 index 4d2ba27..0000000 --- a/SOURCES/0042-nft-Add-new-builtin-chains-to-cache-immediately.patch +++ /dev/null @@ -1,95 +0,0 @@ -From e3dacaff9e1d6f5be93afeb705cd24b38c8ff6f2 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 15 Jan 2019 23:23:03 +0100 -Subject: [PATCH] nft: Add new builtin chains to cache immediately - -Newly created builtin chains missing from cache was the sole reason for -the immediate calls to nft_commit(). With nft_chain_builtin_add() -inserting the new chain into the table's chain list, this is not needed -anymore. Just make sure batch_obj_del() doesn't free the payload of -NFT_COMPAT_CHAIN_ADD jobs since it contains the new chain which has -been added to cache. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 2b801fc515ae094d04207e840ed191196292b968) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 30 +++++++++--------------------- - 1 file changed, 9 insertions(+), 21 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 9c0ad9a2d054f..c2af1a6fd0985 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -644,6 +644,7 @@ static void nft_chain_builtin_add(struct nft_handle *h, - return; - - batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); -+ nftnl_chain_list_add_tail(c, h->table[table->type].chain_cache); - } - - /* find if built-in table already exists */ -@@ -1216,8 +1217,11 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, - h->ops->print_rule(r, 0, FMT_PRINT_RULE); - - c = nft_chain_find(h, table, chain); -- if (c) -- nftnl_chain_rule_add_tail(r, c); -+ if (!c) { -+ errno = ENOENT; -+ return 0; -+ } -+ nftnl_chain_rule_add_tail(r, c); - - return 1; - } -@@ -2282,16 +2286,8 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, - bool found = false; - - /* If built-in chains don't exist for this table, create them */ -- if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) { -+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) - nft_xt_builtin_init(h, table); -- /* Force table and chain creation, otherwise first iptables -L -- * lists no table/chains. -- */ -- if (!list_empty(&h->obj_list)) { -- nft_commit(h); -- flush_chain_cache(h, NULL); -- } -- } - - ops = nft_family_ops_lookup(h->family); - -@@ -2397,16 +2393,8 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain, - int ret = 0; - - /* If built-in chains don't exist for this table, create them */ -- if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) { -+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) - nft_xt_builtin_init(h, table); -- /* Force table and chain creation, otherwise first iptables -L -- * lists no table/chains. -- */ -- if (!list_empty(&h->obj_list)) { -- nft_commit(h); -- flush_chain_cache(h, NULL); -- } -- } - - if (!nft_is_table_compatible(h, table)) { - xtables_error(OTHER_PROBLEM, "table `%s' is incompatible, use 'nft' tool.\n", table); -@@ -2525,8 +2513,8 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o) - break; - case NFT_COMPAT_CHAIN_ZERO: - case NFT_COMPAT_CHAIN_USER_ADD: -- break; - case NFT_COMPAT_CHAIN_ADD: -+ break; - case NFT_COMPAT_CHAIN_USER_DEL: - case NFT_COMPAT_CHAIN_USER_FLUSH: - case NFT_COMPAT_CHAIN_UPDATE: --- -2.21.0 - diff --git a/SOURCES/0043-xtables-Fix-position-of-replaced-rules-in-cache.patch b/SOURCES/0043-xtables-Fix-position-of-replaced-rules-in-cache.patch deleted file mode 100644 index 3f2f7e6..0000000 --- a/SOURCES/0043-xtables-Fix-position-of-replaced-rules-in-cache.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 892eaf39a4bd14ad25e55e5c0d4ef3dc163183da Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 15 Jan 2019 23:23:04 +0100 -Subject: [PATCH] xtables: Fix position of replaced rules in cache - -When replacing a rule, the replacement was simply appended to the -chain's rule list. Instead, insert it where the rule it replaces was. - -This also fixes for zero counters command to remove the old rule from -cache. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 5ca9acf51adf9dcc8e0d82cd8f5b9b2514f900ee) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 34 +++++++++++++++++----------------- - iptables/nft.h | 2 +- - iptables/xtables-arp.c | 2 +- - iptables/xtables-eb.c | 2 +- - iptables/xtables.c | 4 ++-- - 5 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index c2af1a6fd0985..76764fde4e9fb 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1186,7 +1186,7 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain); - - int - nft_rule_append(struct nft_handle *h, const char *chain, const char *table, -- void *data, uint64_t handle, bool verbose) -+ void *data, struct nftnl_rule *ref, bool verbose) - { - struct nftnl_chain *c; - struct nftnl_rule *r; -@@ -1202,8 +1202,9 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, - if (r == NULL) - return 0; - -- if (handle > 0) { -- nftnl_rule_set(r, NFTNL_RULE_HANDLE, &handle); -+ if (ref) { -+ nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, -+ nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE)); - type = NFT_COMPAT_RULE_REPLACE; - } else - type = NFT_COMPAT_RULE_APPEND; -@@ -1216,12 +1217,17 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table, - if (verbose) - h->ops->print_rule(r, 0, FMT_PRINT_RULE); - -- c = nft_chain_find(h, table, chain); -- if (!c) { -- errno = ENOENT; -- return 0; -+ if (ref) { -+ nftnl_chain_rule_insert_at(r, ref); -+ nftnl_chain_rule_del(r); -+ } else { -+ c = nft_chain_find(h, table, chain); -+ if (!c) { -+ errno = ENOENT; -+ return 0; -+ } -+ nftnl_chain_rule_add_tail(r, c); - } -- nftnl_chain_rule_add_tail(r, c); - - return 1; - } -@@ -2109,7 +2115,7 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - r = nft_rule_find(h, c, data, rulenum - 1); - if (r != NULL) - return nft_rule_append(h, chain, table, data, -- 0, verbose); -+ NULL, verbose); - - errno = ENOENT; - goto err; -@@ -2181,11 +2187,7 @@ int nft_rule_replace(struct nft_handle *h, const char *chain, - (unsigned long long) - nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE)); - -- nftnl_rule_list_del(r); -- -- ret = nft_rule_append(h, chain, table, data, -- nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE), -- verbose); -+ ret = nft_rule_append(h, chain, table, data, r, verbose); - } else - errno = ENOENT; - -@@ -2461,9 +2463,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, - - cs.counters.pcnt = cs.counters.bcnt = 0; - -- ret = nft_rule_append(h, chain, table, &cs, -- nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE), -- false); -+ ret = nft_rule_append(h, chain, table, &cs, r, false); - - error: - return ret; -diff --git a/iptables/nft.h b/iptables/nft.h -index dfdffd69342db..97d73c8b534be 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -98,7 +98,7 @@ bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain - */ - struct nftnl_rule; - --int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose); -+int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, struct nftnl_rule *ref, bool verbose); - int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose); - int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose); - int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose); -diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c -index 2dce1a52f16fd..18cdced627c55 100644 ---- a/iptables/xtables-arp.c -+++ b/iptables/xtables-arp.c -@@ -825,7 +825,7 @@ append_entry(struct nft_handle *h, - for (j = 0; j < ndaddrs; j++) { - cs->arp.arp.tgt.s_addr = daddrs[j].s_addr; - if (append) { -- ret = nft_rule_append(h, chain, table, cs, 0, -+ ret = nft_rule_append(h, chain, table, cs, NULL, - verbose); - } else { - ret = nft_rule_insert(h, chain, table, cs, -diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c -index 871891442e431..4c52c29aa4817 100644 ---- a/iptables/xtables-eb.c -+++ b/iptables/xtables-eb.c -@@ -171,7 +171,7 @@ append_entry(struct nft_handle *h, - int ret = 1; - - if (append) -- ret = nft_rule_append(h, chain, table, cs, 0, verbose); -+ ret = nft_rule_append(h, chain, table, cs, NULL, verbose); - else - ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose); - -diff --git a/iptables/xtables.c b/iptables/xtables.c -index da11e8cc159a0..d0167e6396975 100644 ---- a/iptables/xtables.c -+++ b/iptables/xtables.c -@@ -406,7 +406,7 @@ add_entry(const char *chain, - - if (append) { - ret = nft_rule_append(h, chain, table, -- cs, 0, -+ cs, NULL, - verbose); - } else { - ret = nft_rule_insert(h, chain, table, -@@ -426,7 +426,7 @@ add_entry(const char *chain, - &d.mask.v6[j], sizeof(struct in6_addr)); - if (append) { - ret = nft_rule_append(h, chain, table, -- cs, 0, -+ cs, NULL, - verbose); - } else { - ret = nft_rule_insert(h, chain, table, --- -2.21.0 - diff --git a/SOURCES/0044-xtables-Fix-for-inserting-rule-at-wrong-position.patch b/SOURCES/0044-xtables-Fix-for-inserting-rule-at-wrong-position.patch deleted file mode 100644 index ae350d0..0000000 --- a/SOURCES/0044-xtables-Fix-for-inserting-rule-at-wrong-position.patch +++ /dev/null @@ -1,282 +0,0 @@ -From 3c0eab01c78ff0215cafc124fd76d67f39f2b4ca Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 15 Jan 2019 23:23:05 +0100 -Subject: [PATCH] xtables: Fix for inserting rule at wrong position - -iptables-restore allows to insert rules at a certain position which is -problematic for iptables-nft to realize since rule position is not -determined by number but handle of previous or following rule and in -case the rules surrounding the new one are new as well, they don't have -a handle to refer to yet. - -Fix this by making use of NFTNL_RULE_POSITION_ID attribute: When -inserting before a rule which does not have a handle, refer to it using -its NFTNL_RULE_ID value. If the latter doesn't exist either, assign a -new one to it. - -The last used rule ID value is tracked in a new field of struct -nft_handle which is incremented before each use. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 7ea0b7d809229973d950ed99845bdd0b2eb4cbb7) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 30 +++-- - iptables/nft.h | 1 + - .../ipt-restore/0003-restore-ordering_0 | 117 ++++++++++++++++++ - .../testcases/iptables/0005-rule-replace_0 | 38 ++++++ - 4 files changed, 176 insertions(+), 10 deletions(-) - create mode 100755 iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 - create mode 100755 iptables/tests/shell/testcases/iptables/0005-rule-replace_0 - -diff --git a/iptables/nft.c b/iptables/nft.c -index 76764fde4e9fb..2fa973cf03975 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -2065,16 +2065,30 @@ int nft_rule_delete(struct nft_handle *h, const char *chain, - static struct nftnl_rule * - nft_rule_add(struct nft_handle *h, const char *chain, - const char *table, struct iptables_command_state *cs, -- uint64_t handle, bool verbose) -+ struct nftnl_rule *ref, bool verbose) - { - struct nftnl_rule *r; -+ uint64_t ref_id; - - r = nft_rule_new(h, chain, table, cs); - if (r == NULL) - return NULL; - -- if (handle > 0) -- nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle); -+ if (ref) { -+ ref_id = nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE); -+ if (ref_id > 0) { -+ nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, ref_id); -+ DEBUGP("adding after rule handle %"PRIu64"\n", ref_id); -+ } else { -+ ref_id = nftnl_rule_get_u32(ref, NFTNL_RULE_ID); -+ if (!ref_id) { -+ ref_id = ++h->rule_id; -+ nftnl_rule_set_u32(ref, NFTNL_RULE_ID, ref_id); -+ } -+ nftnl_rule_set_u32(r, NFTNL_RULE_POSITION_ID, ref_id); -+ DEBUGP("adding after rule ID %"PRIu64"\n", ref_id); -+ } -+ } - - if (batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r) < 0) { - nftnl_rule_free(r); -@@ -2090,9 +2104,8 @@ nft_rule_add(struct nft_handle *h, const char *chain, - int nft_rule_insert(struct nft_handle *h, const char *chain, - const char *table, void *data, int rulenum, bool verbose) - { -- struct nftnl_rule *r, *new_rule; -+ struct nftnl_rule *r = NULL, *new_rule; - struct nftnl_chain *c; -- uint64_t handle = 0; - - /* If built-in chains don't exist for this table, create them */ - if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) -@@ -2120,16 +2133,13 @@ int nft_rule_insert(struct nft_handle *h, const char *chain, - errno = ENOENT; - goto err; - } -- -- handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE); -- DEBUGP("adding after rule handle %"PRIu64"\n", handle); - } - -- new_rule = nft_rule_add(h, chain, table, data, handle, verbose); -+ new_rule = nft_rule_add(h, chain, table, data, r, verbose); - if (!new_rule) - goto err; - -- if (handle) -+ if (r) - nftnl_chain_rule_insert_at(new_rule, r); - else - nftnl_chain_rule_add(new_rule, c); -diff --git a/iptables/nft.h b/iptables/nft.h -index 97d73c8b534be..0726923a63dd4 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -32,6 +32,7 @@ struct nft_handle { - struct mnl_socket *nl; - uint32_t portid; - uint32_t seq; -+ uint32_t rule_id; - struct list_head obj_list; - int obj_list_num; - struct nftnl_batch *batch; -diff --git a/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 b/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 -new file mode 100755 -index 0000000000000..51f2422e15259 ---- /dev/null -+++ b/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 -@@ -0,0 +1,117 @@ -+#!/bin/bash -+ -+# Make sure iptables-restore does the right thing -+# when encountering INSERT rules with index. -+ -+set -e -+ -+# show rules, drop uninteresting policy settings -+ipt_show() { -+ $XT_MULTI iptables -S | grep -v '^-P' -+} -+ -+# basic issue reproducer -+ -+$XT_MULTI iptables-restore < -Date: Fri, 1 Feb 2019 19:17:50 +0100 -Subject: [PATCH] xtables: Fix for crash when comparing rules with standard - target - -When parsing an nftnl_rule with a standard verdict, -nft_rule_to_iptables_command_state() initialized cs->target but didn't -care about cs->target->t. When later comparing that rule to another, -compare_targets() crashed due to unconditional access to t's fields. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit a880cc28358a32f96467e248266973b6ab83f080) -Signed-off-by: Phil Sutter ---- - iptables/nft-shared.c | 23 +++++++++++++++---- - .../testcases/iptables/0005-delete-rules_0 | 7 ++++++ - iptables/xtables.c | 4 +++- - 3 files changed, 29 insertions(+), 5 deletions(-) - create mode 100755 iptables/tests/shell/testcases/iptables/0005-delete-rules_0 - -diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c -index 7b8ca5e4becaf..dfc1c803cb68d 100644 ---- a/iptables/nft-shared.c -+++ b/iptables/nft-shared.c -@@ -660,19 +660,34 @@ void nft_rule_to_iptables_command_state(const struct nftnl_rule *r, - match->m = m; - } - -- if (cs->target != NULL) -+ if (cs->target != NULL) { - cs->jumpto = cs->target->name; -- else if (cs->jumpto != NULL) -+ } else if (cs->jumpto != NULL) { -+ struct xt_entry_target *t; -+ uint32_t size; -+ - cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); -- else -+ if (!cs->target) -+ return; -+ -+ size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size; -+ t = xtables_calloc(1, size); -+ t->u.target_size = size; -+ t->u.user.revision = cs->target->revision; -+ strcpy(t->u.user.name, cs->jumpto); -+ cs->target->t = t; -+ } else { - cs->jumpto = ""; -+ } - } - - void nft_clear_iptables_command_state(struct iptables_command_state *cs) - { - xtables_rule_matches_free(&cs->matches); -- if (cs->target) -+ if (cs->target) { - free(cs->target->t); -+ cs->target->t = NULL; -+ } - } - - void print_header(unsigned int format, const char *chain, const char *pol, -diff --git a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 -new file mode 100755 -index 0000000000000..9312fd53c3437 ---- /dev/null -+++ b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 -@@ -0,0 +1,7 @@ -+#!/bin/bash -+ -+# test for crash when comparing rules with standard target -+ -+$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP -+$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT -+[[ $? -eq 1 ]] || exit 1 -diff --git a/iptables/xtables.c b/iptables/xtables.c -index d0167e6396975..eaa9fedeb03bb 100644 ---- a/iptables/xtables.c -+++ b/iptables/xtables.c -@@ -1185,8 +1185,10 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, - *table = p.table; - - xtables_rule_matches_free(&cs.matches); -- if (cs.target) -+ if (cs.target) { - free(cs.target->t); -+ cs.target->t = NULL; -+ } - - if (h->family == AF_INET) { - free(args.s.addr.v4); --- -2.21.0 - diff --git a/SOURCES/0046-xtables-Fix-for-false-positive-rule-matching.patch b/SOURCES/0046-xtables-Fix-for-false-positive-rule-matching.patch deleted file mode 100644 index 14a94dc..0000000 --- a/SOURCES/0046-xtables-Fix-for-false-positive-rule-matching.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 27b68bd11b99429d1b830dbe76fc0148b5a24a16 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 4 Feb 2019 21:52:53 +0100 -Subject: [PATCH] xtables: Fix for false-positive rule matching - -When comparing two rules with non-standard targets, differences in -targets' payloads wasn't respected. - -The cause is a rather hideous one: Unlike xtables_find_match(), -xtables_find_target() did not care whether the found target was already -in use or not, so the same target instance was assigned to both rules -and therefore payload comparison happened over the same memory location. - -With legacy iptables it is not possible to reuse a target: The only case -where two rules (i.e., iptables_command_state instances) could exist at -the same time is when comparing rules, but that's handled using libiptc. - -The above change clashes with ebtables-nft's reuse of target objects: -While input parsing still just assigns the object from xtables_targets -list, rule conversion from nftnl to iptables_command_state allocates new -data. To fix this, make ebtables-nft input parsing use the common -command_jump() routine instead of its own simplified copy. In turn, this -also eliminates the ebtables-nft-specific variants of parse_target(), -though with a slight change of behaviour: Names of user-defined chains -are no longer allowed to contain up to 31 but merely 28 characters. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 148131f20421046fea028e638581e938ec985783) -Signed-off-by: Phil Sutter ---- - iptables/nft-bridge.c | 10 ++++ - iptables/nft-bridge.h | 2 - - iptables/nft-shared.c | 5 ++ - .../testcases/iptables/0005-delete-rules_0 | 7 +++ - iptables/xtables-eb-translate.c | 24 +--------- - iptables/xtables-eb.c | 47 +------------------ - libxtables/xtables.c | 18 ++++++- - 7 files changed, 41 insertions(+), 72 deletions(-) - -diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c -index ad583a60c424d..140fcf0a31b84 100644 ---- a/iptables/nft-bridge.c -+++ b/iptables/nft-bridge.c -@@ -45,6 +45,16 @@ void ebt_cs_clean(struct iptables_command_state *cs) - free(m); - m = nm; - } -+ -+ if (cs->target) { -+ free(cs->target->t); -+ cs->target->t = NULL; -+ -+ if (cs->target == cs->target->next) { -+ free(cs->target); -+ cs->target = NULL; -+ } -+ } - } - - static void ebt_print_mac(const unsigned char *mac) -diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h -index de52cd7195bbb..d90066f1030a2 100644 ---- a/iptables/nft-bridge.h -+++ b/iptables/nft-bridge.h -@@ -32,7 +32,6 @@ int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mas - */ - - #define EBT_TABLE_MAXNAMELEN 32 --#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN - #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN - - /* verdicts >0 are "branches" */ -@@ -122,6 +121,5 @@ void ebt_add_match(struct xtables_match *m, - void ebt_add_watcher(struct xtables_target *watcher, - struct iptables_command_state *cs); - int ebt_command_default(struct iptables_command_state *cs); --struct xtables_target *ebt_command_jump(const char *jumpto); - - #endif -diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c -index dfc1c803cb68d..ce40787f92f7d 100644 ---- a/iptables/nft-shared.c -+++ b/iptables/nft-shared.c -@@ -687,6 +687,11 @@ void nft_clear_iptables_command_state(struct iptables_command_state *cs) - if (cs->target) { - free(cs->target->t); - cs->target->t = NULL; -+ -+ if (cs->target == cs->target->next) { -+ free(cs->target); -+ cs->target = NULL; -+ } - } - } - -diff --git a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 -index 9312fd53c3437..5038cbce5a5cf 100755 ---- a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 -+++ b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 -@@ -5,3 +5,10 @@ - $XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP - $XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT - [[ $? -eq 1 ]] || exit 1 -+ -+# test incorrect deletion of rules with deviating payload -+# in non-standard target -+ -+$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j MARK --set-mark 23 -+$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j MARK --set-mark 42 -+[[ $? -eq 1 ]] || exit 1 -diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c -index f98c385555eb1..0fe14d2d0db32 100644 ---- a/iptables/xtables-eb-translate.c -+++ b/iptables/xtables-eb-translate.c -@@ -64,27 +64,6 @@ static int parse_rule_number(const char *rule) - return rule_nr; - } - --static const char * --parse_target(const char *targetname) --{ -- const char *ptr; -- -- if (strlen(targetname) < 1) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target name (too short)"); -- -- if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target '%s' (%d chars max)", -- targetname, EBT_CHAIN_MAXNAMELEN); -- -- for (ptr = targetname; *ptr; ptr++) -- if (isspace(*ptr)) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target name `%s'", targetname); -- return targetname; --} -- - static int get_current_chain(const char *chain) - { - if (strcmp(chain, "PREROUTING") == 0) -@@ -411,8 +390,7 @@ print_zero: - break; - } else if (c == 'j') { - ebt_check_option2(&flags, OPT_JUMP); -- cs.jumpto = parse_target(optarg); -- cs.target = ebt_command_jump(cs.jumpto); -+ command_jump(&cs); - break; - } else if (c == 's') { - ebt_check_option2(&flags, OPT_SOURCE); -diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c -index 4c52c29aa4817..55cb0fe204748 100644 ---- a/iptables/xtables-eb.c -+++ b/iptables/xtables-eb.c -@@ -139,27 +139,6 @@ static int parse_rule_number(const char *rule) - return rule_nr; - } - --static const char * --parse_target(const char *targetname) --{ -- const char *ptr; -- -- if (strlen(targetname) < 1) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target name (too short)"); -- -- if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target '%s' (%d chars max)", -- targetname, EBT_CHAIN_MAXNAMELEN); -- -- for (ptr = targetname; *ptr; ptr++) -- if (isspace(*ptr)) -- xtables_error(PARAMETER_PROBLEM, -- "Invalid target name `%s'", targetname); -- return targetname; --} -- - static int - append_entry(struct nft_handle *h, - const char *chain, -@@ -376,29 +355,6 @@ static struct option *merge_options(struct option *oldopts, - return merge; - } - --/* -- * More glue code. -- */ --struct xtables_target *ebt_command_jump(const char *jumpto) --{ -- struct xtables_target *target; -- unsigned int verdict; -- -- /* Standard target? */ -- if (!ebt_fill_target(jumpto, &verdict)) -- jumpto = "standard"; -- -- /* For ebtables, all targets are preloaded. Hence it is either in -- * xtables_targets or a custom chain to jump to, in which case -- * returning NULL is fine. */ -- for (target = xtables_targets; target; target = target->next) { -- if (!strcmp(target->name, jumpto)) -- break; -- } -- -- return target; --} -- - static void print_help(const struct xtables_target *t, - const struct xtables_rule_match *m, const char *table) - { -@@ -1066,8 +1022,7 @@ print_zero: - } else if (c == 'j') { - ebt_check_option2(&flags, OPT_JUMP); - if (strcmp(optarg, "CONTINUE") != 0) { -- cs.jumpto = parse_target(optarg); -- cs.target = ebt_command_jump(cs.jumpto); -+ command_jump(&cs); - } - break; - } else if (c == 's') { -diff --git a/libxtables/xtables.c b/libxtables/xtables.c -index ea9bb102c8eb4..895f6988eaf57 100644 ---- a/libxtables/xtables.c -+++ b/libxtables/xtables.c -@@ -756,8 +756,24 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) - } - - for (ptr = xtables_targets; ptr; ptr = ptr->next) { -- if (extension_cmp(name, ptr->name, ptr->family)) -+ if (extension_cmp(name, ptr->name, ptr->family)) { -+ struct xtables_target *clone; -+ -+ /* First target of this type: */ -+ if (ptr->t == NULL) -+ break; -+ -+ /* Second and subsequent clones */ -+ clone = xtables_malloc(sizeof(struct xtables_target)); -+ memcpy(clone, ptr, sizeof(struct xtables_target)); -+ clone->udata = NULL; -+ clone->tflags = 0; -+ /* This is a clone: */ -+ clone->next = clone; -+ -+ ptr = clone; - break; -+ } - } - - #ifndef NO_SHARED_LIBS --- -2.21.0 - diff --git a/SOURCES/0047-ebtables-Fix-rule-listing-with-counters.patch b/SOURCES/0047-ebtables-Fix-rule-listing-with-counters.patch deleted file mode 100644 index c166da4..0000000 --- a/SOURCES/0047-ebtables-Fix-rule-listing-with-counters.patch +++ /dev/null @@ -1,75 +0,0 @@ -From b321a8af45e3040ae46091fef2c35d5533ab83bc Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 21 Jan 2019 17:43:34 +0100 -Subject: [PATCH] ebtables: Fix rule listing with counters - -This is a partial revert of commit 583b27eabcad6 ("ebtables-save: add -c -option, using xtables-style counters") which broke ruleset listing with -'--Lc' flag turned on: - -| # ebtables-nft -L --Lc -| Bridge table: filter -| -| Bridge chain: INPUT, entries: 0, policy: ACCEPT -| -| Bridge chain: FORWARD, entries: 2, policy: ACCEPT -| -j foo -| , pcnt = 0 -- bcnt = 0-j ACCEPT -| , pcnt = 0 -- bcnt = 0 -| Bridge chain: OUTPUT, entries: 0, policy: ACCEPT -| -| Bridge chain: foo, entries: 1, policy: RETURN -| -j ACCEPT -| , pcnt = 0 -- bcnt = 0% - -(That percentage sign means no newline after last line of output and -doesn't belong to ebtables-nft's output.) - -Problem was that nft_bridge_print_rule() printed the counters after -nft_bridge_save_rule() had already printed the newline character. - -Note also that there is no need to remove FMT_EBT_SAVE bit from 'format' -variable: It is set only by ebtables-nft-save which doesn't call -nft_bridge_print_rule(). - -Fixes: 583b27eabcad6 ("ebtables-save: add -c option, using xtables-style counters") -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 32ebc39f71e8107d6069a9f6fba8338a2823889d) -Signed-off-by: Phil Sutter ---- - iptables/nft-bridge.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c -index 140fcf0a31b84..43b3e3e9649b8 100644 ---- a/iptables/nft-bridge.c -+++ b/iptables/nft-bridge.c -@@ -479,6 +479,11 @@ static void nft_bridge_save_rule(const void *data, unsigned int format) - (uint64_t)cs->counters.pcnt, - (uint64_t)cs->counters.bcnt); - -+ if (!(format & FMT_NOCOUNTS)) -+ printf(" , pcnt = %"PRIu64" -- bcnt = %"PRIu64"", -+ (uint64_t)cs->counters.pcnt, -+ (uint64_t)cs->counters.bcnt); -+ - if (!(format & FMT_NONEWLINE)) - fputc('\n', stdout); - } -@@ -492,11 +497,7 @@ static void nft_bridge_print_rule(struct nftnl_rule *r, unsigned int num, - printf("%d ", num); - - nft_rule_to_ebtables_command_state(r, &cs); -- nft_bridge_save_rule(&cs, format & ~FMT_EBT_SAVE); -- if (!(format & FMT_NOCOUNTS)) -- printf(" , pcnt = %"PRIu64" -- bcnt = %"PRIu64"", -- (uint64_t)cs.counters.pcnt, -- (uint64_t)cs.counters.bcnt); -+ nft_bridge_save_rule(&cs, format); - ebt_cs_clean(&cs); - } - --- -2.21.0 - diff --git a/SOURCES/0048-Revert-ebtables-use-extrapositioned-negation-consist.patch b/SOURCES/0048-Revert-ebtables-use-extrapositioned-negation-consist.patch deleted file mode 100644 index 3564535..0000000 --- a/SOURCES/0048-Revert-ebtables-use-extrapositioned-negation-consist.patch +++ /dev/null @@ -1,534 +0,0 @@ -From af890b239555d52c269d224ada6382381320585d Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 5 Feb 2019 18:18:02 +0100 -Subject: [PATCH] Revert "ebtables: use extrapositioned negation consistently" - -This reverts commit 5f508b76a0cebaf91965ffa678089222e2d47964. - -While attempts at unifying syntax between arp-, eb- and iptables-nft -increase the opportunity for more code-sharing, they are problematic -when it comes to compatibility. Accepting the old syntax on input helps, -but due to the fact that neither arptables nor ebtables support --check -command we must expect for users to test existence of a rule by -comparing input with output. If that happens in a script, deviating from -the old syntax in output has a high chance of breaking it. - -Therefore revert Florian's patch changing inversion character position -in output and review the old code for consistency - the only thing -changed on top of the actual revert is ebtables' own copy of -print_iface() to make it adhere to the intrapositioned negation scheme -used throughout ebtables. - -Added extension tests by the reverted commit have been kept. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 35b22e82fa62e10950d8e0fa53a755d4abadf346) -Signed-off-by: Phil Sutter ---- - extensions/libebt_802_3.c | 4 ++-- - extensions/libebt_802_3.t | 2 +- - extensions/libebt_arp.c | 14 +++++++------- - extensions/libebt_arp.t | 8 ++++---- - extensions/libebt_ip.c | 16 ++++++++-------- - extensions/libebt_ip.t | 6 +++--- - extensions/libebt_ip6.c | 14 +++++++------- - extensions/libebt_ip6.t | 6 +++--- - extensions/libebt_mark_m.c | 2 +- - extensions/libebt_mark_m.t | 4 ++-- - extensions/libebt_pkttype.c | 5 +---- - extensions/libebt_pkttype.t | 13 +++++++------ - extensions/libebt_standard.t | 4 ++-- - extensions/libebt_stp.c | 5 ++--- - extensions/libebt_vlan.c | 13 ++++--------- - extensions/libebt_vlan.t | 10 +++++----- - iptables/nft-bridge.c | 6 +++--- - 17 files changed, 62 insertions(+), 70 deletions(-) - -diff --git a/extensions/libebt_802_3.c b/extensions/libebt_802_3.c -index 9e91d05262591..f05d02ead5a4a 100644 ---- a/extensions/libebt_802_3.c -+++ b/extensions/libebt_802_3.c -@@ -98,15 +98,15 @@ static void br802_3_print(const void *ip, const struct xt_entry_match *match, - struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data; - - if (info->bitmask & EBT_802_3_SAP) { -+ printf("--802_3-sap "); - if (info->invflags & EBT_802_3_SAP) - printf("! "); -- printf("--802_3-sap "); - printf("0x%.2x ", info->sap); - } - if (info->bitmask & EBT_802_3_TYPE) { -+ printf("--802_3-type "); - if (info->invflags & EBT_802_3_TYPE) - printf("! "); -- printf("--802_3-type "); - printf("0x%.4x ", ntohs(info->type)); - } - } -diff --git a/extensions/libebt_802_3.t b/extensions/libebt_802_3.t -index 61081bd6983a8..ddfb2f0a72baf 100644 ---- a/extensions/libebt_802_3.t -+++ b/extensions/libebt_802_3.t -@@ -1,3 +1,3 @@ - :INPUT,FORWARD,OUTPUT --! --802_3-sap 0x0a -j CONTINUE;=;OK -+--802_3-sap ! 0x0a -j CONTINUE;=;OK - --802_3-type 0x000a -j RETURN;=;OK -diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c -index c1b0ab1db0cf1..a062b7e7e5864 100644 ---- a/extensions/libebt_arp.c -+++ b/extensions/libebt_arp.c -@@ -338,51 +338,51 @@ static void brarp_print(const void *ip, const struct xt_entry_match *match, int - - if (arpinfo->bitmask & EBT_ARP_OPCODE) { - int opcode = ntohs(arpinfo->opcode); -+ printf("--arp-op "); - if (arpinfo->invflags & EBT_ARP_OPCODE) - printf("! "); -- printf("--arp-op "); - if (opcode > 0 && opcode <= ARRAY_SIZE(opcodes)) - printf("%s ", opcodes[opcode - 1]); - else - printf("%d ", opcode); - } - if (arpinfo->bitmask & EBT_ARP_HTYPE) { -+ printf("--arp-htype "); - if (arpinfo->invflags & EBT_ARP_HTYPE) - printf("! "); -- printf("--arp-htype "); - printf("%d ", ntohs(arpinfo->htype)); - } - if (arpinfo->bitmask & EBT_ARP_PTYPE) { -+ printf("--arp-ptype "); - if (arpinfo->invflags & EBT_ARP_PTYPE) - printf("! "); -- printf("--arp-ptype "); - printf("0x%x ", ntohs(arpinfo->ptype)); - } - if (arpinfo->bitmask & EBT_ARP_SRC_IP) { -+ printf("--arp-ip-src "); - if (arpinfo->invflags & EBT_ARP_SRC_IP) - printf("! "); -- printf("--arp-ip-src "); - printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->saddr), - xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->smsk)); - } - if (arpinfo->bitmask & EBT_ARP_DST_IP) { -+ printf("--arp-ip-dst "); - if (arpinfo->invflags & EBT_ARP_DST_IP) - printf("! "); -- printf("--arp-ip-dst "); - printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->daddr), - xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->dmsk)); - } - if (arpinfo->bitmask & EBT_ARP_SRC_MAC) { -+ printf("--arp-mac-src "); - if (arpinfo->invflags & EBT_ARP_SRC_MAC) - printf("! "); -- printf("--arp-mac-src "); - xtables_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk); - printf(" "); - } - if (arpinfo->bitmask & EBT_ARP_DST_MAC) { -+ printf("--arp-mac-dst "); - if (arpinfo->invflags & EBT_ARP_DST_MAC) - printf("! "); -- printf("--arp-mac-dst "); - xtables_print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk); - printf(" "); - } -diff --git a/extensions/libebt_arp.t b/extensions/libebt_arp.t -index a05ab12dc566f..14ff0f097cfd8 100644 ---- a/extensions/libebt_arp.t -+++ b/extensions/libebt_arp.t -@@ -1,11 +1,11 @@ - :INPUT,FORWARD,OUTPUT - -p ARP --arp-op Request;=;OK ---p ARP ! --arp-htype 1;=;OK -+-p ARP --arp-htype ! 1;=;OK - -p ARP --arp-ptype 0x2;=;OK - -p ARP --arp-ip-src 1.2.3.4;=;OK ---p ARP ! --arp-ip-dst 1.2.3.4;=;OK ---p ARP ! --arp-ip-src 0.0.0.0;=;OK ---p ARP ! --arp-ip-dst 0.0.0.0/8;=;OK -+-p ARP ! --arp-ip-dst 1.2.3.4;-p ARP --arp-ip-dst ! 1.2.3.4 -j CONTINUE;OK -+-p ARP --arp-ip-src ! 0.0.0.0;=;OK -+-p ARP --arp-ip-dst ! 0.0.0.0/8;=;OK - -p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK - -p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK - -p ARP --arp-gratuitous;=;OK -diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c -index d48704fe1c802..acb9bfcdbbd9f 100644 ---- a/extensions/libebt_ip.c -+++ b/extensions/libebt_ip.c -@@ -472,35 +472,35 @@ static void brip_print(const void *ip, const struct xt_entry_match *match, - struct in_addr *addrp, *maskp; - - if (info->bitmask & EBT_IP_SOURCE) { -+ printf("--ip-src "); - if (info->invflags & EBT_IP_SOURCE) - printf("! "); -- printf("--ip-src "); - addrp = (struct in_addr *)&info->saddr; - maskp = (struct in_addr *)&info->smsk; - printf("%s%s ", xtables_ipaddr_to_numeric(addrp), - xtables_ipmask_to_numeric(maskp)); - } - if (info->bitmask & EBT_IP_DEST) { -+ printf("--ip-dst "); - if (info->invflags & EBT_IP_DEST) - printf("! "); -- printf("--ip-dst "); - addrp = (struct in_addr *)&info->daddr; - maskp = (struct in_addr *)&info->dmsk; - printf("%s%s ", xtables_ipaddr_to_numeric(addrp), - xtables_ipmask_to_numeric(maskp)); - } - if (info->bitmask & EBT_IP_TOS) { -+ printf("--ip-tos "); - if (info->invflags & EBT_IP_TOS) - printf("! "); -- printf("--ip-tos "); - printf("0x%02X ", info->tos); - } - if (info->bitmask & EBT_IP_PROTO) { - struct protoent *pe; - -+ printf("--ip-proto "); - if (info->invflags & EBT_IP_PROTO) - printf("! "); -- printf("--ip-proto "); - pe = getprotobynumber(info->protocol); - if (pe == NULL) { - printf("%d ", info->protocol); -@@ -509,28 +509,28 @@ static void brip_print(const void *ip, const struct xt_entry_match *match, - } - } - if (info->bitmask & EBT_IP_SPORT) { -+ printf("--ip-sport "); - if (info->invflags & EBT_IP_SPORT) - printf("! "); -- printf("--ip-sport "); - print_port_range(info->sport); - } - if (info->bitmask & EBT_IP_DPORT) { -+ printf("--ip-dport "); - if (info->invflags & EBT_IP_DPORT) - printf("! "); -- printf("--ip-dport "); - print_port_range(info->dport); - } - if (info->bitmask & EBT_IP_ICMP) { -+ printf("--ip-icmp-type "); - if (info->invflags & EBT_IP_ICMP) - printf("! "); -- printf("--ip-icmp-type "); - ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes), - info->icmp_type, info->icmp_code); - } - if (info->bitmask & EBT_IP_IGMP) { -+ printf("--ip-igmp-type "); - if (info->invflags & EBT_IP_IGMP) - printf("! "); -- printf("--ip-igmp-type "); - ebt_print_icmp_type(igmp_types, ARRAY_SIZE(igmp_types), - info->igmp_type, NULL); - } -diff --git a/extensions/libebt_ip.t b/extensions/libebt_ip.t -index 01a91a7385fcc..8be5dfbb22309 100644 ---- a/extensions/libebt_ip.t -+++ b/extensions/libebt_ip.t -@@ -1,13 +1,13 @@ - :INPUT,FORWARD,OUTPUT ---p ip --ip-src ! 192.168.0.0/24 -j ACCEPT;-p IPv4 ! --ip-src 192.168.0.0/24 -j ACCEPT;OK -+-p ip --ip-src ! 192.168.0.0/24 -j ACCEPT;-p IPv4 --ip-src ! 192.168.0.0/24 -j ACCEPT;OK - -p IPv4 --ip-dst 10.0.0.1;=;OK - -p IPv4 --ip-tos 0xFF;=;OK ---p IPv4 ! --ip-tos 0xFF;=;OK -+-p IPv4 --ip-tos ! 0xFF;=;OK - -p IPv4 --ip-proto tcp --ip-dport 22;=;OK - -p IPv4 --ip-proto udp --ip-sport 1024:65535;=;OK - -p IPv4 --ip-proto 253;=;OK - -p IPv4 --ip-proto icmp --ip-icmp-type echo-request;=;OK - -p IPv4 --ip-proto icmp --ip-icmp-type 1/1;=;OK ---p ip --ip-protocol icmp --ip-icmp-type ! 1:10;-p IPv4 --ip-proto icmp ! --ip-icmp-type 1:10/0:255 -j CONTINUE;OK -+-p ip --ip-protocol icmp --ip-icmp-type ! 1:10;-p IPv4 --ip-proto icmp --ip-icmp-type ! 1:10/0:255 -j CONTINUE;OK - --ip-proto icmp --ip-icmp-type 1/1;=;FAIL - ! -p ip --ip-proto icmp --ip-icmp-type 1/1;=;FAIL -diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c -index b727764903ffa..b8a5a5d8c3a92 100644 ---- a/extensions/libebt_ip6.c -+++ b/extensions/libebt_ip6.c -@@ -399,31 +399,31 @@ static void brip6_print(const void *ip, const struct xt_entry_match *match, - struct ebt_ip6_info *ipinfo = (struct ebt_ip6_info *)match->data; - - if (ipinfo->bitmask & EBT_IP6_SOURCE) { -+ printf("--ip6-src "); - if (ipinfo->invflags & EBT_IP6_SOURCE) - printf("! "); -- printf("--ip6-src "); - printf("%s", xtables_ip6addr_to_numeric(&ipinfo->saddr)); - printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->smsk)); - } - if (ipinfo->bitmask & EBT_IP6_DEST) { -+ printf("--ip6-dst "); - if (ipinfo->invflags & EBT_IP6_DEST) - printf("! "); -- printf("--ip6-dst "); - printf("%s", xtables_ip6addr_to_numeric(&ipinfo->daddr)); - printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->dmsk)); - } - if (ipinfo->bitmask & EBT_IP6_TCLASS) { -+ printf("--ip6-tclass "); - if (ipinfo->invflags & EBT_IP6_TCLASS) - printf("! "); -- printf("--ip6-tclass "); - printf("0x%02X ", ipinfo->tclass); - } - if (ipinfo->bitmask & EBT_IP6_PROTO) { - struct protoent *pe; - -+ printf("--ip6-proto "); - if (ipinfo->invflags & EBT_IP6_PROTO) - printf("! "); -- printf("--ip6-proto "); - pe = getprotobynumber(ipinfo->protocol); - if (pe == NULL) { - printf("%d ", ipinfo->protocol); -@@ -432,21 +432,21 @@ static void brip6_print(const void *ip, const struct xt_entry_match *match, - } - } - if (ipinfo->bitmask & EBT_IP6_SPORT) { -+ printf("--ip6-sport "); - if (ipinfo->invflags & EBT_IP6_SPORT) - printf("! "); -- printf("--ip6-sport "); - print_port_range(ipinfo->sport); - } - if (ipinfo->bitmask & EBT_IP6_DPORT) { -+ printf("--ip6-dport "); - if (ipinfo->invflags & EBT_IP6_DPORT) - printf("! "); -- printf("--ip6-dport "); - print_port_range(ipinfo->dport); - } - if (ipinfo->bitmask & EBT_IP6_ICMP6) { -+ printf("--ip6-icmp-type "); - if (ipinfo->invflags & EBT_IP6_ICMP6) - printf("! "); -- printf("--ip6-icmp-type "); - print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code); - } - } -diff --git a/extensions/libebt_ip6.t b/extensions/libebt_ip6.t -index 6b3221ea58f62..fa1038af25649 100644 ---- a/extensions/libebt_ip6.t -+++ b/extensions/libebt_ip6.t -@@ -1,15 +1,15 @@ - :INPUT,FORWARD,OUTPUT ---p ip6 ! --ip6-src dead::beef/64 -j ACCEPT;-p IPv6 ! --ip6-src dead::/64 -j ACCEPT;OK -+-p ip6 --ip6-src ! dead::beef/64 -j ACCEPT;-p IPv6 --ip6-src ! dead::/64 -j ACCEPT;OK - -p IPv6 --ip6-dst dead:beef::/64 -j ACCEPT;=;OK - -p IPv6 --ip6-dst f00:ba::;=;OK - -p IPv6 --ip6-tclass 0xFF;=;OK - -p IPv6 --ip6-proto tcp --ip6-dport 22;=;OK ---p IPv6 --ip6-proto tcp ! --ip6-dport 22;=;OK -+-p IPv6 --ip6-proto tcp --ip6-dport ! 22;=;OK - -p IPv6 --ip6-proto udp --ip6-sport 1024:65535;=;OK - -p IPv6 --ip6-proto 253;=;OK - -p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request -j CONTINUE;=;OK - -p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request;=;OK - -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1;-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type communication-prohibited -j CONTINUE;OK ---p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;OK -+-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type ! 1:10/0:255;=;OK - --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL - ! -p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL -diff --git a/extensions/libebt_mark_m.c b/extensions/libebt_mark_m.c -index 64ad926f19959..2462d0af7d0bc 100644 ---- a/extensions/libebt_mark_m.c -+++ b/extensions/libebt_mark_m.c -@@ -86,9 +86,9 @@ static void brmark_m_print(const void *ip, const struct xt_entry_match *match, - { - struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)match->data; - -+ printf("--mark "); - if (info->invert) - printf("! "); -- printf("--mark "); - if (info->bitmask == EBT_MARK_OR) - printf("/0x%lx ", info->mask); - else if (info->mask != 0xffffffff) -diff --git a/extensions/libebt_mark_m.t b/extensions/libebt_mark_m.t -index 9ad41704fbb82..00035427f8b6e 100644 ---- a/extensions/libebt_mark_m.t -+++ b/extensions/libebt_mark_m.t -@@ -1,6 +1,6 @@ - :INPUT,FORWARD,OUTPUT - --mark 42;--mark 0x2a;OK ----mark ! 42;! --mark 0x2a;OK -+--mark ! 42;--mark ! 0x2a;OK - --mark 42/0xff;--mark 0x2a/0xff;OK --! --mark 0x1/0xff;=;OK -+--mark ! 0x1/0xff;=;OK - --mark /0x2;=;OK -diff --git a/extensions/libebt_pkttype.c b/extensions/libebt_pkttype.c -index 265674d19bde6..4e2d19de7983b 100644 ---- a/extensions/libebt_pkttype.c -+++ b/extensions/libebt_pkttype.c -@@ -75,10 +75,7 @@ static void brpkttype_print(const void *ip, const struct xt_entry_match *match, - { - struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data; - -- if (pt->invert) -- printf("! "); -- -- printf("--pkttype-type "); -+ printf("--pkttype-type %s", pt->invert ? "! " : ""); - - if (pt->pkt_type < ARRAY_SIZE(classes)) - printf("%s ", classes[pt->pkt_type]); -diff --git a/extensions/libebt_pkttype.t b/extensions/libebt_pkttype.t -index f870f5c7f05c4..e3b95ded4903e 100644 ---- a/extensions/libebt_pkttype.t -+++ b/extensions/libebt_pkttype.t -@@ -1,13 +1,14 @@ - :INPUT,FORWARD,OUTPUT -+! --pkttype-type host;--pkttype-type ! host -j CONTINUE;OK - --pkttype-type host;=;OK --! --pkttype-type host;=;OK -+--pkttype-type ! host;=;OK - --pkttype-type broadcast;=;OK --! --pkttype-type broadcast;=;OK -+--pkttype-type ! broadcast;=;OK - --pkttype-type multicast;=;OK --! --pkttype-type multicast;=;OK -+--pkttype-type ! multicast;=;OK - --pkttype-type otherhost;=;OK --! --pkttype-type otherhost;=;OK -+--pkttype-type ! otherhost;=;OK - --pkttype-type outgoing;=;OK --! --pkttype-type outgoing;=;OK -+--pkttype-type ! outgoing;=;OK - --pkttype-type loopback;=;OK --! --pkttype-type loopback;=;OK -+--pkttype-type ! loopback;=;OK -diff --git a/extensions/libebt_standard.t b/extensions/libebt_standard.t -index 72081fd6575a0..0d678fb23c439 100644 ---- a/extensions/libebt_standard.t -+++ b/extensions/libebt_standard.t -@@ -6,6 +6,6 @@ - -d de:ad:be:ef:00:00 -j CONTINUE;=;OK - -d de:ad:be:ef:0:00/ff:ff:ff:ff:0:0 -j DROP;-d de:ad:be:ef:00:00/ff:ff:ff:ff:00:00 -j DROP;OK - -p ARP -j ACCEPT;=;OK --! -p ARP -j ACCEPT;=;OK -+-p ! ARP -j ACCEPT;=;OK - -p 0 -j ACCEPT;=;FAIL --! -p 0 -j ACCEPT;=;FAIL -+-p ! 0 -j ACCEPT;=;FAIL -diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c -index 33e4c8d9c615d..06cf93b8d8449 100644 ---- a/extensions/libebt_stp.c -+++ b/extensions/libebt_stp.c -@@ -307,9 +307,8 @@ static void brstp_print(const void *ip, const struct xt_entry_match *match, - for (i = 0; i < STP_NUMOPS; i++) { - if (!(stpinfo->bitmask & (1 << i))) - continue; -- if (stpinfo->invflags & (1 << i)) -- printf("! "); -- printf("--%s ", brstp_opts[i].name); -+ printf("--%s %s", brstp_opts[i].name, -+ (stpinfo->invflags & (1 << i)) ? "! " : ""); - if (EBT_STP_TYPE == (1 << i)) { - if (stpinfo->type == BPDU_TYPE_CONFIG) - printf("%s", BPDU_TYPE_CONFIG_STRING); -diff --git a/extensions/libebt_vlan.c b/extensions/libebt_vlan.c -index 4a2eb7126895e..a2a9dcce531ce 100644 ---- a/extensions/libebt_vlan.c -+++ b/extensions/libebt_vlan.c -@@ -108,19 +108,14 @@ static void brvlan_print(const void *ip, const struct xt_entry_match *match, - struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data; - - if (vlaninfo->bitmask & EBT_VLAN_ID) { -- if (vlaninfo->invflags & EBT_VLAN_ID) -- printf("! "); -- printf("--vlan-id %d ", vlaninfo->id); -+ printf("--vlan-id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id); - } - if (vlaninfo->bitmask & EBT_VLAN_PRIO) { -- if (vlaninfo->invflags & EBT_VLAN_PRIO) -- printf("! "); -- printf("--vlan-prio %d ", vlaninfo->prio); -+ printf("--vlan-prio %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio); - } - if (vlaninfo->bitmask & EBT_VLAN_ENCAP) { -- if (vlaninfo->invflags & EBT_VLAN_ENCAP) -- printf("! "); -- printf("--vlan-encap %4.4X ", ntohs(vlaninfo->encap)); -+ printf("--vlan-encap %s", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : ""); -+ printf("%4.4X ", ntohs(vlaninfo->encap)); - } - } - -diff --git a/extensions/libebt_vlan.t b/extensions/libebt_vlan.t -index 106374cd9cb80..81c795854fca0 100644 ---- a/extensions/libebt_vlan.t -+++ b/extensions/libebt_vlan.t -@@ -1,13 +1,13 @@ - :INPUT,FORWARD,OUTPUT - -p 802_1Q --vlan-id 42;=;OK ---p 802_1Q ! --vlan-id 42;=;OK -+-p 802_1Q --vlan-id ! 42;=;OK - -p 802_1Q --vlan-prio 1;=;OK ---p 802_1Q ! --vlan-prio 1;=;OK -+-p 802_1Q --vlan-prio ! 1;=;OK - -p 802_1Q --vlan-encap ip;-p 802_1Q --vlan-encap 0800 -j CONTINUE;OK - -p 802_1Q --vlan-encap 0800 ;=;OK ---p 802_1Q ! --vlan-encap 0800 ;=;OK ---p 802_1Q --vlan-encap IPv6 ! --vlan-id 1;-p 802_1Q ! --vlan-id 1 --vlan-encap 86DD -j CONTINUE;OK ---p 802_1Q ! --vlan-id 1 --vlan-encap 86DD;=;OK -+-p 802_1Q --vlan-encap ! 0800 ;=;OK -+-p 802_1Q --vlan-encap IPv6 ! --vlan-id 1;-p 802_1Q --vlan-id ! 1 --vlan-encap 86DD -j CONTINUE;OK -+-p 802_1Q --vlan-id ! 1 --vlan-encap 86DD;=;OK - --vlan-encap ip;=;FAIL - --vlan-id 2;=;FAIL - --vlan-prio 1;=;FAIL -diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c -index 43b3e3e9649b8..2b79ca951cd92 100644 ---- a/iptables/nft-bridge.c -+++ b/iptables/nft-bridge.c -@@ -344,7 +344,7 @@ static void nft_rule_to_ebtables_command_state(const struct nftnl_rule *r, - static void print_iface(const char *option, const char *name, bool invert) - { - if (*name) -- printf("%s%s %s ", invert ? "! " : "", option, name); -+ printf("%s%s %s ", option, invert ? " !" : "", name); - } - - static void nft_bridge_print_table_header(const char *tablename) -@@ -389,9 +389,9 @@ static void print_mac(char option, const unsigned char *mac, - const unsigned char *mask, - bool invert) - { -+ printf("-%c ", option); - if (invert) - printf("! "); -- printf("-%c ", option); - ebt_print_mac_and_mask(mac, mask); - printf(" "); - } -@@ -406,9 +406,9 @@ static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask) - if (bitmask & EBT_NOPROTO) - return; - -+ printf("-p "); - if (invert) - printf("! "); -- printf("-p "); - - if (bitmask & EBT_802_3) { - printf("length "); --- -2.21.0 - diff --git a/SOURCES/0049-arptables-Support-set-counters-option.patch b/SOURCES/0049-arptables-Support-set-counters-option.patch deleted file mode 100644 index 24dae96..0000000 --- a/SOURCES/0049-arptables-Support-set-counters-option.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a4412aa91dff87ab27e4ad6e27f2a6c03ed0b5fb Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 22 Nov 2018 20:50:13 +0100 -Subject: [PATCH] arptables: Support --set-counters option - -Relevant code for this was already present (short option '-c'), just the -long option definition was missing. - -While being at it, add '-c' to help text. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit b0466ae6fbc0a93b69591171c54aa79063e23f3d) -Signed-off-by: Phil Sutter ---- - iptables/xtables-arp.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c -index 18cdced627c55..85bcc841b21f5 100644 ---- a/iptables/xtables-arp.c -+++ b/iptables/xtables-arp.c -@@ -144,6 +144,7 @@ static struct option original_opts[] = { - { "help", 2, 0, 'h' }, - { "line-numbers", 0, 0, '0' }, - { "modprobe", 1, 0, 'M' }, -+ { "set-counters", 1, 0, 'c' }, - { 0 } - }; - -@@ -481,7 +482,7 @@ exit_printhelp(void) - " --line-numbers print line numbers when listing\n" - " --exact -x expand numbers (display exact values)\n" - " --modprobe= try to insert modules using this command\n" --" --set-counters PKTS BYTES set the counter during insert/append\n" -+" --set-counters -c PKTS BYTES set the counter during insert/append\n" - "[!] --version -V print package version.\n"); - printf(" opcode strings: \n"); - for (i = 0; i < NUMOPCODES; i++) --- -2.21.0 - diff --git a/SOURCES/0050-xshared-Explicitly-pass-target-to-command_jump.patch b/SOURCES/0050-xshared-Explicitly-pass-target-to-command_jump.patch deleted file mode 100644 index 040fd49..0000000 --- a/SOURCES/0050-xshared-Explicitly-pass-target-to-command_jump.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 715e2fa36e08f0ee800347d8abea039e5347b1dc Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 5 Feb 2019 17:01:42 +0100 -Subject: [PATCH] xshared: Explicitly pass target to command_jump() - -The use of global 'optarg' variable inside that function is a mess, but -most importantly it limits its applicability to input parsers. Fix this -by having it take the option argument as a parameter. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 932d5c3fb94acc499c8a6264e354ab1e33316b72) -Signed-off-by: Phil Sutter ---- - iptables/ip6tables.c | 2 +- - iptables/iptables.c | 2 +- - iptables/xshared.c | 4 ++-- - iptables/xshared.h | 2 +- - iptables/xtables-arp.c | 2 +- - iptables/xtables-eb-translate.c | 2 +- - iptables/xtables-eb.c | 2 +- - iptables/xtables.c | 2 +- - 8 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c -index fe089de4c85d7..050afa9a36458 100644 ---- a/iptables/ip6tables.c -+++ b/iptables/ip6tables.c -@@ -1441,7 +1441,7 @@ int do_command6(int argc, char *argv[], char **table, - case 'j': - set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags, - cs.invert); -- command_jump(&cs); -+ command_jump(&cs, optarg); - break; - - -diff --git a/iptables/iptables.c b/iptables/iptables.c -index f8041f56ce70d..38c4bfe8ecf5c 100644 ---- a/iptables/iptables.c -+++ b/iptables/iptables.c -@@ -1421,7 +1421,7 @@ int do_command4(int argc, char *argv[], char **table, - case 'j': - set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags, - cs.invert); -- command_jump(&cs); -+ command_jump(&cs, optarg); - break; - - -diff --git a/iptables/xshared.c b/iptables/xshared.c -index b16f5fa68e569..fb186fb1ac657 100644 ---- a/iptables/xshared.c -+++ b/iptables/xshared.c -@@ -653,12 +653,12 @@ const char *xt_parse_target(const char *targetname) - return targetname; - } - --void command_jump(struct iptables_command_state *cs) -+void command_jump(struct iptables_command_state *cs, const char *jumpto) - { - struct option *opts = xt_params->opts; - size_t size; - -- cs->jumpto = xt_parse_target(optarg); -+ cs->jumpto = xt_parse_target(jumpto); - /* TRY_LOAD (may be chain name) */ - cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); - -diff --git a/iptables/xshared.h b/iptables/xshared.h -index db499f29236ed..fd1f96bad1b98 100644 ---- a/iptables/xshared.h -+++ b/iptables/xshared.h -@@ -176,6 +176,6 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags, - - void command_match(struct iptables_command_state *cs); - const char *xt_parse_target(const char *targetname); --void command_jump(struct iptables_command_state *cs); -+void command_jump(struct iptables_command_state *cs, const char *jumpto); - - #endif /* IPTABLES_XSHARED_H */ -diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c -index 85bcc841b21f5..4a873b15c6833 100644 ---- a/iptables/xtables-arp.c -+++ b/iptables/xtables-arp.c -@@ -1161,7 +1161,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, - case 'j': - set_option(&options, OPT_JUMP, &cs.arp.arp.invflags, - invert); -- command_jump(&cs); -+ command_jump(&cs, optarg); - break; - - case 'i': -diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c -index 0fe14d2d0db32..96b2730fa97ed 100644 ---- a/iptables/xtables-eb-translate.c -+++ b/iptables/xtables-eb-translate.c -@@ -390,7 +390,7 @@ print_zero: - break; - } else if (c == 'j') { - ebt_check_option2(&flags, OPT_JUMP); -- command_jump(&cs); -+ command_jump(&cs, optarg); - break; - } else if (c == 's') { - ebt_check_option2(&flags, OPT_SOURCE); -diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c -index 55cb0fe204748..21344843a365a 100644 ---- a/iptables/xtables-eb.c -+++ b/iptables/xtables-eb.c -@@ -1022,7 +1022,7 @@ print_zero: - } else if (c == 'j') { - ebt_check_option2(&flags, OPT_JUMP); - if (strcmp(optarg, "CONTINUE") != 0) { -- command_jump(&cs); -+ command_jump(&cs, optarg); - } - break; - } else if (c == 's') { -diff --git a/iptables/xtables.c b/iptables/xtables.c -index eaa9fedeb03bb..1d777554076d7 100644 ---- a/iptables/xtables.c -+++ b/iptables/xtables.c -@@ -820,7 +820,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], - case 'j': - set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, - cs->invert); -- command_jump(cs); -+ command_jump(cs, optarg); - break; - - --- -2.21.0 - diff --git a/SOURCES/0051-nft-Don-t-assume-NFTNL_RULE_USERDATA-holds-a-comment.patch b/SOURCES/0051-nft-Don-t-assume-NFTNL_RULE_USERDATA-holds-a-comment.patch deleted file mode 100644 index 96d588d..0000000 --- a/SOURCES/0051-nft-Don-t-assume-NFTNL_RULE_USERDATA-holds-a-comment.patch +++ /dev/null @@ -1,72 +0,0 @@ -From e78321d1a719a5dc1b340292fc1971d4daf7e472 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 7 Feb 2019 22:08:53 +0100 -Subject: [PATCH] nft: Don't assume NFTNL_RULE_USERDATA holds a comment - -If this rule attribute is present but does not contain a comment, -get_comment() returns NULL which is then fed into strncpy() causing a -crash. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit d1df0a36b0486c780211cfa574301132bf55f194) -Signed-off-by: Phil Sutter ---- - iptables/nft-shared.c | 39 ++++++++++++++++++++++----------------- - 1 file changed, 22 insertions(+), 17 deletions(-) - -diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c -index ce40787f92f7d..fc484b49e2318 100644 ---- a/iptables/nft-shared.c -+++ b/iptables/nft-shared.c -@@ -639,25 +639,30 @@ void nft_rule_to_iptables_command_state(const struct nftnl_rule *r, - if (nftnl_rule_is_set(r, NFTNL_RULE_USERDATA)) { - const void *data; - uint32_t len, size; -- struct xtables_match *match; -- struct xt_entry_match *m; -+ const char *comment; - - data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len); -- match = xtables_find_match("comment", XTF_TRY_LOAD, -- &cs->matches); -- if (match == NULL) -- return; -- -- size = XT_ALIGN(sizeof(struct xt_entry_match)) + match->size; -- m = xtables_calloc(1, size); -- -- strncpy((char *)m->data, get_comment(data, len), -- match->size - 1); -- m->u.match_size = size; -- m->u.user.revision = 0; -- strcpy(m->u.user.name, match->name); -- -- match->m = m; -+ comment = get_comment(data, len); -+ if (comment) { -+ struct xtables_match *match; -+ struct xt_entry_match *m; -+ -+ match = xtables_find_match("comment", XTF_TRY_LOAD, -+ &cs->matches); -+ if (match == NULL) -+ return; -+ -+ size = XT_ALIGN(sizeof(struct xt_entry_match)) -+ + match->size; -+ m = xtables_calloc(1, size); -+ -+ strncpy((char *)m->data, comment, match->size - 1); -+ m->u.match_size = size; -+ m->u.user.revision = 0; -+ strcpy(m->u.user.name, match->name); -+ -+ match->m = m; -+ } - } - - if (cs->target != NULL) { --- -2.21.0 - diff --git a/SOURCES/0052-nft-Introduce-UDATA_TYPE_EBTABLES_POLICY.patch b/SOURCES/0052-nft-Introduce-UDATA_TYPE_EBTABLES_POLICY.patch deleted file mode 100644 index 157825f..0000000 --- a/SOURCES/0052-nft-Introduce-UDATA_TYPE_EBTABLES_POLICY.patch +++ /dev/null @@ -1,41 +0,0 @@ -From d418438f72d340866be241ca3867cf3ce3e04cf8 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 7 Feb 2019 22:08:54 +0100 -Subject: [PATCH] nft: Introduce UDATA_TYPE_EBTABLES_POLICY - -This will be used later to identify ebtables user-defined chain policy -rules. - -Signed-off-by: Phil Sutter -Acked-by: Pablo Neira Ayuso -Signed-off-by: Florian Westphal -(cherry picked from commit b06cc4e0f67f4beba7560fc329d20f108c87b5fb) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 2fa973cf03975..6129afdbad281 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1115,6 +1115,7 @@ int add_counters(struct nftnl_rule *r, uint64_t packets, uint64_t bytes) - - enum udata_type { - UDATA_TYPE_COMMENT, -+ UDATA_TYPE_EBTABLES_POLICY, - __UDATA_TYPE_MAX, - }; - #define UDATA_TYPE_MAX (__UDATA_TYPE_MAX - 1) -@@ -1131,6 +1132,8 @@ static int parse_udata_cb(const struct nftnl_udata *attr, void *data) - if (value[len - 1] != '\0') - return -1; - break; -+ case UDATA_TYPE_EBTABLES_POLICY: -+ break; - default: - return 0; - } --- -2.21.0 - diff --git a/SOURCES/0053-ebtables-nft-Support-user-defined-chain-policies.patch b/SOURCES/0053-ebtables-nft-Support-user-defined-chain-policies.patch deleted file mode 100644 index 1110b8e..0000000 --- a/SOURCES/0053-ebtables-nft-Support-user-defined-chain-policies.patch +++ /dev/null @@ -1,506 +0,0 @@ -From bbbebb7449605e62a0901b8d81ea2ed45044088b Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 7 Feb 2019 22:08:55 +0100 -Subject: [PATCH] ebtables-nft: Support user-defined chain policies - -Legacy ebtables supports policies for user-defined chains - and what's -worse, they default to ACCEPT unlike anywhere else. So lack of support -for this braindead feature in ebtables-nft is actually a change of -behaviour which very likely affects all ebtables users out there. - -The solution implemented here uses an implicit (and transparent) last -rule in all user-defined ebtables-nft chains with policy other than -RETURN. This rule is identified by an nft comment -"XTABLES_EB_INTERNAL_POLICY_RULE" (since commit ccf154d7420c0 ("xtables: -Don't use native nftables comments") nft comments are not used -otherwise). - -To minimize interference with existing code, this policy rule is removed -from chains during cache population and the policy is saved in -NFTNL_CHAIN_POLICY attribute. When committing changes to the kernel, -nft_commit() traverses through the list of chains and (re-)creates -policy rules if required. - -In ebtables-nft-restore, table flushes are problematic. To avoid weird -kernel error responses, introduce a custom 'table_flush' callback which -removes any pending policy rule add/remove jobs prior to creating the -NFT_COMPAT_TABLE_FLUSH one. - -I've hidden all this mess behind checks for h->family, so hopefully -impact on {ip,ip6,arp}tables-nft should be negligible. - -Signed-off-by: Phil Sutter -Acked-by: Pablo Neira Ayuso -Signed-off-by: Florian Westphal -(cherry picked from commit aff1162b3e4b7ef805425a40306044c7d7dddc67) -Signed-off-by: Phil Sutter ---- - iptables/nft-bridge.c | 2 +- - iptables/nft.c | 228 +++++++++++++++++- - iptables/nft.h | 4 + - .../ebtables/0002-ebtables-save-restore_0 | 7 + - iptables/xtables-eb.c | 20 +- - iptables/xtables-restore.c | 23 +- - 6 files changed, 265 insertions(+), 19 deletions(-) - -diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c -index 2b79ca951cd92..a51792ef03ae1 100644 ---- a/iptables/nft-bridge.c -+++ b/iptables/nft-bridge.c -@@ -358,7 +358,7 @@ static void nft_bridge_print_header(unsigned int format, const char *chain, - bool basechain, uint32_t refs, uint32_t entries) - { - printf("Bridge chain: %s, entries: %u, policy: %s\n", -- chain, entries, basechain ? pol : "RETURN"); -+ chain, entries, pol ?: "RETURN"); - } - - static void print_matches_and_watchers(const struct iptables_command_state *cs, -diff --git a/iptables/nft.c b/iptables/nft.c -index 6129afdbad281..4fdc789d99928 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -55,6 +55,7 @@ - #include "nft.h" - #include "xshared.h" /* proto_to_name */ - #include "nft-shared.h" -+#include "nft-bridge.h" /* EBT_NOPROTO */ - #include "xtables-config-parser.h" - - static void *nft_fn; -@@ -1325,6 +1326,87 @@ retry: - return ret; - } - -+static bool nft_rule_is_policy_rule(struct nftnl_rule *r) -+{ -+ const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {}; -+ const void *data; -+ uint32_t len; -+ -+ if (!nftnl_rule_is_set(r, NFTNL_RULE_USERDATA)) -+ return false; -+ -+ data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len); -+ if (nftnl_udata_parse(data, len, parse_udata_cb, tb) < 0) -+ return NULL; -+ -+ if (!tb[UDATA_TYPE_EBTABLES_POLICY] || -+ nftnl_udata_get_u32(tb[UDATA_TYPE_EBTABLES_POLICY]) != 1) -+ return false; -+ -+ return true; -+} -+ -+static struct nftnl_rule *nft_chain_last_rule(struct nftnl_chain *c) -+{ -+ struct nftnl_rule *r = NULL, *last; -+ struct nftnl_rule_iter *iter; -+ -+ iter = nftnl_rule_iter_create(c); -+ if (!iter) -+ return NULL; -+ -+ do { -+ last = r; -+ r = nftnl_rule_iter_next(iter); -+ } while (r); -+ nftnl_rule_iter_destroy(iter); -+ -+ return last; -+} -+ -+static void nft_bridge_chain_postprocess(struct nft_handle *h, -+ struct nftnl_chain *c) -+{ -+ struct nftnl_rule *last = nft_chain_last_rule(c); -+ struct nftnl_expr_iter *iter; -+ struct nftnl_expr *expr; -+ int verdict; -+ -+ if (!last || !nft_rule_is_policy_rule(last)) -+ return; -+ -+ iter = nftnl_expr_iter_create(last); -+ if (!iter) -+ return; -+ -+ expr = nftnl_expr_iter_next(iter); -+ if (!expr || -+ strcmp("counter", nftnl_expr_get_str(expr, NFTNL_EXPR_NAME))) -+ goto out_iter; -+ -+ expr = nftnl_expr_iter_next(iter); -+ if (!expr || -+ strcmp("immediate", nftnl_expr_get_str(expr, NFTNL_EXPR_NAME)) || -+ !nftnl_expr_is_set(expr, NFTNL_EXPR_IMM_VERDICT)) -+ goto out_iter; -+ -+ verdict = nftnl_expr_get_u32(expr, NFTNL_EXPR_IMM_VERDICT); -+ switch (verdict) { -+ case NF_ACCEPT: -+ case NF_DROP: -+ break; -+ default: -+ goto out_iter; -+ } -+ -+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, verdict); -+ if (batch_rule_add(h, NFT_COMPAT_RULE_DELETE, last) < 0) -+ fprintf(stderr, "Failed to delete old policy rule\n"); -+ nftnl_chain_rule_del(last); -+out_iter: -+ nftnl_expr_iter_destroy(iter); -+} -+ - static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data) - { - struct nftnl_chain *c = data; -@@ -1378,6 +1460,10 @@ retry: - } - - nftnl_rule_free(rule); -+ -+ if (h->family == NFPROTO_BRIDGE) -+ nft_bridge_chain_postprocess(h, c); -+ - return 0; - } - -@@ -1443,6 +1529,15 @@ int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) - if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) - pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - policy = policy_name[pol]; -+ } else if (h->family == NFPROTO_BRIDGE) { -+ if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) { -+ uint32_t pol; -+ -+ pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -+ policy = policy_name[pol]; -+ } else { -+ policy = "RETURN"; -+ } - } - - if (ops->save_chain) -@@ -1637,6 +1732,8 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl - - nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table); - nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain); -+ if (h->family == NFPROTO_BRIDGE) -+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT); - - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); - -@@ -2278,7 +2375,6 @@ static void __nft_print_header(struct nft_handle *h, - struct nftnl_chain *c, unsigned int format) - { - const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); -- uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM); - uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); - uint32_t entries = nft_rule_count(h, c); -@@ -2286,8 +2382,12 @@ static void __nft_print_header(struct nft_handle *h, - .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS), - .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES), - }; -+ const char *pname = NULL; - -- ops->print_header(format, chain_name, policy_name[policy], -+ if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) -+ pname = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)]; -+ -+ ops->print_header(format, chain_name, pname, - &ctrs, basechain, refs - entries, entries); - } - -@@ -2671,8 +2771,111 @@ static int nft_action(struct nft_handle *h, int action) - return ret == 0 ? 1 : 0; - } - -+static int ebt_add_policy_rule(struct nftnl_chain *c, void *data) -+{ -+ uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); -+ struct iptables_command_state cs = { -+ .eb.bitmask = EBT_NOPROTO, -+ }; -+ struct nftnl_udata_buf *udata; -+ struct nft_handle *h = data; -+ struct nftnl_rule *r; -+ const char *pname; -+ -+ if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM)) -+ return 0; /* ignore base chains */ -+ -+ if (!nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) -+ return 0; -+ -+ nftnl_chain_unset(c, NFTNL_CHAIN_POLICY); -+ -+ switch (policy) { -+ case NFT_RETURN: -+ return 0; /* return policy is default for nft chains */ -+ case NF_ACCEPT: -+ pname = "ACCEPT"; -+ break; -+ case NF_DROP: -+ pname = "DROP"; -+ break; -+ default: -+ return -1; -+ } -+ -+ command_jump(&cs, pname); -+ -+ r = nft_rule_new(h, nftnl_chain_get_str(c, NFTNL_CHAIN_NAME), -+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), &cs); -+ if (!r) -+ return -1; -+ -+ udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN); -+ if (!udata) -+ return -1; -+ -+ if (!nftnl_udata_put_u32(udata, UDATA_TYPE_EBTABLES_POLICY, 1)) -+ return -1; -+ -+ nftnl_rule_set_data(r, NFTNL_RULE_USERDATA, -+ nftnl_udata_buf_data(udata), -+ nftnl_udata_buf_len(udata)); -+ nftnl_udata_buf_free(udata); -+ -+ if (batch_rule_add(h, NFT_COMPAT_RULE_APPEND, r) < 0) { -+ nftnl_rule_free(r); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int ebt_set_user_chain_policy(struct nft_handle *h, const char *table, -+ const char *chain, const char *policy) -+{ -+ struct nftnl_chain *c = nft_chain_find(h, table, chain); -+ int pval; -+ -+ if (!c) -+ return 0; -+ -+ if (!strcmp(policy, "DROP")) -+ pval = NF_DROP; -+ else if (!strcmp(policy, "ACCEPT")) -+ pval = NF_ACCEPT; -+ else if (!strcmp(policy, "RETURN")) -+ pval = NFT_RETURN; -+ else -+ return 0; -+ -+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, pval); -+ return 1; -+} -+ -+static void nft_bridge_commit_prepare(struct nft_handle *h) -+{ -+ const struct builtin_table *t; -+ struct nftnl_chain_list *list; -+ int i; -+ -+ for (i = 0; i < NFT_TABLE_MAX; i++) { -+ t = &h->tables[i]; -+ -+ if (!t->name) -+ continue; -+ -+ list = h->table[t->type].chain_cache; -+ if (!list) -+ continue; -+ -+ nftnl_chain_list_foreach(list, ebt_add_policy_rule, h); -+ } -+} -+ - int nft_commit(struct nft_handle *h) - { -+ if (h->family == NFPROTO_BRIDGE) -+ nft_bridge_commit_prepare(h); - return nft_action(h, NFT_COMPAT_COMMIT); - } - -@@ -2681,6 +2884,27 @@ int nft_abort(struct nft_handle *h) - return nft_action(h, NFT_COMPAT_ABORT); - } - -+int nft_abort_policy_rule(struct nft_handle *h, const char *table) -+{ -+ struct obj_update *n, *tmp; -+ -+ list_for_each_entry_safe(n, tmp, &h->obj_list, head) { -+ if (n->type != NFT_COMPAT_RULE_APPEND && -+ n->type != NFT_COMPAT_RULE_DELETE) -+ continue; -+ -+ if (strcmp(table, -+ nftnl_rule_get_str(n->rule, NFTNL_RULE_TABLE))) -+ continue; -+ -+ if (!nft_rule_is_policy_rule(n->rule)) -+ continue; -+ -+ batch_obj_del(h, n); -+ } -+ return 0; -+} -+ - int nft_compatible_revision(const char *name, uint8_t rev, int opt) - { - struct mnl_socket *nl; -diff --git a/iptables/nft.h b/iptables/nft.h -index 0726923a63dd4..56dc207608855 100644 ---- a/iptables/nft.h -+++ b/iptables/nft.h -@@ -137,6 +137,7 @@ uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag); - */ - int nft_commit(struct nft_handle *h); - int nft_abort(struct nft_handle *h); -+int nft_abort_policy_rule(struct nft_handle *h, const char *table); - - /* - * revision compatibility. -@@ -203,4 +204,7 @@ void nft_rule_to_arpt_entry(struct nftnl_rule *r, struct arpt_entry *fw); - - bool nft_is_table_compatible(struct nft_handle *h, const char *name); - -+int ebt_set_user_chain_policy(struct nft_handle *h, const char *table, -+ const char *chain, const char *policy); -+ - #endif -diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 -index b23c1ee18c8ae..080ba49a4974d 100755 ---- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 -+++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 -@@ -50,6 +50,9 @@ $XT_MULTI ebtables -A foo --pkttype-type multicast --limit 100 -j ACCEPT - - $XT_MULTI ebtables -A FORWARD -j foo - -+$XT_MULTI ebtables -N bar -+$XT_MULTI ebtables -P bar RETURN -+ - $XT_MULTI ebtables -t nat -A PREROUTING --redirect-target ACCEPT - #$XT_MULTI ebtables -t nat -A PREROUTING --to-src fe:ed:ba:be:00:01 - -@@ -59,6 +62,8 @@ $XT_MULTI ebtables -t nat -P OUTPUT DROP - $XT_MULTI ebtables -t nat -A POSTROUTING -j ACCEPT - #$XT_MULTI ebtables -t nat -A POSTROUTING --to-dst fe:ed:ba:be:00:01 --dnat-target ACCEPT - -+$XT_MULTI ebtables -t nat -N nat_foo -P DROP -+ - # compare against stored ebtables dump - - DUMP='*filter -@@ -66,6 +71,7 @@ DUMP='*filter - :FORWARD DROP - :OUTPUT ACCEPT - :foo ACCEPT -+:bar RETURN - -A INPUT -p IPv4 -i lo -j ACCEPT - -A FORWARD -j foo - -A OUTPUT -s Broadcast -j DROP -@@ -98,6 +104,7 @@ DUMP='*filter - :PREROUTING ACCEPT - :OUTPUT DROP - :POSTROUTING ACCEPT -+:nat_foo DROP - -A PREROUTING -j redirect - -A OUTPUT -j ACCEPT - -A POSTROUTING -j ACCEPT -diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c -index 21344843a365a..d0f0026e9c538 100644 ---- a/iptables/xtables-eb.c -+++ b/iptables/xtables-eb.c -@@ -811,7 +811,6 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, - case 'E': /* Rename chain */ - case 'X': /* Delete chain */ - /* We allow -N chainname -P policy */ -- /* XXX: Not in ebtables-compat */ - if (command == 'N' && c == 'P') { - command = c; - optind--; /* No table specified */ -@@ -1236,17 +1235,16 @@ print_zero: - - if (command == 'P') { - if (selected_chain < 0) { -- xtables_error(PARAMETER_PROBLEM, -- "Policy %s not allowed for user defined chains", -- policy); -- } -- if (strcmp(policy, "RETURN") == 0) { -- xtables_error(PARAMETER_PROBLEM, -- "Policy RETURN only allowed for user defined chains"); -+ ret = ebt_set_user_chain_policy(h, *table, chain, policy); -+ } else { -+ if (strcmp(policy, "RETURN") == 0) { -+ xtables_error(PARAMETER_PROBLEM, -+ "Policy RETURN only allowed for user defined chains"); -+ } -+ ret = nft_chain_set(h, *table, chain, policy, NULL); -+ if (ret < 0) -+ xtables_error(PARAMETER_PROBLEM, "Wrong policy"); - } -- ret = nft_chain_set(h, *table, chain, policy, NULL); -- if (ret < 0) -- xtables_error(PARAMETER_PROBLEM, "Wrong policy"); - } else if (command == 'L') { - ret = list_rules(h, chain, *table, rule_nr, - 0, -diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c -index 4e00ed86be06d..6e6daffc9a1df 100644 ---- a/iptables/xtables-restore.c -+++ b/iptables/xtables-restore.c -@@ -226,14 +226,20 @@ void xtables_restore_parse(struct nft_handle *h, - curtable->name, chain); - } else if (cb->chain_user_add && - cb->chain_user_add(h, chain, -- curtable->name) < 0) { -- if (errno == EEXIST) -- continue; -- -+ curtable->name) < 0 && -+ errno != EEXIST) { - xtables_error(PARAMETER_PROBLEM, - "cannot create chain " - "'%s' (%s)\n", chain, - strerror(errno)); -+ } else if (h->family == NFPROTO_BRIDGE && -+ !ebt_set_user_chain_policy(h, curtable->name, -+ chain, policy)) { -+ xtables_error(OTHER_PROBLEM, -+ "Can't set policy `%s'" -+ " on `%s' line %u: %s\n", -+ policy, chain, line, -+ ops->strerror(errno)); - } - ret = 1; - } else if (in_table) { -@@ -462,11 +468,18 @@ int xtables_ip6_restore_main(int argc, char *argv[]) - argc, argv); - } - -+static int ebt_table_flush(struct nft_handle *h, const char *table) -+{ -+ /* drop any pending policy rule add/removal jobs */ -+ nft_abort_policy_rule(h, table); -+ return nft_table_flush(h, table); -+} -+ - struct nft_xt_restore_cb ebt_restore_cb = { - .chain_list = get_chain_list, - .commit = nft_commit, - .table_new = nft_table_new, -- .table_flush = nft_table_flush, -+ .table_flush = ebt_table_flush, - .chain_user_flush = nft_chain_user_flush, - .do_command = do_commandeb, - .chain_set = nft_chain_set, --- -2.21.0 - diff --git a/SOURCES/0054-extensions-libipt_realm-Document-allowed-realm-value.patch b/SOURCES/0054-extensions-libipt_realm-Document-allowed-realm-value.patch deleted file mode 100644 index 15e133f..0000000 --- a/SOURCES/0054-extensions-libipt_realm-Document-allowed-realm-value.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8b69d66b21f3699ee64c572bfba5df033ce768e0 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 3 Dec 2018 14:52:28 +0100 -Subject: [PATCH] extensions: libipt_realm: Document allowed realm values - -Older versions of iptables allowed for negative realm values by accident -(they would be cast to unsigned). While this was clearly a bug, document -the fixed behaviour. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 290d76b443bf24999d9caacb3fdd027d6e7112a1) -Signed-off-by: Phil Sutter ---- - extensions/libipt_realm.man | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/extensions/libipt_realm.man b/extensions/libipt_realm.man -index a40b1adc72ba2..72dff9b2e4212 100644 ---- a/extensions/libipt_realm.man -+++ b/extensions/libipt_realm.man -@@ -5,3 +5,5 @@ setups involving dynamic routing protocols like BGP. - Matches a given realm number (and optionally mask). If not a number, value - can be a named realm from /etc/iproute2/rt_realms (mask can not be used in - that case). -+Both value and mask are four byte unsigned integers and may be specified in -+decimal, hex (by prefixing with "0x") or octal (if a leading zero is given). --- -2.21.0 - diff --git a/SOURCES/0055-extensions-TRACE-Point-at-xtables-monitor-in-documen.patch b/SOURCES/0055-extensions-TRACE-Point-at-xtables-monitor-in-documen.patch deleted file mode 100644 index 83d5163..0000000 --- a/SOURCES/0055-extensions-TRACE-Point-at-xtables-monitor-in-documen.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 39808343b03078f992bc5e831ccdd843312f0714 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 18 Dec 2018 12:16:30 +0100 -Subject: [PATCH] extensions: TRACE: Point at xtables-monitor in documentation - -With iptables-nft, logging of trace events is different from legacy. -Explain why and hint at how to receive events in this case. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 9ac39888722ee9c7e97d9b8cb9eb4f33b582130a) -Signed-off-by: Phil Sutter ---- - extensions/libxt_TRACE.man | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/extensions/libxt_TRACE.man b/extensions/libxt_TRACE.man -index 8d590a52e26f8..5187a8d22802f 100644 ---- a/extensions/libxt_TRACE.man -+++ b/extensions/libxt_TRACE.man -@@ -1,13 +1,20 @@ - This target marks packets so that the kernel will log every rule which match --the packets as those traverse the tables, chains, rules. -+the packets as those traverse the tables, chains, rules. It can only be used in -+the -+.BR raw -+table. - .PP --A logging backend, such as ip(6)t_LOG or nfnetlink_log, must be loaded for this --to be visible. -+With iptables-legacy, a logging backend, such as ip(6)t_LOG or nfnetlink_log, -+must be loaded for this to be visible. - The packets are logged with the string prefix: - "TRACE: tablename:chainname:type:rulenum " where type can be "rule" for - plain rule, "return" for implicit rule at the end of a user defined chain - and "policy" for the policy of the built in chains. --.br --It can only be used in the --.BR raw --table. -+.PP -+With iptables-nft, the target is translated into nftables' -+.B "meta nftrace" -+expression. Hence the kernel sends trace events via netlink to userspace where -+they may be displayed using -+.B "xtables-monitor --trace" -+command. For details, refer to -+.BR xtables-monitor (8). --- -2.21.0 - diff --git a/SOURCES/0056-xtables-Catch-errors-when-zeroing-rule-rounters.patch b/SOURCES/0056-xtables-Catch-errors-when-zeroing-rule-rounters.patch deleted file mode 100644 index 3d9de2c..0000000 --- a/SOURCES/0056-xtables-Catch-errors-when-zeroing-rule-rounters.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 4a6f89b263a62f078e73cbc01d09330a217a23c7 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sat, 15 Dec 2018 19:25:04 +0100 -Subject: [PATCH] xtables: Catch errors when zeroing rule rounters - -Covscan complained about call to batch_rule_add() not being checked. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 4c54c892443c20a1d0e1212d541da0e81647058a) -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/iptables/nft.c b/iptables/nft.c -index 4fdc789d99928..2d527358cc7f2 100644 ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -3218,7 +3218,9 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data) - * rule based on its handle only. - */ - nftnl_rule_unset(r, NFTNL_RULE_POSITION); -- batch_rule_add(h, NFT_COMPAT_RULE_REPLACE, r); -+ ret = batch_rule_add(h, NFT_COMPAT_RULE_REPLACE, r); -+ if (ret) -+ return -1; - } - r = nftnl_rule_iter_next(iter); - } --- -2.21.0 - diff --git a/SOURCES/0057-xtables-save-Fix-table-not-found-error-message.patch b/SOURCES/0057-xtables-save-Fix-table-not-found-error-message.patch deleted file mode 100644 index 97b81f8..0000000 --- a/SOURCES/0057-xtables-save-Fix-table-not-found-error-message.patch +++ /dev/null @@ -1,37 +0,0 @@ -From a63cf723111d323afab642e6f6b12a5da660fd5b Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 7 Feb 2019 22:13:31 +0100 -Subject: [PATCH] xtables-save: Fix table not found error message - -First of all, this error message should not appear on stdout, otherwise -it may end in dump files. Next, with completely empty ruleset, even -valid table names cause errors. To avoid this, continue operation if the -not found table is a builtin one. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 2478b6cbb8112f940cec61ec1e62a598472d33d0) -Signed-off-by: Phil Sutter ---- - iptables/xtables-save.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c -index 414a864b6196b..87ebb913f33b7 100644 ---- a/iptables/xtables-save.c -+++ b/iptables/xtables-save.c -@@ -105,8 +105,9 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) - return !!ret; - } - -- if (!nft_table_find(h, tablename)) { -- printf("Table `%s' does not exist\n", tablename); -+ if (!nft_table_find(h, tablename) && -+ !nft_table_builtin_find(h, tablename)) { -+ fprintf(stderr, "Table `%s' does not exist\n", tablename); - return 1; - } - --- -2.21.0 - diff --git a/SOURCES/0058-arptables-nft-fix-decoding-of-hlen-on-bigendian-plat.patch b/SOURCES/0058-arptables-nft-fix-decoding-of-hlen-on-bigendian-plat.patch deleted file mode 100644 index 38a0a5c..0000000 --- a/SOURCES/0058-arptables-nft-fix-decoding-of-hlen-on-bigendian-plat.patch +++ /dev/null @@ -1,49 +0,0 @@ -From dc38548e6f745bcfb141324b36307dbfa941eabd Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Fri, 22 Feb 2019 13:26:05 +0100 -Subject: [PATCH] arptables-nft: fix decoding of hlen on bigendian platforms - -The existing test fail with: -extensions/libarpt_standard.t: ERROR: line 2 (cannot find: arptables -I INPUT -s 192.168.0.1) - -... because hlen is 0 instead of expected "6". -The rule is correct, i.e. this is a decode/display bug: arp_hlen is -specified as 'unsigned short' instead of uint8_t. - -On LSB systems, this doesn't matter but on MSB the value then is '0x600' -instead of '0x006' which becomes 0 when assignment to the u8 header field. - -Signed-off-by: Florian Westphal -Acked-by: Phil Sutter -(cherry picked from commit d68672a641439b72bccfcb39d50f26fe3f915c19) -Signed-off-by: Phil Sutter ---- - iptables/nft-arp.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c -index 37b0985377bef..b436570291b7c 100644 ---- a/iptables/nft-arp.c -+++ b/iptables/nft-arp.c -@@ -338,7 +338,8 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, - struct iptables_command_state *cs = data; - struct arpt_entry *fw = &cs->arp; - struct in_addr addr; -- unsigned short int ar_hrd, ar_pro, ar_op, ar_hln; -+ uint16_t ar_hrd, ar_pro, ar_op; -+ uint8_t ar_hln; - bool inv; - - switch (ctx->payload.offset) { -@@ -364,7 +365,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, - fw->arp.invflags |= ARPT_INV_ARPOP; - break; - case offsetof(struct arphdr, ar_hln): -- get_cmp_data(e, &ar_hln, sizeof(ar_op), &inv); -+ get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv); - fw->arp.arhln = ar_hln; - fw->arp.arhln_mask = 0xff; - if (inv) --- -2.21.0 - diff --git a/SOURCES/0059-extensions-libip6t_mh-fix-bogus-translation-error.patch b/SOURCES/0059-extensions-libip6t_mh-fix-bogus-translation-error.patch deleted file mode 100644 index aa3d991..0000000 --- a/SOURCES/0059-extensions-libip6t_mh-fix-bogus-translation-error.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a1e2de039a97f5ee8f5d7ebd34c82ff48c0fa345 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 19 Nov 2018 14:09:20 +0100 -Subject: [PATCH] extensions: libip6t_mh: fix bogus translation error - - libip6t_mh.txlate: Fail - src: ip6tables-translate -A INPUT -p mh --mh-type 1 -j ACCEPT - exp: nft add rule ip6 filter INPUT meta l4proto 135 mh type 1 counter accept - res: nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1 counter accept - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 5839d7fe62ff667af7132fc7d589b386951f27b3) -Signed-off-by: Phil Sutter ---- - extensions/libip6t_mh.txlate | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/extensions/libip6t_mh.txlate b/extensions/libip6t_mh.txlate -index ccc07c3d5ecb1..f5d638c09ca8a 100644 ---- a/extensions/libip6t_mh.txlate -+++ b/extensions/libip6t_mh.txlate -@@ -1,5 +1,5 @@ - ip6tables-translate -A INPUT -p mh --mh-type 1 -j ACCEPT --nft add rule ip6 filter INPUT meta l4proto 135 mh type 1 counter accept -+nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1 counter accept - - ip6tables-translate -A INPUT -p mh --mh-type 1:3 -j ACCEPT --nft add rule ip6 filter INPUT meta l4proto 135 mh type 1-3 counter accept -+nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1-3 counter accept --- -2.21.0 - diff --git a/SOURCES/0060-xtables-save-Point-at-existing-man-page-in-help-text.patch b/SOURCES/0060-xtables-save-Point-at-existing-man-page-in-help-text.patch deleted file mode 100644 index c3c691e..0000000 --- a/SOURCES/0060-xtables-save-Point-at-existing-man-page-in-help-text.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8a192868ba7dd55a0465f07d8fb42d26dff566d3 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 13 Mar 2019 20:46:17 +0100 -Subject: [PATCH] xtables-save: Point at existing man page in help text - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 934479aa1f1576afba97b137a101a60d8534370c) -Signed-off-by: Phil Sutter ---- - iptables/xtables-save.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c -index 87ebb913f33b7..2cc5a7c7540be 100644 ---- a/iptables/xtables-save.c -+++ b/iptables/xtables-save.c -@@ -187,7 +187,8 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) - exit(0); - default: - fprintf(stderr, -- "Look at manual page `xtables-save.8' for more information.\n"); -+ "Look at manual page `%s.8' for more information.\n", -+ prog_name); - exit(1); - } - } -@@ -333,7 +334,8 @@ int xtables_eb_save_main(int argc_, char *argv_[]) - exit(0); - default: - fprintf(stderr, -- "Look at manual page `xtables-save.8' for more information.\n"); -+ "Look at manual page `%s.8' for more information.\n", -+ prog_name); - exit(1); - } - } -@@ -380,7 +382,8 @@ int xtables_arp_save_main(int argc, char **argv) - exit(0); - default: - fprintf(stderr, -- "Look at manual page `xtables-save.8' for more information.\n"); -+ "Look at manual page `%s.8' for more information.\n", -+ prog_name); - exit(1); - } - } --- -2.21.0 - diff --git a/SOURCES/0061-xtables-restore-Fix-program-names-in-help-texts.patch b/SOURCES/0061-xtables-restore-Fix-program-names-in-help-texts.patch deleted file mode 100644 index 7d2b4f3..0000000 --- a/SOURCES/0061-xtables-restore-Fix-program-names-in-help-texts.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 4c351ba82a79b2781fc580f3f5473da0e5a276b8 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sat, 8 Jun 2019 19:34:13 +0200 -Subject: [PATCH] xtables-restore: Fix program names in help texts - -Avoid referring to wrong or even non-existent commands: - -* When calling xtables_restore_main(), pass the actual program name - taken from argv[0]. -* Use 'prog_name' in unknown parameter and help output instead of - 'xtables-restore' which probably doesn't exist. -* While being at it, fix false whitespace in help text. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit ac531b4681d1a0309a738d7bc3408fc2270eaa03) - -Conflicts: - iptables/xtables-restore.c --> missing commit 093cec72e7f77 ("src: replace IPTABLES_VERSION by PACKAGE_VERSION") - -Signed-off-by: Phil Sutter ---- - iptables/xtables-restore.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c -index 6e6daffc9a1df..7c2759a3c5932 100644 ---- a/iptables/xtables-restore.c -+++ b/iptables/xtables-restore.c -@@ -7,6 +7,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -51,7 +52,7 @@ static void print_usage(const char *name, const char *version) - " [ --help ]\n" - " [ --noflush ]\n" - " [ --table= ]\n" -- " [ --modprobe= ]\n" -+ " [ --modprobe= ]\n" - " [ --ipv4 ]\n" - " [ --ipv6 ]\n", name); - } -@@ -376,8 +377,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) - p.testing = 1; - break; - case 'h': -- print_usage("xtables-restore", -- IPTABLES_VERSION); -+ print_usage(prog_name, IPTABLES_VERSION); - exit(0); - case 'n': - noflush = 1; -@@ -402,7 +402,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) - break; - default: - fprintf(stderr, -- "Try `xtables-restore -h' for more information.\n"); -+ "Try `%s -h' for more information.\n", -+ prog_name); - exit(1); - } - } -@@ -458,13 +459,13 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) - - int xtables_ip4_restore_main(int argc, char *argv[]) - { -- return xtables_restore_main(NFPROTO_IPV4, "iptables-restore", -+ return xtables_restore_main(NFPROTO_IPV4, basename(*argv), - argc, argv); - } - - int xtables_ip6_restore_main(int argc, char *argv[]) - { -- return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore", -+ return xtables_restore_main(NFPROTO_IPV6, basename(*argv), - argc, argv); - } - --- -2.21.0 - diff --git a/SOURCES/0062-extensions-AUDIT-Document-ineffective-type-option.patch b/SOURCES/0062-extensions-AUDIT-Document-ineffective-type-option.patch deleted file mode 100644 index a22d248..0000000 --- a/SOURCES/0062-extensions-AUDIT-Document-ineffective-type-option.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 31695c75575f3998ac0c5d466d0b85276289a730 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Feb 2019 15:38:47 +0100 -Subject: [PATCH] extensions: AUDIT: Document ineffective --type option - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit dffb5ec2a8c7f91351e2a1029a757cb1f41f2d02) -Signed-off-by: Phil Sutter ---- - extensions/libxt_AUDIT.man | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/extensions/libxt_AUDIT.man b/extensions/libxt_AUDIT.man -index cd796967c431a..4f5562e8ca425 100644 ---- a/extensions/libxt_AUDIT.man -+++ b/extensions/libxt_AUDIT.man -@@ -3,12 +3,14 @@ It can be used to record accepted, dropped, and rejected packets. See - auditd(8) for additional details. - .TP - \fB\-\-type\fP {\fBaccept\fP|\fBdrop\fP|\fBreject\fP} --Set type of audit record. -+Set type of audit record. Starting with linux-4.12, this option has no effect -+on generated audit messages anymore. It is still accepted by iptables for -+compatibility reasons, but ignored. - .PP - Example: - .IP - iptables \-N AUDIT_DROP - .IP --iptables \-A AUDIT_DROP \-j AUDIT \-\-type drop -+iptables \-A AUDIT_DROP \-j AUDIT - .IP - iptables \-A AUDIT_DROP \-j DROP --- -2.21.0 - diff --git a/SOURCES/0063-utils-Add-a-manpage-for-nfbpf_compile.patch b/SOURCES/0063-utils-Add-a-manpage-for-nfbpf_compile.patch deleted file mode 100644 index 43b158a..0000000 --- a/SOURCES/0063-utils-Add-a-manpage-for-nfbpf_compile.patch +++ /dev/null @@ -1,140 +0,0 @@ -From b3d9e7d73221e1f7efe9bd7052e85163e5de65aa Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 16 Jan 2019 22:47:59 +0100 -Subject: [PATCH] utils: Add a manpage for nfbpf_compile - -Content is rather sparse, but still better than no manpage at all. - -Cc: Willem de Bruijn -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 032dc4a18ab86173847b6016baf0819ccd7641c5) -Signed-off-by: Phil Sutter ---- - configure.ac | 3 +- - utils/.gitignore | 1 + - utils/Makefile.am | 3 +- - utils/nfbpf_compile.8.in | 70 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 75 insertions(+), 2 deletions(-) - create mode 100644 utils/nfbpf_compile.8.in - -diff --git a/configure.ac b/configure.ac -index 448ec918fd89b..e6c9832fa43ba 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -252,7 +252,8 @@ AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile - libxtables/Makefile utils/Makefile - include/xtables-version.h include/iptables/internal.h - iptables/xtables-monitor.8 -- utils/nfnl_osf.8]) -+ utils/nfnl_osf.8 -+ utils/nfbpf_compile.8]) - AC_OUTPUT - - -diff --git a/utils/.gitignore b/utils/.gitignore -index 7c6afbf4e6a52..6300812b1701b 100644 ---- a/utils/.gitignore -+++ b/utils/.gitignore -@@ -1,3 +1,4 @@ - /nfnl_osf - /nfnl_osf.8 - /nfbpf_compile -+/nfbpf_compile.8 -diff --git a/utils/Makefile.am b/utils/Makefile.am -index 80029e303ff3b..d09a69749b85f 100644 ---- a/utils/Makefile.am -+++ b/utils/Makefile.am -@@ -17,6 +17,7 @@ nfnl_osf_LDADD = ${libnfnetlink_LIBS} - endif - - if ENABLE_BPFC -+man_MANS += nfbpf_compile.8 - sbin_PROGRAMS += nfbpf_compile - nfbpf_compile_LDADD = -lpcap - endif -@@ -26,4 +27,4 @@ sbin_PROGRAMS += nfsynproxy - nfsynproxy_LDADD = -lpcap - endif - --CLEANFILES = nfnl_osf.8 -+CLEANFILES = nfnl_osf.8 nfbpf_compile.8 -diff --git a/utils/nfbpf_compile.8.in b/utils/nfbpf_compile.8.in -new file mode 100644 -index 0000000000000..d02979a5143ef ---- /dev/null -+++ b/utils/nfbpf_compile.8.in -@@ -0,0 +1,70 @@ -+.TH NFBPF_COMPILE 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@" -+ -+.SH NAME -+nfbpf_compile \- generate bytecode for use with xt_bpf -+.SH SYNOPSIS -+ -+.ad l -+.in +8 -+.ti -8 -+.B nfbpf_compile -+[ -+.I LLTYPE -+] -+.I PROGRAM -+ -+.ti -8 -+.I LLTYPE -+:= { -+.BR EN10MB " | " RAW " | " SLIP " | " -+.I ... -+} -+ -+.SH DESCRIPTION -+The -+.B nfbpf_compile -+utility aids in generating BPF byte code suitable for passing to -+the iptables -+.B bpf -+match. -+ -+.SH OPTIONS -+ -+.TP -+.I LLTYPE -+Link-layer header type to operate on. This is a name as defined in -+.RB < pcap/dlt.h > -+but with the leading -+.B DLT_ -+prefix stripped. For use with iptables, -+.B RAW -+should be the right choice (it's also the default if not specified). -+ -+.TP -+.I PROGRAM -+The BPF expression to compile, see -+.BR pcap-filter (7) -+for a description of the language. -+ -+.SH EXIT STATUS -+The program returns 0 on success, 1 otherwise. -+ -+.SH EXAMPLE -+Match incoming TCP packets with size bigger than 100 bytes: -+.P -+.in +8 -+.EE -+bpf=$(nfbpf_compile 'tcp and greater 100') -+.br -+iptables -A INPUT -m bpf --bytecode "$bpf" -j ACCEPT -+.RE -+.P -+The description of -+.B bpf -+match in -+.BR iptables-extensions (8) -+lists a few more examples. -+ -+.SH SEE ALSO -+.BR iptables-extensions (8), -+.BR pcap-filter (7) --- -2.21.0 - diff --git a/SOURCES/arptables.8 b/SOURCES/arptables.8 deleted file mode 100644 index 6a5e21d..0000000 --- a/SOURCES/arptables.8 +++ /dev/null @@ -1,330 +0,0 @@ -.TH ARPTABLES 8 "November 2011" -.\" -.\" Man page originally written by Jochen Friedrich , -.\" maintained by Bart De Schuymer. -.\" It is based on the iptables man page. -.\" -.\" Iptables page by Herve Eychenne March 2000. -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.SH NAME -arptables \- ARP table administration -.SH SYNOPSIS -.BR "arptables " [ "-t table" ] " -" [ AD ] " chain rule-specification " [ options ] -.br -.BR "arptables " [ "-t table" ] " -" [ RI ] " chain rulenum rule-specification " [ options ] -.br -.BR "arptables " [ "-t table" ] " -D chain rulenum " [ options ] -.br -.BR "arptables " [ "-t table" ] " -" [ "LFZ" ] " " [ chain ] " " [ options ] -.br -.BR "arptables " [ "-t table" ] " -" [ "NX" ] " chain" -.br -.BR "arptables " [ "-t table" ] " -E old-chain-name new-chain-name" -.br -.BR "arptables " [ "-t table" ] " -P chain target " [ options ] -.SH DESCRIPTION -.B arptables -is a user space tool, it is used to set up and maintain the -tables of ARP rules in the Linux kernel. These rules inspect -the ARP frames which they see. -.B arptables -is analogous to the -.B iptables -user space tool, but -.B arptables -is less complicated. - -.SS CHAINS -The kernel table is used to divide functionality into -different sets of rules. Each set of rules is called a chain. -Each chain is an ordered list of rules that can match ARP frames. If a -rule matches an ARP frame, then a processing specification tells -what to do with that matching frame. The processing specification is -called a 'target'. However, if the frame does not match the current -rule in the chain, then the next rule in the chain is examined and so forth. -The user can create new (user-defined) chains which can be used as the 'target' of a rule. - -.SS TARGETS -A firewall rule specifies criteria for an ARP frame and a frame -processing specification called a target. When a frame matches a rule, -then the next action performed by the kernel is specified by the target. -The target can be one of these values: -.IR ACCEPT , -.IR DROP , -.IR CONTINUE , -.IR RETURN , -an 'extension' (see below) or a user-defined chain. -.PP -.I ACCEPT -means to let the frame through. -.I DROP -means the frame has to be dropped. -.I CONTINUE -means the next rule has to be checked. This can be handy to know how many -frames pass a certain point in the chain or to log those frames. -.I RETURN -means stop traversing this chain and resume at the next rule in the -previous (calling) chain. -For the extension targets please see the -.B "TARGET EXTENSIONS" -section of this man page. -.SS TABLES -There is only one ARP table in the Linux -kernel. The table is -.BR filter. -You can drop the '-t filter' argument to the arptables command. -The -t argument must be the -first argument on the arptables command line, if used. -.TP -.B "-t, --table" -.br -.BR filter , -is the only table and contains two built-in chains: -.B INPUT -(for frames destined for the host) and -.B OUTPUT -(for locally-generated frames). -.br -.br -.SH ARPTABLES COMMAND LINE ARGUMENTS -After the initial arptables command line argument, the remaining -arguments can be divided into several different groups. These groups -are commands, miscellaneous commands, rule-specifications, match-extensions, -and watcher-extensions. -.SS COMMANDS -The arptables command arguments specify the actions to perform on the table -defined with the -t argument. If you do not use the -t argument to name -a table, the commands apply to the default filter table. -With the exception of the -.B "-Z" -command, only one command may be used on the command line at a time. -.TP -.B "-A, --append" -Append a rule to the end of the selected chain. -.TP -.B "-D, --delete" -Delete the specified rule from the selected chain. There are two ways to -use this command. The first is by specifying an interval of rule numbers -to delete, syntax: start_nr[:end_nr]. Using negative numbers is allowed, for more -details about using negative numbers, see the -I command. The second usage is by -specifying the complete rule as it would have been specified when it was added. -.TP -.B "-I, --insert" -Insert the specified rule into the selected chain at the specified rule number. -If the current number of rules equals N, then the specified number can be -between -N and N+1. For a positive number i, it holds that i and i-N-1 specify the -same place in the chain where the rule should be inserted. The number 0 specifies -the place past the last rule in the chain and using this number is therefore -equivalent with using the -A command. -.TP -.B "-R, --replace" -Replaces the specified rule into the selected chain at the specified rule number. -If the current number of rules equals N, then the specified number can be -between 1 and N. i specifies the place in the chain where the rule should be replaced. -.TP -.B "-P, --policy" -Set the policy for the chain to the given target. The policy can be -.BR ACCEPT ", " DROP " or " RETURN . -.TP -.B "-F, --flush" -Flush the selected chain. If no chain is selected, then every chain will be -flushed. Flushing the chain does not change the policy of the -chain, however. -.TP -.B "-Z, --zero" -Set the counters of the selected chain to zero. If no chain is selected, all the counters -are set to zero. The -.B "-Z" -command can be used in conjunction with the -.B "-L" -command. -When both the -.B "-Z" -and -.B "-L" -commands are used together in this way, the rule counters are printed on the screen -before they are set to zero. -.TP -.B "-L, --list" -List all rules in the selected chain. If no chain is selected, all chains -are listed. -.TP -.B "-N, --new-chain" -Create a new user-defined chain with the given name. The number of -user-defined chains is unlimited. A user-defined chain name has maximum -length of 31 characters. -.TP -.B "-X, --delete-chain" -Delete the specified user-defined chain. There must be no remaining references -to the specified chain, otherwise -.B arptables -will refuse to delete it. If no chain is specified, all user-defined -chains that aren't referenced will be removed. -.TP -.B "-E, --rename-chain" -Rename the specified chain to a new name. Besides renaming a user-defined -chain, you may rename a standard chain name to a name that suits your -taste. For example, if you like PREBRIDGING more than PREROUTING, -then you can use the -E command to rename the PREROUTING chain. If you do -rename one of the standard -.B arptables -chain names, please be sure to mention -this fact should you post a question on the -.B arptables -mailing lists. -It would be wise to use the standard name in your post. Renaming a standard -.B arptables -chain in this fashion has no effect on the structure or function -of the -.B arptables -kernel table. - -.SS MISCELLANOUS COMMANDS -.TP -.B "-V, --version" -Show the version of the arptables userspace program. -.TP -.B "-h, --help" -Give a brief description of the command syntax. -.TP -.BR "-j, --jump " "\fItarget\fP" -The target of the rule. This is one of the following values: -.BR ACCEPT , -.BR DROP , -.BR CONTINUE , -.BR RETURN , -a target extension (see -.BR "TARGET EXTENSIONS" ")" -or a user-defined chain name. -.TP -.BI "-c, --set-counters " "PKTS BYTES" -This enables the administrator to initialize the packet and byte -counters of a rule (during -.B INSERT, -.B APPEND, -.B REPLACE -operations). - -.SS RULE-SPECIFICATIONS -The following command line arguments make up a rule specification (as used -in the add and delete commands). A "!" option before the specification -inverts the test for that specification. Apart from these standard rule -specifications there are some other command line arguments of interest. -.TP -.BR "-s, --source-ip " "[!] \fIaddress\fP[/\fImask]\fP" -The Source IP specification. -.TP -.BR "-d, --destination-ip " "[!] \fIaddress\fP[/\fImask]\fP" -The Destination IP specification. -.TP -.BR "--source-mac " "[!] \fIaddress\fP[/\fImask\fP]" -The source mac address. Both mask and address are written as 6 hexadecimal -numbers separated by colons. -.TP -.BR "--destination-mac " "[!] \fIaddress\fP[/\fImask\fP]" -The destination mac address. Both mask and address are written as 6 hexadecimal -numbers separated by colons. -.TP -.BR "-i, --in-interface " "[!] \fIname\fP" -The interface via which a frame is received (for the -.B INPUT -chain). The flag -.B --in-if -is an alias for this option. -.TP -.BR "-o, --out-interface " "[!] \fIname\fP" -The interface via which a frame is going to be sent (for the -.B OUTPUT -chain). The flag -.B --out-if -is an alias for this option. -.TP -.BR "-l, --h-length " "\fIlength\fP[/\fImask\fP]" -The hardware length (nr of bytes) -.TP -.BR "--opcode " "\fIcode\fP[/\fImask\fP] -The operation code (2 bytes). Available values are: -.BR 1 = Request -.BR 2 = Reply -.BR 3 = Request_Reverse -.BR 4 = Reply_Reverse -.BR 5 = DRARP_Request -.BR 6 = DRARP_Reply -.BR 7 = DRARP_Error -.BR 8 = InARP_Request -.BR 9 = ARP_NAK . -.TP -.BR "--h-type " "\fItype\fP[/\fImask\fP]" -The hardware type (2 bytes, hexadecimal). Available values are: -.BR 1 = Ethernet . -.TP -.BR "--proto-type " "\fItype\fP[/\fImask\fP]" -The protocol type (2 bytes). Available values are: -.BR 0x800 = IPv4 . - -.SS TARGET-EXTENSIONS -.B arptables -extensions are precompiled into the userspace tool. So there is no need -to explicitly load them with a -m option like in -.BR iptables . -However, these -extensions deal with functionality supported by supplemental kernel modules. -.SS mangle -.TP -.BR "--mangle-ip-s IP address" -Mangles Source IP Address to given value. -.TP -.BR "--mangle-ip-d IP address" -Mangles Destination IP Address to given value. -.TP -.BR "--mangle-mac-s MAC address" -Mangles Source MAC Address to given value. -.TP -.BR "--mangle-mac-d MAC address" -Mangles Destination MAC Address to given value. -.TP -.BR "--mangle-target target " -Target of ARP mangle operation -.BR "" ( DROP ", " CONTINUE " or " ACCEPT " -- default is " ACCEPT ). -.SS CLASSIFY -This module allows you to set the skb->priority value (and thus clas- -sify the packet into a specific CBQ class). - -.TP -.BR "--set-class major:minor" - -Set the major and minor class value. The values are always -interpreted as hexadecimal even if no 0x prefix is given. - -.SH NOTES -In this nft-based version of -.BR arptables , -support for -.B FORWARD -chain has not been implemented. Since ARP packets are "forwarded" only by Linux -bridges, the same may be achieved using -.B FORWARD -chain in -.BR ebtables . - -.SH MAILINGLISTS -.BR "" "See " http://netfilter.org/mailinglists.html -.SH SEE ALSO -.BR xtables-nft "(8), " iptables "(8), " ebtables "(8), " arp "(8), " rarp "(8), " ifconfig "(8), " route (8) -.PP -.BR "" "See " http://ebtables.sf.net diff --git a/SOURCES/ebtables.8 b/SOURCES/ebtables.8 deleted file mode 100644 index 67201b6..0000000 --- a/SOURCES/ebtables.8 +++ /dev/null @@ -1,1096 +0,0 @@ -.TH EBTABLES 8 "December 2011" -.\" -.\" Man page written by Bart De Schuymer -.\" It is based on the iptables man page. -.\" -.\" The man page was edited, February 25th 2003, by -.\" Greg Morgan <" dr_kludge_at_users_sourceforge_net > -.\" -.\" Iptables page by Herve Eychenne March 2000. -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.SH NAME -ebtables-nft \- Ethernet bridge frame table administration -.SH SYNOPSIS -.BR "ebtables " [ -t " table ] " - [ ACDI "] chain rule specification [match extensions] [watcher extensions] target" -.br -.BR "ebtables " [ -t " table ] " -P " chain " ACCEPT " | " DROP " | " RETURN -.br -.BR "ebtables " [ -t " table ] " -F " [chain]" -.br -.BR "ebtables " [ -t " table ] " -Z " [chain]" -.br -.BR "ebtables " [ -t " table ] " -L " [" -Z "] [chain] [ [" --Ln "] | [" --Lx "] ] [" --Lc "] [" --Lmac2 ] -.br -.BR "ebtables " [ -t " table ] " -N " chain [" "-P ACCEPT " | " DROP " | " RETURN" ] -.br -.BR "ebtables " [ -t " table ] " -X " [chain]" -.br -.BR "ebtables " [ -t " table ] " -E " old-chain-name new-chain-name" -.br -.BR "ebtables " [ -t " table ] " --init-table -.br -.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-commit -.br -.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-init -.br -.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-save -.br -.SH DESCRIPTION -.B ebtables -is an application program used to set up and maintain the -tables of rules (inside the Linux kernel) that inspect -Ethernet frames. -It is analogous to the -.B iptables -application, but less complicated, due to the fact that the Ethernet protocol -is much simpler than the IP protocol. -.SS CHAINS -There are two ebtables-nft tables with built-in chains in the -Linux kernel. These tables are used to divide functionality into -different sets of rules. Each set of rules is called a chain. -Each chain is an ordered list of rules that can match Ethernet frames. If a -rule matches an Ethernet frame, then a processing specification tells -what to do with that matching frame. The processing specification is -called a 'target'. However, if the frame does not match the current -rule in the chain, then the next rule in the chain is examined and so forth. -The user can create new (user-defined) chains that can be used as the 'target' -of a rule. User-defined chains are very useful to get better performance -over the linear traversal of the rules and are also essential for structuring -the filtering rules into well-organized and maintainable sets of rules. -.SS TARGETS -A firewall rule specifies criteria for an Ethernet frame and a frame -processing specification called a target. When a frame matches a rule, -then the next action performed by the kernel is specified by the target. -The target can be one of these values: -.BR ACCEPT , -.BR DROP , -.BR CONTINUE , -.BR RETURN , -an 'extension' (see below) or a jump to a user-defined chain. -.PP -.B ACCEPT -means to let the frame through. -.B DROP -means the frame has to be dropped. -.B CONTINUE -means the next rule has to be checked. This can be handy, f.e., to know how many -frames pass a certain point in the chain, to log those frames or to apply multiple -targets on a frame. -.B RETURN -means stop traversing this chain and resume at the next rule in the -previous (calling) chain. -For the extension targets please refer to the -.B "TARGET EXTENSIONS" -section of this man page. -.SS TABLES -As stated earlier, there are two ebtables-nft tables in the Linux -kernel. The table names are -.BR filter " and " nat . -Of these two tables, -the filter table is the default table that the command operates on. -If you are working with the filter table, then you can drop the '-t filter' -argument to the ebtables command. However, you will need to provide -the -t argument for -.B nat -table. Moreover, the -t argument must be the -first argument on the ebtables command line, if used. -.TP -.B "-t, --table" -.br -.B filter -is the default table and contains three built-in chains: -.B INPUT -(for frames destined for the bridge itself, on the level of the MAC destination address), -.B OUTPUT -(for locally-generated or (b)routed frames) and -.B FORWARD -(for frames being forwarded by the bridge). -.br -.br -.B nat -is mostly used to change the mac addresses and contains three built-in chains: -.B PREROUTING -(for altering frames as soon as they come in), -.B OUTPUT -(for altering locally generated or (b)routed frames before they are bridged) and -.B POSTROUTING -(for altering frames as they are about to go out). A small note on the naming -of chains PREROUTING and POSTROUTING: it would be more accurate to call them -PREFORWARDING and POSTFORWARDING, but for all those who come from the -iptables world to ebtables it is easier to have the same names. Note that you -can change the name -.BR "" ( -E ) -if you don't like the default. -.SH EBTABLES COMMAND LINE ARGUMENTS -After the initial ebtables '-t table' command line argument, the remaining -arguments can be divided into several groups. These groups -are commands, miscellaneous commands, rule specifications, match extensions, -watcher extensions and target extensions. -.SS COMMANDS -The ebtables command arguments specify the actions to perform on the table -defined with the -t argument. If you do not use the -t argument to name -a table, the commands apply to the default filter table. -Only one command may be used on the command line at a time, except when -the commands -.BR -L " and " -Z -are combined, the commands -.BR -N " and " -P -are combined, or when -.B --atomic-file -is used. -.TP -.B "-A, --append" -Append a rule to the end of the selected chain. -.TP -.B "-D, --delete" -Delete the specified rule or rules from the selected chain. There are two ways to -use this command. The first is by specifying an interval of rule numbers -to delete (directly after -.BR -D ). -Syntax: \fIstart_nr\fP[\fI:end_nr\fP] (use -.B -L --Ln -to list the rules with their rule number). When \fIend_nr\fP is omitted, all rules starting -from \fIstart_nr\fP are deleted. Using negative numbers is allowed, for more -details about using negative numbers, see the -.B -I -command. The second usage is by -specifying the complete rule as it would have been specified when it was added. Only -the first encountered rule that is the same as this specified rule, in other -words the matching rule with the lowest (positive) rule number, is deleted. -.TP -.B "-C, --change-counters" -Change the counters of the specified rule or rules from the selected chain. There are two ways to -use this command. The first is by specifying an interval of rule numbers -to do the changes on (directly after -.BR -C ). -Syntax: \fIstart_nr\fP[\fI:end_nr\fP] (use -.B -L --Ln -to list the rules with their rule number). The details are the same as for the -.BR -D " command. The second usage is by" -specifying the complete rule as it would have been specified when it was added. Only -the counters of the first encountered rule that is the same as this specified rule, in other -words the matching rule with the lowest (positive) rule number, are changed. -In the first usage, the counters are specified directly after the interval specification, -in the second usage directly after -.BR -C . -First the packet counter is specified, then the byte counter. If the specified counters start -with a '+', the counter values are added to the respective current counter values. -If the specified counters start with a '-', the counter values are decreased from the respective -current counter values. No bounds checking is done. If the counters don't start with '+' or '-', -the current counters are changed to the specified counters. -.TP -.B "-I, --insert" -Insert the specified rule into the selected chain at the specified rule number. If the -rule number is not specified, the rule is added at the head of the chain. -If the current number of rules equals -.IR N , -then the specified number can be -between -.IR -N " and " N+1 . -For a positive number -.IR i , -it holds that -.IR i " and " i-N-1 -specify the same place in the chain where the rule should be inserted. The rule number -0 specifies the place past the last rule in the chain and using this number is therefore -equivalent to using the -.BR -A " command." -Rule numbers structly smaller than 0 can be useful when more than one rule needs to be inserted -in a chain. -.TP -.B "-P, --policy" -Set the policy for the chain to the given target. The policy can be -.BR ACCEPT ", " DROP " or " RETURN . -.TP -.B "-F, --flush" -Flush the selected chain. If no chain is selected, then every chain will be -flushed. Flushing a chain does not change the policy of the -chain, however. -.TP -.B "-Z, --zero" -Set the counters of the selected chain to zero. If no chain is selected, all the counters -are set to zero. The -.B "-Z" -command can be used in conjunction with the -.B "-L" -command. -When both the -.B "-Z" -and -.B "-L" -commands are used together in this way, the rule counters are printed on the screen -before they are set to zero. -.TP -.B "-L, --list" -List all rules in the selected chain. If no chain is selected, all chains -are listed. -.br -The following options change the output of the -.B "-L" -command. -.br -.B "--Ln" -.br -Places the rule number in front of every rule. This option is incompatible with the -.BR --Lx " option." -.br -.B "--Lc" -.br -Shows the counters at the end of each rule displayed by the -.B "-L" -command. Both a frame counter (pcnt) and a byte counter (bcnt) are displayed. -The frame counter shows how many frames have matched the specific rule, the byte -counter shows the sum of the frame sizes of these matching frames. Using this option -.BR "" "in combination with the " --Lx " option causes the counters to be written out" -.BR "" "in the '" -c " ' option format." -.br -.B "--Lx" -.br -Changes the output so that it produces a set of ebtables commands that construct -the contents of the chain, when specified. -If no chain is specified, ebtables commands to construct the contents of the -table are given, including commands for creating the user-defined chains (if any). -You can use this set of commands in an ebtables boot or reload -script. For example the output could be used at system startup. -The -.B "--Lx" -option is incompatible with the -.B "--Ln" -listing option. Using the -.BR --Lx " option together with the " --Lc " option will cause the counters to be written out" -.BR "" "in the '" -c " ' option format." -.br -.B "--Lmac2" -.br -Shows all MAC addresses with the same length, adding leading zeroes -if necessary. The default representation omits leading zeroes in the addresses. -.TP -.B "-N, --new-chain" -Create a new user-defined chain with the given name. The number of -user-defined chains is limited only by the number of possible chain names. -A user-defined chain name has a maximum -length of 31 characters. The standard policy of the user-defined chain is -ACCEPT. The policy of the new chain can be initialized to a different standard -target by using the -.B -P -command together with the -.B -N -command. In this case, the chain name does not have to be specified for the -.B -P -command. -.TP -.B "-X, --delete-chain" -Delete the specified user-defined chain. There must be no remaining references (jumps) -to the specified chain, otherwise ebtables will refuse to delete it. If no chain is -specified, all user-defined chains that aren't referenced will be removed. -.TP -.B "-E, --rename-chain" -Rename the specified chain to a new name. Besides renaming a user-defined -chain, you can rename a standard chain to a name that suits your -taste. For example, if you like PREFORWARDING more than PREROUTING, -then you can use the -E command to rename the PREROUTING chain. If you do -rename one of the standard ebtables chain names, please be sure to mention -this fact should you post a question on the ebtables mailing lists. -It would be wise to use the standard name in your post. Renaming a standard -ebtables chain in this fashion has no effect on the structure or functioning -of the ebtables kernel table. -.TP -.B "--init-table" -Replace the current table data by the initial table data. -.TP -.B "--atomic-init" -Copy the kernel's initial data of the table to the specified -file. This can be used as the first action, after which rules are added -to the file. The file can be specified using the -.B --atomic-file -command or through the -.IR EBTABLES_ATOMIC_FILE " environment variable." -.TP -.B "--atomic-save" -Copy the kernel's current data of the table to the specified -file. This can be used as the first action, after which rules are added -to the file. The file can be specified using the -.B --atomic-file -command or through the -.IR EBTABLES_ATOMIC_FILE " environment variable." -.TP -.B "--atomic-commit" -Replace the kernel table data with the data contained in the specified -file. This is a useful command that allows you to load all your rules of a -certain table into the kernel at once, saving the kernel a lot of precious -time and allowing atomic updates of the tables. The file which contains -the table data is constructed by using either the -.B "--atomic-init" -or the -.B "--atomic-save" -command to generate a starting file. After that, using the -.B "--atomic-file" -command when constructing rules or setting the -.IR EBTABLES_ATOMIC_FILE " environment variable" -allows you to extend the file and build the complete table before -committing it to the kernel. This command can be very useful in boot scripts -to populate the ebtables tables in a fast way. -.SS MISCELLANOUS COMMANDS -.TP -.B "-V, --version" -Show the version of the ebtables userspace program. -.TP -.BR "-h, --help " "[\fIlist of module names\fP]" -Give a brief description of the command syntax. Here you can also specify -names of extensions and ebtables will try to write help about those -extensions. E.g. -.IR "ebtables -h snat log ip arp" . -Specify -.I list_extensions -to list all extensions supported by the userspace -utility. -.TP -.BR "-j, --jump " "\fItarget\fP" -The target of the rule. This is one of the following values: -.BR ACCEPT , -.BR DROP , -.BR CONTINUE , -.BR RETURN , -a target extension (see -.BR "TARGET EXTENSIONS" ")" -or a user-defined chain name. -.TP -.B --atomic-file "\fIfile\fP" -Let the command operate on the specified -.IR file . -The data of the table to -operate on will be extracted from the file and the result of the operation -will be saved back into the file. If specified, this option should come -before the command specification. An alternative that should be preferred, -is setting the -.IR EBTABLES_ATOMIC_FILE " environment variable." -.TP -.B -M, --modprobe "\fIprogram\fP" -When talking to the kernel, use this -.I program -to try to automatically load missing kernel modules. -.TP -.B --concurrent -Use a file lock to support concurrent scripts updating the ebtables kernel tables. - -.SS -RULE SPECIFICATIONS -The following command line arguments make up a rule specification (as used -in the add and delete commands). A "!" option before the specification -inverts the test for that specification. Apart from these standard rule -specifications there are some other command line arguments of interest. -See both the -.BR "MATCH EXTENSIONS" -and the -.BR "WATCHER EXTENSIONS" -below. -.TP -.BR "-p, --protocol " "[!] \fIprotocol\fP" -The protocol that was responsible for creating the frame. This can be a -hexadecimal number, above -.IR 0x0600 , -a name (e.g. -.I ARP -) or -.BR LENGTH . -The protocol field of the Ethernet frame can be used to denote the -length of the header (802.2/802.3 networks). When the value of that field is -below or equals -.IR 0x0600 , -the value equals the size of the header and shouldn't be used as a -protocol number. Instead, all frames where the protocol field is used as -the length field are assumed to be of the same 'protocol'. The protocol -name used in ebtables for these frames is -.BR LENGTH . -.br -The file -.B /etc/ethertypes -can be used to show readable -characters instead of hexadecimal numbers for the protocols. For example, -.I 0x0800 -will be represented by -.IR IPV4 . -The use of this file is not case sensitive. -See that file for more information. The flag -.B --proto -is an alias for this option. -.TP -.BR "-i, --in-interface " "[!] \fIname\fP" -The interface (bridge port) via which a frame is received (this option is useful in the -.BR INPUT , -.BR FORWARD , -.BR PREROUTING " and " BROUTING -chains). If the interface name ends with '+', then -any interface name that begins with this name (disregarding '+') will match. -The flag -.B --in-if -is an alias for this option. -.TP -.BR "--logical-in " "[!] \fIname\fP" -The (logical) bridge interface via which a frame is received (this option is useful in the -.BR INPUT , -.BR FORWARD , -.BR PREROUTING " and " BROUTING -chains). -If the interface name ends with '+', then -any interface name that begins with this name (disregarding '+') will match. -.TP -.BR "-o, --out-interface " "[!] \fIname\fP" -The interface (bridge port) via which a frame is going to be sent (this option is useful in the -.BR OUTPUT , -.B FORWARD -and -.B POSTROUTING -chains). If the interface name ends with '+', then -any interface name that begins with this name (disregarding '+') will match. -The flag -.B --out-if -is an alias for this option. -.TP -.BR "--logical-out " "[!] \fIname\fP" -The (logical) bridge interface via which a frame is going to be sent (this option -is useful in the -.BR OUTPUT , -.B FORWARD -and -.B POSTROUTING -chains). -If the interface name ends with '+', then -any interface name that begins with this name (disregarding '+') will match. -.TP -.BR "-s, --source " "[!] \fIaddress\fP[/\fImask\fP]" -The source MAC address. Both mask and address are written as 6 hexadecimal -numbers separated by colons. Alternatively one can specify Unicast, -Multicast, Broadcast or BGA (Bridge Group Address): -.br -.IR "Unicast" "=00:00:00:00:00:00/01:00:00:00:00:00," -.IR "Multicast" "=01:00:00:00:00:00/01:00:00:00:00:00," -.IR "Broadcast" "=ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff or" -.IR "BGA" "=01:80:c2:00:00:00/ff:ff:ff:ff:ff:ff." -Note that a broadcast -address will also match the multicast specification. The flag -.B --src -is an alias for this option. -.TP -.BR "-d, --destination " "[!] \fIaddress\fP[/\fImask\fP]" -The destination MAC address. See -.B -s -(above) for more details on MAC addresses. The flag -.B --dst -is an alias for this option. -.TP -.BR "-c, --set-counter " "\fIpcnt bcnt\fP" -If used with -.BR -A " or " -I ", then the packet and byte counters of the new rule will be set to -.IR pcnt ", resp. " bcnt ". -If used with the -.BR -C " or " -D " commands, only rules with a packet and byte count equal to" -.IR pcnt ", resp. " bcnt " will match." - -.SS MATCH EXTENSIONS -Ebtables extensions are dynamically loaded into the userspace tool, -there is therefore no need to explicitly load them with a --m option like is done in iptables. -These extensions deal with functionality supported by kernel modules supplemental to -the core ebtables code. -.SS 802_3 -Specify 802.3 DSAP/SSAP fields or SNAP type. The protocol must be specified as -.IR "LENGTH " "(see the option " " -p " above). -.TP -.BR "--802_3-sap " "[!] \fIsap\fP" -DSAP and SSAP are two one byte 802.3 fields. The bytes are always -equal, so only one byte (hexadecimal) is needed as an argument. -.TP -.BR "--802_3-type " "[!] \fItype\fP" -If the 802.3 DSAP and SSAP values are 0xaa then the SNAP type field must -be consulted to determine the payload protocol. This is a two byte -(hexadecimal) argument. Only 802.3 frames with DSAP/SSAP 0xaa are -checked for type. -.SS among -Match a MAC address or MAC/IP address pair versus a list of MAC addresses -and MAC/IP address pairs. -A list entry has the following format: -.IR xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip][,] ". Multiple" -list entries are separated by a comma, specifying an IP address corresponding to -the MAC address is optional. Multiple MAC/IP address pairs with the same MAC address -but different IP address (and vice versa) can be specified. If the MAC address doesn't -match any entry from the list, the frame doesn't match the rule (unless "!" was used). -.TP -.BR "--among-dst " "[!] \fIlist\fP" -Compare the MAC destination to the given list. If the Ethernet frame has type -.IR IPv4 " or " ARP , -then comparison with MAC/IP destination address pairs from the -list is possible. -.TP -.BR "--among-src " "[!] \fIlist\fP" -Compare the MAC source to the given list. If the Ethernet frame has type -.IR IPv4 " or " ARP , -then comparison with MAC/IP source address pairs from the list -is possible. -.TP -.BR "--among-dst-file " "[!] \fIfile\fP" -Same as -.BR --among-dst " but the list is read in from the specified file." -.TP -.BR "--among-src-file " "[!] \fIfile\fP" -Same as -.BR --among-src " but the list is read in from the specified file." -.SS arp -Specify (R)ARP fields. The protocol must be specified as -.IR ARP " or " RARP . -.TP -.BR "--arp-opcode " "[!] \fIopcode\fP" -The (R)ARP opcode (decimal or a string, for more details see -.BR "ebtables -h arp" ). -.TP -.BR "--arp-htype " "[!] \fIhardware type\fP" -The hardware type, this can be a decimal or the string -.I Ethernet -(which sets -.I type -to 1). Most (R)ARP packets have Eternet as hardware type. -.TP -.BR "--arp-ptype " "[!] \fIprotocol type\fP" -The protocol type for which the (r)arp is used (hexadecimal or the string -.IR IPv4 , -denoting 0x0800). -Most (R)ARP packets have protocol type IPv4. -.TP -.BR "--arp-ip-src " "[!] \fIaddress\fP[/\fImask\fP]" -The (R)ARP IP source address specification. -.TP -.BR "--arp-ip-dst " "[!] \fIaddress\fP[/\fImask\fP]" -The (R)ARP IP destination address specification. -.TP -.BR "--arp-mac-src " "[!] \fIaddress\fP[/\fImask\fP]" -The (R)ARP MAC source address specification. -.TP -.BR "--arp-mac-dst " "[!] \fIaddress\fP[/\fImask\fP]" -The (R)ARP MAC destination address specification. -.TP -.BR "" "[!]" " --arp-gratuitous" -Checks for ARP gratuitous packets: checks equality of IPv4 source -address and IPv4 destination address inside the ARP header. -.SS ip -Specify IPv4 fields. The protocol must be specified as -.IR IPv4 . -.TP -.BR "--ip-source " "[!] \fIaddress\fP[/\fImask\fP]" -The source IP address. -The flag -.B --ip-src -is an alias for this option. -.TP -.BR "--ip-destination " "[!] \fIaddress\fP[/\fImask\fP]" -The destination IP address. -The flag -.B --ip-dst -is an alias for this option. -.TP -.BR "--ip-tos " "[!] \fItos\fP" -The IP type of service, in hexadecimal numbers. -.BR IPv4 . -.TP -.BR "--ip-protocol " "[!] \fIprotocol\fP" -The IP protocol. -The flag -.B --ip-proto -is an alias for this option. -.TP -.BR "--ip-source-port " "[!] \fIport1\fP[:\fIport2\fP]" -The source port or port range for the IP protocols 6 (TCP), 17 -(UDP), 33 (DCCP) or 132 (SCTP). The -.B --ip-protocol -option must be specified as -.IR TCP ", " UDP ", " DCCP " or " SCTP . -If -.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used." -The flag -.B --ip-sport -is an alias for this option. -.TP -.BR "--ip-destination-port " "[!] \fIport1\fP[:\fIport2\fP]" -The destination port or port range for ip protocols 6 (TCP), 17 -(UDP), 33 (DCCP) or 132 (SCTP). The -.B --ip-protocol -option must be specified as -.IR TCP ", " UDP ", " DCCP " or " SCTP . -If -.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used." -The flag -.B --ip-dport -is an alias for this option. -.SS ip6 -Specify IPv6 fields. The protocol must be specified as -.IR IPv6 . -.TP -.BR "--ip6-source " "[!] \fIaddress\fP[/\fImask\fP]" -The source IPv6 address. -The flag -.B --ip6-src -is an alias for this option. -.TP -.BR "--ip6-destination " "[!] \fIaddress\fP[/\fImask\fP]" -The destination IPv6 address. -The flag -.B --ip6-dst -is an alias for this option. -.TP -.BR "--ip6-tclass " "[!] \fItclass\fP" -The IPv6 traffic class, in hexadecimal numbers. -.TP -.BR "--ip6-protocol " "[!] \fIprotocol\fP" -The IP protocol. -The flag -.B --ip6-proto -is an alias for this option. -.TP -.BR "--ip6-source-port " "[!] \fIport1\fP[:\fIport2\fP]" -The source port or port range for the IPv6 protocols 6 (TCP), 17 -(UDP), 33 (DCCP) or 132 (SCTP). The -.B --ip6-protocol -option must be specified as -.IR TCP ", " UDP ", " DCCP " or " SCTP . -If -.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used." -The flag -.B --ip6-sport -is an alias for this option. -.TP -.BR "--ip6-destination-port " "[!] \fIport1\fP[:\fIport2\fP]" -The destination port or port range for IPv6 protocols 6 (TCP), 17 -(UDP), 33 (DCCP) or 132 (SCTP). The -.B --ip6-protocol -option must be specified as -.IR TCP ", " UDP ", " DCCP " or " SCTP . -If -.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used." -The flag -.B --ip6-dport -is an alias for this option. -.TP -.BR "--ip6-icmp-type " "[!] {\fItype\fP[:\fItype\fP]/\fIcode\fP[:\fIcode\fP]|\fItypename\fP}" -Specify ipv6\-icmp type and code to match. -Ranges for both type and code are supported. Type and code are -separated by a slash. Valid numbers for type and range are 0 to 255. -To match a single type including all valid codes, symbolic names can -be used instead of numbers. The list of known type names is shown by the command -.nf - ebtables \-\-help ip6 -.fi -This option is only valid for \-\-ip6-prococol ipv6-icmp. -.SS limit -This module matches at a limited rate using a token bucket filter. -A rule using this extension will match until this limit is reached. -It can be used with the -.B --log -watcher to give limited logging, for example. Its use is the same -as the limit match of iptables. -.TP -.BR "--limit " "[\fIvalue\fP]" -Maximum average matching rate: specified as a number, with an optional -.IR /second ", " /minute ", " /hour ", or " /day " suffix; the default is " 3/hour . -.TP -.BR "--limit-burst " "[\fInumber\fP]" -Maximum initial number of packets to match: this number gets recharged by -one every time the limit specified above is not reached, up to this -number; the default is -.IR 5 . -.SS mark_m -.TP -.BR "--mark " "[!] [\fIvalue\fP][/\fImask\fP]" -Matches frames with the given unsigned mark value. If a -.IR value " and " mask " are specified, the logical AND of the mark value of the frame and" -the user-specified -.IR mask " is taken before comparing it with the" -user-specified mark -.IR value ". When only a mark " -.IR value " is specified, the packet" -only matches when the mark value of the frame equals the user-specified -mark -.IR value . -If only a -.IR mask " is specified, the logical" -AND of the mark value of the frame and the user-specified -.IR mask " is taken and the frame matches when the result of this logical AND is" -non-zero. Only specifying a -.IR mask " is useful to match multiple mark values." -.SS pkttype -.TP -.BR "--pkttype-type " "[!] \fItype\fP" -Matches on the Ethernet "class" of the frame, which is determined by the -generic networking code. Possible values: -.IR broadcast " (MAC destination is the broadcast address)," -.IR multicast " (MAC destination is a multicast address)," -.IR host " (MAC destination is the receiving network device), or " -.IR otherhost " (none of the above)." -.SS stp -Specify stp BPDU (bridge protocol data unit) fields. The destination -address -.BR "" ( -d ") must be specified as the bridge group address" -.IR "" ( BGA ). -For all options for which a range of values can be specified, it holds that -if the lower bound is omitted (but the colon is not), then the lowest possible lower bound -for that option is used, while if the upper bound is omitted (but the colon again is not), the -highest possible upper bound for that option is used. -.TP -.BR "--stp-type " "[!] \fItype\fP" -The BPDU type (0-255), recognized non-numerical types are -.IR config ", denoting a configuration BPDU (=0), and" -.IR tcn ", denothing a topology change notification BPDU (=128)." -.TP -.BR "--stp-flags " "[!] \fIflag\fP" -The BPDU flag (0-255), recognized non-numerical flags are -.IR topology-change ", denoting the topology change flag (=1), and" -.IR topology-change-ack ", denoting the topology change acknowledgement flag (=128)." -.TP -.BR "--stp-root-prio " "[!] [\fIprio\fP][:\fIprio\fP]" -The root priority (0-65535) range. -.TP -.BR "--stp-root-addr " "[!] [\fIaddress\fP][/\fImask\fP]" -The root mac address, see the option -.BR -s " for more details." -.TP -.BR "--stp-root-cost " "[!] [\fIcost\fP][:\fIcost\fP]" -The root path cost (0-4294967295) range. -.TP -.BR "--stp-sender-prio " "[!] [\fIprio\fP][:\fIprio\fP]" -The BPDU's sender priority (0-65535) range. -.TP -.BR "--stp-sender-addr " "[!] [\fIaddress\fP][/\fImask\fP]" -The BPDU's sender mac address, see the option -.BR -s " for more details." -.TP -.BR "--stp-port " "[!] [\fIport\fP][:\fIport\fP]" -The port identifier (0-65535) range. -.TP -.BR "--stp-msg-age " "[!] [\fIage\fP][:\fIage\fP]" -The message age timer (0-65535) range. -.TP -.BR "--stp-max-age " "[!] [\fIage\fP][:\fIage\fP]" -The max age timer (0-65535) range. -.TP -.BR "--stp-hello-time " "[!] [\fItime\fP][:\fItime\fP]" -The hello time timer (0-65535) range. -.TP -.BR "--stp-forward-delay " "[!] [\fIdelay\fP][:\fIdelay\fP]" -The forward delay timer (0-65535) range. -.SS vlan -Specify 802.1Q Tag Control Information fields. -The protocol must be specified as -.IR 802_1Q " (0x8100)." -.TP -.BR "--vlan-id " "[!] \fIid\fP" -The VLAN identifier field (VID). Decimal number from 0 to 4095. -.TP -.BR "--vlan-prio " "[!] \fIprio\fP" -The user priority field, a decimal number from 0 to 7. -The VID should be set to 0 ("null VID") or unspecified -(in the latter case the VID is deliberately set to 0). -.TP -.BR "--vlan-encap " "[!] \fItype\fP" -The encapsulated Ethernet frame type/length. -Specified as a hexadecimal -number from 0x0000 to 0xFFFF or as a symbolic name -from -.BR /etc/ethertypes . - -.SS WATCHER EXTENSIONS -Watchers only look at frames passing by, they don't modify them nor decide -to accept the frames or not. These watchers only -see the frame if the frame matches the rule, and they see it before the -target is executed. -.SS log -The log watcher writes descriptive data about a frame to the syslog. -.TP -.B "--log" -.br -Log with the default loggin options: log-level= -.IR info , -log-prefix="", no ip logging, no arp logging. -.TP -.B --log-level "\fIlevel\fP" -.br -Defines the logging level. For the possible values, see -.BR "ebtables -h log" . -The default level is -.IR info . -.TP -.BR --log-prefix " \fItext\fP" -.br -Defines the prefix -.I text -to be printed at the beginning of the line with the logging information. -.TP -.B --log-ip -.br -Will log the ip information when a frame made by the ip protocol matches -the rule. The default is no ip information logging. -.TP -.B --log-ip6 -.br -Will log the ipv6 information when a frame made by the ipv6 protocol matches -the rule. The default is no ipv6 information logging. -.TP -.B --log-arp -.br -Will log the (r)arp information when a frame made by the (r)arp protocols -matches the rule. The default is no (r)arp information logging. -.SS nflog -The nflog watcher passes the packet to the loaded logging backend -in order to log the packet. This is usually used in combination with -nfnetlink_log as logging backend, which will multicast the packet -through a -.IR netlink -socket to the specified multicast group. One or more userspace processes -may subscribe to the group to receive the packets. -.TP -.B "--nflog" -.br -Log with the default logging options -.TP -.B --nflog-group "\fInlgroup\fP" -.br -The netlink group (1 - 2^32-1) to which packets are (only applicable for -nfnetlink_log). The default value is 1. -.TP -.B --nflog-prefix "\fIprefix\fP" -.br -A prefix string to include in the log message, up to 30 characters -long, useful for distinguishing messages in the logs. -.TP -.B --nflog-range "\fIsize\fP" -.br -The number of bytes to be copied to userspace (only applicable for -nfnetlink_log). nfnetlink_log instances may specify their own -range, this option overrides it. -.TP -.B --nflog-threshold "\fIsize\fP" -.br -Number of packets to queue inside the kernel before sending them -to userspace (only applicable for nfnetlink_log). Higher values -result in less overhead per packet, but increase delay until the -packets reach userspace. The default value is 1. -.SS ulog -The ulog watcher passes the packet to a userspace -logging daemon using netlink multicast sockets. This differs -from the log watcher in the sense that the complete packet is -sent to userspace instead of a descriptive text and that -netlink multicast sockets are used instead of the syslog. -This watcher enables parsing of packets with userspace programs, the -physical bridge in and out ports are also included in the netlink messages. -The ulog watcher module accepts 2 parameters when the module is loaded -into the kernel (e.g. with modprobe): -.B nlbufsiz -specifies how big the buffer for each netlink multicast -group is. If you say -.IR nlbufsiz=8192 , -for example, up to eight kB of packets will -get accumulated in the kernel until they are sent to userspace. It is -not possible to allocate more than 128kB. Please also keep in mind that -this buffer size is allocated for each nlgroup you are using, so the -total kernel memory usage increases by that factor. The default is 4096. -.B flushtimeout -specifies after how many hundredths of a second the queue should be -flushed, even if it is not full yet. The default is 10 (one tenth of -a second). -.TP -.B "--ulog" -.br -Use the default settings: ulog-prefix="", ulog-nlgroup=1, -ulog-cprange=4096, ulog-qthreshold=1. -.TP -.B --ulog-prefix "\fItext\fP" -.br -Defines the prefix included with the packets sent to userspace. -.TP -.BR --ulog-nlgroup " \fIgroup\fP" -.br -Defines which netlink group number to use (a number from 1 to 32). -Make sure the netlink group numbers used for the iptables ULOG -target differ from those used for the ebtables ulog watcher. -The default group number is 1. -.TP -.BR --ulog-cprange " \fIrange\fP" -.br -Defines the maximum copy range to userspace, for packets matching the -rule. The default range is 0, which means the maximum copy range is -given by -.BR nlbufsiz . -A maximum copy range larger than -128*1024 is meaningless as the packets sent to userspace have an upper -size limit of 128*1024. -.TP -.BR --ulog-qthreshold " \fIthreshold\fP" -.br -Queue at most -.I threshold -number of packets before sending them to -userspace with a netlink socket. Note that packets can be sent to -userspace before the queue is full, this happens when the ulog -kernel timer goes off (the frequency of this timer depends on -.BR flushtimeout ). -.SS TARGET EXTENSIONS -.SS arpreply -The -.B arpreply -target can be used in the -.BR PREROUTING " chain of the " nat " table." -If this target sees an ARP request it will automatically reply -with an ARP reply. The used MAC address for the reply can be specified. -The protocol must be specified as -.IR ARP . -When the ARP message is not an ARP request or when the ARP request isn't -for an IP address on an Ethernet network, it is ignored by this target -.BR "" ( CONTINUE ). -When the ARP request is malformed, it is dropped -.BR "" ( DROP ). -.TP -.BR "--arpreply-mac " "\fIaddress\fP" -Specifies the MAC address to reply with: the Ethernet source MAC and the -ARP payload source MAC will be filled in with this address. -.TP -.BR "--arpreply-target " "\fItarget\fP" -Specifies the standard target. After sending the ARP reply, the rule still -has to give a standard target so ebtables knows what to do with the ARP request. -The default target -.BR "" "is " DROP . -.SS dnat -The -.B dnat -target can only be used in the -.BR PREROUTING " and " OUTPUT " chains of the " nat " table." -It specifies that the destination MAC address has to be changed. -.TP -.BR "--to-destination " "\fIaddress\fP" -.br -Change the destination MAC address to the specified -.IR address . -The flag -.B --to-dst -is an alias for this option. -.TP -.BR "--dnat-target " "\fItarget\fP" -.br -Specifies the standard target. After doing the dnat, the rule still has to -give a standard target so ebtables knows what to do with the dnated frame. -The default target is -.BR ACCEPT . -Making it -.BR CONTINUE " could let you use" -multiple target extensions on the same frame. Making it -.BR DROP " only makes" -sense in the -.BR BROUTING " chain but using the " redirect " target is more logical there. " RETURN " is also allowed. Note that using " RETURN -in a base chain is not allowed (for obvious reasons). -.SS mark -.BR "" "The " mark " target can be used in every chain of every table. It is possible" -to use the marking of a frame/packet in both ebtables and iptables, -if the bridge-nf code is compiled into the kernel. Both put the marking at the -same place. This allows for a form of communication between ebtables and iptables. -.TP -.BR "--mark-set " "\fIvalue\fP" -.br -Mark the frame with the specified non-negative -.IR value . -.TP -.BR "--mark-or " "\fIvalue\fP" -.br -Or the frame with the specified non-negative -.IR value . -.TP -.BR "--mark-and " "\fIvalue\fP" -.br -And the frame with the specified non-negative -.IR value . -.TP -.BR "--mark-xor " "\fIvalue\fP" -.br -Xor the frame with the specified non-negative -.IR value . -.TP -.BR "--mark-target " "\fItarget\fP" -.br -Specifies the standard target. After marking the frame, the rule -still has to give a standard target so ebtables knows what to do. -The default target is -.BR ACCEPT ". Making it " CONTINUE " can let you do other" -things with the frame in subsequent rules of the chain. -.SS redirect -The -.B redirect -target will change the MAC target address to that of the bridge device the -frame arrived on. This target can only be used in the -.BR PREROUTING " chain of the " nat " table." -The MAC address of the bridge is used as destination address." -.TP -.BR "--redirect-target " "\fItarget\fP" -.br -Specifies the standard target. After doing the MAC redirect, the rule -still has to give a standard target so ebtables knows what to do. -The default target is -.BR ACCEPT ". Making it " CONTINUE " could let you use" -multiple target extensions on the same frame. Making it -.BR DROP " in the " BROUTING " chain will let the frames be routed. " RETURN " is also allowed. Note" -.BR "" "that using " RETURN " in a base chain is not allowed." -.SS snat -The -.B snat -target can only be used in the -.BR POSTROUTING " chain of the " nat " table." -It specifies that the source MAC address has to be changed. -.TP -.BR "--to-source " "\fIaddress\fP" -.br -Changes the source MAC address to the specified -.IR address ". The flag" -.B --to-src -is an alias for this option. -.TP -.BR "--snat-target " "\fItarget\fP" -.br -Specifies the standard target. After doing the snat, the rule still has -to give a standard target so ebtables knows what to do. -.BR "" "The default target is " ACCEPT ". Making it " CONTINUE " could let you use" -.BR "" "multiple target extensions on the same frame. Making it " DROP " doesn't" -.BR "" "make sense, but you could do that too. " RETURN " is also allowed. Note" -.BR "" "that using " RETURN " in a base chain is not allowed." -.br -.TP -.BR "--snat-arp " -.br -Also change the hardware source address inside the arp header if the packet is an -arp message and the hardware address length in the arp header is 6 bytes. -.br -.SH FILES -.I /etc/ethertypes -.I /run/ebtables.lock -.SH ENVIRONMENT VARIABLES -.I EBTABLES_ATOMIC_FILE -.SH MAILINGLISTS -.BR "" "See " http://netfilter.org/mailinglists.html -.SH BUGS -The version of ebtables this man page ships with does not support the -.B broute -table. Also there is no support for the -.B among -match. And finally, this list is probably not complete. -.SH SEE ALSO -.BR xtables-nft "(8), " iptables "(8), " brctl "(8), " ifconfig "(8), " route (8) -.PP -.BR "" "See " http://ebtables.sf.net diff --git a/SPECS/iptables.spec b/SPECS/iptables.spec index 7f70aea..6168a67 100644 --- a/SPECS/iptables.spec +++ b/SPECS/iptables.spec @@ -4,11 +4,21 @@ # service legacy actions (RHBZ#748134) %global legacy_actions %{_libexecdir}/initscripts/legacy-actions +# boostrap mode to assist in libip{4,6}tc SONAME bump +%global bootstrap 1 + +%if 0%{?bootstrap} +%global version_old 1.8.2 +%global iptc_so_ver_old 0 +%endif +%global iptc_so_ver 2 + Name: iptables Summary: Tools for managing Linux kernel packet filtering capabilities -Version: 1.8.2 -Release: 12%{?dist} -Source: http://www.netfilter.org/projects/iptables/files/%{name}-%{version}.tar.bz2 +URL: http://www.netfilter.org/projects/iptables +Version: 1.8.4 +Release: 6%{?dist} +Source: %{url}/files/%{name}-%{version}.tar.bz2 Source1: iptables.init Source2: iptables-config Source3: iptables.service @@ -19,73 +29,21 @@ Source7: arptables-helper Source8: ebtables.systemd Source9: ebtables.service Source10: ebtables-config -Source11: ebtables.8 -Source12: arptables.8 -Patch1: 0001-Add-iptables-test.py-testsuite-from-v1.8.2.patch -Patch2: 0002-iptables-apply-Use-mktemp-instead-of-tempfile.patch -Patch3: 0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch -Patch4: 0004-arptables-nft-use-generic-expression-parsing-functio.patch -Patch5: 0005-xtables-Don-t-use-native-nftables-comments.patch -Patch6: 0006-xtables-Introduce-per-table-chain-caches.patch -Patch7: 0007-nft-add-type-field-to-builtin_table.patch -Patch8: 0008-nft-move-chain_cache-back-to-struct-nft_handle.patch -Patch9: 0009-nft-move-initialize-to-struct-nft_handle.patch -Patch10: 0010-xtables-constify-struct-builtin_table-and-struct-bui.patch -Patch11: 0011-nft-Simplify-nftnl_rule_list_chain_save.patch -Patch12: 0012-nft-Review-unclear-return-points.patch -Patch13: 0013-xtables-restore-Review-chain-handling.patch -Patch14: 0014-nft-Review-is_-_compatible-routines.patch -Patch15: 0015-nft-Reduce-__nft_rule_del-signature.patch -Patch16: 0016-nft-Reduce-indenting-level-in-flush_chain_cache.patch -Patch17: 0017-nft-Simplify-per-table-chain-cache-update.patch -Patch18: 0018-nft-Simplify-nft_rule_insert-a-bit.patch -Patch19: 0019-nft-Introduce-fetch_chain_cache.patch -Patch20: 0020-nft-Move-nft_rule_list_get-above-nft_chain_list_get.patch -Patch21: 0021-xtables-Implement-per-chain-rule-cache.patch -Patch22: 0022-nft-Drop-nft_chain_list_find.patch -Patch23: 0023-xtables-Optimize-flushing-a-specific-chain.patch -Patch24: 0024-xtables-Optimize-nft_chain_zero_counters.patch -Patch25: 0025-tests-Extend-verbose-output-and-return-code-tests.patch -Patch26: 0026-xtables-Optimize-user-defined-chain-deletion.patch -Patch27: 0027-xtables-Optimize-list-command-with-given-chain.patch -Patch28: 0028-xtables-Optimize-list-rules-command-with-given-chain.patch -Patch29: 0029-nft-Make-use-of-nftnl_rule_lookup_byindex.patch -Patch30: 0030-nft-Simplify-nft_is_chain_compatible.patch -Patch31: 0031-nft-Simplify-flush_chain_cache.patch -Patch32: 0032-xtables-Set-errno-in-nft_rule_check-if-chain-not-fou.patch -Patch33: 0033-xtables-Speed-up-chain-deletion-in-large-rulesets.patch -Patch34: 0034-arptables-nft-Fix-listing-rules-without-target.patch -Patch35: 0035-arptables-nft-Fix-MARK-target-parsing-and-printing.patch -Patch36: 0036-arptables-nft-Fix-CLASSIFY-target-printing.patch -Patch37: 0037-arptables-nft-Remove-space-between-cnt-and-value.patch -Patch38: 0038-arptables-nft-save-Fix-position-of-j-option.patch -Patch39: 0039-arptables-nft-Don-t-print-default-h-len-h-type-value.patch -Patch40: 0040-tests-shell-Add-arptables-nft-verbose-output-test.patch -Patch41: 0041-arptables-nft-Set-h-type-h-length-masks-by-default-t.patch -Patch42: 0042-nft-Add-new-builtin-chains-to-cache-immediately.patch -Patch43: 0043-xtables-Fix-position-of-replaced-rules-in-cache.patch -Patch44: 0044-xtables-Fix-for-inserting-rule-at-wrong-position.patch -Patch45: 0045-xtables-Fix-for-crash-when-comparing-rules-with-stan.patch -Patch46: 0046-xtables-Fix-for-false-positive-rule-matching.patch -Patch47: 0047-ebtables-Fix-rule-listing-with-counters.patch -Patch48: 0048-Revert-ebtables-use-extrapositioned-negation-consist.patch -Patch49: 0049-arptables-Support-set-counters-option.patch -Patch50: 0050-xshared-Explicitly-pass-target-to-command_jump.patch -Patch51: 0051-nft-Don-t-assume-NFTNL_RULE_USERDATA-holds-a-comment.patch -Patch52: 0052-nft-Introduce-UDATA_TYPE_EBTABLES_POLICY.patch -Patch53: 0053-ebtables-nft-Support-user-defined-chain-policies.patch -Patch54: 0054-extensions-libipt_realm-Document-allowed-realm-value.patch -Patch55: 0055-extensions-TRACE-Point-at-xtables-monitor-in-documen.patch -Patch56: 0056-xtables-Catch-errors-when-zeroing-rule-rounters.patch -Patch57: 0057-xtables-save-Fix-table-not-found-error-message.patch -Patch58: 0058-arptables-nft-fix-decoding-of-hlen-on-bigendian-plat.patch -Patch59: 0059-extensions-libip6t_mh-fix-bogus-translation-error.patch -Patch60: 0060-xtables-save-Point-at-existing-man-page-in-help-text.patch -Patch61: 0061-xtables-restore-Fix-program-names-in-help-texts.patch -Patch62: 0062-extensions-AUDIT-Document-ineffective-type-option.patch -Patch63: 0063-utils-Add-a-manpage-for-nfbpf_compile.patch - -URL: http://www.netfilter.org/ +%if 0%{?bootstrap} +Source11: %{url}/files/%{name}-%{version_old}.tar.bz2 +Source12: 0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch +%endif + +Patch1: 0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch +Patch2: 0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch +Patch3: 0003-xtables-restore-Avoid-access-of-uninitialized-data.patch +Patch4: 0004-extensions-time-Avoid-undefined-shift.patch +Patch5: 0005-extensions-cluster-Avoid-undefined-shift.patch +Patch6: 0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch +Patch7: 0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch +Patch8: 0008-extensions-among-Check-call-to-fstat.patch +Patch9: 0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch + # pf.os: ISC license # iptables-apply: Artistic Licence 2.0 License: GPLv2 and Artistic 2.0 and ISC @@ -102,7 +60,7 @@ BuildRequires: bison BuildRequires: flex BuildRequires: gcc BuildRequires: pkgconfig(libmnl) >= 1.0 -BuildRequires: pkgconfig(libnftnl) >= 1.1.1-4 +BuildRequires: pkgconfig(libnftnl) >= 1.1.5-1 # libpcap-devel for nfbpf_compile BuildRequires: libpcap-devel BuildRequires: autoconf @@ -216,6 +174,14 @@ replacement of the legacy tool. %prep %autosetup -p1 +%if 0%{?bootstrap} +%{__mkdir} -p bootstrap_ver +pushd bootstrap_ver +%{__tar} --strip-components=1 -xf %{SOURCE11} +%{__patch} -p1 <%{SOURCE12} +popd +%endif + %build ./autogen.sh CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing " \ @@ -229,7 +195,31 @@ rm -f include/linux/types.h make %{?_smp_mflags} V=1 +%if 0%{?bootstrap} +pushd bootstrap_ver +./autogen.sh +CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing " \ +%configure --enable-devel --enable-bpf-compiler --with-kernel=/usr --with-kbuild=/usr --with-ksource=/usr + +# do not use rpath +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +rm -f include/linux/types.h + +make %{?_smp_mflags} V=1 +popd +%endif + %install +%if 0%{?bootstrap} +%make_install -C bootstrap_ver +find %{buildroot} -xtype f -not \ + -name 'libip*tc.so.%{iptc_so_ver_old}*' -delete -print +find %{buildroot} -type l -not \ + -name 'libip*tc.so.%{iptc_so_ver_old}*' -delete -print +%endif + make install DESTDIR=%{buildroot} # remove la file(s) rm -f %{buildroot}/%{_libdir}/*.la @@ -310,15 +300,17 @@ mkdir -p %{buildroot}%{_libexecdir}/ install -p -D -m 755 %{SOURCE7} %{buildroot}%{_libexecdir}/ mkdir -p %{buildroot}%{_sysconfdir}/sysconfig echo '# Configure prior to use' > %{buildroot}%{_sysconfdir}/sysconfig/arptables -install -m0644 %{SOURCE12} %{buildroot}%{_mandir}/man8/arptables.8 +for sfx in "" "-restore" "-save"; do + echo '.so man8/arptables-nft${sfx}.8' > \ + %{buildroot}%{_mandir}/man8/arptables${sfx}.8 +done # extra sources for ebtables install -p %{SOURCE9} %{buildroot}%{_unitdir}/ install -m0755 %{SOURCE8} %{buildroot}%{_libexecdir}/ebtables install -m0600 %{SOURCE10} %{buildroot}%{_sysconfdir}/sysconfig/ebtables-config touch %{buildroot}%{_sysconfdir}/sysconfig/ebtables -install -m0644 %{SOURCE11} %{buildroot}%{_mandir}/man8/ebtables.8 - +echo '.so man8/ebtables-nft.8' > %{buildroot}%{_mandir}/man8/ebtables.8 %if 0%{?rhel} %pre @@ -389,7 +381,8 @@ done %doc %{_mandir}/man8/ip6tables* %doc %{_mandir}/man8/xtables-monitor* %doc %{_mandir}/man8/xtables-nft* -%doc %{_mandir}/man8/xtables-translate* +%doc %{_mandir}/man8/*tables-translate* +%doc %{_mandir}/man8/*tables-restore-translate* %dir %{_libdir}/xtables %{_libdir}/xtables/libarpt* %{_libdir}/xtables/libebt* @@ -398,8 +391,11 @@ done %{_libdir}/xtables/libxt* %files libs -%{_libdir}/libip*tc.so.* -%{_libdir}/libxtables.so.* +%{_libdir}/libip*tc.so.%{iptc_so_ver}* +%if 0%{?bootstrap} +%{_libdir}/libip*tc.so.%{iptc_so_ver_old}* +%endif +%{_libdir}/libxtables.so.12* %files devel %dir %{_includedir}/iptables @@ -444,7 +440,7 @@ done %{_libexecdir}/arptables-helper %{_unitdir}/arptables.service %config(noreplace) %{_sysconfdir}/sysconfig/arptables -%doc %{_mandir}/man8/arptables.8* +%doc %{_mandir}/man8/arptables*.8* %files ebtables %{_sbindir}/ebtables* @@ -452,9 +448,44 @@ done %{_unitdir}/ebtables.service %config(noreplace) %{_sysconfdir}/sysconfig/ebtables-config %ghost %{_sysconfdir}/sysconfig/ebtables -%doc %{_mandir}/man8/ebtables.8* +%doc %{_mandir}/man8/ebtables*.8* %changelog +* Mon Dec 09 2019 Phil Sutter - 1.8.4-6 +- Add missing patch in last release, uAPI covscan fix + +* Mon Dec 09 2019 Phil Sutter - 1.8.4-5 +- Fix covscan-indicated problems + +* Wed Dec 04 2019 Phil Sutter - 1.8.4-4 +- Fix for broken xtables-restore --noflush + +* Tue Dec 03 2019 Phil Sutter - 1.8.4-3 +- Reduce globbing in library file names to expose future SONAME changes +- Add bootstrapping for libip*tc SONAME bump + +* Mon Dec 02 2019 Phil Sutter - 1.8.4-2 +- Use upstream-provided man pages for ebtables and arptables + +* Mon Dec 02 2019 Phil Sutter - 1.8.4-1 +- Rebase onto upstream release 1.8.4 + +* Thu Aug 08 2019 Phil Sutter - 1.8.2-16 +- nft: Set socket receive buffer + +* Wed Jul 31 2019 Phil Sutter - 1.8.2-15 +- doc: Install ip{6,}tables-restore-translate.8 man pages + +* Tue Jul 02 2019 Phil Sutter - 1.8.2-14 +- arptables: Print space before comma and counters +- extensions: Fix ipvs vproto parsing +- extensions: Fix ipvs vproto option printing +- extensions: Add testcase for libxt_ipvs + +* Mon Jul 01 2019 Phil Sutter - 1.8.2-13 +- doc: Install ip{6,}tables-translate.8 manpages +- nft: Eliminate dead code in __nft_rule_list + * Wed Jun 12 2019 Phil Sutter - 1.8.2-12 - Add iptables-test.py testsuite to sources - extensions: libip6t_mh: fix bogus translation error