2023-03-01 14:56:06

by Madhu Koriginja

[permalink] [raw]
Subject: [PATCH] [NETFILTER]: Keep conntrack reference until IPsecv6 policy checks are done

Keep the conntrack reference until policy checks have been performed for
IPsec V6 NAT support. The reference needs to be dropped before a packet is
queued to avoid having the conntrack module unloadable.

Signed-off-by: Madhu Koriginja <[email protected]>
---
net/dccp/ipv6.c | 1 +
net/ipv6/ip6_input.c | 14 +++++++-------
net/ipv6/raw.c | 2 +-
net/ipv6/tcp_ipv6.c | 2 ++
net/ipv6/udp.c | 2 ++
5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 58a401e9cf09..eb503096db6c 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -771,6 +771,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)

if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto discard_and_relse;
+ nf_reset(skb);

return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
refcounted) ? -1 : 0;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index acf0749ee5bb..7dc295b7af8f 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -374,10 +374,6 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
/* Only do this once for first final protocol */
have_final = true;

- /* Free reference early: we don't need it any more,
- and it may hold ip_conntrack module loaded
- indefinitely. */
- nf_reset(skb);

skb_postpull_rcsum(skb, skb_network_header(skb),
skb_network_header_len(skb));
@@ -388,9 +384,13 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
!ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
goto discard;
}
- if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
- !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
- goto discard;
+
+ if (!ipprot->flags & INET6_PROTO_NOPOLICY) {
+ if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+ goto discard;
+
+ nf_reset(skb);
+ }

ret = ipprot->handler(skb);
if (ret > 0) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 4856d9320b28..cf68c9418897 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -220,7 +220,6 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)

/* Not releasing hash table! */
if (clone) {
- nf_reset(clone);
rawv6_rcv(sk, clone);
}
}
@@ -428,6 +427,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
kfree_skb(skb);
return NET_RX_DROP;
}
+ nf_reset(skb);

if (!rp->checksum)
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 9a117a79af65..0bc959cfbea4 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1534,6 +1534,8 @@ static int tcp_v6_rcv(struct sk_buff *skb)
if (tcp_v6_inbound_md5_hash(sk, skb))
goto discard_and_relse;

+ nf_reset(skb);
+
if (tcp_filter(sk, skb))
goto discard_and_relse;
th = (const struct tcphdr *)skb->data;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 72b2e7809af6..aacb48e977cb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -567,6 +567,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)

if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
goto drop;
+ nf_reset(skb);

if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
@@ -860,6 +861,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,

if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard;
+ nf_reset(skb);

if (udp_lib_checksum_complete(skb))
goto csum_error;
--
2.25.1



2023-03-01 15:08:07

by Florian Westphal

[permalink] [raw]
Subject: Re: [PATCH] [NETFILTER]: Keep conntrack reference until IPsecv6 policy checks are done

Madhu Koriginja <[email protected]> wrote:
> Keep the conntrack reference until policy checks have been performed for
> IPsec V6 NAT support. The reference needs to be dropped before a packet is
> queued to avoid having the conntrack module unloadable.

In the old days there was no ipv6 nat so its not surpising
that ipv6 discards the conntrack entry earlier than ipv4.

> - if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
> - !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
> - goto discard;
> +
> + if (!ipprot->flags & INET6_PROTO_NOPOLICY) {

This looks wrong, why did you drop the () ?

if (!(ipprot->flags & INET6_PROTO_NOPOLICY)) { ...

rest LGTM.

2023-03-01 15:19:23

by Madhu Koriginja

[permalink] [raw]
Subject: RE: [EXT] Re: [PATCH] [NETFILTER]: Keep conntrack reference until IPsecv6 policy checks are done

Hi Florian,
Got it, it's typo mistake. I will update the patch.
Thanks for quick review.
Regards,
Madhu K

-----Original Message-----
From: Florian Westphal <[email protected]>
Sent: Wednesday, March 1, 2023 8:38 PM
To: Madhu Koriginja <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Vani Namala <[email protected]>
Subject: [EXT] Re: [PATCH] [NETFILTER]: Keep conntrack reference until IPsecv6 policy checks are done

Caution: EXT Email

Madhu Koriginja <[email protected]> wrote:
> Keep the conntrack reference until policy checks have been performed
> for IPsec V6 NAT support. The reference needs to be dropped before a
> packet is queued to avoid having the conntrack module unloadable.

In the old days there was no ipv6 nat so its not surpising that ipv6 discards the conntrack entry earlier than ipv4.

> - if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
> - !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
> - goto discard;
> +
> + if (!ipprot->flags & INET6_PROTO_NOPOLICY) {

This looks wrong, why did you drop the () ?

if (!(ipprot->flags & INET6_PROTO_NOPOLICY)) { ...

rest LGTM.

2023-03-01 15:25:24

by Florian Westphal

[permalink] [raw]
Subject: Re: [EXT] Re: [PATCH] [NETFILTER]: Keep conntrack reference until IPsecv6 policy checks are done

Madhu Koriginja <[email protected]> wrote:
> Got it, it's typo mistake. I will update the patch.

Forgot to mention, please use 'net: ' or perhaps 'net: netfilter: ' as
prefix, not [NETFILTER].

Thanks.