diff mbox series

[net] ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels

Message ID 4f0d0955-8bfc-486e-a44f-0e12af8a403f@strongswan.org (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net] ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 941 this patch: 941
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 3 maintainers not CCed: pabeni@redhat.com edumazet@google.com kuba@kernel.org
netdev/build_clang success Errors and warnings before: 957 this patch: 957
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 958 this patch: 958
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 7 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Tobias Brunner March 15, 2024, 12:25 p.m. UTC
Since the referenced commit, the xfrm_inner_extract_output() function
uses the skb's protocol field to determine the address family.  So not
setting it for IPv4 raw sockets meant that such packets couldn't be
tunneled via IPsec anymore.

IPv6 raw sockets are not affected as they already set the protocol since
9c9c9ad5fae7 ("ipv6: set skb->protocol on tcp, raw and ip6_append_data
genereated skbs").

Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path")
Signed-off-by: Tobias Brunner <tobias@strongswan.org>
---
 net/ipv4/raw.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Nicolas Dichtel March 15, 2024, 1:48 p.m. UTC | #1
Le 15/03/2024 à 13:25, Tobias Brunner a écrit :
> Since the referenced commit, the xfrm_inner_extract_output() function
> uses the skb's protocol field to determine the address family.  So not
> setting it for IPv4 raw sockets meant that such packets couldn't be
> tunneled via IPsec anymore.
> 
> IPv6 raw sockets are not affected as they already set the protocol since
> 9c9c9ad5fae7 ("ipv6: set skb->protocol on tcp, raw and ip6_append_data
> genereated skbs").
> 
> Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path")This is the input part, I presume you were thinking to the output part:
Fixes: f4796398f21b ("xfrm: Remove inner/outer modes from output path")


> Signed-off-by: Tobias Brunner <tobias@strongswan.org>
> ---
>  net/ipv4/raw.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
> index 42ac434cfcfa..322e389021c3 100644
> --- a/net/ipv4/raw.c
> +++ b/net/ipv4/raw.c
> @@ -357,6 +357,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>  		goto error;
>  	skb_reserve(skb, hlen);
>  
> +	skb->protocol = htons(ETH_P_IP);
>  	skb->priority = READ_ONCE(sk->sk_priority);
>  	skb->mark = sockc->mark;
>  	skb->tstamp = sockc->transmit_time;
For !ipsec packet, dst_output()/ ip_output() is called. This last function set
skb->protocol to htons(ETH_P_IP).
What about doing the same in xfrm4_output() to avoid missing another path?


Regards,
Nicolas
Tobias Brunner March 15, 2024, 2:31 p.m. UTC | #2
>> Since the referenced commit, the xfrm_inner_extract_output() function
>> uses the skb's protocol field to determine the address family.  So not
>> setting it for IPv4 raw sockets meant that such packets couldn't be
>> tunneled via IPsec anymore.
>>
>> IPv6 raw sockets are not affected as they already set the protocol since
>> 9c9c9ad5fae7 ("ipv6: set skb->protocol on tcp, raw and ip6_append_data
>> genereated skbs").
>>
>> Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path")This is the input part, I presume you were thinking to the output part:
> Fixes: f4796398f21b ("xfrm: Remove inner/outer modes from output path")

Right, will fix.

>> Signed-off-by: Tobias Brunner <tobias@strongswan.org>
>> ---
>>  net/ipv4/raw.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
>> index 42ac434cfcfa..322e389021c3 100644
>> --- a/net/ipv4/raw.c
>> +++ b/net/ipv4/raw.c
>> @@ -357,6 +357,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>>  		goto error;
>>  	skb_reserve(skb, hlen);
>>  
>> +	skb->protocol = htons(ETH_P_IP);
>>  	skb->priority = READ_ONCE(sk->sk_priority);
>>  	skb->mark = sockc->mark;
>>  	skb->tstamp = sockc->transmit_time;
> For !ipsec packet, dst_output()/ ip_output() is called. This last function set
> skb->protocol to htons(ETH_P_IP).
> What about doing the same in xfrm4_output() to avoid missing another path?

I took this approach because it worked and it aligns the code with the
IPv6 version.  Whether the code path would actually pass through the
function you mention before hitting the problematic one I don't know.

Regards,
Tobias
David Ahern March 15, 2024, 2:55 p.m. UTC | #3
On 3/15/24 8:31 AM, Tobias Brunner wrote:
>>> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
>>> index 42ac434cfcfa..322e389021c3 100644
>>> --- a/net/ipv4/raw.c
>>> +++ b/net/ipv4/raw.c
>>> @@ -357,6 +357,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>>>  		goto error;
>>>  	skb_reserve(skb, hlen);
>>>  
>>> +	skb->protocol = htons(ETH_P_IP);
>>>  	skb->priority = READ_ONCE(sk->sk_priority);
>>>  	skb->mark = sockc->mark;
>>>  	skb->tstamp = sockc->transmit_time;
>> For !ipsec packet, dst_output()/ ip_output() is called. This last function set
>> skb->protocol to htons(ETH_P_IP).
>> What about doing the same in xfrm4_output() to avoid missing another path?
> 
> I took this approach because it worked and it aligns the code with the
> IPv6 version.

I agree with that; setting it in raw_send_hdrinc makes it consistent
across protocols.


Reviewed-by: David Ahern <dsahern@kernel.org>
diff mbox series

Patch

diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 42ac434cfcfa..322e389021c3 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -357,6 +357,7 @@  static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
 		goto error;
 	skb_reserve(skb, hlen);
 
+	skb->protocol = htons(ETH_P_IP);
 	skb->priority = READ_ONCE(sk->sk_priority);
 	skb->mark = sockc->mark;
 	skb->tstamp = sockc->transmit_time;