* [PATCH net] openvswitch: always update flow key after NAT
@ 2022-03-17 12:17 Aaron Conole
2022-03-17 13:42 ` [ovs-dev] " Eelco Chaudron
0 siblings, 1 reply; 4+ messages in thread
From: Aaron Conole @ 2022-03-17 12:17 UTC (permalink / raw)
To: netdev; +Cc: dev, pshelar, Ilya Maximets, Dumitru Ceara, Numan Siddique
During NAT, a tuple collision may occur. When this happens, openvswitch
will make a second pass through NAT which will perform additional packet
modification. This will update the skb data, but not the flow key that
OVS uses. This means that future flow lookups, and packet matches will
have incorrect data. This has been supported since
commit 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack").
That commit failed to properly update the sw_flow_key attributes, since
it only called the ovs_ct_nat_update_key once, rather than each time
ovs_ct_nat_execute was called. As these two operations are linked, the
ovs_ct_nat_execute() function should always make sure that the
sw_flow_key is updated after a successful call through NAT infrastructure.
Fixes: 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack")
Cc: Dumitru Ceara <dceara@redhat.com>
Cc: Numan Siddique <nusiddiq@redhat.com>
Signed-off-by: Aaron Conole <aconole@redhat.com>
---
net/openvswitch/conntrack.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index c07afff57dd3..461dbb3b7090 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -104,6 +104,10 @@ static bool labels_nonzero(const struct ovs_key_ct_labels *labels);
static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
+static void ovs_nat_update_key(struct sw_flow_key *key,
+ const struct sk_buff *skb,
+ enum nf_nat_manip_type maniptype);
+
static u16 key_to_nfproto(const struct sw_flow_key *key)
{
switch (ntohs(key->eth.type)) {
@@ -741,7 +745,7 @@ static bool skb_nfct_cached(struct net *net,
static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
const struct nf_nat_range2 *range,
- enum nf_nat_manip_type maniptype)
+ enum nf_nat_manip_type maniptype, struct sw_flow_key *key)
{
int hooknum, nh_off, err = NF_ACCEPT;
@@ -813,6 +817,10 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
push:
skb_push_rcsum(skb, nh_off);
+ /* Update the flow key if NAT successful. */
+ if (err == NF_ACCEPT)
+ ovs_nat_update_key(key, skb, maniptype);
+
return err;
}
@@ -906,7 +914,7 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
} else {
return NF_ACCEPT; /* Connection is not NATed. */
}
- err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
+ err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype, key);
if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) {
if (ct->status & IPS_SRC_NAT) {
@@ -916,17 +924,13 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
maniptype = NF_NAT_MANIP_SRC;
err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
- maniptype);
+ maniptype, key);
} else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
err = ovs_ct_nat_execute(skb, ct, ctinfo, NULL,
- NF_NAT_MANIP_SRC);
+ NF_NAT_MANIP_SRC, key);
}
}
- /* Mark NAT done if successful and update the flow key. */
- if (err == NF_ACCEPT)
- ovs_nat_update_key(key, skb, maniptype);
-
return err;
}
#else /* !CONFIG_NF_NAT */
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [ovs-dev] [PATCH net] openvswitch: always update flow key after NAT
2022-03-17 12:17 [PATCH net] openvswitch: always update flow key after NAT Aaron Conole
@ 2022-03-17 13:42 ` Eelco Chaudron
2022-03-17 14:01 ` Aaron Conole
0 siblings, 1 reply; 4+ messages in thread
From: Eelco Chaudron @ 2022-03-17 13:42 UTC (permalink / raw)
To: Aaron Conole; +Cc: netdev, dev, Dumitru Ceara, Ilya Maximets
On 17 Mar 2022, at 13:17, Aaron Conole wrote:
> During NAT, a tuple collision may occur. When this happens, openvswitch
> will make a second pass through NAT which will perform additional packet
> modification. This will update the skb data, but not the flow key that
> OVS uses. This means that future flow lookups, and packet matches will
> have incorrect data. This has been supported since
> commit 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack").
>
> That commit failed to properly update the sw_flow_key attributes, since
> it only called the ovs_ct_nat_update_key once, rather than each time
> ovs_ct_nat_execute was called. As these two operations are linked, the
> ovs_ct_nat_execute() function should always make sure that the
> sw_flow_key is updated after a successful call through NAT infrastructure.
>
> Fixes: 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack")
> Cc: Dumitru Ceara <dceara@redhat.com>
> Cc: Numan Siddique <nusiddiq@redhat.com>
> Signed-off-by: Aaron Conole <aconole@redhat.com>
> ---
> net/openvswitch/conntrack.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
> index c07afff57dd3..461dbb3b7090 100644
> --- a/net/openvswitch/conntrack.c
> +++ b/net/openvswitch/conntrack.c
> @@ -104,6 +104,10 @@ static bool labels_nonzero(const struct ovs_key_ct_labels *labels);
>
> static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
>
> +static void ovs_nat_update_key(struct sw_flow_key *key,
> + const struct sk_buff *skb,
> + enum nf_nat_manip_type maniptype);
> +
nit?: Rather than adding this would it be simpler to swap the order of ovs_nat_update_key and ovs_ct_nat_execute?
Also, the function is defined by “#if IS_ENABLED(CONFIG_NF_NAT)” not sure if this will generate warnings if the function is not present?
> static u16 key_to_nfproto(const struct sw_flow_key *key)
> {
> switch (ntohs(key->eth.type)) {
> @@ -741,7 +745,7 @@ static bool skb_nfct_cached(struct net *net,
> static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
> enum ip_conntrack_info ctinfo,
> const struct nf_nat_range2 *range,
> - enum nf_nat_manip_type maniptype)
> + enum nf_nat_manip_type maniptype, struct sw_flow_key *key)
> {
> int hooknum, nh_off, err = NF_ACCEPT;
>
> @@ -813,6 +817,10 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
> push:
> skb_push_rcsum(skb, nh_off);
>
> + /* Update the flow key if NAT successful. */
> + if (err == NF_ACCEPT)
> + ovs_nat_update_key(key, skb, maniptype);
> +
> return err;
> }
>
> @@ -906,7 +914,7 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
> } else {
> return NF_ACCEPT; /* Connection is not NATed. */
> }
> - err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
> + err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype, key);
>
> if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) {
> if (ct->status & IPS_SRC_NAT) {
> @@ -916,17 +924,13 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
> maniptype = NF_NAT_MANIP_SRC;
>
> err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
> - maniptype);
> + maniptype, key);
> } else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
> err = ovs_ct_nat_execute(skb, ct, ctinfo, NULL,
> - NF_NAT_MANIP_SRC);
> + NF_NAT_MANIP_SRC, key);
> }
> }
>
> - /* Mark NAT done if successful and update the flow key. */
> - if (err == NF_ACCEPT)
> - ovs_nat_update_key(key, skb, maniptype);
> -
> return err;
> }
> #else /* !CONFIG_NF_NAT */
The rest of the patch looks fine to me...
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [ovs-dev] [PATCH net] openvswitch: always update flow key after NAT
2022-03-17 13:42 ` [ovs-dev] " Eelco Chaudron
@ 2022-03-17 14:01 ` Aaron Conole
2022-03-17 14:30 ` Eelco Chaudron
0 siblings, 1 reply; 4+ messages in thread
From: Aaron Conole @ 2022-03-17 14:01 UTC (permalink / raw)
To: Eelco Chaudron; +Cc: netdev, dev, Dumitru Ceara, Ilya Maximets
Eelco Chaudron <echaudro@redhat.com> writes:
> On 17 Mar 2022, at 13:17, Aaron Conole wrote:
>
>> During NAT, a tuple collision may occur. When this happens, openvswitch
>> will make a second pass through NAT which will perform additional packet
>> modification. This will update the skb data, but not the flow key that
>> OVS uses. This means that future flow lookups, and packet matches will
>> have incorrect data. This has been supported since
>> commit 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack").
>>
>> That commit failed to properly update the sw_flow_key attributes, since
>> it only called the ovs_ct_nat_update_key once, rather than each time
>> ovs_ct_nat_execute was called. As these two operations are linked, the
>> ovs_ct_nat_execute() function should always make sure that the
>> sw_flow_key is updated after a successful call through NAT infrastructure.
>>
>> Fixes: 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack")
>> Cc: Dumitru Ceara <dceara@redhat.com>
>> Cc: Numan Siddique <nusiddiq@redhat.com>
>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>> ---
>> net/openvswitch/conntrack.c | 20 ++++++++++++--------
>> 1 file changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
>> index c07afff57dd3..461dbb3b7090 100644
>> --- a/net/openvswitch/conntrack.c
>> +++ b/net/openvswitch/conntrack.c
>> @@ -104,6 +104,10 @@ static bool labels_nonzero(const struct ovs_key_ct_labels *labels);
>>
>> static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
>>
>> +static void ovs_nat_update_key(struct sw_flow_key *key,
>> + const struct sk_buff *skb,
>> + enum nf_nat_manip_type maniptype);
>> +
>
> nit?: Rather than adding this would it be simpler to swap the order of
> ovs_nat_update_key and ovs_ct_nat_execute?
I thought it looked messier that way.
> Also, the function is defined by “#if IS_ENABLED(CONFIG_NF_NAT)” not
> sure if this will generate warnings if the function is not present?
Good catch, yes it will. I will submit a v2 with this guard in place if
you think the foward decl is okay to keep.
>> static u16 key_to_nfproto(const struct sw_flow_key *key)
>> {
>> switch (ntohs(key->eth.type)) {
>> @@ -741,7 +745,7 @@ static bool skb_nfct_cached(struct net *net,
>> static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
>> enum ip_conntrack_info ctinfo,
>> const struct nf_nat_range2 *range,
>> - enum nf_nat_manip_type maniptype)
>> + enum nf_nat_manip_type maniptype, struct sw_flow_key *key)
>> {
>> int hooknum, nh_off, err = NF_ACCEPT;
>>
>> @@ -813,6 +817,10 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
>> push:
>> skb_push_rcsum(skb, nh_off);
>>
>> + /* Update the flow key if NAT successful. */
>> + if (err == NF_ACCEPT)
>> + ovs_nat_update_key(key, skb, maniptype);
>> +
>> return err;
>> }
>>
>> @@ -906,7 +914,7 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
>> } else {
>> return NF_ACCEPT; /* Connection is not NATed. */
>> }
>> - err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
>> + err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype, key);
>>
>> if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) {
>> if (ct->status & IPS_SRC_NAT) {
>> @@ -916,17 +924,13 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
>> maniptype = NF_NAT_MANIP_SRC;
>>
>> err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
>> - maniptype);
>> + maniptype, key);
>> } else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
>> err = ovs_ct_nat_execute(skb, ct, ctinfo, NULL,
>> - NF_NAT_MANIP_SRC);
>> + NF_NAT_MANIP_SRC, key);
>> }
>> }
>>
>> - /* Mark NAT done if successful and update the flow key. */
>> - if (err == NF_ACCEPT)
>> - ovs_nat_update_key(key, skb, maniptype);
>> -
>> return err;
>> }
>> #else /* !CONFIG_NF_NAT */
>
> The rest of the patch looks fine to me...
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [ovs-dev] [PATCH net] openvswitch: always update flow key after NAT
2022-03-17 14:01 ` Aaron Conole
@ 2022-03-17 14:30 ` Eelco Chaudron
0 siblings, 0 replies; 4+ messages in thread
From: Eelco Chaudron @ 2022-03-17 14:30 UTC (permalink / raw)
To: Aaron Conole; +Cc: netdev, dev, Dumitru Ceara, Ilya Maximets
On 17 Mar 2022, at 15:01, Aaron Conole wrote:
> Eelco Chaudron <echaudro@redhat.com> writes:
>
>> On 17 Mar 2022, at 13:17, Aaron Conole wrote:
>>
>>> During NAT, a tuple collision may occur. When this happens, openvswitch
>>> will make a second pass through NAT which will perform additional packet
>>> modification. This will update the skb data, but not the flow key that
>>> OVS uses. This means that future flow lookups, and packet matches will
>>> have incorrect data. This has been supported since
>>> commit 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack").
>>>
>>> That commit failed to properly update the sw_flow_key attributes, since
>>> it only called the ovs_ct_nat_update_key once, rather than each time
>>> ovs_ct_nat_execute was called. As these two operations are linked, the
>>> ovs_ct_nat_execute() function should always make sure that the
>>> sw_flow_key is updated after a successful call through NAT infrastructure.
>>>
>>> Fixes: 5d50aa83e2c8 ("openvswitch: support asymmetric conntrack")
>>> Cc: Dumitru Ceara <dceara@redhat.com>
>>> Cc: Numan Siddique <nusiddiq@redhat.com>
>>> Signed-off-by: Aaron Conole <aconole@redhat.com>
>>> ---
>>> net/openvswitch/conntrack.c | 20 ++++++++++++--------
>>> 1 file changed, 12 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
>>> index c07afff57dd3..461dbb3b7090 100644
>>> --- a/net/openvswitch/conntrack.c
>>> +++ b/net/openvswitch/conntrack.c
>>> @@ -104,6 +104,10 @@ static bool labels_nonzero(const struct ovs_key_ct_labels *labels);
>>>
>>> static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info);
>>>
>>> +static void ovs_nat_update_key(struct sw_flow_key *key,
>>> + const struct sk_buff *skb,
>>> + enum nf_nat_manip_type maniptype);
>>> +
>>
>> nit?: Rather than adding this would it be simpler to swap the order of
>> ovs_nat_update_key and ovs_ct_nat_execute?
>
> I thought it looked messier that way.
>
>> Also, the function is defined by “#if IS_ENABLED(CONFIG_NF_NAT)” not
>> sure if this will generate warnings if the function is not present?
>
> Good catch, yes it will. I will submit a v2 with this guard in place if
> you think the foward decl is okay to keep.
I’m fine with either way, but I personally prefer the re-order as the code looks cleaner (but the patch doesn't ;).
>>> static u16 key_to_nfproto(const struct sw_flow_key *key)
>>> {
>>> switch (ntohs(key->eth.type)) {
>>> @@ -741,7 +745,7 @@ static bool skb_nfct_cached(struct net *net,
>>> static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
>>> enum ip_conntrack_info ctinfo,
>>> const struct nf_nat_range2 *range,
>>> - enum nf_nat_manip_type maniptype)
>>> + enum nf_nat_manip_type maniptype, struct sw_flow_key *key)
>>> {
>>> int hooknum, nh_off, err = NF_ACCEPT;
>>>
>>> @@ -813,6 +817,10 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
>>> push:
>>> skb_push_rcsum(skb, nh_off);
>>>
>>> + /* Update the flow key if NAT successful. */
>>> + if (err == NF_ACCEPT)
>>> + ovs_nat_update_key(key, skb, maniptype);
>>> +
>>> return err;
>>> }
>>>
>>> @@ -906,7 +914,7 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
>>> } else {
>>> return NF_ACCEPT; /* Connection is not NATed. */
>>> }
>>> - err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
>>> + err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype, key);
>>>
>>> if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) {
>>> if (ct->status & IPS_SRC_NAT) {
>>> @@ -916,17 +924,13 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
>>> maniptype = NF_NAT_MANIP_SRC;
>>>
>>> err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
>>> - maniptype);
>>> + maniptype, key);
>>> } else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
>>> err = ovs_ct_nat_execute(skb, ct, ctinfo, NULL,
>>> - NF_NAT_MANIP_SRC);
>>> + NF_NAT_MANIP_SRC, key);
>>> }
>>> }
>>>
>>> - /* Mark NAT done if successful and update the flow key. */
>>> - if (err == NF_ACCEPT)
>>> - ovs_nat_update_key(key, skb, maniptype);
>>> -
>>> return err;
>>> }
>>> #else /* !CONFIG_NF_NAT */
>>
>> The rest of the patch looks fine to me...
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-03-17 14:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-17 12:17 [PATCH net] openvswitch: always update flow key after NAT Aaron Conole
2022-03-17 13:42 ` [ovs-dev] " Eelco Chaudron
2022-03-17 14:01 ` Aaron Conole
2022-03-17 14:30 ` Eelco Chaudron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).