On 17/01/2019 17:26, Ben Pfaff wrote:
> On Thu, Jan 17, 2019 at 12:55:54PM +0000, Pieter Jansen van Vuuren wrote:
>> On 16/01/2019 18:38, Ben Pfaff wrote:
>>> On Wed, Jan 16, 2019 at 09:04:16AM +0000, Pieter Jansen van Vuuren wrote:
>>>> +/* These functions specifically help shifting values that are in
>>>> + * network byte order but stored in uint32_t variables. */
>>>> +static uint32_t shift_ovs_be32_left(uint32_t word, int shift)
>>>> +{
>>>> +        uint32_t word_shifted = ntohl((OVS_FORCE ovs_be32)word) << shift;
>>>> +
>>>> +        return (OVS_FORCE uint32_t)htonl(word_shifted);
>>>> +}
>>>> +
>>>> +static uint32_t shift_ovs_be32_right(uint32_t word, int shift)
>>>> +{
>>>> +        uint32_t word_shifted = ntohl((OVS_FORCE ovs_be32)word) >> shift;
>>>> +
>>>> +        return (OVS_FORCE uint32_t)htonl(word_shifted);
>>>> +}
>>>
>>> Let me try this again.
>>>
>>> Why are we storing network-byte-order data in uint32_t?  It should be in
>>> ovs_be32.
>>>
>>
>> Sorry for not explaining this more clearly earlier. I think mask and val in
>> struct tc_pedit_key in tc_pedit.h holds network-byte-order data. I think we
>> inherit this from the kernel UAPI:
>> struct tc_pedit_key {
>>      __u32           mask;  /* AND */
>>      __u32           val;   /*XOR */
>>      __u32           off;  /*offset */
>>      __u32           at;
>>      __u32           offmask;
>>      __u32           shift;
>> };
>> (I think at least mask and val here are actually network-byte-order)
>>
>> Some drivers do this in the kernel for pedit:
>>      /* We are expecting tcf_pedit to return a big endian value */
>>      mask = (__force __be32)~tcf_pedit_mask(action, idx);
>>      exact = (__force __be32)tcf_pedit_val(action, idx);
>> Others:
>>      mask_be32 = *(__be32 *)&mask;
>>      mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32));
>>
>> Also in userspace iproute2, we see this in tc/m_pedit.c:
>>         tkey->val = htonl(tkey->val & retain);
>>         tkey->mask = htonl(tkey->mask | ~retain);
>>
>> Iproute2 indicates that there is an issue somewhere:
>> "
>>   * TODO:
>>   *      1) Big endian broken in some spots
>> "
> 
> OK.  I understand now.
> 
> You might be able to work around this by adding a file
> include/sparse/linux/tc_act/tc_pedit.h in the OVS tree with contents
> something like this:
> 
> #ifndef FIX_LINUX_TC_PEDIT_H
> #define FIX_LINUX_TC_PEDIT_H
> 
> #include_next <linux/tc_act/tc_pedit.h>
> 
> /* Fixes endianness of 'mask' and 'val' members. */
> #define tc_pedit_key rpl_tc_pedit_key
> struct rpl_tc_pedit_key {
>       __be32          mask;  /* AND */
>         __be32                val;   /*XOR */
>         __u32           off;  /*offset */
>         __u32           at;
>         __u32           offmask;
>         __u32           shift;
> };
> 
> #endif
> 

I will do. Thank you.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to