Merge commit 'origin/master'
authorBen Pfaff <blp@nicira.com>
Mon, 15 Sep 2008 22:43:44 +0000 (15:43 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 15 Sep 2008 22:43:44 +0000 (15:43 -0700)
Conflicts:

switch/datapath.c
utilities/dpctl.c

1  2 
lib/ofp-print.c
switch/datapath.c
switch/switch-flow.c
switch/switch-flow.h
switch/table-hash.c
switch/table-linear.c
utilities/dpctl.c

diff --cc lib/ofp-print.c
Simple merge
@@@ -812,8 -809,8 +812,8 @@@ fill_flow_stats(struct ofpbuf *buffer, 
                  int table_idx, time_t now)
  {
      struct ofp_flow_stats *ofs;
-     int length = sizeof *ofs + sizeof *ofs->actions * flow->n_actions;
+     int length = sizeof *ofs + sizeof *ofs->actions * flow->sf_acts->n_actions;
 -    ofs = buffer_put_uninit(buffer, length);
 +    ofs = ofpbuf_put_uninit(buffer, length);
      ofs->length          = htons(length);
      ofs->table_id        = table_idx;
      ofs->pad             = 0;
@@@ -1215,6 -1214,55 +1217,55 @@@ error
      return error;
  }
  
 -        struct buffer *buffer = retrieve_buffer(ntohl(ofm->buffer_id));
+ static int
+ mod_flow(struct datapath *dp, const struct ofp_flow_mod *ofm)
+ {
+     int error = -ENOMEM;
+     int n_actions;
+     int i;
+     struct sw_flow_key key;
+     /* To prevent loops, make sure there's no action to send to the
+      * OFP_TABLE virtual port.
+      */
+     n_actions = (ntohs(ofm->header.length) - sizeof *ofm) 
+             / sizeof *ofm->actions;
+     for (i=0; i<n_actions; i++) {
+         const struct ofp_action *a = &ofm->actions[i];
+         if (a->type == htons(OFPAT_OUTPUT)
+                     && (a->arg.output.port == htons(OFPP_TABLE)
+                         || a->arg.output.port == htons(OFPP_NONE)
+                         || a->arg.output.port == ofm->match.in_port)) {
+             /* xxx Send fancy new error message? */
+             goto error;
+         }
+     }
+     flow_extract_match(&key, &ofm->match);
+     chain_modify(dp->chain, &key, ofm->actions, n_actions);
+     if (ntohl(ofm->buffer_id) != UINT32_MAX) {
++        struct ofpbuf *buffer = retrieve_buffer(ntohl(ofm->buffer_id));
+         if (buffer) {
+             struct sw_flow_key skb_key;
+             uint16_t in_port = ntohs(ofm->match.in_port);
+             flow_extract(buffer, in_port, &skb_key.flow);
+             execute_actions(dp, buffer, in_port, &skb_key,
+                             ofm->actions, n_actions, false);
+         } else {
+             error = -ESRCH; 
+         }
+     }
+     return error;
+ error:
+     if (ntohl(ofm->buffer_id) != (uint32_t) -1)
+         discard_buffer(ntohl(ofm->buffer_id));
+     return error;
+ }
  static int
  recv_flow(struct datapath *dp, const struct sender *sender UNUSED,
            const void *msg)
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -815,9 -812,10 +814,10 @@@ static void do_add_flow(int argc, char 
      ofm->priority = htons(priority);
      ofm->reserved = htonl(0);
  
 -    /* xxx Should we use the buffer library? */
 +    /* xxx Should we use the ofpbuf library? */
      buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0];
  
+     open_vconn(argv[1], &vconn);
      send_openflow_buffer(vconn, buffer);
      vconn_close(vconn);
  }
@@@ -876,13 -873,40 +875,40 @@@ static void do_add_flows(int argc, cha
      fclose(file);
  }
  
- static void do_del_flows(int argc, char *argv[])
+ static void do_mod_flows(int argc, char *argv[])
  {
+     uint16_t idle_timeout, hard_timeout;
      struct vconn *vconn;
-     uint16_t priority;
 -    struct buffer *buffer;
++    struct ofpbuf *buffer;
+     struct ofp_flow_mod *ofm;
+     size_t size;
+     int n_actions = MAX_ADD_ACTS;
+     /* Parse and send. */
+     size = sizeof *ofm + (sizeof ofm->actions[0] * MAX_ADD_ACTS);
+     ofm = make_openflow(size, OFPT_FLOW_MOD, &buffer);
+     str_to_flow(argv[2], &ofm->match, &ofm->actions[0], &n_actions, 
+                 NULL, NULL, &idle_timeout, &hard_timeout);
+     ofm->command = htons(OFPFC_MODIFY);
+     ofm->idle_timeout = htons(idle_timeout);
+     ofm->hard_timeout = htons(hard_timeout);
+     ofm->buffer_id = htonl(UINT32_MAX);
+     ofm->priority = htons(0);
+     ofm->reserved = htonl(0);
+     /* xxx Should we use the buffer library? */
+     buffer->size -= (MAX_ADD_ACTS - n_actions) * sizeof ofm->actions[0];
  
      open_vconn(argv[1], &vconn);
 -    struct buffer *buffer;
+     send_openflow_buffer(vconn, buffer);
+     vconn_close(vconn);
+ }
+ static void do_del_flows(int argc, char *argv[])
+ {
+     struct vconn *vconn;
+     uint16_t priority;
 +    struct ofpbuf *buffer;
      struct ofp_flow_mod *ofm;
      size_t size;