On 15 November 2015 at 22:21, Daniele Di Proietto <diproiet...@vmware.com> wrote: > This will be used by a future commit. > > Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com> > --- > lib/flow.c | 140 > ++++++++++++++++++++++++++++++++++--------------------------- > lib/flow.h | 3 ++ > 2 files changed, 81 insertions(+), 62 deletions(-) > > diff --git a/lib/flow.c b/lib/flow.c > index d5dcb92..2bdce26 100644 > --- a/lib/flow.c > +++ b/lib/flow.c > @@ -402,6 +402,82 @@ invalid: > arp_buf[1] = eth_addr_zero; > } > > +static inline bool > +parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto, > + uint8_t *nw_frag) > +{ > + while (1) { > + if (OVS_LIKELY((*nw_proto != IPPROTO_HOPOPTS) > + && (*nw_proto != IPPROTO_ROUTING) > + && (*nw_proto != IPPROTO_DSTOPTS) > + && (*nw_proto != IPPROTO_AH) > + && (*nw_proto != IPPROTO_FRAGMENT))) { > + /* It's either a terminal header (e.g., TCP, UDP) or one we > + * don't understand. In either case, we're done with the > + * packet, so use it to fill in 'nw_proto'. */ > + return true; > + } > + > + /* We only verify that at least 8 bytes of the next header are > + * available, but many of these headers are longer. Ensure that > + * accesses within the extension header are within those first 8 > + * bytes. All extension headers are required to be at least 8 > + * bytes. */ > + if (OVS_UNLIKELY(*sizep < 8)) { > + return false; > + } > + > + if ((*nw_proto == IPPROTO_HOPOPTS) > + || (*nw_proto == IPPROTO_ROUTING) > + || (*nw_proto == IPPROTO_DSTOPTS)) { > + /* These headers, while different, have the fields we care > + * about in the same location and with the same > + * interpretation. */ > + const struct ip6_ext *ext_hdr = *datap; > + *nw_proto = ext_hdr->ip6e_nxt; > + if (OVS_UNLIKELY(!data_try_pull(datap, sizep, > + (ext_hdr->ip6e_len + 1) * 8))) { > + return false; > + } > + } else if (*nw_proto == IPPROTO_AH) { > + /* A standard AH definition isn't available, but the fields > + * we care about are in the same location as the generic > + * option header--only the header length is calculated > + * differently. */ > + const struct ip6_ext *ext_hdr = *datap; > + *nw_proto = ext_hdr->ip6e_nxt; > + if (OVS_UNLIKELY(!data_try_pull(datap, sizep, > + (ext_hdr->ip6e_len + 2) * 4))) { > + return false; > + } > + } else if (*nw_proto == IPPROTO_FRAGMENT) { > + const struct ovs_16aligned_ip6_frag *frag_hdr = *datap; > + > + *nw_proto = frag_hdr->ip6f_nxt; > + if (!data_try_pull(datap, sizep, sizeof *frag_hdr)) { > + return false; > + } > + > + /* We only process the first fragment. */ > + if (frag_hdr->ip6f_offlg != htons(0)) { > + *nw_frag = FLOW_NW_FRAG_ANY; > + if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) { > + *nw_frag |= FLOW_NW_FRAG_LATER; > + *nw_proto = IPPROTO_FRAGMENT; > + return false;
I think this is supposed to be true? _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev