Fix dereference of previously freed data.
[sliver-openvswitch.git] / lib / vconn.c
index 1c3b699..434fa46 100644 (file)
@@ -129,9 +129,10 @@ check_vconn_classes(void)
 }
 
 /* Prints information on active (if 'active') and passive (if 'passive')
- * connection methods supported by the vconn. */
+ * connection methods supported by the vconn.  If 'bootstrap' is true, also
+ * advertises options to bootstrap the CA certificate. */
 void
-vconn_usage(bool active, bool passive)
+vconn_usage(bool active, bool passive, bool bootstrap UNUSED)
 {
     /* Really this should be implemented via callbacks into the vconn
      * providers, but that seems too heavy-weight to bother with at the
@@ -172,6 +173,10 @@ vconn_usage(bool active, bool passive)
            "  -p, --private-key=FILE  file with private key\n"
            "  -c, --certificate=FILE  file with certificate for private key\n"
            "  -C, --ca-cert=FILE      file with peer CA certificate\n");
+    if (bootstrap) {
+        printf("  --bootstrap-ca-cert=FILE  file with peer CA certificate "
+               "to read or create\n");
+    }
 #endif
 }
 
@@ -367,6 +372,7 @@ vcs_send_error(struct vconn *vconn)
     error->type = htons(OFPET_HELLO_FAILED);
     error->code = htons(OFPHFC_INCOMPATIBLE);
     ofpbuf_put(b, s, strlen(s));
+    update_openflow_length(b);
     retval = do_send(vconn, b);
     if (retval) {
         ofpbuf_delete(b);
@@ -753,10 +759,10 @@ update_openflow_length(struct ofpbuf *buffer)
 
 struct ofpbuf *
 make_add_flow(const struct flow *flow, uint32_t buffer_id,
-              uint16_t idle_timeout, size_t n_actions)
+              uint16_t idle_timeout, size_t actions_len)
 {
     struct ofp_flow_mod *ofm;
-    size_t size = sizeof *ofm + n_actions * sizeof ofm->actions[0];
+    size_t size = sizeof *ofm + actions_len;
     struct ofpbuf *out = ofpbuf_new(size);
     ofm = ofpbuf_put_uninit(out, size);
     memset(ofm, 0, size);
@@ -786,11 +792,14 @@ make_add_simple_flow(const struct flow *flow,
                      uint32_t buffer_id, uint16_t out_port,
                      uint16_t idle_timeout)
 {
-    struct ofpbuf *buffer = make_add_flow(flow, buffer_id, idle_timeout, 1);
+    struct ofp_action_output *oao;
+    struct ofpbuf *buffer = make_add_flow(flow, buffer_id, idle_timeout, 
+            sizeof *oao);
     struct ofp_flow_mod *ofm = buffer->data;
-    ofm->actions[0].type = htons(OFPAT_OUTPUT);
-    ofm->actions[0].arg.output.max_len = htons(0);
-    ofm->actions[0].arg.output.port = htons(out_port);
+    oao = (struct ofp_action_output *)&ofm->actions[0];
+    oao->type = htons(OFPAT_OUTPUT);
+    oao->len = htons(sizeof *oao);
+    oao->port = htons(out_port);
     return buffer;
 }
 
@@ -799,18 +808,24 @@ make_unbuffered_packet_out(const struct ofpbuf *packet,
                            uint16_t in_port, uint16_t out_port)
 {
     struct ofp_packet_out *opo;
-    size_t size = sizeof *opo + sizeof opo->actions[0];
+    struct ofp_action_output *oao;
+    size_t size = sizeof *opo + sizeof *oao;
     struct ofpbuf *out = ofpbuf_new(size + packet->size);
+
     opo = ofpbuf_put_uninit(out, size);
     memset(opo, 0, size);
     opo->header.version = OFP_VERSION;
     opo->header.type = OFPT_PACKET_OUT;
     opo->buffer_id = htonl(UINT32_MAX);
     opo->in_port = htons(in_port);
-    opo->n_actions = htons(1);
-    opo->actions[0].type = htons(OFPAT_OUTPUT);
-    opo->actions[0].arg.output.max_len = htons(0);
-    opo->actions[0].arg.output.port = htons(out_port);
+
+    oao = (struct ofp_action_output *)&opo->actions[0];
+    oao->type = htons(OFPAT_OUTPUT);
+    oao->len = htons(sizeof *oao);
+    oao->port = htons(out_port);
+
+    opo->actions_len = htons(sizeof *oao);
+
     ofpbuf_put(out, packet->data, packet->size);
     update_openflow_length(out);
     return out;
@@ -821,7 +836,8 @@ make_buffered_packet_out(uint32_t buffer_id,
                          uint16_t in_port, uint16_t out_port)
 {
     struct ofp_packet_out *opo;
-    size_t size = sizeof *opo + sizeof opo->actions[0];
+    struct ofp_action_output *oao;
+    size_t size = sizeof *opo + sizeof *oao;
     struct ofpbuf *out = ofpbuf_new(size);
     opo = ofpbuf_put_uninit(out, size);
     memset(opo, 0, size);
@@ -830,10 +846,13 @@ make_buffered_packet_out(uint32_t buffer_id,
     opo->header.length = htons(size);
     opo->buffer_id = htonl(buffer_id);
     opo->in_port = htons(in_port);
-    opo->n_actions = htons(1);
-    opo->actions[0].type = htons(OFPAT_OUTPUT);
-    opo->actions[0].arg.output.max_len = htons(0);
-    opo->actions[0].arg.output.port = htons(out_port);
+
+    oao = (struct ofp_action_output *)&opo->actions[0];
+    oao->type = htons(OFPAT_OUTPUT);
+    oao->len = htons(sizeof *oao);
+    oao->port = htons(out_port);
+
+    opo->actions_len = htons(sizeof *oao);
     return out;
 }