Hi Ales, Lorenzo,

On 2/4/25 1:33 PM, Ales Musil wrote:
> On Tue, Feb 4, 2025 at 1:30 PM Lorenzo Bianconi <lorenzo.bianc...@redhat.com>
> wrote:
> 

I rephrased a bit the NEWS entry:

- Add concept of Transit Routers, users are now allowed to specify
  options:requested-chassis for router ports; if the chassis is remote
  then the router port will behave as a remote port.

Hope that's fine.

>> [...]
>>>
>>>          /* If the router is for l3 gateway, it resides on a chassis
>>>           * and its port type is "l3gateway". */
>>> -        const char *chassis_name = smap_get(&op->od->nbr->options,
>> "chassis");
>>> +        const char *lr_chassis = smap_get(&op->od->nbr->options,
>> "chassis");
>>> +
>>> +        /* If the LRP has requested chassis, that is remote, set the
>> type to
>>> +         * remote and add the appropriate chassis. */
>>> +        const char *req_chassis = smap_get(&op->nbrp->options,
>>> +                                           "requested-chassis");
>>> +        const struct sbrec_chassis *sb_chassis = NULL;
>>> +        const char *type = "patch";
>>>          if (is_cr_port(op)) {
>>> -            sbrec_port_binding_set_type(op->sb, "chassisredirect");
>>> -        } else if (chassis_name) {
>>> -            sbrec_port_binding_set_type(op->sb, "l3gateway");
>>> -        } else {
>>> -            sbrec_port_binding_set_type(op->sb, "patch");
>>> +            type = "chassisredirect";
>>> +        } else if (lr_chassis) {
>>> +            type = "l3gateway";
>>> +        } else if (req_chassis) {
>>> +            const struct sbrec_chassis *tr_chassis = chassis_lookup(
>>> +                sbrec_chassis_by_name, sbrec_chassis_by_hostname,
>> req_chassis);
>>> +            bool trp = tr_chassis &&
>> smap_get_bool(&tr_chassis->other_config,
>>> +                                                   "is-remote", false);
>>> +            sb_chassis = trp ? tr_chassis : NULL;
>>> +            type = trp ? "remote" : "patch";
>>> +        }
>>> +
>>> +        sbrec_port_binding_set_type(op->sb, type);
>>> +        sbrec_port_binding_set_requested_chassis(op->sb, sb_chassis);
>>
> 
> Hi Lorenzo,
> 
> thank you for the review.
> 
> 
>> nit: is it ok to set sbrec_port_binding_set_requested_chassis() even if
>> sb_chassis is NULL? (since you check it for
>> sbrec_port_binding_set_chassis()).
>>
> 
> It is, because this is the only use case within LRP for requested-chassis,
> however it needs to be checked for chassis because we might otherwise
> overwrite what was set by ovn-controller. Does that make sense?
> 
> 
>>
>> Regards,
>> Lorenzo
>>
>>
> Thanks,
> Ales
> 
> 
>>> +        if (sb_chassis) {
>>> +            sbrec_port_binding_set_chassis(op->sb, sb_chassis);
>>>          }
>>>
>>>          if (is_cr_port(op)) {
>>> @@ -4167,6 +4185,14 @@ ovn_port_assign_requested_tnl_id(struct ovn_port
>> *op)
>>>      return true;
>>>  }
>>>
>>> +static bool
>>> +ovn_port_is_trp(struct ovn_port *op)
>>> +{
>>> +    return op->nbrp &&
>>> +           op->sb->chassis &&
>>> +           smap_get_bool(&op->sb->chassis->other_config, "is-remote",
>> false);
>>> +}
>>> +

I found 'trp' too short as a name.  I renamed this function to
is_transit_router_port(), moved it next to the other is_*_port()
functions and added a comment:

/* This function returns true if 'op' is a router port that has as
 * requested chassis a remote chassis, i.e., if 'op' is a transit router
 * port. */
static bool
is_transit_router_port(struct ovn_port *op)
{
    [...]
}

>>>  static bool
>>>  ovn_port_allocate_key(struct ovn_port *op)
>>>  {
>>> @@ -4272,6 +4298,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
>>>                                sbrec_mirror_table,
>>>                                op, queue_id_bitmap,
>>>                                &active_ha_chassis_grps);
>>> +        op->od->is_transit_router |= ovn_port_is_trp(op);
>>>          ovs_list_remove(&op->list);
>>>      }
>>>
>>> @@ -4285,6 +4312,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
>>>                                op, queue_id_bitmap,
>>>                                &active_ha_chassis_grps);
>>>          sbrec_port_binding_set_logical_port(op->sb, op->key);
>>> +        op->od->is_transit_router |= ovn_port_is_trp(op);
>>>          ovs_list_remove(&op->list);
>>>      }
>>>
>>> diff --git a/northd/northd.h b/northd/northd.h
>>> index 6bca6bb1a..0da05d518 100644
>>> --- a/northd/northd.h
>>> +++ b/northd/northd.h
>>> @@ -356,6 +356,10 @@ struct ovn_datapath {
>>>       * If this is true, then 'l3dgw_ports' will be ignored. */
>>>      bool is_gw_router;
>>>
>>> +    /* Indicates whether the router should be considered a transit
>> router.
>>> +     * This is applicable only to routers with "remote" ports. */
>>> +    bool is_transit_router;
>>> +
>>>      /* OVN northd only needs to know about logical router gateway ports
>> for
>>>       * NAT/LB on a distributed router.  The "distributed gateway ports"
>> are
>>>       * populated only when there is a gateway chassis or ha chassis
>> group
>>> diff --git a/ovn-nb.xml b/ovn-nb.xml
>>> index d82f9872b..07bd24fce 100644
>>> --- a/ovn-nb.xml
>>> +++ b/ovn-nb.xml
>>> @@ -3104,6 +3104,32 @@ or
>>>      <column name="external_ids">
>>>        See <em>External IDs</em> at the beginning of this document.
>>>      </column>
>>> +
>>> +    <group title="Transit router">
>>> +      <p>
>>> +        In order to achieve status of <code>Transit Router</code> for
>>> +        <ref table="Logical_Router"/> there needs to be at least one
>>> +        <ref table="Logical_Router_Port"/> that is considered remote.
>>> +        The LRP can be <code>remote</code> only if it has
>>> +        <code>options:requested-chassis</code> set to chassis that is
>>> +        considered remote. See <ref table="Logical_Router_Port"/> for
>> more
>>> +        details.
>>> +      </p>
>>> +
>>> +      <p>
>>> +        In order for the <code>Transit Router</code> to work properly
>> all the
>>> +        tunnel keys for the <code>Transit Router</code> itself and the
>> remote
>>> +        ports keys needs to match  in all AZs e.g. TR in AZ1 and AZ2
>> needs to
>>> +        have the same tunnel key. Remote port for AZ2 in AZ1 needs to
>> have the
>>> +        same tunnel key as local port in AZ2 and vice vers.
>>> +      </p>
>>> +
>>> +      <p>
>>> +        The <code>Transit Router</code> behaves as distributed router
>> which
>>> +        means that it has the same limitations for stateful flows like
>>> +        <code>NAT and LBs</code> and it will lose the CT state between
>> AZs.
>>> +      </p>
>>> +    </group>
>>>    </table>
>>>
>>>    <table name="Meter" title="Meter entry">
>>> @@ -3680,6 +3706,23 @@ or
>>>            learned by the <code>ovn-ic</code> daemon.
>>>          </p>
>>>        </column>
>>> +
>>> +      <column name="options" key="requested-chassis">
>>> +        <p>
>>> +          If set, identifies a specific chassis (by name or hostname)
>> that
>>> +          is allowed to bind this port. This option is valid only for
>> chassis
>>> +          that have <code>options:is-remote=true</code>, in other words
>> for
>>> +          chassis that are in different Availability zone. The option
>> accepts
>>> +          only single value.
>>> +        </p>
>>> +
>>> +        <p>
>>> +          By assigning remote chassis the <ref table="Logical_Router"/>
>> gains
>>> +          status of <code>Transit Router</code> see
>>> +          <ref table="Logical_Router"/> table for more details.
>>> +        </p>
>>> +
>>> +      </column>
>>>      </group>
>>>
>>>      <group title="Attachment">
>>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
>>> index e64b5a660..40dcf338a 100644
>>> --- a/tests/ovn-northd.at
>>> +++ b/tests/ovn-northd.at
>>> @@ -14560,3 +14560,54 @@ wait_row_count Multicast_Group 0 name=239.0.1.68
>>>  OVN_CLEANUP([hv1], [hv2])
>>>  AT_CLEANUP
>>>  ])
>>> +
>>> +OVN_FOR_EACH_NORTHD_NO_HV([
>>> +AT_SETUP([Transit router - remote ports])
>>> +ovn_start NORTHD_TYPE
>>> +
>>> +check ovn-sbctl chassis-add hv2 geneve 192.168.0.12 \
>>> +    -- set chassis hv2 other_config:is-remote=true
>>> +
>>> +check ovn-sbctl chassis-add hv3 geneve 192.168.0.13 \
>>> +    -- set chassis hv3 other_config:is-remote=true
>>> +
>>> +check ovn-sbctl chassis-add hv4 geneve 192.168.0.14
>>> +
>>> +check ovn-nbctl lr-add tr
>>> +ovn-nbctl lrp-add tr tr-local 00:00:00:00:30:1 192.168.100.1/31
>>> +
>>> +ovn-nbctl lrp-add tr tr-az2 00:00:00:00:30:03 192.168.100.3/31 \
>>> +    -- set Logical_Router_Port tr-az2 options:requested-chassis=hv2
>>> +
>>> +ovn-nbctl lrp-add tr tr-az3 00:00:00:00:30:04 192.168.100.4/31 \
>>> +    -- set Logical_Router_Port tr-az3 options:requested-chassis=hv3
>>> +
>>> +ovn-nbctl lrp-add tr tr-az4 00:00:00:00:30:04 192.168.100.4/31 \
>>> +    -- set Logical_Router_Port tr-az4 options:requested-chassis=hv4
>>> +
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +hv2_uuid=$(fetch_column Chassis _uuid name=hv2)
>>> +hv3_uuid=$(fetch_column Chassis _uuid name=hv3)
>>> +hv4_uuid=$(fetch_column Chassis _uuid name=hv4)
>>> +
>>> +check_row_count Port_Binding 1 logical_port=tr-az2 type=remote
>> chassis=$hv2_uuid requested-chassis=$hv2_uuid
>>> +check_row_count Port_Binding 1 logical_port=tr-az3 type=remote
>> chassis=$hv3_uuid requested-chassis=$hv3_uuid
>>> +
>>> +# hv4 is not set as remote, so the port should remain as patch port
>>> +check_row_count Port_Binding 1 logical_port=tr-az4 type=patch
>>> +
>>> +check ovn-sbctl set chassis hv4 other_config:is-remote=true
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +# Setting hv4 as remote should change the tr-az4 to remote too
>>> +check_row_count Port_Binding 1 logical_port=tr-az4 type=remote
>> chassis=$hv4_uuid requested-chassis=$hv4_uuid
>>> +
>>> +check ovn-sbctl remove chassis hv4 other_config is-remote
>>> +check ovn-nbctl --wait=sb sync
>>> +
>>> +# Removing "is-remote" from hv4 should change the tr-az4 back to patch
>> port
>>> +check_row_count Port_Binding 1 logical_port=tr-az4 type=patch
>>> +
>>> +AT_CLEANUP
>>> +])
>>> --
>>> 2.48.1
>>>
>>

Thanks, Ales, Numan, Lorenzo and Quique!  I added Quique's "Tested-by"
[0] and pushed this patch to main.

Regards,
Dumitru

[0] https://mail.openvswitch.org/pipermail/ovs-dev/2025-February/420423.html

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

Reply via email to