Thanks, I'll apply this in a minute.

On Fri, Aug 08, 2014 at 12:31:51PM -0700, Jarno Rajahalme wrote:
> Acked-by: Jarno Rajahalme <jrajaha...@nicira.com>
> 
> On Aug 7, 2014, at 4:13 PM, Ben Pfaff <b...@nicira.com> wrote:
> 
> > Parsing of actions was wrong because OF1.3 says that non-experimenter
> > actions are 4 bytes and don't include padding.  This fixes the problem.
> > 
> > Parsing of instructions seems wrong too because OF1.3 says that
> > non-experimenter instructions are 4 bytes (though it is not explicit about
> > padding as it is for actions).  This fixes the problem there too.
> > 
> > Signed-off-by: Ben Pfaff <b...@nicira.com>
> > ---
> > lib/ofp-util.c |   47 +++++++++++++++++++++++++++++++++++++++--------
> > 1 file changed, 39 insertions(+), 8 deletions(-)
> > 
> > diff --git a/lib/ofp-util.c b/lib/ofp-util.c
> > index 1e641bd..1ba3970 100644
> > --- a/lib/ofp-util.c
> > +++ b/lib/ofp-util.c
> > @@ -61,12 +61,17 @@ struct ofp_prop_header {
> > /* Pulls a property, beginning with struct ofp_prop_header, from the 
> > beginning
> >  * of 'msg'.  Stores the type of the property in '*typep' and, if 
> > 'property' is
> >  * nonnull, the entire property, including the header, in '*property'.  
> > Returns
> > - * 0 if successful, otherwise an error code. */
> > + * 0 if successful, otherwise an error code.
> > + *
> > + * This function pulls the property's stated size padded out to a multiple 
> > of
> > + * 'alignment' bytes.  The common case in OpenFlow is an 'alignment' of 8, 
> > so
> > + * you can use ofputil_pull_property() for that case. */
> > static enum ofperr
> > -ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf *property,
> > -                      uint16_t *typep)
> > +ofputil_pull_property__(struct ofpbuf *msg, struct ofpbuf *property,
> > +                        unsigned int alignment, uint16_t *typep)
> > {
> >     struct ofp_prop_header *oph;
> > +    unsigned int padded_len;
> >     unsigned int len;
> > 
> >     if (ofpbuf_size(msg) < sizeof *oph) {
> > @@ -75,7 +80,8 @@ ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf 
> > *property,
> > 
> >     oph = ofpbuf_data(msg);
> >     len = ntohs(oph->len);
> > -    if (len < sizeof *oph || ROUND_UP(len, 8) > ofpbuf_size(msg)) {
> > +    padded_len = ROUND_UP(len, alignment);
> > +    if (len < sizeof *oph || padded_len > ofpbuf_size(msg)) {
> >         return OFPERR_OFPBPC_BAD_LEN;
> >     }
> > 
> > @@ -83,10 +89,24 @@ ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf 
> > *property,
> >     if (property) {
> >         ofpbuf_use_const(property, ofpbuf_data(msg), len);
> >     }
> > -    ofpbuf_pull(msg, ROUND_UP(len, 8));
> > +    ofpbuf_pull(msg, padded_len);
> >     return 0;
> > }
> > 
> > +/* Pulls a property, beginning with struct ofp_prop_header, from the 
> > beginning
> > + * of 'msg'.  Stores the type of the property in '*typep' and, if 
> > 'property' is
> > + * nonnull, the entire property, including the header, in '*property'.  
> > Returns
> > + * 0 if successful, otherwise an error code.
> > + *
> > + * This function pulls the property's stated size padded out to a multiple 
> > of
> > + * 8 bytes, which is the common case for OpenFlow properties. */
> > +static enum ofperr
> > +ofputil_pull_property(struct ofpbuf *msg, struct ofpbuf *property,
> > +                      uint16_t *typep)
> > +{
> > +    return ofputil_pull_property__(msg, property, 8, typep);
> > +}
> > +
> > static void PRINTF_FORMAT(2, 3)
> > log_property(bool loose, const char *message, ...)
> > {
> > @@ -4443,10 +4463,12 @@ ofputil_encode_port_mod(const struct 
> > ofputil_port_mod *pm,
> > 
> >     return b;
> > }
> > +
> > +/* Table features. */
> > 
> > static enum ofperr
> > pull_table_feature_property(struct ofpbuf *msg, struct ofpbuf *payload,
> > -                        uint16_t *typep)
> > +                            uint16_t *typep)
> > {
> >     enum ofperr error;
> > 
> > @@ -4467,7 +4489,7 @@ parse_action_bitmap(struct ofpbuf *payload, enum 
> > ofp_version ofp_version,
> >         uint16_t type;
> >         enum ofperr error;
> > 
> > -        error = pull_table_feature_property(payload, NULL, &type);
> > +        error = ofputil_pull_property__(payload, NULL, 1, &type);
> >         if (error) {
> >             return error;
> >         }
> > @@ -4489,7 +4511,16 @@ parse_instruction_ids(struct ofpbuf *payload, bool 
> > loose, uint32_t *insts)
> >         enum ofperr error;
> >         uint16_t ofpit;
> > 
> > -        error = pull_table_feature_property(payload, NULL, &ofpit);
> > +        /* OF1.3 and OF1.4 aren't clear about padding in the instruction 
> > IDs.
> > +         * It seems clear that they aren't padded to 8 bytes, though, 
> > because
> > +         * both standards say that "non-experimenter instructions are 4 
> > bytes"
> > +         * and do not mention any padding before the first instruction ID.
> > +         * (There wouldn't be any point in padding to 8 bytes if the IDs 
> > were
> > +         * aligned on an odd 4-byte boundary.)
> > +         *
> > +         * Anyway, we just assume they're all glommed together on byte
> > +         * boundaries. */
> > +        error = ofputil_pull_property__(payload, NULL, 1, &ofpit);
> >         if (error) {
> >             return error;
> >         }
> > -- 
> > 1.7.10.4
> > 
> > _______________________________________________
> > dev mailing list
> > dev@openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev
> 
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to