Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

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

The following patchset contains Netfilter updates for net-next:

1) Clean up and consolidate ct ecache infrastructure by merging ct and
   expect notifiers, from Florian Westphal.

2) Missing counters and timestamp in nfnetlink_queue and _log conntrack
   information.

3) Missing error check for xt_register_template() in iptables mangle,
   as a incremental fix for the previous pull request, also from
   Florian Westphal.

4) Add netfilter hooks for the SRv6 lightweigh tunnel driver, from
   Ryoga Sato. The hooks are enabled via nf_hooks_lwtunnel sysctl
   to make sure existing netfilter rulesets do not break. There is
   a static key to disable the hooks by default.

   The pktgen_bench_xmit_mode_netif_receive.sh shows no noticeable
   impact in the seg6_input path for non-netfilter users: similar
   numbers with and without this patch.

   This is a sample of the perf report output:

    11.67%  kpktgend_0       [ipv6]                    [k] ipv6_get_saddr_eval
     7.89%  kpktgend_0       [ipv6]                    [k] __ipv6_addr_label
     7.52%  kpktgend_0       [ipv6]                    [k] __ipv6_dev_get_saddr
     6.63%  kpktgend_0       [kernel.vmlinux]          [k] asm_exc_nmi
     4.74%  kpktgend_0       [ipv6]                    [k] fib6_node_lookup_1
     3.48%  kpktgend_0       [kernel.vmlinux]          [k] pskb_expand_head
     3.33%  kpktgend_0       [ipv6]                    [k] ip6_rcv_core.isra.29
     3.33%  kpktgend_0       [ipv6]                    [k] seg6_do_srh_encap
     2.53%  kpktgend_0       [ipv6]                    [k] ipv6_dev_get_saddr
     2.45%  kpktgend_0       [ipv6]                    [k] fib6_table_lookup
     2.24%  kpktgend_0       [kernel.vmlinux]          [k] ___cache_free
     2.16%  kpktgend_0       [ipv6]                    [k] ip6_pol_route
     2.11%  kpktgend_0       [kernel.vmlinux]          [k] __ipv6_addr_type
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 30, 2021
2 parents 724812d + 7a3f5b0 commit 9dfa859
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 234 deletions.
7 changes: 7 additions & 0 deletions Documentation/networking/nf_conntrack-sysctl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ nf_conntrack_gre_timeout_stream - INTEGER (seconds)
This extended timeout will be used in case there is an GRE stream
detected.

nf_hooks_lwtunnel - BOOLEAN
- 0 - disabled (default)
- not 0 - enabled

If this option is enabled, the lightweight tunnel netfilter hooks are
enabled. This option cannot be disabled once it is enabled.

nf_flowtable_tcp_timeout - INTEGER (seconds)
default 30

Expand Down
3 changes: 3 additions & 0 deletions include/net/lwtunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ struct lwtunnel_encap_ops {
};

#ifdef CONFIG_LWTUNNEL

DECLARE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);

void lwtstate_free(struct lwtunnel_state *lws);

static inline struct lwtunnel_state *
Expand Down
32 changes: 11 additions & 21 deletions include/net/netfilter/nf_conntrack_ecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,20 @@ struct nf_ct_event {
int report;
};

struct nf_exp_event {
struct nf_conntrack_expect *exp;
u32 portid;
int report;
};

struct nf_ct_event_notifier {
int (*fcn)(unsigned int events, struct nf_ct_event *item);
int (*ct_event)(unsigned int events, const struct nf_ct_event *item);
int (*exp_event)(unsigned int events, const struct nf_exp_event *item);
};

int nf_conntrack_register_notifier(struct net *net,
struct nf_ct_event_notifier *nb);
void nf_conntrack_unregister_notifier(struct net *net,
struct nf_ct_event_notifier *nb);
void nf_conntrack_register_notifier(struct net *net,
const struct nf_ct_event_notifier *nb);
void nf_conntrack_unregister_notifier(struct net *net);

void nf_ct_deliver_cached_events(struct nf_conn *ct);
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
Expand Down Expand Up @@ -151,22 +157,6 @@ nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
}

#ifdef CONFIG_NF_CONNTRACK_EVENTS

struct nf_exp_event {
struct nf_conntrack_expect *exp;
u32 portid;
int report;
};

struct nf_exp_event_notifier {
int (*fcn)(unsigned int events, struct nf_exp_event *item);
};

int nf_ct_expect_register_notifier(struct net *net,
struct nf_exp_event_notifier *nb);
void nf_ct_expect_unregister_notifier(struct net *net,
struct nf_exp_event_notifier *nb);

void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp,
u32 portid, int report);
Expand Down
7 changes: 7 additions & 0 deletions include/net/netfilter/nf_hooks_lwtunnel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <linux/sysctl.h>
#include <linux/types.h>

#ifdef CONFIG_SYSCTL
int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos);
#endif
1 change: 0 additions & 1 deletion include/net/netns/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ struct netns_ct {
struct ct_pcpu __percpu *pcpu_lists;
struct ip_conntrack_stat __percpu *stat;
struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
struct nf_ip_net nf_ct_proto;
#if defined(CONFIG_NF_CONNTRACK_LABELS)
unsigned int labels_used;
Expand Down
3 changes: 3 additions & 0 deletions net/core/lwtunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <net/ip6_fib.h>
#include <net/rtnh.h>

DEFINE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);
EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_enabled);

#ifdef CONFIG_MODULES

static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
Expand Down
2 changes: 2 additions & 0 deletions net/ipv4/netfilter/iptable_mangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ static int __init iptable_mangle_init(void)
{
int ret = xt_register_template(&packet_mangler,
iptable_mangle_table_init);
if (ret < 0)
return ret;

mangle_ops = xt_hook_ops_alloc(&packet_mangler, iptable_mangle_hook);
if (IS_ERR(mangle_ops)) {
Expand Down
75 changes: 72 additions & 3 deletions net/ipv6/seg6_iptunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifdef CONFIG_IPV6_SEG6_HMAC
#include <net/seg6_hmac.h>
#endif
#include <net/lwtunnel.h>
#include <linux/netfilter.h>

static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo)
{
Expand Down Expand Up @@ -295,11 +297,19 @@ static int seg6_do_srh(struct sk_buff *skb)

ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
nf_reset_ct(skb);

return 0;
}

static int seg6_input(struct sk_buff *skb)
static int seg6_input_finish(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
return dst_input(skb);
}

static int seg6_input_core(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
struct dst_entry *orig_dst = skb_dst(skb);
struct dst_entry *dst = NULL;
Expand Down Expand Up @@ -337,10 +347,41 @@ static int seg6_input(struct sk_buff *skb)
if (unlikely(err))
return err;

return dst_input(skb);
if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
dev_net(skb->dev), NULL, skb, NULL,
skb_dst(skb)->dev, seg6_input_finish);

return seg6_input_finish(dev_net(skb->dev), NULL, skb);
}

static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
static int seg6_input_nf(struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;
struct net *net = dev_net(skb->dev);

switch (skb->protocol) {
case htons(ETH_P_IP):
return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, NULL,
skb, NULL, dev, seg6_input_core);
case htons(ETH_P_IPV6):
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, NULL,
skb, NULL, dev, seg6_input_core);
}

return -EINVAL;
}

static int seg6_input(struct sk_buff *skb)
{
if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
return seg6_input_nf(skb);

return seg6_input_core(dev_net(skb->dev), NULL, skb);
}

static int seg6_output_core(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
struct dst_entry *orig_dst = skb_dst(skb);
struct dst_entry *dst = NULL;
Expand Down Expand Up @@ -387,12 +428,40 @@ static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
if (unlikely(err))
goto drop;

if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb,
NULL, skb_dst(skb)->dev, dst_output);

return dst_output(net, sk, skb);
drop:
kfree_skb(skb);
return err;
}

static int seg6_output_nf(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev;

switch (skb->protocol) {
case htons(ETH_P_IP):
return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, sk, skb,
NULL, dev, seg6_output_core);
case htons(ETH_P_IPV6):
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, sk, skb,
NULL, dev, seg6_output_core);
}

return -EINVAL;
}

static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
return seg6_output_nf(net, sk, skb);

return seg6_output_core(net, sk, skb);
}

static int seg6_build_state(struct net *net, struct nlattr *nla,
unsigned int family, const void *cfg,
struct lwtunnel_state **ts,
Expand Down
Loading

0 comments on commit 9dfa859

Please sign in to comment.