diff mbox series

[ovs-dev,v8,2/9] flow: Enhance parse_ipv6_ext_hdrs.

Message ID 1531795191-58140-3-git-send-email-dlu998@gmail.com
State Changes Requested
Headers show
Series Userspace datapath: Add fragmentation support. | expand

Commit Message

Darrell Ball July 17, 2018, 2:39 a.m. UTC
Enhance the api parse_ipv6_ext_hdrs to return the
fragmentation header to be used in later patches.

Signed-off-by: Darrell Ball <dlu998@gmail.com>
Acked-by: Justin Pettit <jpettit@ovn.org>
---
 lib/conntrack.c |  4 ++--
 lib/flow.c      | 31 +++++++++++++++++++++----------
 lib/flow.h      |  3 ++-
 3 files changed, 25 insertions(+), 13 deletions(-)

Comments

Justin Pettit July 31, 2018, 5:22 p.m. UTC | #1
> On Jul 16, 2018, at 7:39 PM, Darrell Ball <dlu998@gmail.com> wrote:
> 
> diff --git a/lib/flow.c b/lib/flow.c
> index 76a8b9a..e84a40d 100644
> --- a/lib/flow.c
> +++ b/lib/flow.c
> @@ -453,9 +453,14 @@ invalid:
>     return true;
> }
> 
> +/* datap points to the first extension header and advances as parsing
> + * occurs; sizep is the remaining size and is decreased accordingly.
> + * nw_proto starts as the first extension header to process and is
> + * updated as the extension headers are parsed. */
> static inline bool
> parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto,
> -                      uint8_t *nw_frag)
> +                      uint8_t *nw_frag,
> +                      const struct ovs_16aligned_ip6_frag **frag_hdr)

I think this comment could use some more explanation.  Does the following seem correct?

/* Parses IPv6 extenstion headers until a terminal header (or header we
 * don't understand) is found.  'datap' points to the first extension
 * header and advances as parsing occurs; 'sizep' is the remaining size
 * and is decreased accordingly.  'nw_proto' starts as the first
 * extension header to process and is updated as the extension headers
 * are parsed.
 *
 * If a fragment header is found, '*frag_hdr' is set to the fragment
 * header.  If it is the first fragment, extension header parsing
 * otherwise continues as usual.  If it's not the first fragment,
 * 'nw_proto' is set to IPPROTO_FRAGMENT and 'nw_frag' has
 * FLOW_NW_FRAG_ANY set.  Additionally, if it's not the first fragment
 * and there are more fragments, 'nw_frag' will also have
 * FLOW_NW_FRAG_LATER set. */

Also, I think this should go with parse_ipv6_ext_hdrs(), since it's the public function.

If you go agree with all of this, I'll go ahead and make the changes myself.

--Justin
Darrell Ball Aug. 17, 2018, 5:40 a.m. UTC | #2
On Tue, Jul 31, 2018 at 10:22 AM, Justin Pettit <jpettit@ovn.org> wrote:

>
> > On Jul 16, 2018, at 7:39 PM, Darrell Ball <dlu998@gmail.com> wrote:
> >
> > diff --git a/lib/flow.c b/lib/flow.c
> > index 76a8b9a..e84a40d 100644
> > --- a/lib/flow.c
> > +++ b/lib/flow.c
> > @@ -453,9 +453,14 @@ invalid:
> >     return true;
> > }
> >
> > +/* datap points to the first extension header and advances as parsing
> > + * occurs; sizep is the remaining size and is decreased accordingly.
> > + * nw_proto starts as the first extension header to process and is
> > + * updated as the extension headers are parsed. */
> > static inline bool
> > parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t
> *nw_proto,
> > -                      uint8_t *nw_frag)
> > +                      uint8_t *nw_frag,
> > +                      const struct ovs_16aligned_ip6_frag **frag_hdr)
>
> I think this comment could use some more explanation.  Does the following
> seem correct?
>
> /* Parses IPv6 extenstion headers until a terminal header (or header we
>  * don't understand) is found.  'datap' points to the first extension
>  * header and advances as parsing occurs; 'sizep' is the remaining size
>  * and is decreased accordingly.  'nw_proto' starts as the first
>  * extension header to process and is updated as the extension headers
>  * are parsed.
>  *
>  * If a fragment header is found, '*frag_hdr' is set to the fragment
>  * header.  If it is the first fragment, extension header parsing
>  * otherwise continues as usual.  If it's not the first fragment,
>  * 'nw_proto' is set to IPPROTO_FRAGMENT and 'nw_frag' has
>  * FLOW_NW_FRAG_ANY set.  Additionally, if it's not the first fragment
>  * and there are more fragments, 'nw_frag' will also have
>  * FLOW_NW_FRAG_LATER set. */
>
> Also, I think this should go with parse_ipv6_ext_hdrs(), since it's the
> public function.
>


Thanks for adding more explanation I made a few modifications and moved to
public API.

/* Parses IPv6 extension headers until a terminal header (or header we

 * don't understand) is found.  'datap' points to the first extension

 * header and advances as parsing occurs; 'sizep' is the remaining size

 * and is decreased accordingly.  'nw_proto' starts as the first

 * extension header to process and is updated as the extension headers

 * are parsed.

 *

 * If a fragment header is found, '*frag_hdr' is set to the fragment

 * header.  If it is the first fragment, extension header parsing

 * otherwise continues as usual.  If it's not the first fragment,

 * 'nw_proto' is set to IPPROTO_FRAGMENT and 'nw_frag' has

 * FLOW_NW_FRAG_LATER set.  Both first and later fragments have

 * FLOW_NW_FRAG_ANY set in 'nw_frag'. */

bool

*parse_ipv6_ext_hdrs*(*const* *void* **datap, size_t *sizep, uint8_t
*nw_proto,

                    uint8_t *nw_frag,

                    *const* *struct* ovs_16aligned_ip6_frag **frag_hdr)



I folded into V9 as well.




>
> If you go agree with all of this, I'll go ahead and make the changes
> myself.
>
> --Justin
>
>
>
diff mbox series

Patch

diff --git a/lib/conntrack.c b/lib/conntrack.c
index 974f985..682feb9 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -1310,7 +1310,6 @@  conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch,
                   const struct nat_action_info_t *nat_action_info,
                   long long now)
 {
-
     struct dp_packet *packet;
     struct conn_lookup_ctx ctx;
 
@@ -1558,7 +1557,8 @@  extract_l3_ipv6(struct conn_key *key, const void *data, size_t size,
     uint8_t nw_proto = ip6->ip6_nxt;
     uint8_t nw_frag = 0;
 
-    if (!parse_ipv6_ext_hdrs(&data, &size, &nw_proto, &nw_frag)) {
+    const struct ovs_16aligned_ip6_frag *frag_hdr;
+    if (!parse_ipv6_ext_hdrs(&data, &size, &nw_proto, &nw_frag, &frag_hdr)) {
         return false;
     }
 
diff --git a/lib/flow.c b/lib/flow.c
index 76a8b9a..e84a40d 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -453,9 +453,14 @@  invalid:
     return true;
 }
 
+/* datap points to the first extension header and advances as parsing
+ * occurs; sizep is the remaining size and is decreased accordingly.
+ * nw_proto starts as the first extension header to process and is
+ * updated as the extension headers are parsed. */
 static inline bool
 parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto,
-                      uint8_t *nw_frag)
+                      uint8_t *nw_frag,
+                      const struct ovs_16aligned_ip6_frag **frag_hdr)
 {
     while (1) {
         if (OVS_LIKELY((*nw_proto != IPPROTO_HOPOPTS)
@@ -502,17 +507,17 @@  parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto,
                 return false;
             }
         } else if (*nw_proto == IPPROTO_FRAGMENT) {
-            const struct ovs_16aligned_ip6_frag *frag_hdr = *datap;
+            *frag_hdr = *datap;
 
-            *nw_proto = frag_hdr->ip6f_nxt;
-            if (!data_try_pull(datap, sizep, sizeof *frag_hdr)) {
+            *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)) {
+            if ((*frag_hdr)->ip6f_offlg != htons(0)) {
                 *nw_frag = FLOW_NW_FRAG_ANY;
-                if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
+                if (((*frag_hdr)->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
                     *nw_frag |= FLOW_NW_FRAG_LATER;
                     *nw_proto = IPPROTO_FRAGMENT;
                     return true;
@@ -524,9 +529,11 @@  parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto,
 
 bool
 parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto,
-                    uint8_t *nw_frag)
+                    uint8_t *nw_frag,
+                    const struct ovs_16aligned_ip6_frag **frag_hdr)
 {
-    return parse_ipv6_ext_hdrs__(datap, sizep, nw_proto, nw_frag);
+    return parse_ipv6_ext_hdrs__(datap, sizep, nw_proto, nw_frag,
+                                 frag_hdr);
 }
 
 bool
@@ -877,7 +884,9 @@  miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
         nw_ttl = nh->ip6_hlim;
         nw_proto = nh->ip6_nxt;
 
-        if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag)) {
+        const struct ovs_16aligned_ip6_frag *frag_hdr;
+        if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag,
+                                   &frag_hdr)) {
             goto out;
         }
     } else {
@@ -1067,7 +1076,9 @@  parse_tcp_flags(struct dp_packet *packet)
         plen = ntohs(nh->ip6_plen); /* Never pull padding. */
         dp_packet_set_l2_pad_size(packet, size - plen);
         size = plen;
-        if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag)) {
+        const struct ovs_16aligned_ip6_frag *frag_hdr;
+        if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag,
+            &frag_hdr)) {
             return 0;
         }
         nw_proto = nh->ip6_nxt;
diff --git a/lib/flow.h b/lib/flow.h
index af7b5e9..e3e30f1 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -130,7 +130,8 @@  void flow_compose(struct dp_packet *, const struct flow *,
 void packet_expand(struct dp_packet *, const struct flow *, size_t size);
 
 bool parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto,
-                         uint8_t *nw_frag);
+                         uint8_t *nw_frag,
+                         const struct ovs_16aligned_ip6_frag **frag_hdr);
 ovs_be16 parse_dl_type(const struct eth_header *data_, size_t size);
 bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key);
 uint16_t parse_tcp_flags(struct dp_packet *packet);