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
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to