From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:21
Hi David,
The following patchset contains Netfilter updates for your net-next
tree, they are:
1) Consolidate GRE protocol tracker using new GRE protocol definitions,
patches from Gao Feng.
2) Properly parse continuation lines in SIP helper, update allowed
characters in Call-ID header and allow tabs in SIP headers as
specified by RFC3261, from Marco Angaroni.
3) Remove useless code in FTP conntrack helper, also from Gao Feng.
4) Add number generation expression for nf_tables, with random and
incremental generators. This also includes specific offset to add
to the result, patches from Laura Garcia Liebana. Liping Zhang
follows with a fix to avoid a race in this new expression.
5) Fix new quota expression inversion logic, added in the previous
pull request.
6) Missing validation of queue configuration in nft_queue, patch
from Liping Zhang.
7) Remove unused ctl_table_path, as part of the deprecation of the
ip_conntrack sysctl interface coming in the previous batch.
Again from Liping Zhang.
8) Add offset attribute to nft_hash expression, so we can generate
any output from a specific base offset. Moreover, check for
possible overflow, patches from Laura Garcia.
9) Allow to invert dynamic set insertion from packet path, to check
for overflows in case the set is full.
10) Revisit nft_set_pktinfo*() logic from nf_tables to ensure
proper initialization of layer 4 protocol. Consolidate pktinfo
structure initialization for bridge and netdev families.
11) Do not inconditionally drop IPv6 packets that we cannot parse
transport protocol for ip6 and inet families, let the user decide
on this via ruleset policy.
12) Get rid of gotos in __nf_ct_try_assign_helper().
13) Check for return value in register_netdevice_notifier() and
nft_register_chain_type(), patches from Gao Feng.
14) Get rid of CONFIG_IP6_NF_IPTABLES dependency in nf_queue
infrastructure that is common to nf_tables, from Liping Zhang.
15) Disable 'found' and 'searched' stats that are updates from the
packet hotpath, not very useful these days.
16) Validate maximum value of u32 netlink attributes in nf_tables,
this introduces nft_parse_u32_check(). From Laura Garcia.
17) Add missing code to integrate nft_queue with maps, patch from
Liping Zhang. This also includes missing support ranges in
nft_queue bridge family.
18) Fix check in nft_payload_fast_eval() that ensure that we don't
go over the skbuff data boundary, from Liping Zhang.
19) Check if transport protocol is set from nf_tables tracing and
payload expression. Again from Liping Zhang.
20) Use net_get_random_once() whenever possible, from Gao Feng.
21) Replace hardcoded value by sizeof() in xt_helper, from Gao Feng.
22) Remove superfluous check for found element in nft_lookup.
23) Simplify TCPMSS logic to check for minimum MTU, from Gao Feng.
24) Replace double linked list by single linked list in Netfilter
core hook infrastructure, patchset from Aaron Conole. This
includes several patches to prepare this update.
25) Fix wrong sequence adjustment of TCP RST with no ACK, from
Gao Feng.
26) Relax check for direction attribute in nft_ct for layer 3 and 4
protocol fields, from Liping Zhang.
27) Add new revision for hashlimit to support higher pps of upto 1
million, from Vishwanath Pai.
28) Evict stale entries in nf_conntrack when reading entries from
/proc/net/nf_conntrack, from Florian Westphal.
29) Fix transparent match for IPv6 request sockets, from Krisztian
Kovacs.
30) Add new range expression for nf_tables.
31) Add missing code to support for flags in nft_log. Expose NF_LOG_*
flags via uapi and use it from the generic logging infrastructure,
instead of using xt specific definitions, from Liping Zhang.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks!
----------------------------------------------------------------
The following changes since commit fe0acb5fcb7fe8cb3d68bbdb8459865c972d8f83:
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue (2016-09-25 06:01:05 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to f20fbc0717f9f007c94b2641134b19228d0ce9ed:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next (2016-09-25 23:34:19 +0200)
----------------------------------------------------------------
Aaron Conole (5):
netfilter: call nf_hook_ingress with rcu_read_lock
netfilter: Remove explicit rcu_read_lock in nf_hook_slow
netfilter: Only allow sane values in nf_register_net_hook
netfilter: nf_queue: whitespace cleanup
netfilter: replace list_head with single linked list
Florian Westphal (4):
netfilter: conntrack: remove packet hotpath stats
netfilter: bridge: add and use br_nf_hook_thresh
netfilter: call nf_hook_state_init with rcu_read_lock held
netfilter: evict stale entries when user reads /proc/net/nf_conntrack
Gao Feng (10):
netfilter: gre: Use consistent GRE_* macros instead of ones defined by netfilter.
netfilter: gre: Use consistent GRE and PTTP header structure instead of the ones defined by netfilter
netfilter: ftp: Remove the useless dlen==0 condition check in find_pattern
netfilter: ftp: Remove the useless code
netfilter: Add the missed return value check of register_netdevice_notifier
netfilter: Add the missed return value check of nft_register_chain_type
netfilter: Enhance the codes used to get random once
netfilter: xt_helper: Use sizeof(variable) instead of literal number
netfilter: xt_TCPMSS: Refactor the codes to decrease one condition check and more readable
netfilter: seqadj: Fix the wrong ack adjust for the RST packet without ack
KOVACS Krisztian (1):
netfilter: xt_socket: fix transparent match for IPv6 request sockets
Laura Garcia Liebana (5):
netfilter: nft_numgen: rename until attribute by modulus
netfilter: nft_hash: Add hash offset value
netfilter: nft_hash: fix hash overflow validation
netfilter: nft_numgen: add number generation offset
netfilter: nf_tables: validate maximum value of u32 netlink attributes
Liping Zhang (12):
netfilter: nft_queue: check the validation of queues_total and queuenum
netfilter: nf_conntrack: remove unused ctl_table_path member in nf_conntrack_l3proto
netfilter: nf_queue: get rid of dependency on IP6_NF_IPTABLES
netfilter: nft_numgen: fix race between num generate and store it
netfilter: nft_queue: add _SREG_QNUM attr to select the queue number
netfilter: nf_queue: improve queue range support for bridge family
netfilter: nf_tables: improve nft payload fast eval
netfilter: nf_tables: check tprot_set first when we use xt.thoff
netfilter: nft_ct: unnecessary to require dir when use ct l3proto/protocol
netfilter: nft_ct: report error if mark and dir specified simultaneously
netfilter: nft_log: complete NFTA_LOG_FLAGS attr support
netfilter: nf_log: get rid of XT_LOG_* macros
Marco Angaroni (3):
netfilter: nf_ct_sip: correct parsing of continuation lines in SIP headers
netfilter: nf_ct_sip: correct allowed characters in Call-ID SIP header
netfilter: nf_ct_sip: allow tab character in SIP headers
Pablo Neira (1):
netfilter: nf_conntrack: simplify __nf_ct_try_assign_helper() return logic
Pablo Neira Ayuso (11):
netfilter: nft_quota: fix overquota logic
netfilter: nft_quota: introduce nft_overquota()
netfilter: nft_dynset: allow to invert match criteria
netfilter: nf_tables: ensure proper initialization of nft_pktinfo fields
netfilter: nf_tables_ipv6: setup pktinfo transport field on failure to parse
netfilter: introduce nft_set_pktinfo_{ipv4, ipv6}_validate()
netfilter: nf_tables_bridge: use nft_set_pktinfo_ipv{4, 6}_validate
netfilter: nf_tables: don't drop IPv6 packets that cannot parse transport
netfilter: nft_lookup: remove superfluous element found check
netfilter: nf_tables: add range expression
Merge branch 'master' of git://git.kernel.org/.../davem/net-next
Vishwanath Pai (2):
netfilter: xt_hashlimit: Prepare for revision 2
netfilter: xt_hashlimit: Create revision 2 to support higher pps rates
include/linux/netdevice.h | 2 +-
include/linux/netfilter.h | 61 ++--
include/linux/netfilter/nf_conntrack_common.h | 4 -
include/linux/netfilter/nf_conntrack_proto_gre.h | 64 +---
include/linux/netfilter_ingress.h | 18 +-
include/net/netfilter/br_netfilter.h | 6 +
include/net/netfilter/nf_conntrack_l3proto.h | 4 -
include/net/netfilter/nf_log.h | 11 +-
include/net/netfilter/nf_queue.h | 69 +++--
include/net/netfilter/nf_tables.h | 19 ++
include/net/netfilter/nf_tables_bridge.h | 7 -
include/net/netfilter/nf_tables_core.h | 3 +
include/net/netfilter/nf_tables_ipv4.h | 43 +++
include/net/netfilter/nf_tables_ipv6.h | 53 +++-
include/net/netns/netfilter.h | 2 +-
include/uapi/linux/if_tunnel.h | 1 +
include/uapi/linux/netfilter/nf_log.h | 12 +
include/uapi/linux/netfilter/nf_tables.h | 45 ++-
include/uapi/linux/netfilter/nfnetlink_conntrack.h | 8 +-
include/uapi/linux/netfilter/xt_hashlimit.h | 23 ++
net/bridge/br_netfilter_hooks.c | 53 +++-
net/bridge/br_netfilter_ipv6.c | 12 +-
net/bridge/netfilter/ebt_log.c | 2 +-
net/bridge/netfilter/ebt_redirect.c | 2 +-
net/bridge/netfilter/ebtables.c | 2 +-
net/bridge/netfilter/nf_tables_bridge.c | 92 +-----
net/bridge/netfilter/nft_reject_bridge.c | 44 ++-
net/core/dev.c | 7 +-
net/ipv4/netfilter/ip_tables.c | 2 +-
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 +-
net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 +-
net/ipv4/netfilter/nf_log_arp.c | 2 +-
net/ipv4/netfilter/nf_log_ipv4.c | 10 +-
net/ipv4/netfilter/nf_nat_proto_gre.c | 13 +-
net/ipv4/netfilter/nf_tables_arp.c | 7 +-
net/ipv4/netfilter/nf_tables_ipv4.c | 5 +-
net/ipv4/tcp_input.c | 1 +
net/ipv4/tcp_ipv4.c | 1 -
net/ipv6/netfilter/ip6_tables.c | 2 +-
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 2 +-
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 2 +-
net/ipv6/netfilter/nf_log_ipv6.c | 18 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 9 +-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 4 +-
net/netfilter/Makefile | 3 +-
net/netfilter/core.c | 152 +++++----
net/netfilter/nf_conntrack_core.c | 16 +-
net/netfilter/nf_conntrack_ftp.c | 15 +-
net/netfilter/nf_conntrack_h323_main.c | 2 +-
net/netfilter/nf_conntrack_helper.c | 17 +-
net/netfilter/nf_conntrack_netlink.c | 6 +-
net/netfilter/nf_conntrack_proto_gre.c | 14 +-
net/netfilter/nf_conntrack_seqadj.c | 20 +-
net/netfilter/nf_conntrack_sip.c | 10 +-
net/netfilter/nf_conntrack_standalone.c | 13 +-
net/netfilter/nf_internals.h | 10 +-
net/netfilter/nf_log_common.c | 4 +-
net/netfilter/nf_queue.c | 18 +-
net/netfilter/nf_tables_api.c | 25 ++
net/netfilter/nf_tables_core.c | 16 +-
net/netfilter/nf_tables_inet.c | 5 +-
net/netfilter/nf_tables_netdev.c | 101 ++----
net/netfilter/nf_tables_trace.c | 20 +-
net/netfilter/nfnetlink_cthelper.c | 2 +-
net/netfilter/nfnetlink_log.c | 8 +-
net/netfilter/nfnetlink_queue.c | 19 +-
net/netfilter/nft_bitwise.c | 8 +-
net/netfilter/nft_byteorder.c | 15 +-
net/netfilter/nft_cmp.c | 3 +
net/netfilter/nft_ct.c | 21 +-
net/netfilter/nft_dynset.c | 20 +-
net/netfilter/nft_exthdr.c | 12 +-
net/netfilter/nft_hash.c | 17 +-
net/netfilter/nft_immediate.c | 4 +
net/netfilter/nft_log.c | 9 +-
net/netfilter/nft_lookup.c | 2 +-
net/netfilter/nft_meta.c | 2 +
net/netfilter/nft_numgen.c | 54 ++--
net/netfilter/nft_payload.c | 4 +
net/netfilter/nft_queue.c | 113 ++++++-
net/netfilter/nft_quota.c | 8 +-
net/netfilter/nft_range.c | 138 +++++++++
net/netfilter/xt_RATEEST.c | 6 +-
net/netfilter/xt_TCPMSS.c | 12 +-
net/netfilter/xt_TEE.c | 8 +-
net/netfilter/xt_connlimit.c | 8 +-
net/netfilter/xt_hashlimit.c | 339 ++++++++++++++++-----
net/netfilter/xt_helper.c | 4 +-
net/netfilter/xt_recent.c | 7 +-
89 files changed, 1381 insertions(+), 680 deletions(-)
delete mode 100644 include/net/netfilter/nf_tables_bridge.h
create mode 100644 include/uapi/linux/netfilter/nf_log.h
create mode 100644 net/netfilter/nft_range.c
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:11
From: Gao Feng <redacted>
There are already some GRE_* macros in kernel, so it is unnecessary
to define these macros. And remove some useless macros
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nf_conntrack_proto_gre.h | 22 ++--------------------
include/uapi/linux/if_tunnel.h | 1 +
net/ipv4/netfilter/nf_nat_proto_gre.c | 4 ++--
net/netfilter/nf_conntrack_proto_gre.c | 4 ++--
4 files changed, 7 insertions(+), 24 deletions(-)
@@ -1,29 +1,11 @@#ifndef _CONNTRACK_PROTO_GRE_H#define _CONNTRACK_PROTO_GRE_H#include<asm/byteorder.h>+#include<net/gre.h>+#include<net/pptp.h>/* GRE PROTOCOL HEADER */-/* GRE Version field */-#define GRE_VERSION_1701 0x0-#define GRE_VERSION_PPTP 0x1--/* GRE Protocol field */-#define GRE_PROTOCOL_PPTP 0x880B--/* GRE Flags */-#define GRE_FLAG_C 0x80-#define GRE_FLAG_R 0x40-#define GRE_FLAG_K 0x20-#define GRE_FLAG_S 0x10-#define GRE_FLAG_A 0x80--#define GRE_IS_C(f) ((f)&GRE_FLAG_C)-#define GRE_IS_R(f) ((f)&GRE_FLAG_R)-#define GRE_IS_K(f) ((f)&GRE_FLAG_K)-#define GRE_IS_S(f) ((f)&GRE_FLAG_S)-#define GRE_IS_A(f) ((f)&GRE_FLAG_A)-/* GRE is a mess: Four different standards */structgre_hdr{#if defined(__LITTLE_ENDIAN_BITFIELD)
@@ -104,11 +104,11 @@ gre_manip_pkt(struct sk_buff *skb,if(maniptype!=NF_NAT_MANIP_DST)returntrue;switch(greh->version){-caseGRE_VERSION_1701:+casentohs(GRE_VERSION_0):/* We do not currently NAT any GREv0 packets.*Trytobehavelike"nf_nat_proto_unknown"*/break;-caseGRE_VERSION_PPTP:+casentohs(GRE_VERSION_1):pr_debug("call_id -> 0x%04x\n",ntohs(tuple->dst.u.gre.key));pgreh->call_id=tuple->dst.u.gre.key;break;
@@ -200,7 +200,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,/* first only delinearize old RFC1701 GRE header */grehdr=skb_header_pointer(skb,dataoff,sizeof(_grehdr),&_grehdr);-if(!grehdr||grehdr->version!=GRE_VERSION_PPTP){+if(!grehdr||grehdr->version!=ntohs(GRE_VERSION_1)){/* try to behave like "nf_conntrack_proto_generic" */tuple->src.u.all=0;tuple->dst.u.all=0;
@@ -212,7 +212,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,if(!pgrehdr)returntrue;-if(ntohs(grehdr->protocol)!=GRE_PROTOCOL_PPTP){+if(grehdr->protocol!=GRE_PROTO_PPP){pr_debug("GRE_VERSION_PPTP but unknown proto\n");returnfalse;}
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:12
From: Gao Feng <redacted>
There are two existing strutures which defines the GRE and PPTP header.
So use these two structures instead of the ones defined by netfilter to
keep consitent with other codes.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nf_conntrack_proto_gre.h | 42 ------------------------
net/ipv4/netfilter/nf_nat_proto_gre.c | 13 ++++----
net/netfilter/nf_conntrack_proto_gre.c | 12 +++----
3 files changed, 13 insertions(+), 54 deletions(-)
@@ -4,48 +4,6 @@#include<net/gre.h>#include<net/pptp.h>-/* GRE PROTOCOL HEADER */--/* GRE is a mess: Four different standards */-structgre_hdr{-#if defined(__LITTLE_ENDIAN_BITFIELD)-__u16rec:3,-srr:1,-seq:1,-key:1,-routing:1,-csum:1,-version:3,-reserved:4,-ack:1;-#elif defined(__BIG_ENDIAN_BITFIELD)-__u16csum:1,-routing:1,-key:1,-seq:1,-srr:1,-rec:3,-ack:1,-reserved:4,-version:3;-#else-#error "Adjust your <asm/byteorder.h> defines"-#endif-__be16protocol;-};--/* modified GRE header for PPTP */-structgre_hdr_pptp{-__u8flags;/* bitfield */-__u8version;/* should be GRE_VERSION_PPTP */-__be16protocol;/* should be GRE_PROTOCOL_PPTP */-__be16payload_len;/* size of ppp payload, not inc. gre header */-__be16call_id;/* peer's call_id for this session */-__be32seq;/* sequence number. Present if S==1 */-__be32ack;/* seq number of highest packet received by */-/* sender in this session */-};-structnf_ct_gre{unsignedintstream_timeout;unsignedinttimeout;
@@ -88,8 +88,8 @@ gre_manip_pkt(struct sk_buff *skb,conststructnf_conntrack_tuple*tuple,enumnf_nat_manip_typemaniptype){-conststructgre_hdr*greh;-structgre_hdr_pptp*pgreh;+conststructgre_base_hdr*greh;+structpptp_gre_header*pgreh;/* pgreh includes two optional 32bit fields which are not required*tobethere.That'swherethemagic'8'comesfrom*/
@@ -97,18 +97,19 @@ gre_manip_pkt(struct sk_buff *skb,returnfalse;greh=(void*)skb->data+hdroff;-pgreh=(structgre_hdr_pptp*)greh;+pgreh=(structpptp_gre_header*)greh;/* we only have destination manip of a packet, since 'source key'*isnotpresentinthepacketitself*/if(maniptype!=NF_NAT_MANIP_DST)returntrue;-switch(greh->version){-casentohs(GRE_VERSION_0):++switch(greh->flags&GRE_VERSION){+caseGRE_VERSION_0:/* We do not currently NAT any GREv0 packets.*Trytobehavelike"nf_nat_proto_unknown"*/break;-casentohs(GRE_VERSION_1):+caseGRE_VERSION_1:pr_debug("call_id -> 0x%04x\n",ntohs(tuple->dst.u.gre.key));pgreh->call_id=tuple->dst.u.gre.key;break;
@@ -192,15 +192,15 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,staticboolgre_pkt_to_tuple(conststructsk_buff*skb,unsignedintdataoff,structnet*net,structnf_conntrack_tuple*tuple){-conststructgre_hdr_pptp*pgrehdr;-structgre_hdr_pptp_pgrehdr;+conststructpptp_gre_header*pgrehdr;+structpptp_gre_header_pgrehdr;__be16srckey;-conststructgre_hdr*grehdr;-structgre_hdr_grehdr;+conststructgre_base_hdr*grehdr;+structgre_base_hdr_grehdr;/* first only delinearize old RFC1701 GRE header */grehdr=skb_header_pointer(skb,dataoff,sizeof(_grehdr),&_grehdr);-if(!grehdr||grehdr->version!=ntohs(GRE_VERSION_1)){+if(!grehdr||(grehdr->flags&GRE_VERSION)!=GRE_VERSION_1){/* try to behave like "nf_conntrack_proto_generic" */tuple->src.u.all=0;tuple->dst.u.all=0;
@@ -213,7 +213,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,returntrue;if(grehdr->protocol!=GRE_PROTO_PPP){-pr_debug("GRE_VERSION_PPTP but unknown proto\n");+pr_debug("Unsupported GRE proto(0x%x)\n",ntohs(grehdr->protocol));returnfalse;}
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:14
From: Marco Angaroni <redacted>
Current parsing methods for SIP header Call-ID do not check correctly all
characters allowed by RFC 3261. In particular "," character is allowed
instead of "'" character. As a result Call-ID headers like the following
are discarded by IPVS SIP persistence engine.
Call-ID: -.!%*_+`'~()<>:\"/[]?{}
Above example is composed using all non-alphanumeric characters listed
in RFC 3261 for Call-ID header syntax.
Proposed fix is in nf_conntrack_sip module; function iswordc() checks this
range: (c >= '(' && c <= '/') which includes these characters: ()*+,-./
They are all allowed except ",". Instead "'" is not included in the list.
Below is an extract of relevant SIP ABNF syntax.
Call-ID = ( "Call-ID" / "i" ) HCOLON callid
callid = word [ "@" word ]
HCOLON = *( SP / HTAB ) ":" SWS
SWS = [LWS] ; sep whitespace
LWS = [*WSP CRLF] 1*WSP ; linear whitespace
WSP = SP / HTAB
word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
"_" / "+" / "`" / "'" / "~" /
"(" / ")" / "<" / ">" /
":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" /
"{" / "}" )
Signed-off-by: Marco Angaroni <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_sip.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:18
Use xor to decide to break further rule evaluation or not, since the
existing logic doesn't achieve the expected inversion.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_quota.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:23
From: Laura Garcia Liebana <redacted>
Add support to pass through an offset to the hash value. With this
feature, the sysadmin is able to generate a hash with a given
offset value.
Example:
meta mark set jhash ip saddr mod 2 seed 0xabcd offset 100
This option generates marks according to the source address from 100 to
101.
Signed-off-by: Laura Garcia Liebana <redacted>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nft_hash.c | 17 +++++++++++++----
2 files changed, 15 insertions(+), 4 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:24
The dynset expression matches if we can fit a new entry into the set.
If there is no room for it, then it breaks the rule evaluation.
This patch introduces the inversion flag so you can add rules to
explicitly drop packets that don't fit into the set. For example:
# nft filter input flow table xyz size 4 { ip saddr timeout 120s counter } overflow drop
This is useful to provide a replacement for connlimit.
For the rule above, every new entry uses the IPv4 address as key in the
set, this entry gets a timeout of 120 seconds that gets refresh on every
packet seen. If we get new flow and our set already contains 4 entries
already, then this packet is dropped.
You can already express this in positive logic, assuming default policy
to drop:
# nft filter input flow table xyz size 4 { ip saddr timeout 10s counter } accept
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 6 ++++++
net/netfilter/nft_dynset.c | 20 +++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:27
These functions are extracted from the netdev family, they initialize
the pktinfo structure and validate that the IPv4 and IPv6 headers are
well-formed given that these functions are called from a path where
layer 3 sanitization did not happen yet.
These functions are placed in include/net/netfilter/nf_tables_ipv{4,6}.h
so they can be reused by a follow up patch to use them from the bridge
family too.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_ipv4.h | 42 ++++++++++++++++++
include/net/netfilter/nf_tables_ipv6.h | 49 +++++++++++++++++++++
net/netfilter/nf_tables_netdev.c | 79 +---------------------------------
3 files changed, 93 insertions(+), 77 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:29
This is overly conservative and not flexible at all, so better let them
go through and let the filtering policy decide what to do with them. We
use skb_header_pointer() all over the place so we would just fail to
match when trying to access fields from malformed traffic.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_ipv6.h | 6 ++----
net/ipv6/netfilter/nf_tables_ipv6.c | 4 +---
net/ipv6/netfilter/nft_chain_route_ipv6.c | 4 +---
3 files changed, 4 insertions(+), 10 deletions(-)
@@ -22,9 +22,7 @@ static unsigned int nft_do_chain_ipv6(void *priv,{structnft_pktinfopkt;-/* malformed packet, drop it */-if(nft_set_pktinfo_ipv6(&pkt,skb,state)<0)-returnNF_DROP;+nft_set_pktinfo_ipv6(&pkt,skb,state);returnnft_do_chain(&pkt,priv);}
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:30
From: Pablo Neira <pablo@netfilter.org>
Instead of several goto's just to return the result, simply return it.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_helper.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
@@ -189,7 +189,6 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,structnf_conntrack_helper*helper=NULL;structnf_conn_help*help;structnet*net=nf_ct_net(ct);-intret=0;/* We already got a helper explicitly attached. The function*nf_conntrack_alter_reply-incaseNATisinuse-asksforlooking
@@ -223,15 +222,13 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,if(helper==NULL){if(help)RCU_INIT_POINTER(help->helper,NULL);-gotoout;+return0;}if(help==NULL){help=nf_ct_helper_ext_add(ct,helper,flags);-if(help==NULL){-ret=-ENOMEM;-gotoout;-}+if(help==NULL)+return-ENOMEM;}else{/* We only allow helper re-assignment of the same sort since*wecannotreallocatethehelperextensionarea.
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:37
From: Laura Garcia Liebana <redacted>
Add support of an offset value for incremental counter and random. With
this option the sysadmin is able to start the counter to a certain value
and then apply the generated number.
Example:
meta mark set numgen inc mod 2 offset 100
This will generate marks with the serie 100, 101, 100, 101, ...
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Laura Garcia Liebana <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nft_numgen.c | 32 ++++++++++++++++++++++++++------
2 files changed, 28 insertions(+), 6 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:39
From: Liping Zhang <redacted>
Currently, the user can specify the queue numbers by _QUEUE_NUM and
_QUEUE_TOTAL attributes, this is enough in most situations.
But acctually, it is not very flexible, for example:
tcp dport 80 mapped to queue0
tcp dport 81 mapped to queue1
tcp dport 82 mapped to queue2
In order to do this thing, we must add 3 nft rules, and more
mapping meant more rules ...
So take one register to select the queue number, then we can add one
simple rule to mapping queues, maybe like this:
queue num tcp dport map { 80:0, 81:1, 82:2 ... }
Florian Westphal also proposed wider usage scenarios:
queue num jhash ip saddr . ip daddr mod ...
queue num meta cpu ...
queue num meta mark ...
The last point is how to load a queue number from sreg, although we can
use *(u16*)®s->data[reg] to load the queue number, just like nat expr
to load its l4port do.
But we will cooperate with hash expr, meta cpu, meta mark expr and so on.
They all store the result to u32 type, so cast it to u16 pointer and
dereference it will generate wrong result in the big endian system.
So just keep it simple, we treat queue number as u32 type, although u16
type is already enough.
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 +
net/netfilter/nft_queue.c | 102 +++++++++++++++++++++++++++----
2 files changed, 92 insertions(+), 12 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:42
From: Liping Zhang <redacted>
pkt->xt.thoff is not always set properly, but we use it without any check.
For payload expr, it will cause wrong results. For nftrace, we may notify
the wrong network or transport header to the user space, furthermore,
input the following nft rules, warning message will be printed out:
# nft add rule arp filter output meta nftrace set 1
WARNING: CPU: 0 PID: 13428 at net/netfilter/nf_tables_trace.c:263
nft_trace_notify+0x4a3/0x5e0 [nf_tables]
Call Trace:
[<ffffffff813d58ae>] dump_stack+0x63/0x85
[<ffffffff810a4c0b>] __warn+0xcb/0xf0
[<ffffffff810a4d3d>] warn_slowpath_null+0x1d/0x20
[<ffffffffa0589703>] nft_trace_notify+0x4a3/0x5e0 [nf_tables]
[ ... ]
[<ffffffffa05690a8>] nft_do_chain_arp+0x78/0x90 [nf_tables_arp]
[<ffffffff816f4aa2>] nf_iterate+0x62/0x80
[<ffffffff816f4b33>] nf_hook_slow+0x73/0xd0
[<ffffffff81732bbf>] arp_xmit+0x8f/0xb0
[ ... ]
[<ffffffff81732d36>] arp_solicit+0x106/0x2c0
So before we use pkt->xt.thoff, check the tprot_set first.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_core.c | 5 ++++-
net/netfilter/nf_tables_trace.c | 20 +++++++++++---------
net/netfilter/nft_payload.c | 4 ++++
3 files changed, 19 insertions(+), 10 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:43
From: Gao Feng <redacted>
There are some codes which are used to get one random once in netfilter.
We could use net_get_random_once to simplify these codes.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_RATEEST.c | 6 +-----
net/netfilter/xt_connlimit.c | 8 +-------
net/netfilter/xt_recent.c | 7 ++-----
3 files changed, 4 insertions(+), 17 deletions(-)
@@ -366,14 +366,8 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)unsignedinti;intret;-if(unlikely(!connlimit_rnd)){-u_int32_trand;+net_get_random_once(&connlimit_rnd,sizeof(connlimit_rnd));-do{-get_random_bytes(&rand,sizeof(rand));-}while(!rand);-cmpxchg(&connlimit_rnd,0,rand);-}ret=nf_ct_l3proto_try_module_get(par->family);if(ret<0){pr_info("cannot load conntrack support for "
@@ -340,10 +339,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par,intret=-EINVAL;size_tsz;-if(unlikely(!hash_rnd_inited)){-get_random_bytes(&hash_rnd,sizeof(hash_rnd));-hash_rnd_inited=true;-}+net_get_random_once(&hash_rnd,sizeof(hash_rnd));+if(info->check_set&~XT_RECENT_VALID_FLAGS){pr_info("Unsupported user space flags (%08x)\n",info->check_set);
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:44
From: Gao Feng <redacted>
It's better to use sizeof(info->name)-1 as index to force set the string
tail instead of literal number '29'.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:48
From: Florian Westphal <fw@strlen.de>
This makes things simpler because we can store the head of the list
in the nf_state structure without worrying about concurrent add/delete
of hook elements from the list.
A future commit will make use of this to implement a simpler
linked-list.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Aaron Conole <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter.h | 8 +++++++-
include/linux/netfilter_ingress.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)
@@ -174,10 +174,16 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,if(!list_empty(hook_list)){structnf_hook_statestate;+intret;+/* We may already have this, but read-locks nest anyway */+rcu_read_lock();nf_hook_state_init(&state,hook_list,hook,thresh,pf,indev,outdev,sk,net,okfn);-returnnf_hook_slow(skb,&state);++ret=nf_hook_slow(skb,&state);+rcu_read_unlock();+returnret;}return1;}
@@ -291,16 +291,13 @@ repeat:/* Returns 1 if okfn() needs to be executed by the caller,-*-EPERMforNF_DROP,0otherwise.*/+*-EPERMforNF_DROP,0otherwise.Callermustholdrcu_read_lock.*/intnf_hook_slow(structsk_buff*skb,structnf_hook_state*state){structnf_hook_ops*elem;unsignedintverdict;intret=0;-/* We may already have this, but read-locks nest anyway */-rcu_read_lock();-elem=list_entry_rcu(state->hook_list,structnf_hook_ops,list);next_hook:verdict=nf_iterate(state->hook_list,skb,state,&elem);
@@ -1275,7 +1275,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,skb->nfct=NULL;}-/* rcu_read_lock()ed by nf_hook_slow */+/* rcu_read_lock()ed by nf_hook_thresh */l3proto=__nf_ct_l3proto_find(pf);ret=l3proto->get_l4proto(skb,skb_network_offset(skb),&dataoff,&protonum);
@@ -736,7 +736,7 @@ static int callforward_do_filter(struct net *net,conststructnf_afinfo*afinfo;intret=0;-/* rcu_read_lock()ed by nf_hook_slow() */+/* rcu_read_lock()ed by nf_hook_thresh */afinfo=nf_get_afinfo(family);if(!afinfo)return0;
@@ -346,7 +346,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,/* Called from the helper function, this call never fails */help=nfct_help(ct);-/* rcu_read_lock()ed by nf_hook_slow */+/* rcu_read_lock()ed by nf_hook_thresh */helper=rcu_dereference(help->helper);nf_log_packet(nf_ct_net(ct),nf_ct_l3num(ct),0,skb,NULL,NULL,NULL,
@@ -442,7 +442,9 @@ __build_packet_message(struct nfnl_log_net *log,if(nla_put_be32(inst->skb,NFULA_IFINDEX_PHYSINDEV,htonl(indev->ifindex))||/* this is the bridge group "brX" */-/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */+/* rcu_read_lock()ed by nf_hook_thresh or+*nf_log_packet.+*/nla_put_be32(inst->skb,NFULA_IFINDEX_INDEV,htonl(br_port_get_rcu(indev)->br->dev->ifindex)))gotonla_put_failure;
@@ -477,7 +479,9 @@ __build_packet_message(struct nfnl_log_net *log,if(nla_put_be32(inst->skb,NFULA_IFINDEX_PHYSOUTDEV,htonl(outdev->ifindex))||/* this is the bridge group "brX" */-/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */+/* rcu_read_lock()ed by nf_hook_thresh or+*nf_log_packet.+*/nla_put_be32(inst->skb,NFULA_IFINDEX_OUTDEV,htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))gotonla_put_failure;
@@ -55,12 +55,34 @@ struct nf_hook_state {structnet_device*out;structsock*sk;structnet*net;-structlist_head*hook_list;+structnf_hook_entry__rcu*hook_entries;int(*okfn)(structnet*,structsock*,structsk_buff*);};+typedefunsignedintnf_hookfn(void*priv,+structsk_buff*skb,+conststructnf_hook_state*state);+structnf_hook_ops{+structlist_headlist;++/* User fills in from here down. */+nf_hookfn*hook;+structnet_device*dev;+void*priv;+u_int8_tpf;+unsignedinthooknum;+/* Hooks are ordered in ascending priority. */+intpriority;+};++structnf_hook_entry{+structnf_hook_entry__rcu*next;+structnf_hook_opsops;+conststructnf_hook_ops*orig_ops;+};+staticinlinevoidnf_hook_state_init(structnf_hook_state*p,-structlist_head*hook_list,+structnf_hook_entry*hook_entry,unsignedinthook,intthresh,u_int8_tpf,structnet_device*indev,
@@ -76,26 +98,11 @@ static inline void nf_hook_state_init(struct nf_hook_state *p,p->out=outdev;p->sk=sk;p->net=net;-p->hook_list=hook_list;+RCU_INIT_POINTER(p->hook_entries,hook_entry);p->okfn=okfn;}-typedefunsignedintnf_hookfn(void*priv,-structsk_buff*skb,-conststructnf_hook_state*state);--structnf_hook_ops{-structlist_headlist;-/* User fills in from here down. */-nf_hookfn*hook;-structnet_device*dev;-void*priv;-u_int8_tpf;-unsignedinthooknum;-/* Hooks are ordered in ascending priority. */-intpriority;-};structnf_sockopt_ops{structlist_headlist;
@@ -161,7 +168,8 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,int(*okfn)(structnet*,structsock*,structsk_buff*),intthresh){-structlist_head*hook_list;+structnf_hook_entry*hook_head;+intret=1;#ifdef HAVE_JUMP_LABELif(__builtin_constant_p(pf)&&
@@ -170,22 +178,19 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,return1;#endif-hook_list=&net->nf.hooks[pf][hook];--if(!list_empty(hook_list)){+rcu_read_lock();+hook_head=rcu_dereference(net->nf.hooks[pf][hook]);+if(hook_head){structnf_hook_statestate;-intret;-/* We may already have this, but read-locks nest anyway */-rcu_read_lock();-nf_hook_state_init(&state,hook_list,hook,thresh,+nf_hook_state_init(&state,hook_head,hook,thresh,pf,indev,outdev,sk,net,okfn);ret=nf_hook_slow(skb,&state);-rcu_read_unlock();-returnret;}-return1;+rcu_read_unlock();++returnret;}staticinlineintnf_hook(u_int8_tpf,unsignedinthook,structnet*net,
@@ -11,23 +11,30 @@ static inline bool nf_hook_ingress_active(const struct sk_buff *skb)if(!static_key_false(&nf_hooks_needed[NFPROTO_NETDEV][NF_NETDEV_INGRESS]))returnfalse;#endif-return!list_empty(&skb->dev->nf_hooks_ingress);+returnrcu_access_pointer(skb->dev->nf_hooks_ingress);}/* caller must hold rcu_read_lock */staticinlineintnf_hook_ingress(structsk_buff*skb){+structnf_hook_entry*e=rcu_dereference(skb->dev->nf_hooks_ingress);structnf_hook_statestate;-nf_hook_state_init(&state,&skb->dev->nf_hooks_ingress,-NF_NETDEV_INGRESS,INT_MIN,NFPROTO_NETDEV,-skb->dev,NULL,NULL,dev_net(skb->dev),NULL);+/* Must recheck the ingress hook head, in the event it became NULL+*afterthecheckinnf_hook_ingress_activeevaluatedtotrue.+*/+if(unlikely(!e))+return0;++nf_hook_state_init(&state,e,NF_NETDEV_INGRESS,INT_MIN,+NFPROTO_NETDEV,skb->dev,NULL,NULL,+dev_net(skb->dev),NULL);returnnf_hook_slow(skb,&state);}staticinlinevoidnf_hook_ingress_init(structnet_device*dev){-INIT_LIST_HEAD(&dev->nf_hooks_ingress);+RCU_INIT_POINTER(dev->nf_hooks_ingress,NULL);}#else /* CONFIG_NETFILTER_INGRESS */staticinlineintnf_hook_ingress_active(structsk_buff*skb)
@@ -1002,28 +1002,21 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net,int(*okfn)(structnet*,structsock*,structsk_buff*)){-structnf_hook_ops*elem;+structnf_hook_entry*elem;structnf_hook_statestate;-structlist_head*head;intret;-head=&net->nf.hooks[NFPROTO_BRIDGE][hook];+elem=rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);-list_for_each_entry_rcu(elem,head,list){-structnf_hook_ops*next;+while(elem&&(elem->ops.priority<=NF_BR_PRI_BRNF))+elem=rcu_dereference(elem->next);-next=list_entry_rcu(list_next_rcu(&elem->list),-structnf_hook_ops,list);-if(next->priority<=NF_BR_PRI_BRNF)-continue;-}--if(&elem->list==head)+if(!elem)returnokfn(net,sk,skb);/* We may already have this, but read-locks nest anyway */rcu_read_lock();-nf_hook_state_init(&state,head,hook,NF_BR_PRI_BRNF+1,+nf_hook_state_init(&state,elem,hook,NF_BR_PRI_BRNF+1,NFPROTO_BRIDGE,indev,outdev,sk,net,okfn);ret=nf_hook_slow(skb,&state);
@@ -61,33 +62,50 @@ EXPORT_SYMBOL(nf_hooks_needed);#endifstaticDEFINE_MUTEX(nf_hook_mutex);+#define nf_entry_dereference(e) \+rcu_dereference_protected(e,lockdep_is_held(&nf_hook_mutex))-staticstructlist_head*nf_find_hook_list(structnet*net,-conststructnf_hook_ops*reg)+staticstructnf_hook_entry*nf_hook_entry_head(structnet*net,+conststructnf_hook_ops*reg){-structlist_head*hook_list=NULL;+structnf_hook_entry*hook_head=NULL;if(reg->pf!=NFPROTO_NETDEV)-hook_list=&net->nf.hooks[reg->pf][reg->hooknum];+hook_head=nf_entry_dereference(net->nf.hooks[reg->pf]+[reg->hooknum]);elseif(reg->hooknum==NF_NETDEV_INGRESS){#ifdef CONFIG_NETFILTER_INGRESSif(reg->dev&&dev_net(reg->dev)==net)-hook_list=®->dev->nf_hooks_ingress;+hook_head=+nf_entry_dereference(+reg->dev->nf_hooks_ingress);#endif}-returnhook_list;+returnhook_head;}-structnf_hook_entry{-conststructnf_hook_ops*orig_ops;-structnf_hook_opsops;-};+/* must hold nf_hook_mutex */+staticvoidnf_set_hooks_head(structnet*net,conststructnf_hook_ops*reg,+structnf_hook_entry*entry)+{+switch(reg->pf){+caseNFPROTO_NETDEV:+/* We already checked in nf_register_net_hook() that this is+*usedfromingress.+*/+rcu_assign_pointer(reg->dev->nf_hooks_ingress,entry);+break;+default:+rcu_assign_pointer(net->nf.hooks[reg->pf][reg->hooknum],+entry);+break;+}+}intnf_register_net_hook(structnet*net,conststructnf_hook_ops*reg){-structlist_head*hook_list;+structnf_hook_entry*hooks_entry;structnf_hook_entry*entry;-structnf_hook_ops*elem;if(reg->pf==NFPROTO_NETDEV&&(reg->hooknum!=NF_NETDEV_INGRESS||
@@ -100,19 +118,30 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)entry->orig_ops=reg;entry->ops=*reg;+entry->next=NULL;++mutex_lock(&nf_hook_mutex);+hooks_entry=nf_hook_entry_head(net,reg);-hook_list=nf_find_hook_list(net,reg);-if(!hook_list){-kfree(entry);-return-ENOENT;+if(hooks_entry&&hooks_entry->orig_ops->priority>reg->priority){+/* This is the case where we need to insert at the head */+entry->next=hooks_entry;+hooks_entry=NULL;}-mutex_lock(&nf_hook_mutex);-list_for_each_entry(elem,hook_list,list){-if(reg->priority<elem->priority)-break;+while(hooks_entry&&+reg->priority>=hooks_entry->orig_ops->priority&&+nf_entry_dereference(hooks_entry->next)){+hooks_entry=nf_entry_dereference(hooks_entry->next);+}++if(hooks_entry){+entry->next=nf_entry_dereference(hooks_entry->next);+rcu_assign_pointer(hooks_entry->next,entry);+}else{+nf_set_hooks_head(net,reg,entry);}-list_add_rcu(&entry->ops.list,elem->list.prev);+mutex_unlock(&nf_hook_mutex);#ifdef CONFIG_NETFILTER_INGRESSif(reg->pf==NFPROTO_NETDEV&®->hooknum==NF_NETDEV_INGRESS)
@@ -127,24 +156,33 @@ EXPORT_SYMBOL(nf_register_net_hook);voidnf_unregister_net_hook(structnet*net,conststructnf_hook_ops*reg){-structlist_head*hook_list;-structnf_hook_entry*entry;-structnf_hook_ops*elem;--hook_list=nf_find_hook_list(net,reg);-if(!hook_list)-return;+structnf_hook_entry*hooks_entry;mutex_lock(&nf_hook_mutex);-list_for_each_entry(elem,hook_list,list){-entry=container_of(elem,structnf_hook_entry,ops);-if(entry->orig_ops==reg){-list_del_rcu(&entry->ops.list);-break;+hooks_entry=nf_hook_entry_head(net,reg);+if(hooks_entry->orig_ops==reg){+nf_set_hooks_head(net,reg,+nf_entry_dereference(hooks_entry->next));+gotounlock;+}+while(hooks_entry&&nf_entry_dereference(hooks_entry->next)){+structnf_hook_entry*next=+nf_entry_dereference(hooks_entry->next);+structnf_hook_entry*nnext;++if(next->orig_ops!=reg){+hooks_entry=next;+continue;}+nnext=nf_entry_dereference(next->next);+rcu_assign_pointer(hooks_entry->next,nnext);+hooks_entry=next;+break;}++unlock:mutex_unlock(&nf_hook_mutex);-if(&elem->list==hook_list){+if(!hooks_entry){WARN(1,"nf_unregister_net_hook: hook not found!\n");return;}
@@ -156,10 +194,10 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);#endifsynchronize_net();-nf_queue_nf_hook_drop(net,&entry->ops);+nf_queue_nf_hook_drop(net,hooks_entry);/* other cpu might still process nfqueue verdict that used reg */synchronize_net();-kfree(entry);+kfree(hooks_entry);}EXPORT_SYMBOL(nf_unregister_net_hook);
@@ -269,20 +306,23 @@ unsigned int nf_iterate(struct list_head *head,*Thecallermustnotblockbetweencallstothis*functionbecauseofriskofcontinuingfromdeletedelement.*/-list_for_each_entry_continue_rcu((*elemp),head,list){-if(state->thresh>(*elemp)->priority)+while(*entryp){+if(state->thresh>(*entryp)->ops.priority){+*entryp=rcu_dereference((*entryp)->next);continue;+}/* Optimization: we don't need to hold modulereferencehere,sincefunctioncan'tsleep.--RR*/repeat:-verdict=(*elemp)->hook((*elemp)->priv,skb,state);+verdict=(*entryp)->ops.hook((*entryp)->ops.priv,skb,state);if(verdict!=NF_ACCEPT){#ifdef CONFIG_NETFILTER_DEBUGif(unlikely((verdict&NF_VERDICT_MASK)>NF_MAX_VERDICT)){NFDEBUG("Evil return from %p(%u).\n",-(*elemp)->hook,state->hook);+(*entryp)->ops.hook,state->hook);+*entryp=rcu_dereference((*entryp)->next);continue;}#endif
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:55
From: Liping Zhang <redacted>
Currently, if the user want to match ct l3proto, we must specify the
direction, for example:
# nft add rule filter input ct original l3proto ipv4
^^^^^^^^
Otherwise, error message will be reported:
# nft add rule filter input ct l3proto ipv4
nft add rule filter input ct l3proto ipv4
<cmdline>:1:1-38: Error: Could not process rule: Invalid argument
add rule filter input ct l3proto ipv4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Actually, there's no need to require NFTA_CT_DIRECTION attr, because
ct l3proto and protocol are unrelated to direction.
And for compatibility, even if the user specify the NFTA_CT_DIRECTION
attr, do not report error, just skip it.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_ct.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
@@ -283,8 +283,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,caseNFT_CT_L3PROTOCOL:caseNFT_CT_PROTOCOL:-if(tb[NFTA_CT_DIRECTION]==NULL)-return-EINVAL;+/* For compatibility, do not report error if NFTA_CT_DIRECTION+*attributeisspecified.+*/len=sizeof(u8);break;caseNFT_CT_SRC:
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:56
From: Liping Zhang <redacted>
NFT_CT_MARK is unrelated to direction, so if NFTA_CT_DIRECTION attr is
specified, report EINVAL to the userspace. This validation check was
already done at nft_ct_get_init, but we missed it in nft_ct_set_init.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_ct.c | 2 ++
1 file changed, 2 insertions(+)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:06:57
From: Vishwanath Pai <redacted>
I am planning to add a revision 2 for the hashlimit xtables module to
support higher packets per second rates. This patch renames all the
functions and variables related to revision 1 by adding _v1 at the
end of the names.
Signed-off-by: Vishwanath Pai <redacted>
Signed-off-by: Joshua Hunt <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_hashlimit.c | 61 ++++++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 30 deletions(-)
@@ -56,7 +56,7 @@ static inline struct hashlimit_net *hashlimit_pernet(struct net *net)}/* need to declare this at the top */-staticconststructfile_operationsdl_file_ops;+staticconststructfile_operationsdl_file_ops_v1;/* hash table crap */structdsthash_dst{
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:00
From: KOVACS Krisztian <redacted>
The introduction of TCP_NEW_SYN_RECV state, and the addition of request
sockets to the ehash table seems to have broken the --transparent option
of the socket match for IPv6 (around commit a9407000).
Now that the socket lookup finds the TCP_NEW_SYN_RECV socket instead of the
listener, the --transparent option tries to match on the no_srccheck flag
of the request socket.
Unfortunately, that flag was only set for IPv4 sockets in tcp_v4_init_req()
by copying the transparent flag of the listener socket. This effectively
causes '-m socket --transparent' not match on the ACK packet sent by the
client in a TCP handshake.
Based on the suggestion from Eric Dumazet, this change moves the code
initializing no_srccheck to tcp_conn_request(), rendering the above
scenario working again.
Fixes: a940700003 ("netfilter: xt_socket: prepare for TCP_NEW_SYN_RECV support")
Signed-off-by: Alex Badics <redacted>
Signed-off-by: KOVACS Krisztian <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/tcp_input.c | 1 +
net/ipv4/tcp_ipv4.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:23
From: Marco Angaroni <redacted>
Current parsing methods for SIP headers do not properly manage
continuation lines: in case of Call-ID header the first character of
Call-ID header value is truncated. As a result IPVS SIP persistence
engine hashes over a call-id that is not exactly the one present in
the originale message.
Example: "Call-ID: \r\n abcdeABCDE1234"
results in extracted call-id equal to "bcdeABCDE1234".
In above example Call-ID is represented as a string in C language.
Obviously in real message the first bytes after colon (":") are
"20 0d 0a 20".
Proposed fix is in nf_conntrack_sip module.
Since sip_follow_continuation() function walks past the leading
spaces or tabs of the continuation line, sip_skip_whitespace()
should simply return the ouput of sip_follow_continuation().
Otherwise another iteration of the for loop is done and dptr
is incremented by one pointing to the second character of the
first word in the header.
Below is an extract of relevant SIP ABNF syntax.
Call-ID = ( "Call-ID" / "i" ) HCOLON callid
callid = word [ "@" word ]
HCOLON = *( SP / HTAB ) ":" SWS
SWS = [LWS] ; sep whitespace
LWS = [*WSP CRLF] 1*WSP ; linear whitespace
WSP = SP / HTAB
word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
"_" / "+" / "`" / "'" / "~" /
"(" / ")" / "<" / ">" /
":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" /
"{" / "}" )
Signed-off-by: Marco Angaroni <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_sip.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:25
From: Gao Feng <redacted>
The caller function "help" has already make sure the datalen could not be zero
before invoke find_pattern as a parameter by the following codes
if (dataoff >= skb->len) {
pr_debug("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
skb->len);
return NF_ACCEPT;
}
datalen = skb->len - dataoff;
And the latter codes "ends_in_nl = (fb_ptr[datalen - 1] == '\n');" use datalen
directly without checking if it is zero.
So it is unneccessary to check it in find_pattern too.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_ftp.c | 2 --
1 file changed, 2 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:26
From: Gao Feng <redacted>
There are some debug code which are commented out in find_pattern by #if 0.
Now remove them.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_ftp.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
@@ -309,19 +309,8 @@ static int find_pattern(const char *data, size_t dlen,elsereturn0;}-if(strncasecmp(data,pattern,plen)!=0){-#if 0-size_ti;--pr_debug("ftp: string mismatch\n");-for(i=0;i<plen;i++){-pr_debug("ftp:char %u `%c'(%u) vs `%c'(%u)\n",-i,data[i],data[i],-pattern[i],pattern[i]);-}-#endif+if(strncasecmp(data,pattern,plen)!=0)return0;-}pr_debug("Pattern matches!\n");/* Now we've found the constant string, try to skip
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:27
From: Laura Garcia Liebana <redacted>
The _until_ attribute is renamed to _modulus_ as the behaviour is similar to
other expresions with number limits (ex. nft_hash).
Renaming is possible because there isn't a kernel release yet with these
changes.
Signed-off-by: Laura Garcia Liebana <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 4 ++--
net/netfilter/nft_numgen.c | 30 +++++++++++++++---------------
2 files changed, 17 insertions(+), 17 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:29
This is patch renames the existing function to nft_overquota() and make
it return a boolean that tells us if we have exceeded our byte quota.
Just a cleanup.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_quota.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:30
From: Marco Angaroni <redacted>
Current parsing methods for SIP headers do not allow the presence of
tab characters between header name and header value. As a result Call-ID
SIP headers like the following are discarded by IPVS SIP persistence
engine:
"Call-ID\t: mycallid@abcde"
"Call-ID:\tmycallid@abcde"
In above examples Call-IDs are represented as strings in C language.
Obviously in real message we have byte "09" before/after colon (":").
Proposed fix is in nf_conntrack_sip module.
Function sip_skip_whitespace() should skip tabs in addition to spaces,
since in SIP grammar whitespace (WSP) corresponds to space or tab.
Below is an extract of relevant SIP ABNF syntax.
Call-ID = ( "Call-ID" / "i" ) HCOLON callid
callid = word [ "@" word ]
HCOLON = *( SP / HTAB ) ":" SWS
SWS = [LWS] ; sep whitespace
LWS = [*WSP CRLF] 1*WSP ; linear whitespace
WSP = SP / HTAB
word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
"_" / "+" / "`" / "'" / "~" /
"(" / ")" / "<" / ">" /
":" / "\" / DQUOTE /
"/" / "[" / "]" / "?" /
"{" / "}" )
Signed-off-by: Marco Angaroni <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_sip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:32
From: Liping Zhang <redacted>
Although the validation of queues_total and queuenum is checked in nft
utility, but user can add nft rules via nfnetlink, so it is necessary
to check the validation at the nft_queue expr init routine too.
Tested by run ./nft-test.py any/queue.t:
any/queue.t: 6 unit tests, 0 error, 0 warning
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_queue.c | 11 +++++++++++
1 file changed, 11 insertions(+)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:36
This patch introduces nft_set_pktinfo_unspec() that ensures proper
initialization all of pktinfo fields for non-IP traffic. This is used
by the bridge, netdev and arp families.
This new function relies on nft_set_pktinfo_proto_unspec() to set a new
tprot_set field that indicates if transport protocol information is
available. Remain fields are zeroed.
The meta expression has been also updated to check to tprot_set in first
place given that zero is a valid tprot value. Even a handcrafted packet
may come with the IPPROTO_RAW (255) protocol number so we can't rely on
this value as tprot unset.
Reported-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 18 ++++++++++++++++++
include/net/netfilter/nf_tables_ipv4.h | 1 +
include/net/netfilter/nf_tables_ipv6.h | 1 +
net/bridge/netfilter/nf_tables_bridge.c | 6 +++---
net/ipv4/netfilter/nf_tables_arp.c | 2 +-
net/netfilter/nf_tables_netdev.c | 4 +++-
net/netfilter/nft_meta.c | 2 ++
7 files changed, 29 insertions(+), 5 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:37
Make sure the pktinfo protocol fields are initialized if this fails to
parse the transport header.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_ipv6.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
@@ -15,9 +15,10 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,nft_set_pktinfo(pkt,skb,state);protohdr=ipv6_find_hdr(pkt->skb,&thoff,-1,&frag_off,NULL);-/* If malformed, drop it */-if(protohdr<0)+if(protohdr<0){+nft_set_pktinfo_proto_unspec(pkt,skb);return-1;+}pkt->tprot_set=true;pkt->tprot=protohdr;
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:39
Consolidate pktinfo setup and validation by using the new generic
functions so we converge to the netdev family codebase.
We only need a linear IPv4 and IPv6 header from the reject expression,
so move nft_bridge_iphdr_validate() and nft_bridge_ip6hdr_validate()
to net/bridge/netfilter/nft_reject_bridge.c.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_bridge.h | 7 ----
net/bridge/netfilter/nf_tables_bridge.c | 72 +-------------------------------
net/bridge/netfilter/nft_reject_bridge.c | 44 ++++++++++++++++++-
3 files changed, 45 insertions(+), 78 deletions(-)
delete mode 100644 include/net/netfilter/nf_tables_bridge.h
@@ -37,6 +36,30 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb,skb_pull(nskb,ETH_HLEN);}+staticintnft_bridge_iphdr_validate(structsk_buff*skb)+{+structiphdr*iph;+u32len;++if(!pskb_may_pull(skb,sizeof(structiphdr)))+return0;++iph=ip_hdr(skb);+if(iph->ihl<5||iph->version!=4)+return0;++len=ntohs(iph->tot_len);+if(skb->len<len)+return0;+elseif(len<(iph->ihl*4))+return0;++if(!pskb_may_pull(skb,iph->ihl*4))+return0;++return1;+}+/* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT)*orthebridgeport(NF_BRIDGEPREROUTING).*/
@@ -143,6 +166,25 @@ static void nft_reject_br_send_v4_unreach(struct net *net,br_forward(br_port_get_rcu(dev),nskb,false,true);}+staticintnft_bridge_ip6hdr_validate(structsk_buff*skb)+{+structipv6hdr*hdr;+u32pkt_len;++if(!pskb_may_pull(skb,sizeof(structipv6hdr)))+return0;++hdr=ipv6_hdr(skb);+if(hdr->version!=6)+return0;++pkt_len=ntohs(hdr->payload_len);+if(pkt_len+sizeof(structipv6hdr)>skb->len)+return0;++return1;+}+staticvoidnft_reject_br_send_v6_tcp_reset(structnet*net,structsk_buff*oldskb,conststructnet_device*dev,
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:41
From: Gao Feng <redacted>
There are some codes of netfilter module which did not check the return
value of register_netdevice_notifier. Add the checks now.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_netdev.c | 18 +++++++++++++-----
net/netfilter/nfnetlink_queue.c | 9 ++++++++-
net/netfilter/xt_TEE.c | 8 +++++++-
3 files changed, 28 insertions(+), 7 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:45
From: Florian Westphal <fw@strlen.de>
These counters sit in hot path and do show up in perf, this is especially
true for 'found' and 'searched' which get incremented for every packet
processed.
Information like
searched=212030105
new=623431
found=333613
delete=623327
does not seem too helpful nowadays:
- on busy systems found and searched will overflow every few hours
(these are 32bit integers), other more busy ones every few days.
- for debugging there are better methods, such as iptables' trace target,
the conntrack log sysctls. Nowadays we also have perf tool.
This removes packet path stat counters except those that
are expected to be 0 (or close to 0) on a normal system, e.g.
'insert_failed' (race happened) or 'invalid' (proto tracker rejects).
The insert stat is retained for the ctnetlink case.
The found stat is retained for the tuple-is-taken check when NAT has to
determine if it needs to pick a different source address.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/nf_conntrack_common.h | 4 ----
include/uapi/linux/netfilter/nfnetlink_conntrack.h | 8 ++++----
net/netfilter/nf_conntrack_core.c | 14 ++------------
net/netfilter/nf_conntrack_netlink.c | 6 +-----
net/netfilter/nf_conntrack_standalone.c | 8 ++++----
5 files changed, 11 insertions(+), 29 deletions(-)
@@ -231,13 +231,13 @@ enum ctattr_secctx {enumctattr_stats_cpu{CTA_STATS_UNSPEC,-CTA_STATS_SEARCHED,+CTA_STATS_SEARCHED,/* no longer used */CTA_STATS_FOUND,-CTA_STATS_NEW,+CTA_STATS_NEW,/* no longer used */CTA_STATS_INVALID,CTA_STATS_IGNORE,-CTA_STATS_DELETE,-CTA_STATS_DELETE_LIST,+CTA_STATS_DELETE,/* no longer used */+CTA_STATS_DELETE_LIST,/* no longer used */CTA_STATS_INSERT,CTA_STATS_INSERT_FAILED,CTA_STATS_DROP,
@@ -1177,10 +1169,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,}spin_unlock(&nf_conntrack_expect_lock);}-if(!exp){+if(!exp)__nf_ct_try_assign_helper(ct,tmpl,GFP_ATOMIC);-NF_CT_STAT_INC(net,new);-}/* Now it is inserted into the unconfirmed list, bump refcount */nf_conntrack_get(&ct->ct_general);
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:46
From: Liping Zhang <redacted>
After we generate a new number, we still use the priv->counter and
store it to the dreg. This is not correct, another cpu may already
change it to a new number. So we must use the generated number, not
the priv->counter itself.
Fixes: 91dbc6be0a62 ("netfilter: nf_tables: add number generator expression")
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_numgen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:48
From: Laura Garcia Liebana <redacted>
The overflow validation in the init() function establishes that the
maximum value that the hash could reach is less than U32_MAX, which is
likely to be true.
The fix detects the overflow when the maximum hash value is less than
the offset itself.
Fixes: 70ca767ea1b2 ("netfilter: nft_hash: Add hash offset value")
Reported-by: Liping Zhang <redacted>
Signed-off-by: Laura Garcia Liebana <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_hash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:50
From: Liping Zhang <redacted>
After commit ac2863445686 ("netfilter: bridge: add nf_afinfo to enable
queuing to userspace"), we can queue packets to the user space in bridge
family. But when the user specify the queue range, packets will be only
delivered to the first queue num. Because in nfqueue_hash, we only support
ipv4 and ipv6 family. Now add support for bridge family too.
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_queue.h | 56 ++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 13 deletions(-)
@@ -41,22 +41,19 @@ static inline void init_hashrandom(u32 *jhash_initval)*jhash_initval=prandom_u32();}-staticinlineu32hash_v4(conststructsk_buff*skb,u32jhash_initval)+staticinlineu32hash_v4(conststructiphdr*iph,u32initval){-conststructiphdr*iph=ip_hdr(skb);-/* packets in either direction go into same queue */if((__forceu32)iph->saddr<(__forceu32)iph->daddr)returnjhash_3words((__forceu32)iph->saddr,-(__forceu32)iph->daddr,iph->protocol,jhash_initval);+(__forceu32)iph->daddr,iph->protocol,initval);returnjhash_3words((__forceu32)iph->daddr,-(__forceu32)iph->saddr,iph->protocol,jhash_initval);+(__forceu32)iph->saddr,iph->protocol,initval);}-staticinlineu32hash_v6(conststructsk_buff*skb,u32jhash_initval)+staticinlineu32hash_v6(conststructipv6hdr*ip6h,u32initval){-conststructipv6hdr*ip6h=ipv6_hdr(skb);u32a,b,c;if((__forceu32)ip6h->saddr.s6_addr32[3]<
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:51
From: Liping Zhang <redacted>
There's an off-by-one issue in nft_payload_fast_eval, skb_tail_pointer
and ptr + priv->len all point to the last valid address plus 1. So if
they are equal, we can still fetch the valid data. It's unnecessary to
fall back to nft_payload_eval.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:54
From: Liping Zhang <redacted>
hash_v6 is used by both nftables and ip6tables, so depend on
IP6_NF_IPTABLES is not properly.
Actually, it only parses ipv6hdr and computes a hash value, so
even if IPV6 is disabled, there's no side effect too, remove it.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_queue.h | 4 ----
1 file changed, 4 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:56
We already checked for !found just a bit before:
if (!found) {
regs->verdict.code = NFT_BREAK;
return;
}
if (found && set->flags & NFT_SET_MAP)
^^^^^
So this redundant check can just go away.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_lookup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:57
From: Gao Feng <redacted>
The origin codes perform two condition checks with dst_mtu(skb_dst(skb))
and in_mtu. And the last statement is "min(dst_mtu(skb_dst(skb)),
in_mtu) - minlen". It may let reader think about how about the result.
Would it be negative.
Now assign the result of min(dst_mtu(skb_dst(skb)), in_mtu) to a new
variable, then only perform one condition check, and it is more readable.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/xt_TCPMSS.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:07:58
From: Florian Westphal <fw@strlen.de>
This replaces the last uses of NF_HOOK_THRESH().
Followup patch will remove it and rename nf_hook_thresh.
The reason is that inet (non-bridge) netfilter no longer invokes the
hooks from hooks, so we do no longer need the thresh value to skip hooks
with a lower priority.
The bridge netfilter however may need to do this. br_nf_hook_thresh is a
wrapper that is supposed to do this, i.e. only call hooks with a
priority that exceeds NF_BR_PRI_BRNF.
It's used only in the recursion cases of br_netfilter. It invokes
nf_hook_slow while holding an rcu read-side critical section to make a
future cleanup simpler.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Aaron Conole <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/br_netfilter.h | 6 ++++
net/bridge/br_netfilter_hooks.c | 60 ++++++++++++++++++++++++++++++------
net/bridge/br_netfilter_ipv6.c | 12 +++-----
3 files changed, 62 insertions(+), 16 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:00
From: Aaron Conole <redacted>
This commit ensures that the rcu read-side lock is held while the
ingress hook is called. This ensures that a call to nf_hook_slow (and
ultimately nf_ingress) will be read protected.
Signed-off-by: Aaron Conole <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/core/dev.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:02
From: Aaron Conole <redacted>
This commit adds an upfront check for sane values to be passed when
registering a netfilter hook. This will be used in a future patch for a
simplified hook list traversal.
Signed-off-by: Aaron Conole <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/core.c | 5 +++++
1 file changed, 5 insertions(+)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:03
From: Aaron Conole <redacted>
A future patch will modify the hook drop and outfn functions. This will
cause the line lengths to take up too much space. This is simply a
readability change.
Signed-off-by: Aaron Conole <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_queue.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:04
From: Gao Feng <redacted>
It is valid that the TCP RST packet which does not set ack flag, and bytes
of ack number are zero. But current seqadj codes would adjust the "0" ack
to invalid ack number. Actually seqadj need to check the ack flag before
adjust it for these RST packets.
The following is my test case
client is 10.26.98.245, and add one iptable rule:
iptables -I INPUT -p tcp --sport 12345 -m connbytes --connbytes 2:
--connbytes-dir reply --connbytes-mode packets -j REJECT --reject-with
tcp-reset
This iptables rule could generate on TCP RST without ack flag.
server:10.172.135.55
Enable the synproxy with seqadjust by the following iptables rules
iptables -t raw -A PREROUTING -i eth0 -p tcp -d 10.172.135.55 --dport 12345
-m tcp --syn -j CT --notrack
iptables -A INPUT -i eth0 -p tcp -d 10.172.135.55 --dport 12345 -m conntrack
--ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7
--mss 1460
iptables -A OUTPUT -o eth0 -p tcp -s 10.172.135.55 --sport 12345 -m conntrack
--ctstate INVALID,UNTRACKED -m tcp --tcp-flags SYN,RST,ACK SYN,ACK -j ACCEPT
The following is my test result.
1. packet trace on client
root@routers:/tmp# tcpdump -i eth0 tcp port 12345 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
IP 10.26.98.245.45154 > 10.172.135.55.12345: Flags [S], seq 3695959829,
win 29200, options [mss 1460,sackOK,TS val 452367884 ecr 0,nop,wscale 7],
length 0
IP 10.172.135.55.12345 > 10.26.98.245.45154: Flags [S.], seq 546723266,
ack 3695959830, win 0, options [mss 1460,sackOK,TS val 15643479 ecr 452367884,
nop,wscale 7], length 0
IP 10.26.98.245.45154 > 10.172.135.55.12345: Flags [.], ack 1, win 229,
options [nop,nop,TS val 452367885 ecr 15643479], length 0
IP 10.172.135.55.12345 > 10.26.98.245.45154: Flags [.], ack 1, win 226,
options [nop,nop,TS val 15643479 ecr 452367885], length 0
IP 10.26.98.245.45154 > 10.172.135.55.12345: Flags [R], seq 3695959830,
win 0, length 0
2. seqadj log on server
[62873.867319] Adjusting sequence number from 602341895->546723267,
ack from 3695959830->3695959830
[62873.867644] Adjusting sequence number from 602341895->546723267,
ack from 3695959830->3695959830
[62873.869040] Adjusting sequence number from 3695959830->3695959830,
ack from 0->55618628
To summarize, it is clear that the seqadj codes adjust the 0 ack when receive
one TCP RST packet without ack.
Signed-off-by: Gao Feng <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_seqadj.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
@@ -169,7 +169,7 @@ int nf_ct_seq_adjust(struct sk_buff *skb,s32seqoff,ackoff;structnf_conn_seqadj*seqadj=nfct_seqadj(ct);structnf_ct_seqadj*this_way,*other_way;-intres;+intres=1;this_way=&seqadj->seq[dir];other_way=&seqadj->seq[!dir];
@@ -184,27 +184,31 @@ int nf_ct_seq_adjust(struct sk_buff *skb,elseseqoff=this_way->offset_before;+newseq=htonl(ntohl(tcph->seq)+seqoff);+inet_proto_csum_replace4(&tcph->check,skb,tcph->seq,newseq,false);+pr_debug("Adjusting sequence number from %u->%u\n",+ntohl(tcph->seq),ntohl(newseq));+tcph->seq=newseq;++if(!tcph->ack)+gotoout;+if(after(ntohl(tcph->ack_seq)-other_way->offset_before,other_way->correction_pos))ackoff=other_way->offset_after;elseackoff=other_way->offset_before;-newseq=htonl(ntohl(tcph->seq)+seqoff);newack=htonl(ntohl(tcph->ack_seq)-ackoff);--inet_proto_csum_replace4(&tcph->check,skb,tcph->seq,newseq,false);inet_proto_csum_replace4(&tcph->check,skb,tcph->ack_seq,newack,false);--pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",+pr_debug("Adjusting ack number from %u->%u, ack from %u->%u\n",ntohl(tcph->seq),ntohl(newseq),ntohl(tcph->ack_seq),ntohl(newack));--tcph->seq=newseq;tcph->ack_seq=newack;res=nf_ct_sack_adjust(skb,protoff,tcph,ct,ctinfo);+out:spin_unlock_bh(&ct->lock);returnres;
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:09
From: Vishwanath Pai <redacted>
Create a new revision for the hashlimit iptables extension module. Rev 2
will support higher pps of upto 1 million, Version 1 supports only 10k.
To support this we have to increase the size of the variables avg and
burst in hashlimit_cfg to 64-bit. Create two new structs hashlimit_cfg2
and xt_hashlimit_mtinfo2 and also create newer versions of all the
functions for match, checkentry and destroy.
Some of the functions like hashlimit_mt, hashlimit_mt_check etc are very
similar in both rev1 and rev2 with only minor changes, so I have split
those functions and moved all the common code to a *_common function.
Signed-off-by: Vishwanath Pai <redacted>
Signed-off-by: Joshua Hunt <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/xt_hashlimit.h | 23 ++
net/netfilter/xt_hashlimit.c | 330 ++++++++++++++++++++++------
2 files changed, 285 insertions(+), 68 deletions(-)
@@ -6,6 +6,7 @@/* timings are in milliseconds. */#define XT_HASHLIMIT_SCALE 10000+#define XT_HASHLIMIT_SCALE_v2 1000000llu/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490*seconds,oronepacketevery59hours.*/
@@ -63,6 +64,20 @@ struct hashlimit_cfg1 {__u8srcmask,dstmask;};+structhashlimit_cfg2{+__u64avg;/* Average secs between packets * scale */+__u64burst;/* Period multiplier for upper limit. */+__u32mode;/* bitmask of XT_HASHLIMIT_HASH_* */++/* user specified */+__u32size;/* how many buckets */+__u32max;/* max number of entries */+__u32gc_interval;/* gc interval */+__u32expire;/* when do entries expire? */++__u8srcmask,dstmask;+};+structxt_hashlimit_mtinfo1{charname[IFNAMSIZ];structhashlimit_cfg1cfg;
@@ -71,4 +86,12 @@ struct xt_hashlimit_mtinfo1 {structxt_hashlimit_htable*hinfo__attribute__((aligned(8)));};+structxt_hashlimit_mtinfo2{+charname[NAME_MAX];+structhashlimit_cfg2cfg;++/* Used internally by the kernel */+structxt_hashlimit_htable*hinfo__attribute__((aligned(8)));+};+#endif /* _UAPI_XT_HASHLIMIT_H */
@@ -57,6 +57,7 @@ static inline struct hashlimit_net *hashlimit_pernet(struct net *net)/* need to declare this at the top */staticconststructfile_operationsdl_file_ops_v1;+staticconststructfile_operationsdl_file_ops;/* hash table crap */structdsthash_dst{
@@ -86,8 +87,8 @@ struct dsthash_ent {unsignedlongexpires;/* precalculated expiry time */struct{unsignedlongprev;/* last modification */-u_int32_tcredit;-u_int32_tcredit_cap,cost;+u_int64_tcredit;+u_int64_tcredit_cap,cost;}rateinfo;structrcu_headrcu;};
@@ -98,7 +99,7 @@ struct xt_hashlimit_htable {u_int8_tfamily;boolrnd_initialized;-structhashlimit_cfg1cfg;/* config */+structhashlimit_cfg2cfg;/* config *//* used internally */spinlock_tlock;/* lock for list_head */
@@ -238,10 +265,14 @@ static int htable_create_v1(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,sizeof(structlist_head)*size);if(hinfo==NULL)return-ENOMEM;-minfo->hinfo=hinfo;+*out_hinfo=hinfo;/* copy match config into hashtable config */-memcpy(&hinfo->cfg,&minfo->cfg,sizeof(hinfo->cfg));+ret=cfg_copy(&hinfo->cfg,(void*)cfg,2);++if(ret)+returnret;+hinfo->cfg.size=size;if(hinfo->cfg.max==0)hinfo->cfg.max=8*hinfo->cfg.size;
@@ -255,17 +286,18 @@ static int htable_create_v1(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,hinfo->count=0;hinfo->family=family;hinfo->rnd_initialized=false;-hinfo->name=kstrdup(minfo->name,GFP_KERNEL);+hinfo->name=kstrdup(name,GFP_KERNEL);if(!hinfo->name){vfree(hinfo);return-ENOMEM;}spin_lock_init(&hinfo->lock);-hinfo->pde=proc_create_data(minfo->name,0,+hinfo->pde=proc_create_data(name,0,(family==NFPROTO_IPV4)?hashlimit_net->ipt_hashlimit:hashlimit_net->ip6t_hashlimit,-&dl_file_ops_v1,hinfo);+(revision==1)?&dl_file_ops_v1:&dl_file_ops,+hinfo);if(hinfo->pde==NULL){kfree(hinfo->name);vfree(hinfo);
@@ -399,6 +431,7 @@ static void htable_put(struct xt_hashlimit_htable *hinfo)CREDITS_PER_JIFFY*HZ*60*60*24<2^32ie.*/#define MAX_CPJ_v1 (0xFFFFFFFF / (HZ*60*60*24))+#define MAX_CPJ (0xFFFFFFFFFFFFFFFF / (HZ*60*60*24))/* Repeated shift and or gives us all 1s, final shift and add 1 gives*usthepowerof2belowthetheoreticalmax,soGCCsimplydoesa
@@ -408,8 +441,11 @@ static void htable_put(struct xt_hashlimit_htable *hinfo)#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))+#define _POW2_BELOW64(x) (_POW2_BELOW32(x)|_POW2_BELOW32((x)>>32))#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)+#define POW2_BELOW64(x) ((_POW2_BELOW64(x)>>1) + 1)+#define CREDITS_PER_JIFFY POW2_BELOW64(MAX_CPJ)#define CREDITS_PER_JIFFY_v1 POW2_BELOW32(MAX_CPJ_v1)/* in byte mode, the lowest possible rate is one packet/second.
@@ -425,15 +461,24 @@ static u32 xt_hashlimit_len_to_chunks(u32 len)}/* Precision saver. */-staticu32user2credits(u32user)+staticu64user2credits(u64user,intrevision){-/* If multiplying would overflow... */-if(user>0xFFFFFFFF/(HZ*CREDITS_PER_JIFFY_v1))-/* Divide first. */-return(user/XT_HASHLIMIT_SCALE)*\-HZ*CREDITS_PER_JIFFY_v1;+if(revision==1){+/* If multiplying would overflow... */+if(user>0xFFFFFFFF/(HZ*CREDITS_PER_JIFFY_v1))+/* Divide first. */+return(user/XT_HASHLIMIT_SCALE)*\+HZ*CREDITS_PER_JIFFY_v1;++return(user*HZ*CREDITS_PER_JIFFY_v1)\+/XT_HASHLIMIT_SCALE;+}else{+if(user>0xFFFFFFFFFFFFFFFF/(HZ*CREDITS_PER_JIFFY))+return(user/XT_HASHLIMIT_SCALE_v2)*\+HZ*CREDITS_PER_JIFFY;-return(user*HZ*CREDITS_PER_JIFFY_v1)/XT_HASHLIMIT_SCALE;+return(user*HZ*CREDITS_PER_JIFFY)/XT_HASHLIMIT_SCALE_v2;+}}staticu32user2credits_byte(u32user)
@@ -648,70 +696,126 @@ hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)dh->rateinfo.credit-=cost;spin_unlock(&dh->lock);rcu_read_unlock_bh();-return!(info->cfg.mode&XT_HASHLIMIT_INVERT);+return!(cfg->mode&XT_HASHLIMIT_INVERT);}spin_unlock(&dh->lock);rcu_read_unlock_bh();/* default match is underlimit - so over the limit, we need to invert */-returninfo->cfg.mode&XT_HASHLIMIT_INVERT;+returncfg->mode&XT_HASHLIMIT_INVERT;hotdrop:par->hotdrop=true;returnfalse;}-staticinthashlimit_mt_check_v1(conststructxt_mtchk_param*par)+staticbool+hashlimit_mt_v1(conststructsk_buff*skb,structxt_action_param*par)+{+conststructxt_hashlimit_mtinfo1*info=par->matchinfo;+structxt_hashlimit_htable*hinfo=info->hinfo;+structhashlimit_cfg2cfg={};+intret;++ret=cfg_copy(&cfg,(void*)&info->cfg,1);++if(ret)+returnret;++returnhashlimit_mt_common(skb,par,hinfo,&cfg,1);+}++staticbool+hashlimit_mt(conststructsk_buff*skb,structxt_action_param*par)+{+conststructxt_hashlimit_mtinfo2*info=par->matchinfo;+structxt_hashlimit_htable*hinfo=info->hinfo;++returnhashlimit_mt_common(skb,par,hinfo,&info->cfg,2);+}++staticinthashlimit_mt_check_common(conststructxt_mtchk_param*par,+structxt_hashlimit_htable**hinfo,+structhashlimit_cfg2*cfg,+constchar*name,intrevision){structnet*net=par->net;-structxt_hashlimit_mtinfo1*info=par->matchinfo;intret;-if(info->cfg.gc_interval==0||info->cfg.expire==0)-return-EINVAL;-if(info->name[sizeof(info->name)-1]!='\0')+if(cfg->gc_interval==0||cfg->expire==0)return-EINVAL;if(par->family==NFPROTO_IPV4){-if(info->cfg.srcmask>32||info->cfg.dstmask>32)+if(cfg->srcmask>32||cfg->dstmask>32)return-EINVAL;}else{-if(info->cfg.srcmask>128||info->cfg.dstmask>128)+if(cfg->srcmask>128||cfg->dstmask>128)return-EINVAL;}-if(info->cfg.mode&~XT_HASHLIMIT_ALL){+if(cfg->mode&~XT_HASHLIMIT_ALL){pr_info("Unknown mode mask %X, kernel too old?\n",-info->cfg.mode);+cfg->mode);return-EINVAL;}/* Check for overflow. */-if(info->cfg.mode&XT_HASHLIMIT_BYTES){-if(user2credits_byte(info->cfg.avg)==0){-pr_info("overflow, rate too high: %u\n",info->cfg.avg);+if(cfg->mode&XT_HASHLIMIT_BYTES){+if(user2credits_byte(cfg->avg)==0){+pr_info("overflow, rate too high: %llu\n",cfg->avg);return-EINVAL;}-}elseif(info->cfg.burst==0||-user2credits(info->cfg.avg*info->cfg.burst)<-user2credits(info->cfg.avg)){-pr_info("overflow, try lower: %u/%u\n",-info->cfg.avg,info->cfg.burst);+}elseif(cfg->burst==0||+user2credits(cfg->avg*cfg->burst,revision)<+user2credits(cfg->avg,revision)){+pr_info("overflow, try lower: %llu/%llu\n",+cfg->avg,cfg->burst);return-ERANGE;}mutex_lock(&hashlimit_mutex);-info->hinfo=htable_find_get(net,info->name,par->family);-if(info->hinfo==NULL){-ret=htable_create_v1(net,info,par->family);+*hinfo=htable_find_get(net,name,par->family);+if(*hinfo==NULL){+ret=htable_create(net,cfg,name,par->family,+hinfo,revision);if(ret<0){mutex_unlock(&hashlimit_mutex);returnret;}}mutex_unlock(&hashlimit_mutex);+return0;}+staticinthashlimit_mt_check_v1(conststructxt_mtchk_param*par)+{+structxt_hashlimit_mtinfo1*info=par->matchinfo;+structhashlimit_cfg2cfg={};+intret;++if(info->name[sizeof(info->name)-1]!='\0')+return-EINVAL;++ret=cfg_copy(&cfg,(void*)&info->cfg,1);++if(ret)+returnret;++returnhashlimit_mt_check_common(par,&info->hinfo,+&cfg,info->name,1);+}++staticinthashlimit_mt_check(conststructxt_mtchk_param*par)+{+structxt_hashlimit_mtinfo2*info=par->matchinfo;++if(info->name[sizeof(info->name)-1]!='\0')+return-EINVAL;++returnhashlimit_mt_check_common(par,&info->hinfo,&info->cfg,+info->name,2);+}+staticvoidhashlimit_mt_destroy_v1(conststructxt_mtdtor_param*par){conststructxt_hashlimit_mtinfo1*info=par->matchinfo;
@@ -822,6 +947,34 @@ static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family,default:BUG();}+}++staticintdl_seq_real_show_v1(structdsthash_ent*ent,u_int8_tfamily,+structseq_file*s)+{+conststructxt_hashlimit_htable*ht=s->private;++spin_lock(&ent->lock);+/* recalculate to show accurate numbers */+rateinfo_recalc(ent,jiffies,ht->cfg.mode,1);++dl_seq_print(ent,family,s);++spin_unlock(&ent->lock);+returnseq_has_overflowed(s);+}++staticintdl_seq_real_show(structdsthash_ent*ent,u_int8_tfamily,+structseq_file*s)+{+conststructxt_hashlimit_htable*ht=s->private;++spin_lock(&ent->lock);+/* recalculate to show accurate numbers */+rateinfo_recalc(ent,jiffies,ht->cfg.mode,2);++dl_seq_print(ent,family,s);+spin_unlock(&ent->lock);returnseq_has_overflowed(s);}
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:10
From: Florian Westphal <fw@strlen.de>
Fabian reports a possible conntrack memory leak (could not reproduce so
far), however, one minor issue can be easily resolved:
cat /proc/net/nf_conntrack | wc -l = 5
4 minutes required to clean up the table.
We should not report those timed-out entries to the user in first place.
And instead of just skipping those timed-out entries while iterating over
the table we can also zap them (we already do this during ctnetlink
walks, but I forgot about the /proc interface).
Fixes: f330a7fdbe16 ("netfilter: conntrack: get rid of conntrack timer")
Reported-by: Fabian Frederick <redacted>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_standalone.c | 5 +++++
1 file changed, 5 insertions(+)
@@ -212,6 +212,11 @@ static int ct_seq_show(struct seq_file *s, void *v)if(unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))return0;+if(nf_ct_should_gc(ct)){+nf_ct_kill(ct);+gotorelease;+}+/* we only want to print DIR_ORIGINAL */if(NF_CT_DIRECTION(hash))gotorelease;
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:13
Inverse ranges != [a,b] are not currently possible because rules are
composites of && operations, and we need to express this:
data < a || data > b
This patch adds a new range expression. Positive ranges can be already
through two cmp expressions:
cmp(sreg, data, >=)
cmp(sreg, data, <=)
This new range expression provides an alternative way to express this.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_core.h | 3 +
include/uapi/linux/netfilter/nf_tables.h | 29 +++++++
net/netfilter/Makefile | 3 +-
net/netfilter/nf_tables_core.c | 7 +-
net/netfilter/nft_range.c | 138 +++++++++++++++++++++++++++++++
5 files changed, 178 insertions(+), 2 deletions(-)
create mode 100644 net/netfilter/nft_range.c
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:14
From: Liping Zhang <redacted>
nf_log is used by both nftables and iptables, so use XT_LOG_XXX macros
here is not appropriate. Replace them with NF_LOG_XXX.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/nf_log_ipv4.c | 6 +++---
net/ipv6/netfilter/nf_log_ipv6.c | 14 +++++++-------
net/netfilter/nf_log_common.c | 4 ++--
3 files changed, 12 insertions(+), 12 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2016-09-25 23:08:14
From: Liping Zhang <redacted>
NFTA_LOG_FLAGS attribute is already supported, but the related
NF_LOG_XXX flags are not exposed to the userspace. So we cannot
explicitly enable log flags to log uid, tcp sequence, ip options
and so on, i.e. such rule "nft add rule filter output log uid"
is not supported yet.
So move NF_LOG_XXX macro definitions to the uapi/../nf_log.h. In
order to keep consistent with other modules, change NF_LOG_MASK to
refer to all supported log flags. On the other hand, add a new
NF_LOG_DEFAULT_MASK to refer to the original default log flags.
Finally, if user specify the unsupported log flags or NFTA_LOG_GROUP
and NFTA_LOG_FLAGS are set at the same time, report EINVAL to the
userspace.
Signed-off-by: Liping Zhang <redacted>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_log.h | 11 +++--------
include/uapi/linux/netfilter/nf_log.h | 12 ++++++++++++
net/bridge/netfilter/ebt_log.c | 2 +-
net/ipv4/netfilter/ip_tables.c | 2 +-
net/ipv4/netfilter/nf_log_arp.c | 2 +-
net/ipv4/netfilter/nf_log_ipv4.c | 4 ++--
net/ipv6/netfilter/ip6_tables.c | 2 +-
net/ipv6/netfilter/nf_log_ipv6.c | 4 ++--
net/netfilter/nf_tables_core.c | 2 +-
net/netfilter/nft_log.c | 9 ++++++++-
10 files changed, 32 insertions(+), 18 deletions(-)
create mode 100644 include/uapi/linux/netfilter/nf_log.h
@@ -2,15 +2,10 @@#define _NF_LOG_H#include<linux/netfilter.h>+#include<linux/netfilter/nf_log.h>-/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will-*disappearonceiptablesisreplacedwithpkttables.PleaseDONOTusethem-*foranynewcode!*/-#define NF_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */-#define NF_LOG_TCPOPT 0x02 /* Log TCP options */-#define NF_LOG_IPOPT 0x04 /* Log IP options */-#define NF_LOG_UID 0x08 /* Log UID owning local socket */-#define NF_LOG_MASK 0x0f+/* Log tcp sequence, tcp options, ip options and uid owning local socket */+#define NF_LOG_DEFAULT_MASK 0x0f/* This flag indicates that copy_len field in nf_loginfo is set */#define NF_LOG_F_COPY_LEN 0x1