From b7265c59ab7dd0ec5dccb96e7b0dc1432404feb7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 5 Feb 2018 13:02:34 +0100 Subject: kernel: backport a series of netfilter cleanup patches to 4.14 Preparation for backporting upstream NAT offload support Signed-off-by: Felix Fietkau --- ...ove-reroute-indirection-to-struct-nf_ipv6.patch | 223 +++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch (limited to 'target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch') diff --git a/target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch b/target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch new file mode 100644 index 0000000000..f7fb81e440 --- /dev/null +++ b/target/linux/generic/backport-4.14/308-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch @@ -0,0 +1,223 @@ +From: Pablo Neira Ayuso +Date: Mon, 27 Nov 2017 22:50:26 +0100 +Subject: [PATCH] netfilter: move reroute indirection to struct nf_ipv6_ops + +We cannot make a direct call to nf_ip6_reroute() because that would result +in autoloading the 'ipv6' module because of symbol dependencies. +Therefore, define reroute indirection in nf_ipv6_ops where this really +belongs to. + +For IPv4, we can indeed make a direct function call, which is faster, +given IPv4 is built-in in the networking code by default. Still, +CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline +stub for IPv4 in such case. + +Signed-off-by: Pablo Neira Ayuso +--- + +--- a/include/linux/netfilter.h ++++ b/include/linux/netfilter.h +@@ -274,8 +274,6 @@ struct nf_queue_entry; + + struct nf_afinfo { + unsigned short family; +- int (*reroute)(struct net *net, struct sk_buff *skb, +- const struct nf_queue_entry *entry); + int route_key_size; + }; + +@@ -294,6 +292,7 @@ __sum16 nf_checksum_partial(struct sk_bu + u_int8_t protocol, unsigned short family); + int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, + bool strict, unsigned short family); ++int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); + + int nf_register_afinfo(const struct nf_afinfo *afinfo); + void nf_unregister_afinfo(const struct nf_afinfo *afinfo); +--- a/include/linux/netfilter_ipv4.h ++++ b/include/linux/netfilter_ipv4.h +@@ -18,6 +18,8 @@ struct ip_rt_info { + + int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); + ++struct nf_queue_entry; ++ + #ifdef CONFIG_INET + __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, + unsigned int dataoff, u_int8_t protocol); +@@ -26,6 +28,7 @@ __sum16 nf_ip_checksum_partial(struct sk + u_int8_t protocol); + int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl, + bool strict); ++int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry); + #else + static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, + unsigned int dataoff, u_int8_t protocol) +@@ -45,6 +48,11 @@ static inline int nf_ip_route(struct net + { + return -EOPNOTSUPP; + } ++static inline int nf_ip_reroute(struct sk_buff *skb, ++ const struct nf_queue_entry *entry) ++{ ++ return -EOPNOTSUPP; ++} + #endif /* CONFIG_INET */ + + #endif /*__LINUX_IP_NETFILTER_H*/ +--- a/include/linux/netfilter_ipv6.h ++++ b/include/linux/netfilter_ipv6.h +@@ -18,6 +18,8 @@ struct ip6_rt_info { + u_int32_t mark; + }; + ++struct nf_queue_entry; ++ + /* + * Hook functions for ipv6 to allow xt_* modules to be built-in even + * if IPv6 is a module. +@@ -35,6 +37,7 @@ struct nf_ipv6_ops { + u_int8_t protocol); + int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl, + bool strict); ++ int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry); + }; + + #ifdef CONFIG_NETFILTER +--- a/net/bridge/netfilter/nf_tables_bridge.c ++++ b/net/bridge/netfilter/nf_tables_bridge.c +@@ -95,15 +95,8 @@ static const struct nf_chain_type filter + (1 << NF_BR_POST_ROUTING), + }; + +-static int nf_br_reroute(struct net *net, struct sk_buff *skb, +- const struct nf_queue_entry *entry) +-{ +- return 0; +-} +- + static const struct nf_afinfo nf_br_afinfo = { + .family = AF_BRIDGE, +- .reroute = nf_br_reroute, + .route_key_size = 0, + }; + +--- a/net/ipv4/netfilter.c ++++ b/net/ipv4/netfilter.c +@@ -80,8 +80,7 @@ int ip_route_me_harder(struct net *net, + } + EXPORT_SYMBOL(ip_route_me_harder); + +-static int nf_ip_reroute(struct net *net, struct sk_buff *skb, +- const struct nf_queue_entry *entry) ++int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry) + { + const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); + +@@ -92,10 +91,12 @@ static int nf_ip_reroute(struct net *net + skb->mark == rt_info->mark && + iph->daddr == rt_info->daddr && + iph->saddr == rt_info->saddr)) +- return ip_route_me_harder(net, skb, RTN_UNSPEC); ++ return ip_route_me_harder(entry->state.net, skb, ++ RTN_UNSPEC); + } + return 0; + } ++EXPORT_SYMBOL_GPL(nf_ip_reroute); + + __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, + unsigned int dataoff, u_int8_t protocol) +@@ -163,7 +164,6 @@ EXPORT_SYMBOL_GPL(nf_ip_route); + + static const struct nf_afinfo nf_ip_afinfo = { + .family = AF_INET, +- .reroute = nf_ip_reroute, + .route_key_size = sizeof(struct ip_rt_info), + }; + +--- a/net/ipv6/netfilter.c ++++ b/net/ipv6/netfilter.c +@@ -68,7 +68,7 @@ int ip6_route_me_harder(struct net *net, + } + EXPORT_SYMBOL(ip6_route_me_harder); + +-static int nf_ip6_reroute(struct net *net, struct sk_buff *skb, ++static int nf_ip6_reroute(struct sk_buff *skb, + const struct nf_queue_entry *entry) + { + struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); +@@ -78,7 +78,7 @@ static int nf_ip6_reroute(struct net *ne + if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || + !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) || + skb->mark != rt_info->mark) +- return ip6_route_me_harder(net, skb); ++ return ip6_route_me_harder(entry->state.net, skb); + } + return 0; + } +@@ -171,11 +171,11 @@ static const struct nf_ipv6_ops ipv6ops + .checksum = nf_ip6_checksum, + .checksum_partial = nf_ip6_checksum_partial, + .route = nf_ip6_route, ++ .reroute = nf_ip6_reroute, + }; + + static const struct nf_afinfo nf_ip6_afinfo = { + .family = AF_INET6, +- .reroute = nf_ip6_reroute, + .route_key_size = sizeof(struct ip6_rt_info), + }; + +--- a/net/netfilter/nf_queue.c ++++ b/net/netfilter/nf_queue.c +@@ -250,7 +250,6 @@ void nf_reinject(struct nf_queue_entry * + const struct nf_hook_entry *hook_entry; + const struct nf_hook_entries *hooks; + struct sk_buff *skb = entry->skb; +- const struct nf_afinfo *afinfo; + const struct net *net; + unsigned int i; + int err; +@@ -277,8 +276,7 @@ void nf_reinject(struct nf_queue_entry * + verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state); + + if (verdict == NF_ACCEPT) { +- afinfo = nf_get_afinfo(entry->state.pf); +- if (!afinfo || afinfo->reroute(entry->state.net, skb, entry) < 0) ++ if (nf_reroute(skb, entry) < 0) + verdict = NF_DROP; + } + +--- a/net/netfilter/utils.c ++++ b/net/netfilter/utils.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + + __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, + unsigned int dataoff, u_int8_t protocol, +@@ -69,3 +70,21 @@ int nf_route(struct net *net, struct dst + return ret; + } + EXPORT_SYMBOL_GPL(nf_route); ++ ++int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry) ++{ ++ const struct nf_ipv6_ops *v6ops; ++ int ret = 0; ++ ++ switch (entry->state.pf) { ++ case AF_INET: ++ ret = nf_ip_reroute(skb, entry); ++ break; ++ case AF_INET6: ++ v6ops = rcu_dereference(nf_ipv6_ops); ++ if (v6ops) ++ ret = v6ops->reroute(skb, entry); ++ break; ++ } ++ return ret; ++} -- cgit v1.2.3