-
Notifications
You must be signed in to change notification settings - Fork 54.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module
IPV6=m DEFRAG_IPV6=m CONNTRACK=y yields: net/netfilter/nf_conntrack_proto.o: In function `nf_ct_netns_do_get': net/netfilter/nf_conntrack_proto.c:802: undefined reference to `nf_defrag_ipv6_enable' net/netfilter/nf_conntrack_proto.o:(.rodata+0x640): undefined reference to `nf_conntrack_l4proto_icmpv6' Setting DEFRAG_IPV6=y causes undefined references to ip6_rhash_params ip6_frag_init and ip6_expire_frag_queue so it would be needed to force IPV6=y too. This patch gets rid of the 'followup linker error' by removing the dependency of ipv6.ko symbols from netfilter ipv6 defrag. Shared code is placed into a header, then used from both. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
- Loading branch information
Showing
7 changed files
with
126 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef _IPV6_FRAG_H | ||
#define _IPV6_FRAG_H | ||
#include <linux/kernel.h> | ||
#include <net/addrconf.h> | ||
#include <net/ipv6.h> | ||
#include <net/inet_frag.h> | ||
|
||
enum ip6_defrag_users { | ||
IP6_DEFRAG_LOCAL_DELIVER, | ||
IP6_DEFRAG_CONNTRACK_IN, | ||
__IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX, | ||
IP6_DEFRAG_CONNTRACK_OUT, | ||
__IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX, | ||
IP6_DEFRAG_CONNTRACK_BRIDGE_IN, | ||
__IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, | ||
}; | ||
|
||
/* | ||
* Equivalent of ipv4 struct ip | ||
*/ | ||
struct frag_queue { | ||
struct inet_frag_queue q; | ||
|
||
int iif; | ||
__u16 nhoffset; | ||
u8 ecn; | ||
}; | ||
|
||
#if IS_ENABLED(CONFIG_IPV6) | ||
static inline void ip6frag_init(struct inet_frag_queue *q, const void *a) | ||
{ | ||
struct frag_queue *fq = container_of(q, struct frag_queue, q); | ||
const struct frag_v6_compare_key *key = a; | ||
|
||
q->key.v6 = *key; | ||
fq->ecn = 0; | ||
} | ||
|
||
static inline u32 ip6frag_key_hashfn(const void *data, u32 len, u32 seed) | ||
{ | ||
return jhash2(data, | ||
sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); | ||
} | ||
|
||
static inline u32 ip6frag_obj_hashfn(const void *data, u32 len, u32 seed) | ||
{ | ||
const struct inet_frag_queue *fq = data; | ||
|
||
return jhash2((const u32 *)&fq->key.v6, | ||
sizeof(struct frag_v6_compare_key) / sizeof(u32), seed); | ||
} | ||
|
||
static inline int | ||
ip6frag_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr) | ||
{ | ||
const struct frag_v6_compare_key *key = arg->key; | ||
const struct inet_frag_queue *fq = ptr; | ||
|
||
return !!memcmp(&fq->key, key, sizeof(*key)); | ||
} | ||
|
||
static inline void | ||
ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq) | ||
{ | ||
struct net_device *dev = NULL; | ||
struct sk_buff *head; | ||
|
||
rcu_read_lock(); | ||
spin_lock(&fq->q.lock); | ||
|
||
if (fq->q.flags & INET_FRAG_COMPLETE) | ||
goto out; | ||
|
||
inet_frag_kill(&fq->q); | ||
|
||
dev = dev_get_by_index_rcu(net, fq->iif); | ||
if (!dev) | ||
goto out; | ||
|
||
__IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | ||
__IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); | ||
|
||
/* Don't send error if the first segment did not arrive. */ | ||
head = fq->q.fragments; | ||
if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !head) | ||
goto out; | ||
|
||
head->dev = dev; | ||
skb_get(head); | ||
spin_unlock(&fq->q.lock); | ||
|
||
icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); | ||
kfree_skb(head); | ||
goto out_rcu_unlock; | ||
|
||
out: | ||
spin_unlock(&fq->q.lock); | ||
out_rcu_unlock: | ||
rcu_read_unlock(); | ||
inet_frag_put(&fq->q); | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters