Commit 022c10d6 authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for net-next:

1) Fix error path of nf_tables_updobj(), from Dan Carpenter.

2) Move large structure away from stack in the nf_tables offload
   infrastructure, from Arnd Bergmann.

3) Move indirect flow_block logic to nf_tables_offload.

4) Support for synproxy objects, from Fernando Fernandez Mancera.

5) Support for fwd and dup offload.

6) Add __nft_offload_get_chain() helper, this implicitly fixes missing
   mutex and check for offload flags in the indirect block support,
   patch from wenxu.

7) Remove rules on device unregistration, from wenxu. This includes
   two preparation patches to reuse nft_flow_offload_chain() and
   nft_flow_offload_rule().

Large batch from Jeremy Sowden to make a second pass to the
CONFIG_HEADER_TEST support and a bit of housekeeping:

8) Missing include guard in conntrack label header, from Jeremy Sowden.

9) A few coding style errors: trailing whitespace, incorrect indent in
   Kconfig, and semicolons at the end of function definitions.

10) Remove unused ipt_init() and ip6t_init() declarations.

11) Inline xt_hashlimit, ebt_802_3 and xt_physdev headers. They are
    only used once.

12) Update include directive in several netfilter files.

13) Remove unused include/net/netfilter/ipv6/nf_conntrack_icmpv6.h.

14) Move nf_ip6_ext_hdr() to include/linux/netfilter_ipv6.h

15) Move several synproxy structure definitions to nf_synproxy.h

16) Move nf_bridge_frag_data structure to include/linux/netfilter_bridge.h

17) Clean up static inline definitions in nf_conntrack_ecache.h.

18) Replace defined(CONFIG...) || defined(CONFIG...MODULE) with IS_ENABLED(CONFIG...).

19) Missing inline function conditional definitions based on Kconfig
    preferences in synproxy and nf_conntrack_timeout.

20) Update br_nf_pre_routing_ipv6() definition.

21) Move conntrack code in linux/skbuff.h to nf_conntrack headers.

22) Several patches to remove superfluous CONFIG_NETFILTER and
    CONFIG_NF_CONNTRACK checks in headers, coming from the initial batch
    support for CONFIG_HEADER_TEST for netfilter.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 172ca830 0d32e704
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#ifdef CONFIG_NETFILTER
static inline int NF_DROP_GETERR(int verdict) static inline int NF_DROP_GETERR(int verdict)
{ {
return -(verdict >> NF_VERDICT_QBITS); return -(verdict >> NF_VERDICT_QBITS);
...@@ -118,6 +117,7 @@ struct nf_hook_entries { ...@@ -118,6 +117,7 @@ struct nf_hook_entries {
*/ */
}; };
#ifdef CONFIG_NETFILTER
static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e) static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e)
{ {
unsigned int n = e->num_hook_entries; unsigned int n = e->num_hook_entries;
...@@ -422,7 +422,7 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) ...@@ -422,7 +422,7 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
} }
#endif /*CONFIG_NETFILTER*/ #endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <linux/netfilter/nf_conntrack_zones_common.h> #include <linux/netfilter/nf_conntrack_zones_common.h>
extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu; extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
extern bool ip_set_get_ip4_port(const struct sk_buff *skb, bool src, extern bool ip_set_get_ip4_port(const struct sk_buff *skb, bool src,
__be16 *port, u8 *proto); __be16 *port, u8 *proto);
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
extern bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src, extern bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src,
__be16 *port, u8 *proto); __be16 *port, u8 *proto);
#else #else
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#ifndef _NF_CONNTRACK_COMMON_H #ifndef _NF_CONNTRACK_COMMON_H
#define _NF_CONNTRACK_COMMON_H #define _NF_CONNTRACK_COMMON_H
#include <linux/atomic.h>
#include <uapi/linux/netfilter/nf_conntrack_common.h> #include <uapi/linux/netfilter/nf_conntrack_common.h>
struct ip_conntrack_stat { struct ip_conntrack_stat {
...@@ -19,4 +20,23 @@ struct ip_conntrack_stat { ...@@ -19,4 +20,23 @@ struct ip_conntrack_stat {
unsigned int search_restart; unsigned int search_restart;
}; };
#define NFCT_INFOMASK 7UL
#define NFCT_PTRMASK ~(NFCT_INFOMASK)
struct nf_conntrack {
atomic_t use;
};
void nf_conntrack_destroy(struct nf_conntrack *nfct);
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{
if (nfct && atomic_dec_and_test(&nfct->use))
nf_conntrack_destroy(nfct);
}
static inline void nf_conntrack_get(struct nf_conntrack *nfct)
{
if (nfct)
atomic_inc(&nfct->use);
}
#endif /* _NF_CONNTRACK_COMMON_H */ #endif /* _NF_CONNTRACK_COMMON_H */
...@@ -35,15 +35,12 @@ struct xt_action_param { ...@@ -35,15 +35,12 @@ struct xt_action_param {
union { union {
const void *matchinfo, *targinfo; const void *matchinfo, *targinfo;
}; };
#if IS_ENABLED(CONFIG_NETFILTER)
const struct nf_hook_state *state; const struct nf_hook_state *state;
#endif
int fragoff; int fragoff;
unsigned int thoff; unsigned int thoff;
bool hotdrop; bool hotdrop;
}; };
#if IS_ENABLED(CONFIG_NETFILTER)
static inline struct net *xt_net(const struct xt_action_param *par) static inline struct net *xt_net(const struct xt_action_param *par)
{ {
return par->state->net; return par->state->net;
...@@ -78,7 +75,6 @@ static inline u_int8_t xt_family(const struct xt_action_param *par) ...@@ -78,7 +75,6 @@ static inline u_int8_t xt_family(const struct xt_action_param *par)
{ {
return par->state->pf; return par->state->pf;
} }
#endif
/** /**
* struct xt_mtchk_param - parameters for match extensions' * struct xt_mtchk_param - parameters for match extensions'
...@@ -340,7 +336,7 @@ void xt_free_table_info(struct xt_table_info *info); ...@@ -340,7 +336,7 @@ void xt_free_table_info(struct xt_table_info *info);
/** /**
* xt_recseq - recursive seqcount for netfilter use * xt_recseq - recursive seqcount for netfilter use
* *
* Packet processing changes the seqcount only if no recursion happened * Packet processing changes the seqcount only if no recursion happened
* get_counters() can use read_seqcount_begin()/read_seqcount_retry(), * get_counters() can use read_seqcount_begin()/read_seqcount_retry(),
* because we use the normal seqcount convention : * because we use the normal seqcount convention :
...@@ -450,9 +446,7 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu) ...@@ -450,9 +446,7 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu)
return cnt; return cnt;
} }
#if IS_ENABLED(CONFIG_NETFILTER)
struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *); struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <net/compat.h> #include <net/compat.h>
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _XT_HASHLIMIT_H
#define _XT_HASHLIMIT_H
#include <uapi/linux/netfilter/xt_hashlimit.h>
#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \
XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \
XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES |\
XT_HASHLIMIT_RATE_MATCH)
#endif /*_XT_HASHLIMIT_H*/
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _XT_PHYSDEV_H
#define _XT_PHYSDEV_H
#include <linux/if.h>
#include <uapi/linux/netfilter/xt_physdev.h>
#endif /*_XT_PHYSDEV_H*/
...@@ -49,7 +49,6 @@ struct arpt_error { ...@@ -49,7 +49,6 @@ struct arpt_error {
} }
extern void *arpt_alloc_initial_table(const struct xt_table *); extern void *arpt_alloc_initial_table(const struct xt_table *);
#if IS_ENABLED(CONFIG_NETFILTER)
int arpt_register_table(struct net *net, const struct xt_table *table, int arpt_register_table(struct net *net, const struct xt_table *table,
const struct arpt_replace *repl, const struct arpt_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res); const struct nf_hook_ops *ops, struct xt_table **res);
...@@ -58,7 +57,6 @@ void arpt_unregister_table(struct net *net, struct xt_table *table, ...@@ -58,7 +57,6 @@ void arpt_unregister_table(struct net *net, struct xt_table *table,
extern unsigned int arpt_do_table(struct sk_buff *skb, extern unsigned int arpt_do_table(struct sk_buff *skb,
const struct nf_hook_state *state, const struct nf_hook_state *state,
struct xt_table *table); struct xt_table *table);
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <net/compat.h> #include <net/compat.h>
......
...@@ -5,6 +5,13 @@ ...@@ -5,6 +5,13 @@
#include <uapi/linux/netfilter_bridge.h> #include <uapi/linux/netfilter_bridge.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
struct nf_bridge_frag_data {
char mac[ETH_HLEN];
bool vlan_present;
u16 vlan_tci;
__be16 vlan_proto;
};
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_BRIDGE_EBT_802_3_H
#define __LINUX_BRIDGE_EBT_802_3_H
#include <linux/skbuff.h>
#include <uapi/linux/netfilter_bridge/ebt_802_3.h>
static inline struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
{
return (struct ebt_802_3_hdr *)skb_mac_header(skb);
}
#endif
...@@ -105,7 +105,7 @@ struct ebt_table { ...@@ -105,7 +105,7 @@ struct ebt_table {
#define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \ #define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \
~(__alignof__(struct _xt_align)-1)) ~(__alignof__(struct _xt_align)-1))
#if IS_ENABLED(CONFIG_NETFILTER)
extern int ebt_register_table(struct net *net, extern int ebt_register_table(struct net *net,
const struct ebt_table *table, const struct ebt_table *table,
const struct nf_hook_ops *ops, const struct nf_hook_ops *ops,
...@@ -115,7 +115,6 @@ extern void ebt_unregister_table(struct net *net, struct ebt_table *table, ...@@ -115,7 +115,6 @@ extern void ebt_unregister_table(struct net *net, struct ebt_table *table,
extern unsigned int ebt_do_table(struct sk_buff *skb, extern unsigned int ebt_do_table(struct sk_buff *skb,
const struct nf_hook_state *state, const struct nf_hook_state *state,
struct ebt_table *table); struct ebt_table *table);
#endif
/* True if the hook mask denotes that the rule is in a base chain, /* True if the hook mask denotes that the rule is in a base chain,
* used in the check() functions */ * used in the check() functions */
......
...@@ -17,21 +17,16 @@ ...@@ -17,21 +17,16 @@
#include <linux/if.h> #include <linux/if.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/init.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/init.h>
#include <uapi/linux/netfilter_ipv4/ip_tables.h> #include <uapi/linux/netfilter_ipv4/ip_tables.h>
extern void ipt_init(void) __init;
#if IS_ENABLED(CONFIG_NETFILTER)
int ipt_register_table(struct net *net, const struct xt_table *table, int ipt_register_table(struct net *net, const struct xt_table *table,
const struct ipt_replace *repl, const struct ipt_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res); const struct nf_hook_ops *ops, struct xt_table **res);
void ipt_unregister_table(struct net *net, struct xt_table *table, void ipt_unregister_table(struct net *net, struct xt_table *table,
const struct nf_hook_ops *ops); const struct nf_hook_ops *ops);
#endif
/* Standard entry. */ /* Standard entry. */
struct ipt_standard { struct ipt_standard {
...@@ -67,11 +62,9 @@ struct ipt_error { ...@@ -67,11 +62,9 @@ struct ipt_error {
} }
extern void *ipt_alloc_initial_table(const struct xt_table *); extern void *ipt_alloc_initial_table(const struct xt_table *);
#if IS_ENABLED(CONFIG_NETFILTER)
extern unsigned int ipt_do_table(struct sk_buff *skb, extern unsigned int ipt_do_table(struct sk_buff *skb,
const struct nf_hook_state *state, const struct nf_hook_state *state,
struct xt_table *table); struct xt_table *table);
#endif
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <net/compat.h> #include <net/compat.h>
......
/* IPv6-specific defines for netfilter. /* IPv6-specific defines for netfilter.
* (C)1998 Rusty Russell -- This code is GPL. * (C)1998 Rusty Russell -- This code is GPL.
* (C)1999 David Jeffery * (C)1999 David Jeffery
* this header was blatantly ripped from netfilter_ipv4.h * this header was blatantly ripped from netfilter_ipv4.h
* it's amazing what adding a bunch of 6s can do =8^) * it's amazing what adding a bunch of 6s can do =8^)
*/ */
#ifndef __LINUX_IP6_NETFILTER_H #ifndef __LINUX_IP6_NETFILTER_H
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#include <uapi/linux/netfilter_ipv6.h> #include <uapi/linux/netfilter_ipv6.h>
#include <net/tcp.h> #include <net/tcp.h>
/* Check for an extension */
static inline int
nf_ip6_ext_hdr(u8 nexthdr)
{ return (nexthdr == IPPROTO_HOPOPTS) ||
(nexthdr == IPPROTO_ROUTING) ||
(nexthdr == IPPROTO_FRAGMENT) ||
(nexthdr == IPPROTO_ESP) ||
(nexthdr == IPPROTO_AH) ||
(nexthdr == IPPROTO_NONE) ||
(nexthdr == IPPROTO_DSTOPTS);
}
/* Extra routing may needed on local out, as the QUEUE target never returns /* Extra routing may needed on local out, as the QUEUE target never returns
* control to the table. * control to the table.
*/ */
...@@ -20,7 +32,7 @@ struct ip6_rt_info { ...@@ -20,7 +32,7 @@ struct ip6_rt_info {
}; };
struct nf_queue_entry; struct nf_queue_entry;
struct nf_ct_bridge_frag_data; struct nf_bridge_frag_data;
/* /*
* Hook functions for ipv6 to allow xt_* modules to be built-in even * Hook functions for ipv6 to allow xt_* modules to be built-in even
...@@ -49,9 +61,9 @@ struct nf_ipv6_ops { ...@@ -49,9 +61,9 @@ struct nf_ipv6_ops {
int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user); int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user);
int (*br_fragment)(struct net *net, struct sock *sk, int (*br_fragment)(struct net *net, struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data, struct nf_bridge_frag_data *data,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)); struct sk_buff *));
#endif #endif
}; };
...@@ -123,16 +135,16 @@ static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb, ...@@ -123,16 +135,16 @@ static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb,
} }
int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data, struct nf_bridge_frag_data *data,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)); struct sk_buff *));
static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk, static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data, struct nf_bridge_frag_data *data,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)) struct sk_buff *))
{ {
#if IS_MODULE(CONFIG_IPV6) #if IS_MODULE(CONFIG_IPV6)
......
...@@ -17,16 +17,13 @@ ...@@ -17,16 +17,13 @@
#include <linux/if.h> #include <linux/if.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/init.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/init.h>
#include <uapi/linux/netfilter_ipv6/ip6_tables.h> #include <uapi/linux/netfilter_ipv6/ip6_tables.h>
extern void ip6t_init(void) __init;
extern void *ip6t_alloc_initial_table(const struct xt_table *); extern void *ip6t_alloc_initial_table(const struct xt_table *);
#if IS_ENABLED(CONFIG_NETFILTER)
int ip6t_register_table(struct net *net, const struct xt_table *table, int ip6t_register_table(struct net *net, const struct xt_table *table,
const struct ip6t_replace *repl, const struct ip6t_replace *repl,
const struct nf_hook_ops *ops, struct xt_table **res); const struct nf_hook_ops *ops, struct xt_table **res);
...@@ -35,19 +32,6 @@ void ip6t_unregister_table(struct net *net, struct xt_table *table, ...@@ -35,19 +32,6 @@ void ip6t_unregister_table(struct net *net, struct xt_table *table,
extern unsigned int ip6t_do_table(struct sk_buff *skb, extern unsigned int ip6t_do_table(struct sk_buff *skb,
const struct nf_hook_state *state, const struct nf_hook_state *state,
struct xt_table *table); struct xt_table *table);
#endif
/* Check for an extension */
static inline int
ip6t_ext_hdr(u8 nexthdr)
{ return (nexthdr == IPPROTO_HOPOPTS) ||
(nexthdr == IPPROTO_ROUTING) ||
(nexthdr == IPPROTO_FRAGMENT) ||
(nexthdr == IPPROTO_ESP) ||
(nexthdr == IPPROTO_AH) ||
(nexthdr == IPPROTO_NONE) ||
(nexthdr == IPPROTO_DSTOPTS);
}
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <net/compat.h> #include <net/compat.h>
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <net/flow.h> #include <net/flow.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <linux/netfilter/nf_conntrack_common.h>
#endif
/* The interface for checksum offload between the stack and networking drivers /* The interface for checksum offload between the stack and networking drivers
* is as follows... * is as follows...
...@@ -244,12 +247,6 @@ struct bpf_prog; ...@@ -244,12 +247,6 @@ struct bpf_prog;
union bpf_attr; union bpf_attr;
struct skb_ext; struct skb_ext;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack {
atomic_t use;
};
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
struct nf_bridge_info { struct nf_bridge_info {
enum { enum {
...@@ -914,7 +911,6 @@ static inline bool skb_pfmemalloc(const struct sk_buff *skb) ...@@ -914,7 +911,6 @@ static inline bool skb_pfmemalloc(const struct sk_buff *skb)
#define SKB_DST_NOREF 1UL #define SKB_DST_NOREF 1UL
#define SKB_DST_PTRMASK ~(SKB_DST_NOREF) #define SKB_DST_PTRMASK ~(SKB_DST_NOREF)
#define SKB_NFCT_PTRMASK ~(7UL)
/** /**
* skb_dst - returns skb dst_entry * skb_dst - returns skb dst_entry
* @skb: buffer * @skb: buffer
...@@ -4040,25 +4036,27 @@ static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr, ...@@ -4040,25 +4036,27 @@ static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
static inline struct nf_conntrack *skb_nfct(const struct sk_buff *skb) static inline struct nf_conntrack *skb_nfct(const struct sk_buff *skb)
{ {
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
return (void *)(skb->_nfct & SKB_NFCT_PTRMASK); return (void *)(skb->_nfct & NFCT_PTRMASK);
#else #else
return NULL; return NULL;
#endif #endif
} }
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) static inline unsigned long skb_get_nfct(const struct sk_buff *skb)
void nf_conntrack_destroy(struct nf_conntrack *nfct);
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{ {
if (nfct && atomic_dec_and_test(&nfct->use)) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
nf_conntrack_destroy(nfct); return skb->_nfct;
#else
return 0UL;
#endif
} }
static inline void nf_conntrack_get(struct nf_conntrack *nfct)
static inline void skb_set_nfct(struct sk_buff *skb, unsigned long nfct)
{ {
if (nfct) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
atomic_inc(&nfct->use); skb->_nfct = nfct;
}
#endif #endif
}
#ifdef CONFIG_SKB_EXTENSIONS #ifdef CONFIG_SKB_EXTENSIONS
enum skb_ext_id { enum skb_ext_id {
......
...@@ -55,7 +55,6 @@ static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) ...@@ -55,7 +55,6 @@ static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
struct net_device *setup_pre_routing(struct sk_buff *skb, struct net_device *setup_pre_routing(struct sk_buff *skb,
const struct net *net); const struct net *net);
#if IS_ENABLED(CONFIG_NETFILTER)
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
int br_validate_ipv6(struct net *net, struct sk_buff *skb); int br_validate_ipv6(struct net *net, struct sk_buff *skb);
unsigned int br_nf_pre_routing_ipv6(void *priv, unsigned int br_nf_pre_routing_ipv6(void *priv,
...@@ -68,12 +67,11 @@ static inline int br_validate_ipv6(struct net *net, struct sk_buff *skb) ...@@ -68,12 +67,11 @@ static inline int br_validate_ipv6(struct net *net, struct sk_buff *skb)
} }
static inline unsigned int static inline unsigned int
br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, struct sk_buff *skb, br_nf_pre_routing_ipv6(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
return NF_ACCEPT; return NF_ACCEPT;
} }
#endif #endif
#endif
#endif /* _BR_NETFILTER_H_ */ #endif /* _BR_NETFILTER_H_ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ICMPv6 tracking.
*
* 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
* - separated from nf_conntrack_icmp.h
*
* Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h
*/
#ifndef _NF_CONNTRACK_ICMPV6_H
#define _NF_CONNTRACK_ICMPV6_H
#ifndef ICMPV6_NI_QUERY
#define ICMPV6_NI_QUERY 139
#endif
#ifndef ICMPV6_NI_REPLY
#define ICMPV6_NI_REPLY 140
#endif
#endif /* _NF_CONNTRACK_ICMPV6_H */
...@@ -13,17 +13,14 @@ ...@@ -13,17 +13,14 @@
#ifndef _NF_CONNTRACK_H #ifndef _NF_CONNTRACK_H
#define _NF_CONNTRACK_H #define _NF_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/atomic.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tcp.h> #include <linux/netfilter/nf_conntrack_tcp.h>
#include <linux/netfilter/nf_conntrack_dccp.h> #include <linux/netfilter/nf_conntrack_dccp.h>
#include <linux/netfilter/nf_conntrack_sctp.h> #include <linux/netfilter/nf_conntrack_sctp.h>
#include <linux/netfilter/nf_conntrack_proto_gre.h> #include <linux/netfilter/nf_conntrack_proto_gre.h>
#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_tuple.h>
...@@ -59,7 +56,6 @@ struct nf_conntrack_net { ...@@ -59,7 +56,6 @@ struct nf_conntrack_net {
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
struct nf_conn { struct nf_conn {
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
/* Usage count in here is 1 for hash table, 1 per skb, /* Usage count in here is 1 for hash table, 1 per skb,
* plus 1 for any connection(s) we are `master' for * plus 1 for any connection(s) we are `master' for
* *
...@@ -69,7 +65,6 @@ struct nf_conn { ...@@ -69,7 +65,6 @@ struct nf_conn {
* beware nf_ct_get() is different and don't inc refcnt. * beware nf_ct_get() is different and don't inc refcnt.
*/ */
struct nf_conntrack ct_general; struct nf_conntrack ct_general;
#endif
spinlock_t lock; spinlock_t lock;
/* jiffies32 when this ct is considered dead */ /* jiffies32 when this ct is considered dead */
...@@ -150,18 +145,14 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, ...@@ -150,18 +145,14 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
const struct nf_conn *ignored_conntrack); const struct nf_conn *ignored_conntrack);
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#define NFCT_INFOMASK 7UL
#define NFCT_PTRMASK ~(NFCT_INFOMASK)
/* Return conntrack_info and tuple hash for given skb. */ /* Return conntrack_info and tuple hash for given skb. */
static inline struct nf_conn * static inline struct nf_conn *
nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
{ {
*ctinfo = skb->_nfct & NFCT_INFOMASK; unsigned long nfct = skb_get_nfct(skb);
return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK); *ctinfo = nfct & NFCT_INFOMASK;
return (struct nf_conn *)(nfct & NFCT_PTRMASK);
} }
/* decrement reference count on a conntrack */ /* decrement reference count on a conntrack */
...@@ -171,8 +162,6 @@ static inline void nf_ct_put(struct nf_conn *ct) ...@@ -171,8 +162,6 @@ static inline void nf_ct_put(struct nf_conn *ct)
nf_conntrack_put(&ct->ct_general); nf_conntrack_put(&ct->ct_general);
} }
#endif
/* Protocol module loading */ /* Protocol module loading */
int nf_ct_l3proto_try_module_get(unsigned short l3proto); int nf_ct_l3proto_try_module_get(unsigned short l3proto);
void nf_ct_l3proto_module_put(unsigned short l3proto); void nf_ct_l3proto_module_put(unsigned short l3proto);
...@@ -324,16 +313,12 @@ void nf_ct_tmpl_free(struct nf_conn *tmpl); ...@@ -324,16 +313,12 @@ void nf_ct_tmpl_free(struct nf_conn *tmpl);
u32 nf_ct_get_id(const struct nf_conn *ct); u32 nf_ct_get_id(const struct nf_conn *ct);
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
static inline void static inline void
nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info) nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info)
{ {
skb->_nfct = (unsigned long)ct | info; skb_set_nfct(skb, (unsigned long)ct | info);
} }
#endif
#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v)) #define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
......
...@@ -45,7 +45,7 @@ struct nf_conn_acct *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) ...@@ -45,7 +45,7 @@ struct nf_conn_acct *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
#else #else
return NULL; return NULL;
#endif #endif
}; }
/* Check if connection tracking accounting is enabled */ /* Check if connection tracking accounting is enabled */
static inline bool nf_ct_acct_enabled(struct net *net) static inline bool nf_ct_acct_enabled(struct net *net)
...@@ -65,11 +65,9 @@ static inline void nf_ct_set_acct(struct net *net, bool enable) ...@@ -65,11 +65,9 @@ static inline void nf_ct_set_acct(struct net *net, bool enable)
#endif #endif
} }
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
void nf_conntrack_acct_pernet_init(struct net *net); void nf_conntrack_acct_pernet_init(struct net *net);
int nf_conntrack_acct_init(void); int nf_conntrack_acct_init(void);
void nf_conntrack_acct_fini(void); void nf_conntrack_acct_fini(void);
#endif /* IS_ENABLED(CONFIG_NF_CONNTRACK) */
#endif /* _NF_CONNTRACK_ACCT_H */ #endif /* _NF_CONNTRACK_ACCT_H */
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#include <linux/types.h> #include <linux/types.h>
#include <uapi/linux/if_ether.h> #include <uapi/linux/if_ether.h>
struct nf_hook_ops;
struct nf_ct_bridge_info { struct nf_ct_bridge_info {
#if IS_ENABLED(CONFIG_NETFILTER)
struct nf_hook_ops *ops; struct nf_hook_ops *ops;
#endif
unsigned int ops_size; unsigned int ops_size;
struct module *me; struct module *me;
}; };
...@@ -16,11 +16,4 @@ struct nf_ct_bridge_info { ...@@ -16,11 +16,4 @@ struct nf_ct_bridge_info {
void nf_ct_bridge_register(struct nf_ct_bridge_info *info); void nf_ct_bridge_register(struct nf_ct_bridge_info *info);
void nf_ct_bridge_unregister(struct nf_ct_bridge_info *info); void nf_ct_bridge_unregister(struct nf_ct_bridge_info *info);
struct nf_ct_bridge_frag_data {
char mac[ETH_HLEN];
bool vlan_present;
u16 vlan_tci;
__be16 vlan_proto;
};
#endif #endif
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
#define _NF_CONNTRACK_CORE_H #define _NF_CONNTRACK_CORE_H
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_ecache.h> #include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
/* This header is used to share core functionality between the /* This header is used to share core functionality between the
standalone connection tracking module, and the compatibility layer's use standalone connection tracking module, and the compatibility layer's use
of connection tracking. */ of connection tracking. */
#if IS_ENABLED(CONFIG_NETFILTER) unsigned int nf_conntrack_in(struct sk_buff *skb,
unsigned int nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state); const struct nf_hook_state *state);
#endif
int nf_conntrack_init_net(struct net *net); int nf_conntrack_init_net(struct net *net);
void nf_conntrack_cleanup_net(struct net *net); void nf_conntrack_cleanup_net(struct net *net);
......
...@@ -61,9 +61,10 @@ nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) ...@@ -61,9 +61,10 @@ nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp)
#else #else
return NULL; return NULL;
#endif #endif
}; }
#ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_EVENTS
/* This structure is passed to event handler */ /* This structure is passed to event handler */
struct nf_ct_event { struct nf_ct_event {
struct nf_conn *ct; struct nf_conn *ct;
...@@ -84,9 +85,26 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct); ...@@ -84,9 +85,26 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct);
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
u32 portid, int report); u32 portid, int report);
#else
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct)
{
}
static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
struct nf_conn *ct,
u32 portid,
int report)
{
return 0;
}
#endif
static inline void static inline void
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
struct net *net = nf_ct_net(ct); struct net *net = nf_ct_net(ct);
struct nf_conntrack_ecache *e; struct nf_conntrack_ecache *e;
...@@ -98,31 +116,42 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) ...@@ -98,31 +116,42 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
return; return;
set_bit(event, &e->cache); set_bit(event, &e->cache);
#endif
} }
static inline int static inline int
nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
u32 portid, int report) u32 portid, int report)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
const struct net *net = nf_ct_net(ct); const struct net *net = nf_ct_net(ct);
if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
return 0; return 0;
return nf_conntrack_eventmask_report(1 << event, ct, portid, report); return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
#else
return 0;
#endif
} }
static inline int static inline int
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
const struct net *net = nf_ct_net(ct); const struct net *net = nf_ct_net(ct);
if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
return 0; return 0;
return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
#else
return 0;
#endif
} }
#ifdef CONFIG_NF_CONNTRACK_EVENTS
struct nf_exp_event { struct nf_exp_event {
struct nf_conntrack_expect *exp; struct nf_conntrack_expect *exp;
u32 portid; u32 portid;
...@@ -148,41 +177,18 @@ void nf_conntrack_ecache_pernet_fini(struct net *net); ...@@ -148,41 +177,18 @@ void nf_conntrack_ecache_pernet_fini(struct net *net);
int nf_conntrack_ecache_init(void); int nf_conntrack_ecache_init(void);
void nf_conntrack_ecache_fini(void); void nf_conntrack_ecache_fini(void);
static inline void nf_conntrack_ecache_delayed_work(struct net *net) #else /* CONFIG_NF_CONNTRACK_EVENTS */
static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
struct nf_conntrack_expect *exp,
u32 portid,
int report)
{ {
if (!delayed_work_pending(&net->ct.ecache_dwork)) {
schedule_delayed_work(&net->ct.ecache_dwork, HZ);
net->ct.ecache_dwork_pending = true;
}
} }
static inline void nf_conntrack_ecache_work(struct net *net) static inline void nf_conntrack_ecache_pernet_init(struct net *net)
{ {
if (net->ct.ecache_dwork_pending) {
net->ct.ecache_dwork_pending = false;
mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0);
}
} }
#else /* CONFIG_NF_CONNTRACK_EVENTS */
static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
struct nf_conn *ct) {}
static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
struct nf_conn *ct,
u32 portid,
int report) { return 0; }
static inline int nf_conntrack_event(enum ip_conntrack_events event,
struct nf_conn *ct) { return 0; }
static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
struct nf_conn *ct,
u32 portid,
int report) { return 0; }
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
struct nf_conntrack_expect *exp,
u32 portid,
int report) {}
static inline void nf_conntrack_ecache_pernet_init(struct net *net) {}
static inline void nf_conntrack_ecache_pernet_fini(struct net *net) static inline void nf_conntrack_ecache_pernet_fini(struct net *net)
{ {
...@@ -197,14 +203,26 @@ static inline void nf_conntrack_ecache_fini(void) ...@@ -197,14 +203,26 @@ static inline void nf_conntrack_ecache_fini(void)
{ {
} }
#endif /* CONFIG_NF_CONNTRACK_EVENTS */
static inline void nf_conntrack_ecache_delayed_work(struct net *net) static inline void nf_conntrack_ecache_delayed_work(struct net *net)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
if (!delayed_work_pending(&net->ct.ecache_dwork)) {
schedule_delayed_work(&net->ct.ecache_dwork, HZ);
net->ct.ecache_dwork_pending = true;
}
#endif
} }
static inline void nf_conntrack_ecache_work(struct net *net) static inline void nf_conntrack_ecache_work(struct net *net)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
if (net->ct.ecache_dwork_pending) {
net->ct.ecache_dwork_pending = false;
mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0);
}
#endif
} }
#endif /* CONFIG_NF_CONNTRACK_EVENTS */
#endif /*_NF_CONNTRACK_ECACHE_H*/ #endif /*_NF_CONNTRACK_ECACHE_H*/
...@@ -126,7 +126,7 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t, ...@@ -126,7 +126,7 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
const union nf_inet_addr *, const union nf_inet_addr *,
u_int8_t, const __be16 *, const __be16 *); u_int8_t, const __be16 *, const __be16 *);
void nf_ct_expect_put(struct nf_conntrack_expect *exp); void nf_ct_expect_put(struct nf_conntrack_expect *exp);
int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
u32 portid, int report, unsigned int flags); u32 portid, int report, unsigned int flags);
static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect, static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect,
unsigned int flags) unsigned int flags)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
enum nf_ct_ext_id { enum nf_ct_ext_id {
NF_CT_EXT_HELPER, NF_CT_EXT_HELPER,
#if defined(CONFIG_NF_NAT) || defined(CONFIG_NF_NAT_MODULE) #if IS_ENABLED(CONFIG_NF_NAT)
NF_CT_EXT_NAT, NF_CT_EXT_NAT,
#endif #endif
NF_CT_EXT_SEQADJ, NF_CT_EXT_SEQADJ,
......
...@@ -75,7 +75,6 @@ bool nf_conntrack_invert_icmp_tuple(struct nf_conntrack_tuple *tuple, ...@@ -75,7 +75,6 @@ bool nf_conntrack_invert_icmp_tuple(struct nf_conntrack_tuple *tuple,
bool nf_conntrack_invert_icmpv6_tuple(struct nf_conntrack_tuple *tuple, bool nf_conntrack_invert_icmpv6_tuple(struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_tuple *orig); const struct nf_conntrack_tuple *orig);
#if IS_ENABLED(CONFIG_NETFILTER)
int nf_conntrack_inet_error(struct nf_conn *tmpl, struct sk_buff *skb, int nf_conntrack_inet_error(struct nf_conn *tmpl, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
const struct nf_hook_state *state, const struct nf_hook_state *state,
...@@ -132,7 +131,6 @@ int nf_conntrack_gre_packet(struct nf_conn *ct, ...@@ -132,7 +131,6 @@ int nf_conntrack_gre_packet(struct nf_conn *ct,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state); const struct nf_hook_state *state);
#endif
void nf_conntrack_generic_init_net(struct net *net); void nf_conntrack_generic_init_net(struct net *net);
void nf_conntrack_tcp_init_net(struct net *net); void nf_conntrack_tcp_init_net(struct net *net);
...@@ -181,41 +179,41 @@ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, ...@@ -181,41 +179,41 @@ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
static inline struct nf_generic_net *nf_generic_pernet(struct net *net) static inline struct nf_generic_net *nf_generic_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.generic; return &net->ct.nf_ct_proto.generic;
} }
static inline struct nf_tcp_net *nf_tcp_pernet(struct net *net) static inline struct nf_tcp_net *nf_tcp_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.tcp; return &net->ct.nf_ct_proto.tcp;
} }
static inline struct nf_udp_net *nf_udp_pernet(struct net *net) static inline struct nf_udp_net *nf_udp_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.udp; return &net->ct.nf_ct_proto.udp;
} }
static inline struct nf_icmp_net *nf_icmp_pernet(struct net *net) static inline struct nf_icmp_net *nf_icmp_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.icmp; return &net->ct.nf_ct_proto.icmp;
} }
static inline struct nf_icmp_net *nf_icmpv6_pernet(struct net *net) static inline struct nf_icmp_net *nf_icmpv6_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.icmpv6; return &net->ct.nf_ct_proto.icmpv6;
} }
#endif #endif
#ifdef CONFIG_NF_CT_PROTO_DCCP #ifdef CONFIG_NF_CT_PROTO_DCCP
static inline struct nf_dccp_net *nf_dccp_pernet(struct net *net) static inline struct nf_dccp_net *nf_dccp_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.dccp; return &net->ct.nf_ct_proto.dccp;
} }
#endif #endif
#ifdef CONFIG_NF_CT_PROTO_SCTP #ifdef CONFIG_NF_CT_PROTO_SCTP
static inline struct nf_sctp_net *nf_sctp_pernet(struct net *net) static inline struct nf_sctp_net *nf_sctp_pernet(struct net *net)
{ {
return &net->ct.nf_ct_proto.sctp; return &net->ct.nf_ct_proto.sctp;
} }
#endif #endif
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <linux/types.h>
#include <net/net_namespace.h> #ifndef _NF_CONNTRACK_LABELS_H
#define _NF_CONNTRACK_LABELS_H
#include <linux/netfilter/nf_conntrack_common.h> #include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h> #include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <linux/types.h>
#include <net/net_namespace.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_extend.h>
#include <uapi/linux/netfilter/xt_connlabel.h> #include <uapi/linux/netfilter/xt_connlabel.h>
#define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE) #define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE)
...@@ -51,3 +54,5 @@ static inline void nf_conntrack_labels_fini(void) {} ...@@ -51,3 +54,5 @@ static inline void nf_conntrack_labels_fini(void) {}
static inline int nf_connlabels_get(struct net *net, unsigned int bit) { return 0; } static inline int nf_connlabels_get(struct net *net, unsigned int bit) { return 0; }
static inline void nf_connlabels_put(struct net *net) {} static inline void nf_connlabels_put(struct net *net) {}
#endif #endif
#endif /* _NF_CONNTRACK_LABELS_H */
...@@ -32,6 +32,7 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct) ...@@ -32,6 +32,7 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct)
static inline bool nf_ct_add_synproxy(struct nf_conn *ct, static inline bool nf_ct_add_synproxy(struct nf_conn *ct,
const struct nf_conn *tmpl) const struct nf_conn *tmpl)
{ {
#if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY)
if (tmpl && nfct_synproxy(tmpl)) { if (tmpl && nfct_synproxy(tmpl)) {
if (!nfct_seqadj_ext_add(ct)) if (!nfct_seqadj_ext_add(ct))
return false; return false;
...@@ -39,47 +40,9 @@ static inline bool nf_ct_add_synproxy(struct nf_conn *ct, ...@@ -39,47 +40,9 @@ static inline bool nf_ct_add_synproxy(struct nf_conn *ct,
if (!nfct_synproxy_ext_add(ct)) if (!nfct_synproxy_ext_add(ct))
return false; return false;
} }
#endif
return true; return true;
} }
struct synproxy_stats {
unsigned int syn_received;
unsigned int cookie_invalid;
unsigned int cookie_valid;
unsigned int cookie_retrans;
unsigned int conn_reopened;
};
struct synproxy_net {
struct nf_conn *tmpl;
struct synproxy_stats __percpu *stats;
unsigned int hook_ref4;
unsigned int hook_ref6;
};
extern unsigned int synproxy_net_id;
static inline struct synproxy_net *synproxy_pernet(struct net *net)
{
return net_generic(net, synproxy_net_id);
}
struct synproxy_options {
u8 options;
u8 wscale;
u16 mss_option;
u16 mss_encode;
u32 tsval;
u32 tsecr;
};
struct tcphdr;
struct nf_synproxy_info;
bool synproxy_parse_options(const struct sk_buff *skb, unsigned int doff,
const struct tcphdr *th,
struct synproxy_options *opts);
void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info,
struct synproxy_options *opts);
#endif /* _NF_CONNTRACK_SYNPROXY_H */ #endif /* _NF_CONNTRACK_SYNPROXY_H */
...@@ -32,6 +32,7 @@ struct nf_conn_timeout { ...@@ -32,6 +32,7 @@ struct nf_conn_timeout {
static inline unsigned int * static inline unsigned int *
nf_ct_timeout_data(const struct nf_conn_timeout *t) nf_ct_timeout_data(const struct nf_conn_timeout *t)
{ {
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
struct nf_ct_timeout *timeout; struct nf_ct_timeout *timeout;
timeout = rcu_dereference(t->timeout); timeout = rcu_dereference(t->timeout);
...@@ -39,6 +40,9 @@ nf_ct_timeout_data(const struct nf_conn_timeout *t) ...@@ -39,6 +40,9 @@ nf_ct_timeout_data(const struct nf_conn_timeout *t)
return NULL; return NULL;
return (unsigned int *)timeout->data; return (unsigned int *)timeout->data;
#else
return NULL;
#endif
} }
static inline static inline
......
...@@ -38,22 +38,6 @@ struct nf_conn_tstamp *nf_ct_tstamp_ext_add(struct nf_conn *ct, gfp_t gfp) ...@@ -38,22 +38,6 @@ struct nf_conn_tstamp *nf_ct_tstamp_ext_add(struct nf_conn *ct, gfp_t gfp)
#endif #endif
}; };
static inline bool nf_ct_tstamp_enabled(struct net *net)
{
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
return net->ct.sysctl_tstamp != 0;
#else
return false;
#endif
}
static inline void nf_ct_set_tstamp(struct net *net, bool enable)
{
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
net->ct.sysctl_tstamp = enable;
#endif
}
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
void nf_conntrack_tstamp_pernet_init(struct net *net); void nf_conntrack_tstamp_pernet_init(struct net *net);
......
...@@ -121,10 +121,9 @@ struct nf_conntrack_tuple_hash { ...@@ -121,10 +121,9 @@ struct nf_conntrack_tuple_hash {
struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple tuple;
}; };
#if IS_ENABLED(CONFIG_NETFILTER)
static inline bool __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, static inline bool __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
const struct nf_conntrack_tuple *t2) const struct nf_conntrack_tuple *t2)
{ {
return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) && return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) &&
t1->src.u.all == t2->src.u.all && t1->src.u.all == t2->src.u.all &&
t1->src.l3num == t2->src.l3num); t1->src.l3num == t2->src.l3num);
...@@ -184,6 +183,5 @@ nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, ...@@ -184,6 +183,5 @@ nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
return nf_ct_tuple_src_mask_cmp(t, tuple, mask) && return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
__nf_ct_tuple_dst_equal(t, tuple); __nf_ct_tuple_dst_equal(t, tuple);
} }
#endif
#endif /* _NF_CONNTRACK_TUPLE_H */ #endif /* _NF_CONNTRACK_TUPLE_H */
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
#define _NF_CONNTRACK_ZONES_H #define _NF_CONNTRACK_ZONES_H
#include <linux/netfilter/nf_conntrack_zones_common.h> #include <linux/netfilter/nf_conntrack_zones_common.h>
#include <net/netfilter/nf_conntrack.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack_extend.h>
static inline const struct nf_conntrack_zone * static inline const struct nf_conntrack_zone *
nf_ct_zone(const struct nf_conn *ct) nf_ct_zone(const struct nf_conn *ct)
...@@ -87,5 +85,5 @@ static inline bool nf_ct_zone_equal_any(const struct nf_conn *a, ...@@ -87,5 +85,5 @@ static inline bool nf_ct_zone_equal_any(const struct nf_conn *a,
return true; return true;
#endif #endif
} }
#endif /* IS_ENABLED(CONFIG_NF_CONNTRACK) */
#endif /* _NF_CONNTRACK_ZONES_H */ #endif /* _NF_CONNTRACK_ZONES_H */
...@@ -7,4 +7,10 @@ ...@@ -7,4 +7,10 @@
void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif); void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif);
void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif); void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif);
struct nft_offload_ctx;
struct nft_flow_rule;
int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow,
enum flow_action_id id, int oif);
#endif #endif
...@@ -17,9 +17,7 @@ struct nf_flowtable_type { ...@@ -17,9 +17,7 @@ struct nf_flowtable_type {
int family; int family;
int (*init)(struct nf_flowtable *ft); int (*init)(struct nf_flowtable *ft);
void (*free)(struct nf_flowtable *ft); void (*free)(struct nf_flowtable *ft);
#if IS_ENABLED(CONFIG_NETFILTER)
nf_hookfn *hook; nf_hookfn *hook;
#endif
struct module *owner; struct module *owner;
}; };
...@@ -117,14 +115,12 @@ struct flow_ports { ...@@ -117,14 +115,12 @@ struct flow_ports {
__be16 source, dest; __be16 source, dest;
}; };
#if IS_ENABLED(CONFIG_NETFILTER)
unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state); const struct nf_hook_state *state);
unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state); const struct nf_hook_state *state);
#endif
#define MODULE_ALIAS_NF_FLOWTABLE(family) \ #define MODULE_ALIAS_NF_FLOWTABLE(family) \
MODULE_ALIAS("nf-flowtable-" __stringify(family)) MODULE_ALIAS("nf-flowtable-" __stringify(family))
#endif /* _FLOW_OFFLOAD_H */ #endif /* _NF_FLOW_TABLE_H */
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef _NF_NAT_H #ifndef _NF_NAT_H
#define _NF_NAT_H #define _NF_NAT_H
#include <linux/list.h>
#include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4.h>
#include <linux/netfilter/nf_nat.h> #include <linux/netfilter/nf_conntrack_pptp.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_tuple.h>
#include <uapi/linux/netfilter/nf_nat.h>
enum nf_nat_manip_type { enum nf_nat_manip_type {
NF_NAT_MANIP_SRC, NF_NAT_MANIP_SRC,
...@@ -14,20 +19,14 @@ enum nf_nat_manip_type { ...@@ -14,20 +19,14 @@ enum nf_nat_manip_type {
#define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \ #define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \
(hooknum) != NF_INET_LOCAL_IN) (hooknum) != NF_INET_LOCAL_IN)
#include <linux/list.h>
#include <linux/netfilter/nf_conntrack_pptp.h>
#include <net/netfilter/nf_conntrack_extend.h>
/* per conntrack: nat application helper private data */ /* per conntrack: nat application helper private data */
union nf_conntrack_nat_help { union nf_conntrack_nat_help {
/* insert nat helper private data here */ /* insert nat helper private data here */
#if defined(CONFIG_NF_NAT_PPTP) || defined(CONFIG_NF_NAT_PPTP_MODULE) #if IS_ENABLED(CONFIG_NF_NAT_PPTP)
struct nf_nat_pptp nat_pptp_info; struct nf_nat_pptp nat_pptp_info;
#endif #endif
}; };
struct nf_conn;
/* The structure embedded in the conntrack structure. */ /* The structure embedded in the conntrack structure. */
struct nf_conn_nat { struct nf_conn_nat {
union nf_conntrack_nat_help help; union nf_conntrack_nat_help help;
...@@ -48,7 +47,7 @@ struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct); ...@@ -48,7 +47,7 @@ struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct);
static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct) static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
{ {
#if defined(CONFIG_NF_NAT) || defined(CONFIG_NF_NAT_MODULE) #if IS_ENABLED(CONFIG_NF_NAT)
return nf_ct_ext_find(ct, NF_CT_EXT_NAT); return nf_ct_ext_find(ct, NF_CT_EXT_NAT);
#else #else
return NULL; return NULL;
...@@ -69,12 +68,10 @@ static inline bool nf_nat_oif_changed(unsigned int hooknum, ...@@ -69,12 +68,10 @@ static inline bool nf_nat_oif_changed(unsigned int hooknum,
#endif #endif
} }
#if IS_ENABLED(CONFIG_NETFILTER)
int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
const struct nf_hook_ops *nat_ops, unsigned int ops_count); const struct nf_hook_ops *nat_ops, unsigned int ops_count);
void nf_nat_unregister_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, void nf_nat_unregister_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops,
unsigned int ops_count); unsigned int ops_count);
#endif
unsigned int nf_nat_packet(struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int nf_nat_packet(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
unsigned int hooknum, struct sk_buff *skb); unsigned int hooknum, struct sk_buff *skb);
...@@ -94,7 +91,6 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct, ...@@ -94,7 +91,6 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
unsigned int hooknum, unsigned int hdrlen); unsigned int hooknum, unsigned int hdrlen);
#if IS_ENABLED(CONFIG_NETFILTER)
int nf_nat_ipv4_register_fn(struct net *net, const struct nf_hook_ops *ops); int nf_nat_ipv4_register_fn(struct net *net, const struct nf_hook_ops *ops);
void nf_nat_ipv4_unregister_fn(struct net *net, const struct nf_hook_ops *ops); void nf_nat_ipv4_unregister_fn(struct net *net, const struct nf_hook_ops *ops);
...@@ -107,7 +103,6 @@ void nf_nat_inet_unregister_fn(struct net *net, const struct nf_hook_ops *ops); ...@@ -107,7 +103,6 @@ void nf_nat_inet_unregister_fn(struct net *net, const struct nf_hook_ops *ops);
unsigned int unsigned int
nf_nat_inet_fn(void *priv, struct sk_buff *skb, nf_nat_inet_fn(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state); const struct nf_hook_state *state);
#endif
int nf_xfrm_me_harder(struct net *n, struct sk_buff *s, unsigned int family); int nf_xfrm_me_harder(struct net *n, struct sk_buff *s, unsigned int family);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#ifndef _NF_NAT_MASQUERADE_H_ #ifndef _NF_NAT_MASQUERADE_H_
#define _NF_NAT_MASQUERADE_H_ #define _NF_NAT_MASQUERADE_H_
#include <linux/skbuff.h>
#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat.h>
unsigned int unsigned int
......
...@@ -15,9 +15,7 @@ struct nf_queue_entry { ...@@ -15,9 +15,7 @@ struct nf_queue_entry {
unsigned int id; unsigned int id;
unsigned int hook_index; /* index in hook_entries->hook[] */ unsigned int hook_index; /* index in hook_entries->hook[] */
#if IS_ENABLED(CONFIG_NETFILTER)
struct nf_hook_state state; struct nf_hook_state state;
#endif
u16 size; /* sizeof(entry) + saved route keys */ u16 size; /* sizeof(entry) + saved route keys */
/* extra space to store route keys */ /* extra space to store route keys */
...@@ -123,9 +121,7 @@ nfqueue_hash(const struct sk_buff *skb, u16 queue, u16 queues_total, u8 family, ...@@ -123,9 +121,7 @@ nfqueue_hash(const struct sk_buff *skb, u16 queue, u16 queues_total, u8 family,
return queue; return queue;
} }
#if IS_ENABLED(CONFIG_NETFILTER)
int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
unsigned int index, unsigned int verdict); unsigned int index, unsigned int verdict);
#endif
#endif /* _NF_QUEUE_H */ #endif /* _NF_QUEUE_H */
...@@ -11,6 +11,44 @@ ...@@ -11,6 +11,44 @@
#include <net/netfilter/nf_conntrack_seqadj.h> #include <net/netfilter/nf_conntrack_seqadj.h>
#include <net/netfilter/nf_conntrack_synproxy.h> #include <net/netfilter/nf_conntrack_synproxy.h>
struct synproxy_stats {
unsigned int syn_received;
unsigned int cookie_invalid;
unsigned int cookie_valid;
unsigned int cookie_retrans;
unsigned int conn_reopened;
};
struct synproxy_net {
struct nf_conn *tmpl;
struct synproxy_stats __percpu *stats;
unsigned int hook_ref4;
unsigned int hook_ref6;
};
extern unsigned int synproxy_net_id;
static inline struct synproxy_net *synproxy_pernet(struct net *net)
{
return net_generic(net, synproxy_net_id);
}
struct synproxy_options {
u8 options;
u8 wscale;
u16 mss_option;
u16 mss_encode;
u32 tsval;
u32 tsecr;
};
struct nf_synproxy_info;
bool synproxy_parse_options(const struct sk_buff *skb, unsigned int doff,
const struct tcphdr *th,
struct synproxy_options *opts);
void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info,
struct synproxy_options *opts);
void synproxy_send_client_synack(struct net *net, const struct sk_buff *skb, void synproxy_send_client_synack(struct net *net, const struct sk_buff *skb,
const struct tcphdr *th, const struct tcphdr *th,
const struct synproxy_options *opts); const struct synproxy_options *opts);
...@@ -20,10 +58,10 @@ bool synproxy_recv_client_ack(struct net *net, ...@@ -20,10 +58,10 @@ bool synproxy_recv_client_ack(struct net *net,
const struct tcphdr *th, const struct tcphdr *th,
struct synproxy_options *opts, u32 recv_seq); struct synproxy_options *opts, u32 recv_seq);
#if IS_ENABLED(CONFIG_NETFILTER) struct nf_hook_state;
unsigned int ipv4_synproxy_hook(void *priv, struct sk_buff *skb, unsigned int ipv4_synproxy_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *nhs); const struct nf_hook_state *nhs);
#endif
int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net); int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net);
void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net); void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net);
...@@ -37,10 +75,8 @@ bool synproxy_recv_client_ack_ipv6(struct net *net, const struct sk_buff *skb, ...@@ -37,10 +75,8 @@ bool synproxy_recv_client_ack_ipv6(struct net *net, const struct sk_buff *skb,
const struct tcphdr *th, const struct tcphdr *th,
struct synproxy_options *opts, u32 recv_seq); struct synproxy_options *opts, u32 recv_seq);
#if IS_ENABLED(CONFIG_NETFILTER)
unsigned int ipv6_synproxy_hook(void *priv, struct sk_buff *skb, unsigned int ipv6_synproxy_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *nhs); const struct nf_hook_state *nhs);
#endif
int nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net); int nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net);
void nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net); void nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net);
#else #else
......
...@@ -26,7 +26,6 @@ struct nft_pktinfo { ...@@ -26,7 +26,6 @@ struct nft_pktinfo {
struct xt_action_param xt; struct xt_action_param xt;
}; };
#if IS_ENABLED(CONFIG_NETFILTER)
static inline struct net *nft_net(const struct nft_pktinfo *pkt) static inline struct net *nft_net(const struct nft_pktinfo *pkt)
{ {
return pkt->xt.state->net; return pkt->xt.state->net;
...@@ -59,7 +58,6 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt, ...@@ -59,7 +58,6 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
pkt->skb = skb; pkt->skb = skb;
pkt->xt.state = state; pkt->xt.state = state;
} }
#endif
static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt, static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
struct sk_buff *skb) struct sk_buff *skb)
...@@ -947,11 +945,9 @@ struct nft_chain_type { ...@@ -947,11 +945,9 @@ struct nft_chain_type {
int family; int family;
struct module *owner; struct module *owner;
unsigned int hook_mask; unsigned int hook_mask;
#if IS_ENABLED(CONFIG_NETFILTER)
nf_hookfn *hooks[NF_MAX_HOOKS]; nf_hookfn *hooks[NF_MAX_HOOKS];
int (*ops_register)(struct net *net, const struct nf_hook_ops *ops); int (*ops_register)(struct net *net, const struct nf_hook_ops *ops);
void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops); void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops);
#endif
}; };
int nft_chain_validate_dependency(const struct nft_chain *chain, int nft_chain_validate_dependency(const struct nft_chain *chain,
...@@ -977,9 +973,7 @@ struct nft_stats { ...@@ -977,9 +973,7 @@ struct nft_stats {
* @flow_block: flow block (for hardware offload) * @flow_block: flow block (for hardware offload)
*/ */
struct nft_base_chain { struct nft_base_chain {
#if IS_ENABLED(CONFIG_NETFILTER)
struct nf_hook_ops ops; struct nf_hook_ops ops;
#endif
const struct nft_chain_type *type; const struct nft_chain_type *type;
u8 policy; u8 policy;
u8 flags; u8 flags;
...@@ -1179,9 +1173,7 @@ struct nft_flowtable { ...@@ -1179,9 +1173,7 @@ struct nft_flowtable {
use:30; use:30;
u64 handle; u64 handle;
/* runtime data below here */ /* runtime data below here */
#if IS_ENABLED(CONFIG_NETFILTER)
struct nf_hook_ops *ops ____cacheline_aligned; struct nf_hook_ops *ops ____cacheline_aligned;
#endif
struct nf_flowtable data; struct nf_flowtable data;
}; };
......
...@@ -26,6 +26,7 @@ struct nft_offload_ctx { ...@@ -26,6 +26,7 @@ struct nft_offload_ctx {
u8 protonum; u8 protonum;
} dep; } dep;
unsigned int num_actions; unsigned int num_actions;
struct net *net;
struct nft_offload_reg regs[NFT_REG32_15 + 1]; struct nft_offload_reg regs[NFT_REG32_15 + 1];
}; };
...@@ -61,13 +62,9 @@ struct nft_flow_rule { ...@@ -61,13 +62,9 @@ struct nft_flow_rule {
#define NFT_OFFLOAD_F_ACTION (1 << 0) #define NFT_OFFLOAD_F_ACTION (1 << 0)
struct nft_rule; struct nft_rule;
struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule); struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule);
void nft_flow_rule_destroy(struct nft_flow_rule *flow); void nft_flow_rule_destroy(struct nft_flow_rule *flow);
int nft_flow_rule_offload_commit(struct net *net); int nft_flow_rule_offload_commit(struct net *net);
void nft_indr_block_get_and_ing_cmd(struct net_device *dev,
flow_indr_block_bind_cb_t *cb,
void *cb_priv,
enum flow_block_command command);
#define NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \ #define NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \
(__reg)->base_offset = \ (__reg)->base_offset = \
...@@ -80,4 +77,7 @@ void nft_indr_block_get_and_ing_cmd(struct net_device *dev, ...@@ -80,4 +77,7 @@ void nft_indr_block_get_and_ing_cmd(struct net_device *dev,
int nft_chain_offload_priority(struct nft_base_chain *basechain); int nft_chain_offload_priority(struct nft_base_chain *basechain);
int nft_offload_init(void);
void nft_offload_exit(void);
#endif #endif
...@@ -1481,7 +1481,8 @@ enum nft_ct_expectation_attributes { ...@@ -1481,7 +1481,8 @@ enum nft_ct_expectation_attributes {
#define NFT_OBJECT_CT_TIMEOUT 7 #define NFT_OBJECT_CT_TIMEOUT 7
#define NFT_OBJECT_SECMARK 8 #define NFT_OBJECT_SECMARK 8
#define NFT_OBJECT_CT_EXPECT 9 #define NFT_OBJECT_CT_EXPECT 9
#define __NFT_OBJECT_MAX 10 #define NFT_OBJECT_SYNPROXY 10
#define __NFT_OBJECT_MAX 11
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
/** /**
......
...@@ -11,7 +11,13 @@ ...@@ -11,7 +11,13 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_802_3.h> #include <linux/skbuff.h>
#include <uapi/linux/netfilter_bridge/ebt_802_3.h>
static struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
{
return (struct ebt_802_3_hdr *)skb_mac_header(skb);
}
static bool static bool
ebt_802_3_mt(const struct sk_buff *skb, struct xt_action_param *par) ebt_802_3_mt(const struct sk_buff *skb, struct xt_action_param *par)
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <net/netfilter/nf_conntrack_bridge.h> #include <net/netfilter/nf_conntrack_bridge.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include "../br_private.h" #include "../br_private.h"
...@@ -27,9 +26,9 @@ ...@@ -27,9 +26,9 @@
*/ */
static int nf_br_ip_fragment(struct net *net, struct sock *sk, static int nf_br_ip_fragment(struct net *net, struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data, struct nf_bridge_frag_data *data,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)) struct sk_buff *))
{ {
int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
...@@ -279,7 +278,7 @@ static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb, ...@@ -279,7 +278,7 @@ static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb,
} }
static void nf_ct_bridge_frag_save(struct sk_buff *skb, static void nf_ct_bridge_frag_save(struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data) struct nf_bridge_frag_data *data)
{ {
if (skb_vlan_tag_present(skb)) { if (skb_vlan_tag_present(skb)) {
data->vlan_present = true; data->vlan_present = true;
...@@ -294,10 +293,10 @@ static void nf_ct_bridge_frag_save(struct sk_buff *skb, ...@@ -294,10 +293,10 @@ static void nf_ct_bridge_frag_save(struct sk_buff *skb,
static unsigned int static unsigned int
nf_ct_bridge_refrag(struct sk_buff *skb, const struct nf_hook_state *state, nf_ct_bridge_refrag(struct sk_buff *skb, const struct nf_hook_state *state,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)) struct sk_buff *))
{ {
struct nf_ct_bridge_frag_data data; struct nf_bridge_frag_data data;
if (!BR_INPUT_SKB_CB(skb)->frag_max_size) if (!BR_INPUT_SKB_CB(skb)->frag_max_size)
return NF_ACCEPT; return NF_ACCEPT;
...@@ -320,7 +319,7 @@ nf_ct_bridge_refrag(struct sk_buff *skb, const struct nf_hook_state *state, ...@@ -320,7 +319,7 @@ nf_ct_bridge_refrag(struct sk_buff *skb, const struct nf_hook_state *state,
/* Actually only slow path refragmentation needs this. */ /* Actually only slow path refragmentation needs this. */
static int nf_ct_bridge_frag_restore(struct sk_buff *skb, static int nf_ct_bridge_frag_restore(struct sk_buff *skb,
const struct nf_ct_bridge_frag_data *data) const struct nf_bridge_frag_data *data)
{ {
int err; int err;
...@@ -341,7 +340,7 @@ static int nf_ct_bridge_frag_restore(struct sk_buff *skb, ...@@ -341,7 +340,7 @@ static int nf_ct_bridge_frag_restore(struct sk_buff *skb,
} }
static int nf_ct_bridge_refrag_post(struct net *net, struct sock *sk, static int nf_ct_bridge_refrag_post(struct net *net, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *skb) struct sk_buff *skb)
{ {
int err; int err;
......
...@@ -272,7 +272,7 @@ config IP_NF_TARGET_CLUSTERIP ...@@ -272,7 +272,7 @@ config IP_NF_TARGET_CLUSTERIP
The CLUSTERIP target allows you to build load-balancing clusters of The CLUSTERIP target allows you to build load-balancing clusters of
network servers without having a dedicated load-balancing network servers without having a dedicated load-balancing
router/server/switch. router/server/switch.
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_ECN config IP_NF_TARGET_ECN
...@@ -281,7 +281,7 @@ config IP_NF_TARGET_ECN ...@@ -281,7 +281,7 @@ config IP_NF_TARGET_ECN
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
---help--- ---help---
This option adds a `ECN' target, which can be used in the iptables mangle This option adds a `ECN' target, which can be used in the iptables mangle
table. table.
You can use this target to remove the ECN bits from the IPv4 header of You can use this target to remove the ECN bits from the IPv4 header of
an IP packet. This is particularly useful, if you need to work around an IP packet. This is particularly useful, if you need to work around
...@@ -306,7 +306,7 @@ config IP_NF_RAW ...@@ -306,7 +306,7 @@ config IP_NF_RAW
This option adds a `raw' table to iptables. This table is the very This option adds a `raw' table to iptables. This table is the very
first in the netfilter framework and hooks in at the PREROUTING first in the netfilter framework and hooks in at the PREROUTING
and OUTPUT chains. and OUTPUT chains.
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.rst>. If unsure, say `N'. <file:Documentation/kbuild/modules.rst>. If unsure, say `N'.
...@@ -318,7 +318,7 @@ config IP_NF_SECURITY ...@@ -318,7 +318,7 @@ config IP_NF_SECURITY
help help
This option adds a `security' table to iptables, for use This option adds a `security' table to iptables, for use
with Mandatory Access Control (MAC) policy. with Mandatory Access Control (MAC) policy.
If unsure, say N. If unsure, say N.
endif # IP_NF_IPTABLES endif # IP_NF_IPTABLES
......
...@@ -31,7 +31,7 @@ obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o ...@@ -31,7 +31,7 @@ obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
# flow table support # flow table support
obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o
# generic IP tables # generic IP tables
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
# the three instances of ip_tables # the three instances of ip_tables
......
...@@ -113,9 +113,9 @@ int __nf_ip6_route(struct net *net, struct dst_entry **dst, ...@@ -113,9 +113,9 @@ int __nf_ip6_route(struct net *net, struct dst_entry **dst,
EXPORT_SYMBOL_GPL(__nf_ip6_route); EXPORT_SYMBOL_GPL(__nf_ip6_route);
int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
struct nf_ct_bridge_frag_data *data, struct nf_bridge_frag_data *data,
int (*output)(struct net *, struct sock *sk, int (*output)(struct net *, struct sock *sk,
const struct nf_ct_bridge_frag_data *data, const struct nf_bridge_frag_data *data,
struct sk_buff *)) struct sk_buff *))
{ {
int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <net/ipv6.h> #include <net/ipv6.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6.h>
#include <linux/netfilter_ipv6/ip6t_ipv6header.h> #include <linux/netfilter_ipv6/ip6t_ipv6header.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -42,7 +42,7 @@ ipv6header_mt6(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -42,7 +42,7 @@ ipv6header_mt6(const struct sk_buff *skb, struct xt_action_param *par)
len = skb->len - ptr; len = skb->len - ptr;
temp = 0; temp = 0;
while (ip6t_ext_hdr(nexthdr)) { while (nf_ip6_ext_hdr(nexthdr)) {
const struct ipv6_opt_hdr *hp; const struct ipv6_opt_hdr *hp;
struct ipv6_opt_hdr _hdr; struct ipv6_opt_hdr _hdr;
int hdrlen; int hdrlen;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <net/route.h> #include <net/route.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6.h>
#include <linux/netfilter/xt_LOG.h> #include <linux/netfilter/xt_LOG.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
...@@ -70,7 +70,7 @@ static void dump_ipv6_packet(struct net *net, struct nf_log_buf *m, ...@@ -70,7 +70,7 @@ static void dump_ipv6_packet(struct net *net, struct nf_log_buf *m,
fragment = 0; fragment = 0;
ptr = ip6hoff + sizeof(struct ipv6hdr); ptr = ip6hoff + sizeof(struct ipv6hdr);
currenthdr = ih->nexthdr; currenthdr = ih->nexthdr;
while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) { while (currenthdr != NEXTHDR_NONE && nf_ip6_ext_hdr(currenthdr)) {
struct ipv6_opt_hdr _hdr; struct ipv6_opt_hdr _hdr;
const struct ipv6_opt_hdr *hp; const struct ipv6_opt_hdr *hp;
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <net/sock.h> #include <net/sock.h>
#include <net/inet_sock.h> #include <net/inet_sock.h>
#include <net/inet6_hashtables.h> #include <net/inet6_hashtables.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/netfilter/nf_socket.h> #include <net/netfilter/nf_socket.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
......
...@@ -20,7 +20,7 @@ config NETFILTER_FAMILY_ARP ...@@ -20,7 +20,7 @@ config NETFILTER_FAMILY_ARP
bool bool
config NETFILTER_NETLINK_ACCT config NETFILTER_NETLINK_ACCT
tristate "Netfilter NFACCT over NFNETLINK interface" tristate "Netfilter NFACCT over NFNETLINK interface"
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
select NETFILTER_NETLINK select NETFILTER_NETLINK
help help
...@@ -34,7 +34,7 @@ config NETFILTER_NETLINK_QUEUE ...@@ -34,7 +34,7 @@ config NETFILTER_NETLINK_QUEUE
help help
If this option is enabled, the kernel will include support If this option is enabled, the kernel will include support
for queueing packets via NFNETLINK. for queueing packets via NFNETLINK.
config NETFILTER_NETLINK_LOG config NETFILTER_NETLINK_LOG
tristate "Netfilter LOG over NFNETLINK interface" tristate "Netfilter LOG over NFNETLINK interface"
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
...@@ -1502,7 +1502,7 @@ config NETFILTER_XT_MATCH_REALM ...@@ -1502,7 +1502,7 @@ config NETFILTER_XT_MATCH_REALM
This option adds a `realm' match, which allows you to use the realm This option adds a `realm' match, which allows you to use the realm
key from the routing subsystem inside iptables. key from the routing subsystem inside iptables.
This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option
in tc world. in tc world.
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
...@@ -1523,7 +1523,7 @@ config NETFILTER_XT_MATCH_SCTP ...@@ -1523,7 +1523,7 @@ config NETFILTER_XT_MATCH_SCTP
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
default IP_SCTP default IP_SCTP
help help
With this option enabled, you will be able to use the With this option enabled, you will be able to use the
`sctp' match in order to match on SCTP source/destination ports `sctp' match in order to match on SCTP source/destination ports
and SCTP chunk types. and SCTP chunk types.
......
...@@ -124,7 +124,7 @@ nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o ...@@ -124,7 +124,7 @@ nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o
obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o
# generic X tables # generic X tables
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
# combos # combos
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_extend.h>
static DEFINE_MUTEX(nf_ct_ecache_mutex); static DEFINE_MUTEX(nf_ct_ecache_mutex);
......
...@@ -25,8 +25,10 @@ ...@@ -25,8 +25,10 @@
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
......
...@@ -21,10 +21,11 @@ ...@@ -21,10 +21,11 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
static DEFINE_MUTEX(nf_ct_helper_mutex); static DEFINE_MUTEX(nf_ct_helper_mutex);
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_timeout.h> #include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
static const unsigned int nf_ct_icmpv6_timeout = 30*HZ; static const unsigned int nf_ct_icmpv6_timeout = 30*HZ;
......
...@@ -1167,7 +1167,6 @@ static int __init nf_conntrack_standalone_init(void) ...@@ -1167,7 +1167,6 @@ static int __init nf_conntrack_standalone_init(void)
if (ret < 0) if (ret < 0)
goto out_start; goto out_start;
BUILD_BUG_ON(SKB_NFCT_PTRMASK != NFCT_PTRMASK);
BUILD_BUG_ON(NFCT_INFOMASK <= IP_CT_NUMBER); BUILD_BUG_ON(NFCT_INFOMASK <= IP_CT_NUMBER);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_timeout.h> #include <net/netfilter/nf_conntrack_timeout.h>
struct nf_ct_timeout * struct nf_ct_timeout *
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_offload.h>
#include <net/netfilter/nf_dup_netdev.h> #include <net/netfilter/nf_dup_netdev.h>
static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev) static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev)
...@@ -50,5 +51,25 @@ void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif) ...@@ -50,5 +51,25 @@ void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)
} }
EXPORT_SYMBOL_GPL(nf_dup_netdev_egress); EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);
int nft_fwd_dup_netdev_offload(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow,
enum flow_action_id id, int oif)
{
struct flow_action_entry *entry;
struct net_device *dev;
/* nft_flow_rule_destroy() releases the reference on this device. */
dev = dev_get_by_index(ctx->net, oif);
if (!dev)
return -EOPNOTSUPP;
entry = &flow->rule->action.entries[ctx->num_actions++];
entry->id = id;
entry->dev = dev;
return 0;
}
EXPORT_SYMBOL_GPL(nft_fwd_dup_netdev_offload);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <net/netfilter/nf_flow_table.h> #include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_tuple.h>
struct flow_offload_entry { struct flow_offload_entry {
......
...@@ -18,12 +18,12 @@ ...@@ -18,12 +18,12 @@
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_seqadj.h> #include <net/netfilter/nf_conntrack_seqadj.h>
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
#include <linux/netfilter/nf_nat.h> #include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_helper.h>
#include <uapi/linux/netfilter/nf_nat.h>
#include "nf_internals.h" #include "nf_internals.h"
......
...@@ -2853,7 +2853,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, ...@@ -2853,7 +2853,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
return nft_table_validate(net, table); return nft_table_validate(net, table);
if (chain->flags & NFT_CHAIN_HW_OFFLOAD) { if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
flow = nft_flow_rule_create(rule); flow = nft_flow_rule_create(net, rule);
if (IS_ERR(flow)) if (IS_ERR(flow))
return PTR_ERR(flow); return PTR_ERR(flow);
...@@ -5151,7 +5151,7 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, ...@@ -5151,7 +5151,7 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
newobj = nft_obj_init(ctx, type, attr); newobj = nft_obj_init(ctx, type, attr);
if (IS_ERR(newobj)) { if (IS_ERR(newobj)) {
err = PTR_ERR(newobj); err = PTR_ERR(newobj);
goto err1; goto err_free_trans;
} }
nft_trans_obj(trans) = obj; nft_trans_obj(trans) = obj;
...@@ -5160,9 +5160,9 @@ static int nf_tables_updobj(const struct nft_ctx *ctx, ...@@ -5160,9 +5160,9 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
list_add_tail(&trans->list, &ctx->net->nft.commit_list); list_add_tail(&trans->list, &ctx->net->nft.commit_list);
return 0; return 0;
err1:
err_free_trans:
kfree(trans); kfree(trans);
kfree(newobj);
return err; return err;
} }
...@@ -7669,11 +7669,6 @@ static struct pernet_operations nf_tables_net_ops = { ...@@ -7669,11 +7669,6 @@ static struct pernet_operations nf_tables_net_ops = {
.exit = nf_tables_exit_net, .exit = nf_tables_exit_net,
}; };
static struct flow_indr_block_ing_entry block_ing_entry = {
.cb = nft_indr_block_get_and_ing_cmd,
.list = LIST_HEAD_INIT(block_ing_entry.list),
};
static int __init nf_tables_module_init(void) static int __init nf_tables_module_init(void)
{ {
int err; int err;
...@@ -7699,14 +7694,20 @@ static int __init nf_tables_module_init(void) ...@@ -7699,14 +7694,20 @@ static int __init nf_tables_module_init(void)
if (err < 0) if (err < 0)
goto err4; goto err4;
err = nft_offload_init();
if (err < 0)
goto err5;
/* must be last */ /* must be last */
err = nfnetlink_subsys_register(&nf_tables_subsys); err = nfnetlink_subsys_register(&nf_tables_subsys);
if (err < 0) if (err < 0)
goto err5; goto err6;
nft_chain_route_init(); nft_chain_route_init();
flow_indr_add_block_ing_cb(&block_ing_entry);
return err; return err;
err6:
nft_offload_exit();
err5: err5:
rhltable_destroy(&nft_objname_ht); rhltable_destroy(&nft_objname_ht);
err4: err4:
...@@ -7722,8 +7723,8 @@ static int __init nf_tables_module_init(void) ...@@ -7722,8 +7723,8 @@ static int __init nf_tables_module_init(void)
static void __exit nf_tables_module_exit(void) static void __exit nf_tables_module_exit(void)
{ {
flow_indr_del_block_ing_cb(&block_ing_entry);
nfnetlink_subsys_unregister(&nf_tables_subsys); nfnetlink_subsys_unregister(&nf_tables_subsys);
nft_offload_exit();
unregister_netdevice_notifier(&nf_tables_flowtable_notifier); unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
nft_chain_filter_fini(); nft_chain_filter_fini();
nft_chain_route_fini(); nft_chain_route_fini();
......
...@@ -28,13 +28,10 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions) ...@@ -28,13 +28,10 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
return flow; return flow;
} }
struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule) struct nft_flow_rule *nft_flow_rule_create(struct net *net,
const struct nft_rule *rule)
{ {
struct nft_offload_ctx ctx = { struct nft_offload_ctx *ctx;
.dep = {
.type = NFT_OFFLOAD_DEP_UNSPEC,
},
};
struct nft_flow_rule *flow; struct nft_flow_rule *flow;
int num_actions = 0, err; int num_actions = 0, err;
struct nft_expr *expr; struct nft_expr *expr;
...@@ -52,21 +49,32 @@ struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule) ...@@ -52,21 +49,32 @@ struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
expr = nft_expr_first(rule); expr = nft_expr_first(rule);
ctx = kzalloc(sizeof(struct nft_offload_ctx), GFP_KERNEL);
if (!ctx) {
err = -ENOMEM;
goto err_out;
}
ctx->net = net;
ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
while (expr->ops && expr != nft_expr_last(rule)) { while (expr->ops && expr != nft_expr_last(rule)) {
if (!expr->ops->offload) { if (!expr->ops->offload) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_out; goto err_out;
} }
err = expr->ops->offload(&ctx, flow, expr); err = expr->ops->offload(ctx, flow, expr);
if (err < 0) if (err < 0)
goto err_out; goto err_out;
expr = nft_expr_next(expr); expr = nft_expr_next(expr);
} }
flow->proto = ctx.dep.l3num; flow->proto = ctx->dep.l3num;
kfree(ctx);
return flow; return flow;
err_out: err_out:
kfree(ctx);
nft_flow_rule_destroy(flow); nft_flow_rule_destroy(flow);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -74,6 +82,19 @@ struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule) ...@@ -74,6 +82,19 @@ struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule)
void nft_flow_rule_destroy(struct nft_flow_rule *flow) void nft_flow_rule_destroy(struct nft_flow_rule *flow)
{ {
struct flow_action_entry *entry;
int i;
flow_action_for_each(i, entry, &flow->rule->action) {
switch (entry->id) {
case FLOW_ACTION_REDIRECT:
case FLOW_ACTION_MIRRED:
dev_put(entry->dev);
break;
default:
break;
}
}
kfree(flow->rule); kfree(flow->rule);
kfree(flow); kfree(flow);
} }
...@@ -134,20 +155,20 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain) ...@@ -134,20 +155,20 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain)
return 0; return 0;
} }
static int nft_flow_offload_rule(struct nft_trans *trans, static int nft_flow_offload_rule(struct nft_chain *chain,
struct nft_rule *rule,
struct nft_flow_rule *flow,
enum flow_cls_command command) enum flow_cls_command command)
{ {
struct nft_flow_rule *flow = nft_trans_flow_rule(trans);
struct nft_rule *rule = nft_trans_rule(trans);
struct flow_cls_offload cls_flow = {}; struct flow_cls_offload cls_flow = {};
struct nft_base_chain *basechain; struct nft_base_chain *basechain;
struct netlink_ext_ack extack; struct netlink_ext_ack extack;
__be16 proto = ETH_P_ALL; __be16 proto = ETH_P_ALL;
if (!nft_is_base_chain(trans->ctx.chain)) if (!nft_is_base_chain(chain))
return -EOPNOTSUPP; return -EOPNOTSUPP;
basechain = nft_base_chain(trans->ctx.chain); basechain = nft_base_chain(chain);
if (flow) if (flow)
proto = flow->proto; proto = flow->proto;
...@@ -273,12 +294,13 @@ static int nft_indr_block_offload_cmd(struct nft_base_chain *chain, ...@@ -273,12 +294,13 @@ static int nft_indr_block_offload_cmd(struct nft_base_chain *chain,
#define FLOW_SETUP_BLOCK TC_SETUP_BLOCK #define FLOW_SETUP_BLOCK TC_SETUP_BLOCK
static int nft_flow_offload_chain(struct nft_trans *trans, static int nft_flow_offload_chain(struct nft_chain *chain,
u8 *ppolicy,
enum flow_block_command cmd) enum flow_block_command cmd)
{ {
struct nft_chain *chain = trans->ctx.chain;
struct nft_base_chain *basechain; struct nft_base_chain *basechain;
struct net_device *dev; struct net_device *dev;
u8 policy;
if (!nft_is_base_chain(chain)) if (!nft_is_base_chain(chain))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -288,10 +310,10 @@ static int nft_flow_offload_chain(struct nft_trans *trans, ...@@ -288,10 +310,10 @@ static int nft_flow_offload_chain(struct nft_trans *trans,
if (!dev) if (!dev)
return -EOPNOTSUPP; return -EOPNOTSUPP;
policy = ppolicy ? *ppolicy : basechain->policy;
/* Only default policy to accept is supported for now. */ /* Only default policy to accept is supported for now. */
if (cmd == FLOW_BLOCK_BIND && if (cmd == FLOW_BLOCK_BIND && policy != -1 && policy != NF_ACCEPT)
nft_trans_chain_policy(trans) != -1 &&
nft_trans_chain_policy(trans) != NF_ACCEPT)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (dev->netdev_ops->ndo_setup_tc) if (dev->netdev_ops->ndo_setup_tc)
...@@ -304,6 +326,7 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -304,6 +326,7 @@ int nft_flow_rule_offload_commit(struct net *net)
{ {
struct nft_trans *trans; struct nft_trans *trans;
int err = 0; int err = 0;
u8 policy;
list_for_each_entry(trans, &net->nft.commit_list, list) { list_for_each_entry(trans, &net->nft.commit_list, list) {
if (trans->ctx.family != NFPROTO_NETDEV) if (trans->ctx.family != NFPROTO_NETDEV)
...@@ -314,13 +337,17 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -314,13 +337,17 @@ int nft_flow_rule_offload_commit(struct net *net)
if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
continue; continue;
err = nft_flow_offload_chain(trans, FLOW_BLOCK_BIND); policy = nft_trans_chain_policy(trans);
err = nft_flow_offload_chain(trans->ctx.chain, &policy,
FLOW_BLOCK_BIND);
break; break;
case NFT_MSG_DELCHAIN: case NFT_MSG_DELCHAIN:
if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
continue; continue;
err = nft_flow_offload_chain(trans, FLOW_BLOCK_UNBIND); policy = nft_trans_chain_policy(trans);
err = nft_flow_offload_chain(trans->ctx.chain, &policy,
FLOW_BLOCK_BIND);
break; break;
case NFT_MSG_NEWRULE: case NFT_MSG_NEWRULE:
if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
...@@ -330,14 +357,20 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -330,14 +357,20 @@ int nft_flow_rule_offload_commit(struct net *net)
!(trans->ctx.flags & NLM_F_APPEND)) !(trans->ctx.flags & NLM_F_APPEND))
return -EOPNOTSUPP; return -EOPNOTSUPP;
err = nft_flow_offload_rule(trans, FLOW_CLS_REPLACE); err = nft_flow_offload_rule(trans->ctx.chain,
nft_trans_rule(trans),
nft_trans_flow_rule(trans),
FLOW_CLS_REPLACE);
nft_flow_rule_destroy(nft_trans_flow_rule(trans)); nft_flow_rule_destroy(nft_trans_flow_rule(trans));
break; break;
case NFT_MSG_DELRULE: case NFT_MSG_DELRULE:
if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
continue; continue;
err = nft_flow_offload_rule(trans, FLOW_CLS_DESTROY); err = nft_flow_offload_rule(trans->ctx.chain,
nft_trans_rule(trans),
nft_trans_flow_rule(trans),
FLOW_CLS_DESTROY);
break; break;
} }
...@@ -348,32 +381,103 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -348,32 +381,103 @@ int nft_flow_rule_offload_commit(struct net *net)
return err; return err;
} }
void nft_indr_block_get_and_ing_cmd(struct net_device *dev, static struct nft_chain *__nft_offload_get_chain(struct net_device *dev)
flow_indr_block_bind_cb_t *cb,
void *cb_priv,
enum flow_block_command command)
{ {
struct nft_base_chain *basechain;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
const struct nft_table *table; const struct nft_table *table;
const struct nft_chain *chain; struct nft_chain *chain;
list_for_each_entry_rcu(table, &net->nft.tables, list) { list_for_each_entry(table, &net->nft.tables, list) {
if (table->family != NFPROTO_NETDEV) if (table->family != NFPROTO_NETDEV)
continue; continue;
list_for_each_entry_rcu(chain, &table->chains, list) { list_for_each_entry(chain, &table->chains, list) {
if (nft_is_base_chain(chain)) { if (!nft_is_base_chain(chain) ||
struct nft_base_chain *basechain; !(chain->flags & NFT_CHAIN_HW_OFFLOAD))
continue;
basechain = nft_base_chain(chain);
if (!strncmp(basechain->dev_name, dev->name, basechain = nft_base_chain(chain);
IFNAMSIZ)) { if (strncmp(basechain->dev_name, dev->name, IFNAMSIZ))
nft_indr_block_ing_cmd(dev, basechain, continue;
cb, cb_priv,
command); return chain;
return;
}
}
} }
} }
return NULL;
}
static void nft_indr_block_cb(struct net_device *dev,
flow_indr_block_bind_cb_t *cb, void *cb_priv,
enum flow_block_command cmd)
{
struct net *net = dev_net(dev);
struct nft_chain *chain;
mutex_lock(&net->nft.commit_mutex);
chain = __nft_offload_get_chain(dev);
if (chain) {
struct nft_base_chain *basechain;
basechain = nft_base_chain(chain);
nft_indr_block_ing_cmd(dev, basechain, cb, cb_priv, cmd);
}
mutex_unlock(&net->nft.commit_mutex);
}
static void nft_offload_chain_clean(struct nft_chain *chain)
{
struct nft_rule *rule;
list_for_each_entry(rule, &chain->rules, list) {
nft_flow_offload_rule(chain, rule,
NULL, FLOW_CLS_DESTROY);
}
nft_flow_offload_chain(chain, NULL, FLOW_BLOCK_UNBIND);
}
static int nft_offload_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev);
struct nft_chain *chain;
mutex_lock(&net->nft.commit_mutex);
chain = __nft_offload_get_chain(dev);
if (chain)
nft_offload_chain_clean(chain);
mutex_unlock(&net->nft.commit_mutex);
return NOTIFY_DONE;
}
static struct flow_indr_block_ing_entry block_ing_entry = {
.cb = nft_indr_block_cb,
.list = LIST_HEAD_INIT(block_ing_entry.list),
};
static struct notifier_block nft_offload_netdev_notifier = {
.notifier_call = nft_offload_netdev_event,
};
int nft_offload_init(void)
{
int err;
err = register_netdevice_notifier(&nft_offload_netdev_notifier);
if (err < 0)
return err;
flow_indr_add_block_ing_cb(&block_ing_entry);
return 0;
}
void nft_offload_exit(void)
{
flow_indr_del_block_ing_cb(&block_ing_entry);
unregister_netdevice_notifier(&nft_offload_netdev_notifier);
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_offload.h>
#include <net/netfilter/nf_dup_netdev.h> #include <net/netfilter/nf_dup_netdev.h>
struct nft_dup_netdev { struct nft_dup_netdev {
...@@ -56,6 +57,16 @@ static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -56,6 +57,16 @@ static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
return -1; return -1;
} }
static int nft_dup_netdev_offload(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow,
const struct nft_expr *expr)
{
const struct nft_dup_netdev *priv = nft_expr_priv(expr);
int oif = ctx->regs[priv->sreg_dev].data.data[0];
return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_MIRRED, oif);
}
static struct nft_expr_type nft_dup_netdev_type; static struct nft_expr_type nft_dup_netdev_type;
static const struct nft_expr_ops nft_dup_netdev_ops = { static const struct nft_expr_ops nft_dup_netdev_ops = {
.type = &nft_dup_netdev_type, .type = &nft_dup_netdev_type,
...@@ -63,6 +74,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = { ...@@ -63,6 +74,7 @@ static const struct nft_expr_ops nft_dup_netdev_ops = {
.eval = nft_dup_netdev_eval, .eval = nft_dup_netdev_eval,
.init = nft_dup_netdev_init, .init = nft_dup_netdev_init,
.dump = nft_dup_netdev_dump, .dump = nft_dup_netdev_dump,
.offload = nft_dup_netdev_offload,
}; };
static struct nft_expr_type nft_dup_netdev_type __read_mostly = { static struct nft_expr_type nft_dup_netdev_type __read_mostly = {
......
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/ip.h> /* for ipv4 options. */ #include <net/ip.h> /* for ipv4 options. */
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_core.h> #include <net/netfilter/nf_tables_core.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <linux/netfilter/nf_conntrack_common.h> #include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_flow_table.h> #include <net/netfilter/nf_flow_table.h>
struct nft_flow_offload { struct nft_flow_offload {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_offload.h>
#include <net/netfilter/nf_dup_netdev.h> #include <net/netfilter/nf_dup_netdev.h>
#include <net/neighbour.h> #include <net/neighbour.h>
#include <net/ip.h> #include <net/ip.h>
...@@ -63,6 +64,16 @@ static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -63,6 +64,16 @@ static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
return -1; return -1;
} }
static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx,
struct nft_flow_rule *flow,
const struct nft_expr *expr)
{
const struct nft_fwd_netdev *priv = nft_expr_priv(expr);
int oif = ctx->regs[priv->sreg_dev].data.data[0];
return nft_fwd_dup_netdev_offload(ctx, flow, FLOW_ACTION_REDIRECT, oif);
}
struct nft_fwd_neigh { struct nft_fwd_neigh {
enum nft_registers sreg_dev:8; enum nft_registers sreg_dev:8;
enum nft_registers sreg_addr:8; enum nft_registers sreg_addr:8;
...@@ -194,6 +205,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = { ...@@ -194,6 +205,7 @@ static const struct nft_expr_ops nft_fwd_netdev_ops = {
.eval = nft_fwd_netdev_eval, .eval = nft_fwd_netdev_eval,
.init = nft_fwd_netdev_init, .init = nft_fwd_netdev_init,
.dump = nft_fwd_netdev_dump, .dump = nft_fwd_netdev_dump,
.offload = nft_fwd_netdev_offload,
}; };
static const struct nft_expr_ops * static const struct nft_expr_ops *
......
...@@ -24,7 +24,7 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts, ...@@ -24,7 +24,7 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts,
const struct tcphdr *tcp, const struct tcphdr *tcp,
struct synproxy_net *snet, struct synproxy_net *snet,
struct nf_synproxy_info *info, struct nf_synproxy_info *info,
struct nft_synproxy *priv) const struct nft_synproxy *priv)
{ {
this_cpu_inc(snet->stats->syn_received); this_cpu_inc(snet->stats->syn_received);
if (tcp->ece && tcp->cwr) if (tcp->ece && tcp->cwr)
...@@ -41,14 +41,13 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts, ...@@ -41,14 +41,13 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts,
NF_SYNPROXY_OPT_ECN); NF_SYNPROXY_OPT_ECN);
} }
static void nft_synproxy_eval_v4(const struct nft_expr *expr, static void nft_synproxy_eval_v4(const struct nft_synproxy *priv,
struct nft_regs *regs, struct nft_regs *regs,
const struct nft_pktinfo *pkt, const struct nft_pktinfo *pkt,
const struct tcphdr *tcp, const struct tcphdr *tcp,
struct tcphdr *_tcph, struct tcphdr *_tcph,
struct synproxy_options *opts) struct synproxy_options *opts)
{ {
struct nft_synproxy *priv = nft_expr_priv(expr);
struct nf_synproxy_info info = priv->info; struct nf_synproxy_info info = priv->info;
struct net *net = nft_net(pkt); struct net *net = nft_net(pkt);
struct synproxy_net *snet = synproxy_pernet(net); struct synproxy_net *snet = synproxy_pernet(net);
...@@ -73,14 +72,13 @@ static void nft_synproxy_eval_v4(const struct nft_expr *expr, ...@@ -73,14 +72,13 @@ static void nft_synproxy_eval_v4(const struct nft_expr *expr,
} }
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6) #if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
static void nft_synproxy_eval_v6(const struct nft_expr *expr, static void nft_synproxy_eval_v6(const struct nft_synproxy *priv,
struct nft_regs *regs, struct nft_regs *regs,
const struct nft_pktinfo *pkt, const struct nft_pktinfo *pkt,
const struct tcphdr *tcp, const struct tcphdr *tcp,
struct tcphdr *_tcph, struct tcphdr *_tcph,
struct synproxy_options *opts) struct synproxy_options *opts)
{ {
struct nft_synproxy *priv = nft_expr_priv(expr);
struct nf_synproxy_info info = priv->info; struct nf_synproxy_info info = priv->info;
struct net *net = nft_net(pkt); struct net *net = nft_net(pkt);
struct synproxy_net *snet = synproxy_pernet(net); struct synproxy_net *snet = synproxy_pernet(net);
...@@ -105,9 +103,9 @@ static void nft_synproxy_eval_v6(const struct nft_expr *expr, ...@@ -105,9 +103,9 @@ static void nft_synproxy_eval_v6(const struct nft_expr *expr,
} }
#endif /* CONFIG_NF_TABLES_IPV6*/ #endif /* CONFIG_NF_TABLES_IPV6*/
static void nft_synproxy_eval(const struct nft_expr *expr, static void nft_synproxy_do_eval(const struct nft_synproxy *priv,
struct nft_regs *regs, struct nft_regs *regs,
const struct nft_pktinfo *pkt) const struct nft_pktinfo *pkt)
{ {
struct synproxy_options opts = {}; struct synproxy_options opts = {};
struct sk_buff *skb = pkt->skb; struct sk_buff *skb = pkt->skb;
...@@ -140,23 +138,22 @@ static void nft_synproxy_eval(const struct nft_expr *expr, ...@@ -140,23 +138,22 @@ static void nft_synproxy_eval(const struct nft_expr *expr,
switch (skb->protocol) { switch (skb->protocol) {
case htons(ETH_P_IP): case htons(ETH_P_IP):
nft_synproxy_eval_v4(expr, regs, pkt, tcp, &_tcph, &opts); nft_synproxy_eval_v4(priv, regs, pkt, tcp, &_tcph, &opts);
return; return;
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6) #if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
case htons(ETH_P_IPV6): case htons(ETH_P_IPV6):
nft_synproxy_eval_v6(expr, regs, pkt, tcp, &_tcph, &opts); nft_synproxy_eval_v6(priv, regs, pkt, tcp, &_tcph, &opts);
return; return;
#endif #endif
} }
regs->verdict.code = NFT_BREAK; regs->verdict.code = NFT_BREAK;
} }
static int nft_synproxy_init(const struct nft_ctx *ctx, static int nft_synproxy_do_init(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nlattr * const tb[],
const struct nlattr * const tb[]) struct nft_synproxy *priv)
{ {
struct synproxy_net *snet = synproxy_pernet(ctx->net); struct synproxy_net *snet = synproxy_pernet(ctx->net);
struct nft_synproxy *priv = nft_expr_priv(expr);
u32 flags; u32 flags;
int err; int err;
...@@ -206,8 +203,7 @@ static int nft_synproxy_init(const struct nft_ctx *ctx, ...@@ -206,8 +203,7 @@ static int nft_synproxy_init(const struct nft_ctx *ctx,
return err; return err;
} }
static void nft_synproxy_destroy(const struct nft_ctx *ctx, static void nft_synproxy_do_destroy(const struct nft_ctx *ctx)
const struct nft_expr *expr)
{ {
struct synproxy_net *snet = synproxy_pernet(ctx->net); struct synproxy_net *snet = synproxy_pernet(ctx->net);
...@@ -229,10 +225,8 @@ static void nft_synproxy_destroy(const struct nft_ctx *ctx, ...@@ -229,10 +225,8 @@ static void nft_synproxy_destroy(const struct nft_ctx *ctx,
nf_ct_netns_put(ctx->net, ctx->family); nf_ct_netns_put(ctx->net, ctx->family);
} }
static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_synproxy_do_dump(struct sk_buff *skb, struct nft_synproxy *priv)
{ {
const struct nft_synproxy *priv = nft_expr_priv(expr);
if (nla_put_be16(skb, NFTA_SYNPROXY_MSS, htons(priv->info.mss)) || if (nla_put_be16(skb, NFTA_SYNPROXY_MSS, htons(priv->info.mss)) ||
nla_put_u8(skb, NFTA_SYNPROXY_WSCALE, priv->info.wscale) || nla_put_u8(skb, NFTA_SYNPROXY_WSCALE, priv->info.wscale) ||
nla_put_be32(skb, NFTA_SYNPROXY_FLAGS, htonl(priv->info.options))) nla_put_be32(skb, NFTA_SYNPROXY_FLAGS, htonl(priv->info.options)))
...@@ -244,6 +238,15 @@ static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -244,6 +238,15 @@ static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr)
return -1; return -1;
} }
static void nft_synproxy_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_synproxy *priv = nft_expr_priv(expr);
nft_synproxy_do_eval(priv, regs, pkt);
}
static int nft_synproxy_validate(const struct nft_ctx *ctx, static int nft_synproxy_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nft_expr *expr,
const struct nft_data **data) const struct nft_data **data)
...@@ -252,6 +255,28 @@ static int nft_synproxy_validate(const struct nft_ctx *ctx, ...@@ -252,6 +255,28 @@ static int nft_synproxy_validate(const struct nft_ctx *ctx,
(1 << NF_INET_FORWARD)); (1 << NF_INET_FORWARD));
} }
static int nft_synproxy_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[])
{
struct nft_synproxy *priv = nft_expr_priv(expr);
return nft_synproxy_do_init(ctx, tb, priv);
}
static void nft_synproxy_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr)
{
nft_synproxy_do_destroy(ctx);
}
static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
struct nft_synproxy *priv = nft_expr_priv(expr);
return nft_synproxy_do_dump(skb, priv);
}
static struct nft_expr_type nft_synproxy_type; static struct nft_expr_type nft_synproxy_type;
static const struct nft_expr_ops nft_synproxy_ops = { static const struct nft_expr_ops nft_synproxy_ops = {
.eval = nft_synproxy_eval, .eval = nft_synproxy_eval,
...@@ -271,14 +296,89 @@ static struct nft_expr_type nft_synproxy_type __read_mostly = { ...@@ -271,14 +296,89 @@ static struct nft_expr_type nft_synproxy_type __read_mostly = {
.maxattr = NFTA_SYNPROXY_MAX, .maxattr = NFTA_SYNPROXY_MAX,
}; };
static int nft_synproxy_obj_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[],
struct nft_object *obj)
{
struct nft_synproxy *priv = nft_obj_data(obj);
return nft_synproxy_do_init(ctx, tb, priv);
}
static void nft_synproxy_obj_destroy(const struct nft_ctx *ctx,
struct nft_object *obj)
{
nft_synproxy_do_destroy(ctx);
}
static int nft_synproxy_obj_dump(struct sk_buff *skb,
struct nft_object *obj, bool reset)
{
struct nft_synproxy *priv = nft_obj_data(obj);
return nft_synproxy_do_dump(skb, priv);
}
static void nft_synproxy_obj_eval(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_synproxy *priv = nft_obj_data(obj);
nft_synproxy_do_eval(priv, regs, pkt);
}
static void nft_synproxy_obj_update(struct nft_object *obj,
struct nft_object *newobj)
{
struct nft_synproxy *newpriv = nft_obj_data(newobj);
struct nft_synproxy *priv = nft_obj_data(obj);
priv->info = newpriv->info;
}
static struct nft_object_type nft_synproxy_obj_type;
static const struct nft_object_ops nft_synproxy_obj_ops = {
.type = &nft_synproxy_obj_type,
.size = sizeof(struct nft_synproxy),
.init = nft_synproxy_obj_init,
.destroy = nft_synproxy_obj_destroy,
.dump = nft_synproxy_obj_dump,
.eval = nft_synproxy_obj_eval,
.update = nft_synproxy_obj_update,
};
static struct nft_object_type nft_synproxy_obj_type __read_mostly = {
.type = NFT_OBJECT_SYNPROXY,
.ops = &nft_synproxy_obj_ops,
.maxattr = NFTA_SYNPROXY_MAX,
.policy = nft_synproxy_policy,
.owner = THIS_MODULE,
};
static int __init nft_synproxy_module_init(void) static int __init nft_synproxy_module_init(void)
{ {
return nft_register_expr(&nft_synproxy_type); int err;
err = nft_register_obj(&nft_synproxy_obj_type);
if (err < 0)
return err;
err = nft_register_expr(&nft_synproxy_type);
if (err < 0)
goto err;
return 0;
err:
nft_unregister_obj(&nft_synproxy_obj_type);
return err;
} }
static void __exit nft_synproxy_module_exit(void) static void __exit nft_synproxy_module_exit(void)
{ {
return nft_unregister_expr(&nft_synproxy_type); nft_unregister_expr(&nft_synproxy_type);
nft_unregister_obj(&nft_synproxy_obj_type);
} }
module_init(nft_synproxy_module_init); module_init(nft_synproxy_module_init);
...@@ -287,3 +387,4 @@ module_exit(nft_synproxy_module_exit); ...@@ -287,3 +387,4 @@ module_exit(nft_synproxy_module_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Fernando Fernandez <ffmancera@riseup.net>"); MODULE_AUTHOR("Fernando Fernandez <ffmancera@riseup.net>");
MODULE_ALIAS_NFT_EXPR("synproxy"); MODULE_ALIAS_NFT_EXPR("synproxy");
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_SYNPROXY);
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
......
...@@ -34,9 +34,14 @@ ...@@ -34,9 +34,14 @@
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/xt_hashlimit.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <uapi/linux/netfilter/xt_hashlimit.h>
#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \
XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \
XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES |\
XT_HASHLIMIT_RATE_MATCH)
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
/* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be>
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/if.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netfilter_bridge.h> #include <linux/netfilter_bridge.h>
#include <linux/netfilter/xt_physdev.h>
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include <net/netfilter/br_netfilter.h> #include <uapi/linux/netfilter/xt_physdev.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
......
...@@ -24,12 +24,12 @@ ...@@ -24,12 +24,12 @@
#include <uapi/linux/tc_act/tc_ct.h> #include <uapi/linux/tc_act/tc_ct.h>
#include <net/tc_act/tc_ct.h> #include <net/tc_act/tc_ct.h>
#include <linux/netfilter/nf_nat.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h> #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <uapi/linux/netfilter/nf_nat.h>
static struct tc_action_ops act_ct_ops; static struct tc_action_ops act_ct_ops;
static unsigned int ct_net_id; static unsigned int ct_net_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment