[ovs-dev] [PATCH 1/4] ofp-parse: Factor out duplicated code into new functions.

Ben Pfaff blp at nicira.com
Fri Oct 1 20:34:17 UTC 2010


On Wed, Sep 29, 2010 at 01:41:05PM -0700, Justin Pettit wrote:
> On Sep 23, 2010, at 3:05 PM, Ben Pfaff wrote:
> 
> > +
> > +/* Parses 'string' as a OFPT_FLOW_MOD with subtype OFPFC_ADD and returns an
> 
> "as a" -> "as an"

Fixed, thanks.

> > + * ofpbuf that contains it. */
> > +struct ofpbuf *
> > +parse_ofp_add_flow_str(char *string)
> > +{
> > ...
> > +    /* parse_ofp_str() will expand and reallocate the data in 'buffer', so we
> > +     * can't keep pointers to across the parse_ofp_str() call. */
> 
> "to" -> "to it"?

Fixed, thanks.
 
> > +struct ofpbuf *
> > +parse_ofp_add_flow_file(FILE *stream)
> > +{
> > ...
> > +        if (!ds_get_line(&s, stream)) {
> > +            break;
> > +        }
> 
> Isn't this the opposite of what you want?  I believe ds_get_line()
> will return 0 if there's a string available.

Oops, failed to test this.  Here's the tested version:

--8<--------------------------cut here-------------------------->8--

From: Ben Pfaff <blp at nicira.com>
Date: Fri, 1 Oct 2010 13:29:29 -0700
Subject: [PATCH] ofp-parse: Factor out duplicated code into new functions.

---
 lib/learning-switch.c |   40 +----------------------------
 lib/ofp-parse.c       |   65 ++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/ofp-parse.h       |    3 ++
 utilities/ovs-ofctl.c |   41 ++----------------------------
 4 files changed, 72 insertions(+), 77 deletions(-)

diff --git a/lib/learning-switch.c b/lib/learning-switch.c
index 4e7645d..b20506b 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -252,45 +252,9 @@ static void
 send_default_flows(struct lswitch *sw, struct rconn *rconn,
                    FILE *default_flows)
 {
-    char line[1024];
+    struct ofpbuf *b;
 
-    while (fgets(line, sizeof line, default_flows)) {
-        struct ofpbuf *b;
-        struct ofp_flow_mod *ofm;
-        uint16_t priority, idle_timeout, hard_timeout;
-        uint64_t cookie;
-        struct ofp_match match;
-
-        char *comment;
-
-        /* Delete comments. */
-        comment = strchr(line, '#');
-        if (comment) {
-            *comment = '\0';
-        }
-
-        /* Drop empty lines. */
-        if (line[strspn(line, " \t\n")] == '\0') {
-            continue;
-        }
-
-        /* Parse and send.  str_to_flow() will expand and reallocate the data
-         * in 'buffer', so we can't keep pointers to across the str_to_flow()
-         * call. */
-        make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &b);
-        parse_ofp_str(line, &match, b,
-                      NULL, NULL, &priority, &idle_timeout, &hard_timeout,
-                      &cookie);
-        ofm = b->data;
-        ofm->match = match;
-        ofm->command = htons(OFPFC_ADD);
-        ofm->cookie = htonll(cookie);
-        ofm->idle_timeout = htons(idle_timeout);
-        ofm->hard_timeout = htons(hard_timeout);
-        ofm->buffer_id = htonl(UINT32_MAX);
-        ofm->priority = htons(priority);
-
-        update_openflow_length(b);
+    while ((b = parse_ofp_add_flow_file(default_flows)) != NULL) {
         queue_tx(sw, rconn, b);
     }
 }
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 32e790a..3e24e1a 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <stdlib.h>
 
+#include "dynamic-string.h"
 #include "netdev.h"
 #include "ofp-util.h"
 #include "ofpbuf.h"
@@ -29,7 +30,7 @@
 #include "socket-util.h"
 #include "vconn.h"
 #include "vlog.h"
-
+#include "xtoxll.h"
 
 VLOG_DEFINE_THIS_MODULE(ofp_parse)
 
@@ -502,3 +503,65 @@ parse_ofp_str(char *string, struct ofp_match *match, struct ofpbuf *actions,
         free(new);
     }
 }
+
+/* Parses 'string' as an OFPT_FLOW_MOD with subtype OFPFC_ADD and returns an
+ * ofpbuf that contains it. */
+struct ofpbuf *
+parse_ofp_add_flow_str(char *string)
+{
+    struct ofpbuf *buffer;
+    struct ofp_flow_mod *ofm;
+    uint16_t priority, idle_timeout, hard_timeout;
+    uint64_t cookie;
+    struct ofp_match match;
+
+    /* parse_ofp_str() will expand and reallocate the data in 'buffer', so we
+     * can't keep pointers to it across the parse_ofp_str() call. */
+    make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
+    parse_ofp_str(string, &match, buffer,
+                  NULL, NULL, &priority, &idle_timeout, &hard_timeout,
+                  &cookie);
+    ofm = buffer->data;
+    ofm->match = match;
+    ofm->command = htons(OFPFC_ADD);
+    ofm->cookie = htonll(cookie);
+    ofm->idle_timeout = htons(idle_timeout);
+    ofm->hard_timeout = htons(hard_timeout);
+    ofm->buffer_id = htonl(UINT32_MAX);
+    ofm->priority = htons(priority);
+    update_openflow_length(buffer);
+
+    return buffer;
+}
+
+/* Parses an OFPT_FLOW_MOD with subtype OFPFC_ADD from 'stream' and returns an
+ * ofpbuf that contains it.  Returns a null pointer if end-of-file is reached
+ * before reading a flow. */
+struct ofpbuf *
+parse_ofp_add_flow_file(FILE *stream)
+{
+    struct ofpbuf *b = NULL;
+    struct ds s = DS_EMPTY_INITIALIZER;
+
+    while (!ds_get_line(&s, stream)) {
+        char *line = ds_cstr(&s);
+        char *comment;
+
+        /* Delete comments. */
+        comment = strchr(line, '#');
+        if (comment) {
+            *comment = '\0';
+        }
+
+        /* Drop empty lines. */
+        if (line[strspn(line, " \t\n")] == '\0') {
+            continue;
+        }
+
+        b = parse_ofp_add_flow_str(line);
+        break;
+    }
+    ds_destroy(&s);
+
+    return b;
+}
diff --git a/lib/ofp-parse.h b/lib/ofp-parse.h
index aa0489c..ac8e6d2 100644
--- a/lib/ofp-parse.h
+++ b/lib/ofp-parse.h
@@ -20,6 +20,7 @@
 #define OFP_PARSE_H 1
 
 #include <stdint.h>
+#include <stdio.h>
 
 struct ofp_match;
 struct ofpbuf;
@@ -29,5 +30,7 @@ void parse_ofp_str(char *string, struct ofp_match *match,
                    uint16_t *out_port, uint16_t *priority,
                    uint16_t *idle_timeout, uint16_t *hard_timeout,
                    uint64_t *cookie);
+struct ofpbuf *parse_ofp_add_flow_str(char *string);
+struct ofpbuf *parse_ofp_add_flow_file(FILE *);
 
 #endif /* ofp-parse.h */
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 55278fb..c21c4f9 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -524,8 +524,8 @@ static void
 do_add_flows(int argc OVS_UNUSED, char *argv[])
 {
     struct vconn *vconn;
+    struct ofpbuf *b;
     FILE *file;
-    char line[1024];
 
     file = fopen(argv[2], "r");
     if (file == NULL) {
@@ -533,43 +533,8 @@ do_add_flows(int argc OVS_UNUSED, char *argv[])
     }
 
     open_vconn(argv[1], &vconn);
-    while (fgets(line, sizeof line, file)) {
-        struct ofpbuf *buffer;
-        struct ofp_flow_mod *ofm;
-        uint16_t priority, idle_timeout, hard_timeout;
-        uint64_t cookie;
-        struct ofp_match match;
-
-        char *comment;
-
-        /* Delete comments. */
-        comment = strchr(line, '#');
-        if (comment) {
-            *comment = '\0';
-        }
-
-        /* Drop empty lines. */
-        if (line[strspn(line, " \t\n")] == '\0') {
-            continue;
-        }
-
-        /* Parse and send.  parse_ofp_str() will expand and reallocate
-         * the data in 'buffer', so we can't keep pointers to across the
-         * parse_ofp_str() call. */
-        make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer);
-        parse_ofp_str(line, &match, buffer,
-                      NULL, NULL, &priority, &idle_timeout, &hard_timeout,
-                      &cookie);
-        ofm = buffer->data;
-        ofm->match = match;
-        ofm->command = htons(OFPFC_ADD);
-        ofm->cookie = htonll(cookie);
-        ofm->idle_timeout = htons(idle_timeout);
-        ofm->hard_timeout = htons(hard_timeout);
-        ofm->buffer_id = htonl(UINT32_MAX);
-        ofm->priority = htons(priority);
-
-        send_openflow_buffer(vconn, buffer);
+    while ((b = parse_ofp_add_flow_file(file)) != NULL) {
+        send_openflow_buffer(vconn, b);
     }
     vconn_close(vconn);
     fclose(file);
-- 
1.7.1





More information about the dev mailing list