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

Reply via email to