On Tue, Mar 31, 2015 at 05:26:19PM -0700, Jesse Gross wrote: > On Tue, Mar 31, 2015 at 4:21 PM, Ben Pfaff <b...@nicira.com> wrote: > > On Mon, Mar 30, 2015 at 03:14:46PM -0700, Jesse Gross wrote: > >> The GRE checksum is a 16 bit field stored in a 32 bit option (the > >> rest is reserved). The current code treats the checksum as a 32-bit > >> field and places it in the right place for little endian systems but > >> not big endian. This fixes the problem by storing the 16 bit field > >> directly. > >> > >> Signed-off-by: Jesse Gross <je...@nicira.com> > >> --- > >> lib/netdev-vport.c | 6 ++---- > >> lib/odp-util.c | 8 ++++---- > >> 2 files changed, 6 insertions(+), 8 deletions(-) > >> > >> diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c > >> index 1ee68bc..a9639d3 100644 > >> --- a/lib/netdev-vport.c > >> +++ b/lib/netdev-vport.c > >> @@ -996,10 +996,8 @@ netdev_gre_push_header__(struct dp_packet *packet, > >> greh = push_ip_header(packet, header, size, &ip_tot_size); > >> > >> if (greh->flags & htons(GRE_CSUM)) { > >> - ovs_16aligned_be32 *options = (ovs_16aligned_be32 *) (greh + 1); > >> - > >> - put_16aligned_be32(options, > >> - (OVS_FORCE ovs_be32) csum(greh, ip_tot_size - > >> sizeof (struct ip_header))); > >> + ovs_be16 *csum_opt = (ovs_be16 *) (greh + 1); > >> + *csum_opt = csum(greh, ip_tot_size - sizeof (struct ip_header)); > > > > Does the above zero the other 16 bits? > > This should be OK because the entire header was memset to zero when it > was built at flow creation time. > > >> diff --git a/lib/odp-util.c b/lib/odp-util.c > >> index 827b91c..5990edc 100644 > >> --- a/lib/odp-util.c > >> +++ b/lib/odp-util.c > >> @@ -565,7 +565,7 @@ format_odp_tnl_push_header(struct ds *ds, struct > >> ovs_action_push_tnl *data) > >> greh->flags, ntohs(greh->protocol)); > >> options = (ovs_16aligned_be32 *)(greh + 1); > >> if (greh->flags & htons(GRE_CSUM)) { > >> - ds_put_format(ds, ",csum=0x%"PRIx32, > >> ntohl(get_16aligned_be32(options))); > >> + ds_put_format(ds, ",csum=0x%"PRIx16, ntohs(*((ovs_be16 > >> *)options))); > >> options++; > >> } > >> if (greh->flags & htons(GRE_KEY)) { > >> @@ -913,12 +913,12 @@ ovs_parse_tnl_push(const char *s, struct > >> ovs_action_push_tnl *data) > >> ovs_16aligned_be32 *options = (ovs_16aligned_be32 *) (greh + 1); > >> > >> if (greh->flags & htons(GRE_CSUM)) { > >> - uint32_t csum; > >> + uint16_t csum; > >> > >> - if (!ovs_scan_len(s, &n, ",csum=0x%"SCNx32, &csum)) { > >> + if (!ovs_scan_len(s, &n, ",csum=0x%"SCNx16, &csum)) { > >> return -EINVAL; > >> } > >> - put_16aligned_be32(options, htonl(csum)); > >> + *((ovs_be16 *)options) = htons(csum); > >> options++; > > > > What about here? > > This one isn't zeroed so I so added a memset before the checksum is set: > > + memset(options, 0, sizeof *options);
Thanks! _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev