On 2023/05/22 20:41, Ilya Maximets wrote:
> On 5/22/23 07:05, Nobuhiro MIKI wrote:
>> On 2023/05/20 10:12, Ilya Maximets wrote:
>>> On 5/20/23 02:34, Ilya Maximets wrote:
>>>> On 5/16/23 07:33, Nobuhiro MIKI wrote:
>>>>> It supports flowlabel based load balancing by controlling the flowlabel
>>>>> of outer IPv6 header, which is already implemented in Linux kernel as
>>>>> seg6_flowlabel sysctl [1].
>>>>>
>>>>> [1]: https://docs.kernel.org/networking/seg6-sysctl.html
>>>>>
>>>>> Signed-off-by: Nobuhiro MIKI <[email protected]>
>>>>> ---
>>>>>  include/linux/openvswitch.h   |  3 +-
>>>>>  lib/netdev-native-tnl.c       | 23 ++++++++++-
>>>>>  lib/netdev-vport.c            |  8 ++++
>>>>>  lib/netdev.h                  | 12 ++++++
>>>>>  tests/tunnel-push-pop-ipv6.at | 72 +++++++++++++++++++++++++++++++++++
>>>>>  vswitchd/vswitch.xml          | 26 +++++++++++++
>>>>>  6 files changed, 141 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
>>>>> index e305c331516b..278829cfa826 100644
>>>>> --- a/include/linux/openvswitch.h
>>>>> +++ b/include/linux/openvswitch.h
>>>>> @@ -855,7 +855,8 @@ struct ovs_action_push_tnl {
>>>>>   odp_port_t tnl_port;
>>>>>   odp_port_t out_port;
>>>>>   uint32_t header_len;
>>>>> - uint32_t tnl_type;     /* For logging. */
>>>>> + uint32_t tnl_type;       /* For logging. */
>>>>> + uint32_t srv6_flowlabel; /* Only for SRv6. */
>>>>>   uint32_t header[TNL_PUSH_HEADER_SIZE / 4];
>>>>>  };
>>>>>  #endif
>>>>> diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
>>>>> index db1c4c6d9bfc..796169fe43ac 100644
>>>>> --- a/lib/netdev-native-tnl.c
>>>>> +++ b/lib/netdev-native-tnl.c
>>>>> @@ -910,6 +910,7 @@ netdev_srv6_build_header(const struct netdev *netdev,
>>>>>      }
>>>>>  
>>>>>      data->header_len += sizeof *srh + 8 * srh->rt_hdr.hdrlen;
>>>>> +    data->srv6_flowlabel = tnl_cfg->srv6_flowlabel;
>>>>>      data->tnl_type = OVS_VPORT_TYPE_SRV6;
>>>>>  out:
>>>>>      ovs_mutex_unlock(&dev->mutex);
>>>>> @@ -922,10 +923,28 @@ netdev_srv6_push_header(const struct netdev *netdev 
>>>>> OVS_UNUSED,
>>>>>                          struct dp_packet *packet,
>>>>>                          const struct ovs_action_push_tnl *data)
>>>>>  {
>>>>> +    struct ovs_16aligned_ip6_hdr *ip6 = dp_packet_l3(packet);
>>>>> +    ovs_be32 ipv6_label = 0;
>>>>>      int ip_tot_size;
>>>>> +    uint32_t flow;
>>>>>  
>>>>> -    netdev_tnl_push_ip_header(packet, data->header, data->header_len,
>>>>> -                              &ip_tot_size, 0);
>>>>> +    switch (data->srv6_flowlabel) {
>>>>
>>>> I understand why you added a new filed into the ovs_action_push_tnl 
>>>> structure,
>>>> but I'm not sure we should do that.
>>>>
>>>> If you'll look at the GRE seqno, for exmaple, you'll see that we're 
>>>> accessing
>>>> it via the original tnl_cfg structure stored in netdev.  The problem is 
>>>> that
>>>> it's not really thread safe, as I pointed out in review for the previous 
>>>> version.
>>>> I went ahead and tried to fix the thread-safety issues.  Patch set posted 
>>>> here:
>>>>
>>>>   
>>>> https://patchwork.ozlabs.org/project/openvswitch/list/?series=355820&state=*
>>>>
>>>> After these changes you should be able to directly use tunnel config like 
>>>> this:
>>>>
>>>>     switch (netdev_get_tunnel_config(netdev)->srv6_flowlabel) {
>>>>
>>>> And it's going to be safe to do so.  And we'll not need to change the 
>>>> action
>>>> structure.
>>>>
>>>> What do you think?
>>>
>>> One other option is to use the ipv6 label of the built header itself to 
>>> communicate
>>> the desired mode.   i.e. Write a enum value to the ipv6_label field during 
>>> the header
>>> build and check it here.
>>>
>>
>> Hi Ilya,
>>
>> Thanks for your reviews.
>>
>> There is something I don't understand in the handling of tnl_cfg structure.
>> It seems that the netdev given for each of the header push and header build 
>> is different.
>> For header build, t2 (which matches the port name used by ovs-ofctl) is 
>> given as netdev
>> and srv6_flowlabel enum value contains a valid value. But during header 
>> push, srv6_sys
>> is given as netdev and the srv6_flowlabel enum value is always 0. As for GRE 
>> seqno, it
>> may not be affected by this since its initial value is 0 and it is only 
>> incremented.
> 
> Hmm, interesting.  Thanks for pointing out!  I'll take a look.
> 

Thanks for your cooperation.
Please let me know if there is anything I can do to help.

>>
>> It seems to me that investigating and fixing why netdev is different for 
>> header build and
>> header push would be well beyond the scope of this patch set. So, as you 
>> commented, I'll
>> implement writing an enum value to the ipv6_label field at header build and 
>> replacing it
>> with a hash value at header push.
> 
> Ack.  Sounds good to me.  We also do the same thing for UDP checksum.
> We write 0xffff to the checksum field as an indicator that it needs
> to be calculated on push, see udp_build_header().
> 

Thanks for giving me the example.
OK. It seems that the plan for the implementation has been decided, I'll 
prepare v5.

Best Regards,
Nobuhiro MIKI

>> For reference, the investigation I did can be
>> reproduced below:
> 
> Thanks.
> 
>>
>> 2023-05-22T03:34:18.844Z|00157|native_tnl|INFO|netdev name in header build: 
>> t2
>> 2023-05-22T03:34:18.844Z|00158|native_tnl|INFO|srv6_flowlabel in header 
>> build: 1
>> 2023-05-22T03:34:18.844Z|00159|native_tnl|INFO|netdev name in header push: 
>> srv6_sys
>> 2023-05-22T03:34:18.844Z|00160|native_tnl|INFO|srv6_flowlabel in header 
>> push: 0
>>
>> diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
>> index cf7ed080a839..e941db13c46a 100644
>> --- a/lib/netdev-native-tnl.c
>> +++ b/lib/netdev-native-tnl.c
>> @@ -855,6 +855,9 @@ netdev_srv6_build_header(const struct netdev *netdev,
>>                           struct ovs_action_push_tnl *data,
>>                           const struct netdev_tnl_build_header_params 
>> *params)
>>  {
>> +    VLOG_INFO("netdev name in header build: %s", netdev->name);
>> +    VLOG_INFO("srv6_flowlabel in header build: %d", 
>> netdev_get_tunnel_config(netdev)->srv6_flowlabel);
>> +
>>      struct netdev_vport *dev = netdev_vport_cast(netdev);
>>      struct netdev_tunnel_config *tnl_cfg;
>>      const struct in6_addr *segs;
>> @@ -930,6 +933,9 @@ netdev_srv6_push_header(const struct netdev *netdev 
>> OVS_UNUSED,
>>      int ip_tot_size;
>>      uint32_t flow;
>>
>> +    VLOG_INFO("netdev name in header push: %s", netdev->name);
>> +    VLOG_INFO("srv6_flowlabel in header push: %d", 
>> netdev_get_tunnel_config(netdev)->srv6_flowlabel);
>> +
>>      switch (data->srv6_flowlabel) {
>>      case SRV6_FLOWLABEL_COPY:
>>          flow = ntohl(get_16aligned_be32(&ip6->ip6_flow));
>>
>>
>> Best Regards,
>> Nobuhiro MIKI
> 
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to