On 4/25/23 16:35, Mark Michelson wrote:
> On 4/18/23 10:32, Dumitru Ceara wrote:
>> On 4/14/23 15:10, Mark Michelson wrote:
>>> Current code always skips conntrack for traffic that ingresses or
>>> egresses on a localnet port. However, this makes it impossible for
>>> traffic to be load-balanced when it arrives on a localnet port.
>>>
>>> This patch allows for traffic to be load balanced on localnet ports by
>>> making two changes:
>>> * Localnet ports now have a conntrack zone assigned.
>>> * When a load balancer is configured on a logical switch containing a
>>>    localnet port, then conntack is no longer skipped for traffic
>>
>> typo: 'conntack'
>>
>>>    involving the localnet port.
>>
>> Will this change behavior when both ACLs and LBs are applied to a switch
>> with a localnet port?
> 
> The biggest change is that localnet traffic will be sent to conntrack in
> the PRE_STATEFUL ingress/egress stages, with the intent of defragmenting
> the traffic. This also will happen if LBs are applied but *no* ACLs are
> defined on the logical switch.
> 

But what about the case when "allow-related" ACLs are applied on the
logical switch but no LB is?  Shouldn't we send traffic to conntrack in
that case too?

> As far as behavior changes are concerned, this will result in more
> conntrack entries being created, but it should not affect how traffic is
> handled when localnet ports are involved.
> 

I'm assuming this might also (to some extent) affect latency in the
datapath due to the additional conntrack.  But again, that's probably
fine if users configured load balancers on that switch.

>>
>>>
>>> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2164652
>>>
>>> Co-authored-by: Dumitru Ceara <dce...@redhat.com>
>>> Signed-off-by: Mark Michelson <mmich...@redhat.com>
>>> ---
>>> This patch is based on an inlined patch provided by Dumitru Ceara on the
>>> referenced bugzilla issue. I modified it to only skip conntrack when a
>>> load balancer is present on the logical switch, and I added a simple
>>> test case to verify the logical flows are populated as expected.
>>>
>>> Dumitru, if you want more than the "Co-authored-by" citation on this
>>> issue, please let me know and I'll adjust it.
>>
>> I'm ok as co-author and, to keep the robot happy, if we decide to apply
>> this to main:
>>
>> Signed-off-by: Dumitru Ceara <dce...@redhat.com>
>>
>>> ---
>>>   controller/ovn-controller.c | 13 ++++----
>>>   northd/northd.c             | 25 +++++++++++-----
>>>   tests/ovn-northd.at         | 60 +++++++++++++++++++++++++++++++++++++
>>
>> Would it be possible to add a system test too?
> 
> Can do!
> 

Thanks!

>>
>> Thanks,
>> Dumitru
>>
>>>   3 files changed, 84 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
>>> index e170e9262..3a89e386f 100644
>>> --- a/controller/ovn-controller.c
>>> +++ b/controller/ovn-controller.c
>>> @@ -723,7 +723,7 @@ get_snat_ct_zone(const struct
>>> sbrec_datapath_binding *dp)
>>>   }
>>>     static void
>>> -update_ct_zones(const struct shash *binding_lports,
>>> +update_ct_zones(const struct sset *local_lports,
>>>                   const struct hmap *local_datapaths,
>>>                   struct simap *ct_zones, unsigned long *ct_zone_bitmap,
>>>                   struct shash *pending_ct_zones)
>>> @@ -736,9 +736,9 @@ update_ct_zones(const struct shash *binding_lports,
>>>       unsigned long unreq_snat_zones_map[BITMAP_N_LONGS(MAX_CT_ZONES)];
>>>       struct simap unreq_snat_zones =
>>> SIMAP_INITIALIZER(&unreq_snat_zones);
>>>   -    struct shash_node *shash_node;
>>> -    SHASH_FOR_EACH (shash_node, binding_lports) {
>>> -        sset_add(&all_users, shash_node->name);
>>> +    const char *local_lport;
>>> +    SSET_FOR_EACH (local_lport, local_lports) {
>>> +        sset_add(&all_users, local_lport);
>>>       }
>>>         /* Local patched datapath (gateway routers) need zones
>>> assigned. */
>>> @@ -2392,7 +2392,7 @@ en_ct_zones_run(struct engine_node *node, void
>>> *data)
>>>           EN_OVSDB_GET(engine_get_input("OVS_bridge", node));
>>>         restore_ct_zones(bridge_table, ovs_table, ct_zones_data);
>>> -    update_ct_zones(&rt_data->lbinding_data.lports,
>>> &rt_data->local_datapaths,
>>> +    update_ct_zones(&rt_data->local_lports, &rt_data->local_datapaths,
>>>                       &ct_zones_data->current, ct_zones_data->bitmap,
>>>                       &ct_zones_data->pending);
>>>   @@ -2482,7 +2482,8 @@ ct_zones_runtime_data_handler(struct
>>> engine_node *node, void *data)
>>>           SHASH_FOR_EACH (shash_node, &tdp->lports) {
>>>               struct tracked_lport *t_lport = shash_node->data;
>>>               if (strcmp(t_lport->pb->type, "")
>>> -                && strcmp(t_lport->pb->type, "localport")) {
>>> +                && strcmp(t_lport->pb->type, "localport")
>>> +                && strcmp(t_lport->pb->type, "localnet")) {
>>>                   /* We allocate zone-id's only to VIF and localport
>>> lports. */
>>>                   continue;
>>>               }
>>> diff --git a/northd/northd.c b/northd/northd.c
>>> index da3c8cf77..8439446aa 100644
>>> --- a/northd/northd.c
>>> +++ b/northd/northd.c
>>> @@ -5959,10 +5959,12 @@ build_pre_acls(struct ovn_datapath *od, const
>>> struct hmap *port_groups,
>>>                                        S_SWITCH_IN_PRE_ACL,
>>> S_SWITCH_OUT_PRE_ACL,
>>>                                        110, lflows);
>>>           }
>>> -        for (size_t i = 0; i < od->n_localnet_ports; i++) {
>>> -            skip_port_from_conntrack(od, od->localnet_ports[i],
>>> -                                     S_SWITCH_IN_PRE_ACL,
>>> S_SWITCH_OUT_PRE_ACL,
>>> -                                     110, lflows);
>>> +        if (!od->has_lb_vip) {
>>> +            for (size_t i = 0; i < od->n_localnet_ports; i++) {
>>> +                skip_port_from_conntrack(od, od->localnet_ports[i],
>>> +                                         S_SWITCH_IN_PRE_ACL,
>>> S_SWITCH_OUT_PRE_ACL,
>>> +                                         110, lflows);
>>> +            }
>>>           }
>>>             /* stateless filters always take precedence over stateful
>>> ACLs. */
>>> @@ -6130,10 +6132,17 @@ build_pre_lb(struct ovn_datapath *od, const
>>> struct shash *meter_groups,
>>>                                    S_SWITCH_IN_PRE_LB,
>>> S_SWITCH_OUT_PRE_LB,
>>>                                    110, lflows);
>>>       }
>>> -    for (size_t i = 0; i < od->n_localnet_ports; i++) {
>>> -        skip_port_from_conntrack(od, od->localnet_ports[i],
>>> -                                 S_SWITCH_IN_PRE_LB,
>>> S_SWITCH_OUT_PRE_LB,
>>> -                                 110, lflows);
>>> +    /* Localnet ports have no need for going through conntrack, unless
>>> +     * the logical switch has a load balancer. Then, conntrack is
>>> necessary
>>> +     * so that traffic arriving via the localnet port can be load
>>> +     * balanced.
>>> +     */
>>> +    if (!od->has_lb_vip) {
>>> +        for (size_t i = 0; i < od->n_localnet_ports; i++) {
>>> +            skip_port_from_conntrack(od, od->localnet_ports[i],
>>> +                                     S_SWITCH_IN_PRE_LB,
>>> S_SWITCH_OUT_PRE_LB,
>>> +                                     110, lflows);
>>> +        }
>>>       }
>>>         /* Do not sent statless flows via conntrack */
>>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
>>> index 9fee00094..909b06719 100644
>>> --- a/tests/ovn-northd.at
>>> +++ b/tests/ovn-northd.at
>>> @@ -8830,3 +8830,63 @@ mac_binding_timestamp: true
>>>     AT_CLEANUP
>>>   ])
>>> +
>>> +OVN_FOR_EACH_NORTHD_NO_HV([
>>> +AT_SETUP([Localnet ports on LS with LB])
>>> +ovn_start
>>> +# In the past, traffic arriving on localnet ports has skipped
>>> conntrack.
>>> +# This test ensures that we still skip conntrack for localnet ports,
>>> +# *except* for the case where the logical switch has a load balancer
>>> +# configured. In this case, the localnet port will not skip conntrack,
>>> +# allowing for traffic to be load balanced on the localnet port.
>>> +
>>> +check ovn-nbctl ls-add sw
>>> +check ovn-nbctl lsp-add sw sw-ln
>>> +check ovn-nbctl lsp-set-type sw-ln localnet
>>> +check ovn-nbctl lsp-set-addresses sw-ln unknown
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +# Since this test is only concerned with logical flows, we don't
>>> need to
>>> +# configure anything else that we normally would with regards to
>>> localnet
>>> +# ports
>>> +
>>> +
>>> +# First, ensure that conntrack is skipped for the localnet port
>>> since there
>>> +# isn't a load balancer configured.
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_in_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +  table=??(ls_in_pre_lb       ), priority=110  , match=(ip && inport
>>> == "sw-ln"), action=(next;)
>>> +])
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_out_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +  table=??(ls_out_pre_lb      ), priority=110  , match=(ip &&
>>> outport == "sw-ln"), action=(ct_clear; next;)
>>> +])
>>> +
>>> +# Now add a load balancer and ensure that we no longer are skipping
>>> conntrack
>>> +# for the localnet port
>>> +
>>> +check ovn-nbctl lb-add lb 10.0.0.1:80 10.0.0.100:8080 tcp
>>> +check ovn-nbctl ls-lb-add sw lb
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_in_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +])
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_out_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +])
>>> +
>>> +# And ensure that removing the load balancer from the switch results
>>> in skipping
>>> +# conntrack again
>>> +check ovn-nbctl ls-lb-del sw lb
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_in_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +  table=??(ls_in_pre_lb       ), priority=110  , match=(ip && inport
>>> == "sw-ln"), action=(next;)
>>> +])
>>> +
>>> +AT_CHECK([ovn-sbctl lflow-list sw | grep ls_out_pre_lb | grep
>>> priority=110 | grep sw-ln | sed 's/table=../table=??/'], [0], [dnl
>>> +  table=??(ls_out_pre_lb      ), priority=110  , match=(ip &&
>>> outport == "sw-ln"), action=(ct_clear; next;)
>>> +])
>>> +
>>> +AT_CLEANUP
>>> +])
>>
> 

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to