]> git.proxmox.com Git - mirror_ovs.git/blob - lib/vconn.c
vconn: Fix comparison that should be assignment in vconn_open_block().
[mirror_ovs.git] / lib / vconn.c
1 /*
2 * Copyright (c) 2008, 2009, 2010 Nicira Networks.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18 #include "vconn-provider.h"
19 #include <assert.h>
20 #include <errno.h>
21 #include <inttypes.h>
22 #include <netinet/in.h>
23 #include <poll.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "coverage.h"
27 #include "dynamic-string.h"
28 #include "fatal-signal.h"
29 #include "flow.h"
30 #include "ofp-print.h"
31 #include "ofp-util.h"
32 #include "ofpbuf.h"
33 #include "openflow/nicira-ext.h"
34 #include "openflow/openflow.h"
35 #include "packets.h"
36 #include "poll-loop.h"
37 #include "random.h"
38 #include "util.h"
39 #include "vlog.h"
40
41 VLOG_DEFINE_THIS_MODULE(vconn);
42
43 COVERAGE_DEFINE(vconn_open);
44 COVERAGE_DEFINE(vconn_received);
45 COVERAGE_DEFINE(vconn_sent);
46
47 /* State of an active vconn.*/
48 enum vconn_state {
49 /* This is the ordinary progression of states. */
50 VCS_CONNECTING, /* Underlying vconn is not connected. */
51 VCS_SEND_HELLO, /* Waiting to send OFPT_HELLO message. */
52 VCS_RECV_HELLO, /* Waiting to receive OFPT_HELLO message. */
53 VCS_CONNECTED, /* Connection established. */
54
55 /* These states are entered only when something goes wrong. */
56 VCS_SEND_ERROR, /* Sending OFPT_ERROR message. */
57 VCS_DISCONNECTED /* Connection failed or connection closed. */
58 };
59
60 static struct vconn_class *vconn_classes[] = {
61 &tcp_vconn_class,
62 &unix_vconn_class,
63 #ifdef HAVE_OPENSSL
64 &ssl_vconn_class,
65 #endif
66 };
67
68 static struct pvconn_class *pvconn_classes[] = {
69 &ptcp_pvconn_class,
70 &punix_pvconn_class,
71 #ifdef HAVE_OPENSSL
72 &pssl_pvconn_class,
73 #endif
74 };
75
76 /* Rate limit for individual OpenFlow messages going over the vconn, output at
77 * DBG level. This is very high because, if these are enabled, it is because
78 * we really need to see them. */
79 static struct vlog_rate_limit ofmsg_rl = VLOG_RATE_LIMIT_INIT(600, 600);
80
81 /* Rate limit for OpenFlow message parse errors. These always indicate a bug
82 * in the peer and so there's not much point in showing a lot of them. */
83 static struct vlog_rate_limit bad_ofmsg_rl = VLOG_RATE_LIMIT_INIT(1, 5);
84
85 static int do_recv(struct vconn *, struct ofpbuf **);
86 static int do_send(struct vconn *, struct ofpbuf *);
87
88 /* Check the validity of the vconn class structures. */
89 static void
90 check_vconn_classes(void)
91 {
92 #ifndef NDEBUG
93 size_t i;
94
95 for (i = 0; i < ARRAY_SIZE(vconn_classes); i++) {
96 struct vconn_class *class = vconn_classes[i];
97 assert(class->name != NULL);
98 assert(class->open != NULL);
99 if (class->close || class->recv || class->send
100 || class->run || class->run_wait || class->wait) {
101 assert(class->close != NULL);
102 assert(class->recv != NULL);
103 assert(class->send != NULL);
104 assert(class->wait != NULL);
105 } else {
106 /* This class delegates to another one. */
107 }
108 }
109
110 for (i = 0; i < ARRAY_SIZE(pvconn_classes); i++) {
111 struct pvconn_class *class = pvconn_classes[i];
112 assert(class->name != NULL);
113 assert(class->listen != NULL);
114 if (class->close || class->accept || class->wait) {
115 assert(class->close != NULL);
116 assert(class->accept != NULL);
117 assert(class->wait != NULL);
118 } else {
119 /* This class delegates to another one. */
120 }
121 }
122 #endif
123 }
124
125 /* Prints information on active (if 'active') and passive (if 'passive')
126 * connection methods supported by the vconn. If 'bootstrap' is true, also
127 * advertises options to bootstrap the CA certificate. */
128 void
129 vconn_usage(bool active, bool passive, bool bootstrap OVS_UNUSED)
130 {
131 /* Really this should be implemented via callbacks into the vconn
132 * providers, but that seems too heavy-weight to bother with at the
133 * moment. */
134
135 printf("\n");
136 if (active) {
137 printf("Active OpenFlow connection methods:\n");
138 printf(" tcp:IP[:PORT] "
139 "PORT (default: %d) at remote IP\n", OFP_TCP_PORT);
140 #ifdef HAVE_OPENSSL
141 printf(" ssl:IP[:PORT] "
142 "SSL PORT (default: %d) at remote IP\n", OFP_SSL_PORT);
143 #endif
144 printf(" unix:FILE Unix domain socket named FILE\n");
145 }
146
147 if (passive) {
148 printf("Passive OpenFlow connection methods:\n");
149 printf(" ptcp:[PORT][:IP] "
150 "listen to TCP PORT (default: %d) on IP\n",
151 OFP_TCP_PORT);
152 #ifdef HAVE_OPENSSL
153 printf(" pssl:[PORT][:IP] "
154 "listen for SSL on PORT (default: %d) on IP\n",
155 OFP_SSL_PORT);
156 #endif
157 printf(" punix:FILE "
158 "listen on Unix domain socket FILE\n");
159 }
160
161 #ifdef HAVE_OPENSSL
162 printf("PKI configuration (required to use SSL):\n"
163 " -p, --private-key=FILE file with private key\n"
164 " -c, --certificate=FILE file with certificate for private key\n"
165 " -C, --ca-cert=FILE file with peer CA certificate\n");
166 if (bootstrap) {
167 printf(" --bootstrap-ca-cert=FILE file with peer CA certificate "
168 "to read or create\n");
169 }
170 #endif
171 }
172
173 /* Given 'name', a connection name in the form "TYPE:ARGS", stores the class
174 * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
175 * a null pointer into '*classp' if 'name' is in the wrong form or if no such
176 * class exists. */
177 static int
178 vconn_lookup_class(const char *name, struct vconn_class **classp)
179 {
180 size_t prefix_len;
181
182 prefix_len = strcspn(name, ":");
183 if (name[prefix_len] != '\0') {
184 size_t i;
185
186 for (i = 0; i < ARRAY_SIZE(vconn_classes); i++) {
187 struct vconn_class *class = vconn_classes[i];
188 if (strlen(class->name) == prefix_len
189 && !memcmp(class->name, name, prefix_len)) {
190 *classp = class;
191 return 0;
192 }
193 }
194 }
195
196 *classp = NULL;
197 return EAFNOSUPPORT;
198 }
199
200 /* Returns 0 if 'name' is a connection name in the form "TYPE:ARGS" and TYPE is
201 * a supported connection type, otherwise EAFNOSUPPORT. */
202 int
203 vconn_verify_name(const char *name)
204 {
205 struct vconn_class *class;
206 return vconn_lookup_class(name, &class);
207 }
208
209 /* Attempts to connect to an OpenFlow device. 'name' is a connection name in
210 * the form "TYPE:ARGS", where TYPE is an active vconn class's name and ARGS
211 * are vconn class-specific.
212 *
213 * The vconn will automatically negotiate an OpenFlow protocol version
214 * acceptable to both peers on the connection. The version negotiated will be
215 * no lower than 'min_version' and no higher than OFP_VERSION.
216 *
217 * Returns 0 if successful, otherwise a positive errno value. If successful,
218 * stores a pointer to the new connection in '*vconnp', otherwise a null
219 * pointer. */
220 int
221 vconn_open(const char *name, int min_version, struct vconn **vconnp)
222 {
223 struct vconn_class *class;
224 struct vconn *vconn;
225 char *suffix_copy;
226 int error;
227
228 COVERAGE_INC(vconn_open);
229 check_vconn_classes();
230
231 /* Look up the class. */
232 error = vconn_lookup_class(name, &class);
233 if (!class) {
234 goto error;
235 }
236
237 /* Call class's "open" function. */
238 suffix_copy = xstrdup(strchr(name, ':') + 1);
239 error = class->open(name, suffix_copy, &vconn);
240 free(suffix_copy);
241 if (error) {
242 goto error;
243 }
244
245 /* Success. */
246 assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
247 vconn->min_version = min_version;
248 *vconnp = vconn;
249 return 0;
250
251 error:
252 *vconnp = NULL;
253 return error;
254 }
255
256 /* Allows 'vconn' to perform maintenance activities, such as flushing output
257 * buffers. */
258 void
259 vconn_run(struct vconn *vconn)
260 {
261 if (vconn->class->run) {
262 (vconn->class->run)(vconn);
263 }
264 }
265
266 /* Arranges for the poll loop to wake up when 'vconn' needs to perform
267 * maintenance activities. */
268 void
269 vconn_run_wait(struct vconn *vconn)
270 {
271 if (vconn->class->run_wait) {
272 (vconn->class->run_wait)(vconn);
273 }
274 }
275
276 int
277 vconn_open_block(const char *name, int min_version, struct vconn **vconnp)
278 {
279 struct vconn *vconn;
280 int error;
281
282 fatal_signal_run();
283
284 error = vconn_open(name, min_version, &vconn);
285 if (!error) {
286 while ((error = vconn_connect(vconn)) == EAGAIN) {
287 vconn_run(vconn);
288 vconn_run_wait(vconn);
289 vconn_connect_wait(vconn);
290 poll_block();
291 }
292 assert(error != EINPROGRESS);
293 }
294
295 if (error) {
296 vconn_close(vconn);
297 *vconnp = NULL;
298 } else {
299 *vconnp = vconn;
300 }
301 return error;
302 }
303
304 /* Closes 'vconn'. */
305 void
306 vconn_close(struct vconn *vconn)
307 {
308 if (vconn != NULL) {
309 char *name = vconn->name;
310 (vconn->class->close)(vconn);
311 free(name);
312 }
313 }
314
315 /* Returns the name of 'vconn', that is, the string passed to vconn_open(). */
316 const char *
317 vconn_get_name(const struct vconn *vconn)
318 {
319 return vconn->name;
320 }
321
322 /* Returns the IP address of the peer, or 0 if the peer is not connected over
323 * an IP-based protocol or if its IP address is not yet known. */
324 ovs_be32
325 vconn_get_remote_ip(const struct vconn *vconn)
326 {
327 return vconn->remote_ip;
328 }
329
330 /* Returns the transport port of the peer, or 0 if the connection does not
331 * contain a port or if the port is not yet known. */
332 ovs_be16
333 vconn_get_remote_port(const struct vconn *vconn)
334 {
335 return vconn->remote_port;
336 }
337
338 /* Returns the IP address used to connect to the peer, or 0 if the
339 * connection is not an IP-based protocol or if its IP address is not
340 * yet known. */
341 ovs_be32
342 vconn_get_local_ip(const struct vconn *vconn)
343 {
344 return vconn->local_ip;
345 }
346
347 /* Returns the transport port used to connect to the peer, or 0 if the
348 * connection does not contain a port or if the port is not yet known. */
349 ovs_be16
350 vconn_get_local_port(const struct vconn *vconn)
351 {
352 return vconn->local_port;
353 }
354
355 static void
356 vcs_connecting(struct vconn *vconn)
357 {
358 int retval = (vconn->class->connect)(vconn);
359 assert(retval != EINPROGRESS);
360 if (!retval) {
361 vconn->state = VCS_SEND_HELLO;
362 } else if (retval != EAGAIN) {
363 vconn->state = VCS_DISCONNECTED;
364 vconn->error = retval;
365 }
366 }
367
368 static void
369 vcs_send_hello(struct vconn *vconn)
370 {
371 struct ofpbuf *b;
372 int retval;
373
374 make_openflow(sizeof(struct ofp_header), OFPT_HELLO, &b);
375 retval = do_send(vconn, b);
376 if (!retval) {
377 vconn->state = VCS_RECV_HELLO;
378 } else {
379 ofpbuf_delete(b);
380 if (retval != EAGAIN) {
381 vconn->state = VCS_DISCONNECTED;
382 vconn->error = retval;
383 }
384 }
385 }
386
387 static void
388 vcs_recv_hello(struct vconn *vconn)
389 {
390 struct ofpbuf *b;
391 int retval;
392
393 retval = do_recv(vconn, &b);
394 if (!retval) {
395 struct ofp_header *oh = b->data;
396
397 if (oh->type == OFPT_HELLO) {
398 if (b->size > sizeof *oh) {
399 struct ds msg = DS_EMPTY_INITIALIZER;
400 ds_put_format(&msg, "%s: extra-long hello:\n", vconn->name);
401 ds_put_hex_dump(&msg, b->data, b->size, 0, true);
402 VLOG_WARN_RL(&bad_ofmsg_rl, "%s", ds_cstr(&msg));
403 ds_destroy(&msg);
404 }
405
406 vconn->version = MIN(OFP_VERSION, oh->version);
407 if (vconn->version < vconn->min_version) {
408 VLOG_WARN_RL(&bad_ofmsg_rl,
409 "%s: version negotiation failed: we support "
410 "versions 0x%02x to 0x%02x inclusive but peer "
411 "supports no later than version 0x%02"PRIx8,
412 vconn->name, vconn->min_version, OFP_VERSION,
413 oh->version);
414 vconn->state = VCS_SEND_ERROR;
415 } else {
416 VLOG_DBG("%s: negotiated OpenFlow version 0x%02x "
417 "(we support versions 0x%02x to 0x%02x inclusive, "
418 "peer no later than version 0x%02"PRIx8")",
419 vconn->name, vconn->version, vconn->min_version,
420 OFP_VERSION, oh->version);
421 vconn->state = VCS_CONNECTED;
422 }
423 ofpbuf_delete(b);
424 return;
425 } else {
426 char *s = ofp_to_string(b->data, b->size, 1);
427 VLOG_WARN_RL(&bad_ofmsg_rl,
428 "%s: received message while expecting hello: %s",
429 vconn->name, s);
430 free(s);
431 retval = EPROTO;
432 ofpbuf_delete(b);
433 }
434 }
435
436 if (retval != EAGAIN) {
437 vconn->state = VCS_DISCONNECTED;
438 vconn->error = retval == EOF ? ECONNRESET : retval;
439 }
440 }
441
442 static void
443 vcs_send_error(struct vconn *vconn)
444 {
445 struct ofp_error_msg *error;
446 struct ofpbuf *b;
447 char s[128];
448 int retval;
449
450 snprintf(s, sizeof s, "We support versions 0x%02x to 0x%02x inclusive but "
451 "you support no later than version 0x%02"PRIx8".",
452 vconn->min_version, OFP_VERSION, vconn->version);
453 error = make_openflow(sizeof *error, OFPT_ERROR, &b);
454 error->type = htons(OFPET_HELLO_FAILED);
455 error->code = htons(OFPHFC_INCOMPATIBLE);
456 ofpbuf_put(b, s, strlen(s));
457 update_openflow_length(b);
458 retval = do_send(vconn, b);
459 if (retval) {
460 ofpbuf_delete(b);
461 }
462 if (retval != EAGAIN) {
463 vconn->state = VCS_DISCONNECTED;
464 vconn->error = retval ? retval : EPROTO;
465 }
466 }
467
468 /* Tries to complete the connection on 'vconn'. If 'vconn''s connection is
469 * complete, returns 0 if the connection was successful or a positive errno
470 * value if it failed. If the connection is still in progress, returns
471 * EAGAIN. */
472 int
473 vconn_connect(struct vconn *vconn)
474 {
475 enum vconn_state last_state;
476
477 assert(vconn->min_version >= 0);
478 do {
479 last_state = vconn->state;
480 switch (vconn->state) {
481 case VCS_CONNECTING:
482 vcs_connecting(vconn);
483 break;
484
485 case VCS_SEND_HELLO:
486 vcs_send_hello(vconn);
487 break;
488
489 case VCS_RECV_HELLO:
490 vcs_recv_hello(vconn);
491 break;
492
493 case VCS_CONNECTED:
494 return 0;
495
496 case VCS_SEND_ERROR:
497 vcs_send_error(vconn);
498 break;
499
500 case VCS_DISCONNECTED:
501 return vconn->error;
502
503 default:
504 NOT_REACHED();
505 }
506 } while (vconn->state != last_state);
507
508 return EAGAIN;
509 }
510
511 /* Tries to receive an OpenFlow message from 'vconn'. If successful, stores
512 * the received message into '*msgp' and returns 0. The caller is responsible
513 * for destroying the message with ofpbuf_delete(). On failure, returns a
514 * positive errno value and stores a null pointer into '*msgp'. On normal
515 * connection close, returns EOF.
516 *
517 * vconn_recv will not block waiting for a packet to arrive. If no packets
518 * have been received, it returns EAGAIN immediately. */
519 int
520 vconn_recv(struct vconn *vconn, struct ofpbuf **msgp)
521 {
522 int retval = vconn_connect(vconn);
523 if (!retval) {
524 retval = do_recv(vconn, msgp);
525 }
526 return retval;
527 }
528
529 static int
530 do_recv(struct vconn *vconn, struct ofpbuf **msgp)
531 {
532 int retval = (vconn->class->recv)(vconn, msgp);
533 if (!retval) {
534 struct ofp_header *oh;
535
536 COVERAGE_INC(vconn_received);
537 if (VLOG_IS_DBG_ENABLED()) {
538 char *s = ofp_to_string((*msgp)->data, (*msgp)->size, 1);
539 VLOG_DBG_RL(&ofmsg_rl, "%s: received: %s", vconn->name, s);
540 free(s);
541 }
542
543 oh = ofpbuf_at_assert(*msgp, 0, sizeof *oh);
544 if (oh->version != vconn->version
545 && oh->type != OFPT_HELLO
546 && oh->type != OFPT_ERROR
547 && oh->type != OFPT_ECHO_REQUEST
548 && oh->type != OFPT_ECHO_REPLY
549 && oh->type != OFPT_VENDOR)
550 {
551 if (vconn->version < 0) {
552 VLOG_ERR_RL(&bad_ofmsg_rl,
553 "%s: received OpenFlow message type %"PRIu8" "
554 "before version negotiation complete",
555 vconn->name, oh->type);
556 } else {
557 VLOG_ERR_RL(&bad_ofmsg_rl,
558 "%s: received OpenFlow version 0x%02"PRIx8" "
559 "!= expected %02x",
560 vconn->name, oh->version, vconn->version);
561 }
562 ofpbuf_delete(*msgp);
563 retval = EPROTO;
564 }
565 }
566 if (retval) {
567 *msgp = NULL;
568 }
569 return retval;
570 }
571
572 /* Tries to queue 'msg' for transmission on 'vconn'. If successful, returns 0,
573 * in which case ownership of 'msg' is transferred to the vconn. Success does
574 * not guarantee that 'msg' has been or ever will be delivered to the peer,
575 * only that it has been queued for transmission.
576 *
577 * Returns a positive errno value on failure, in which case the caller
578 * retains ownership of 'msg'.
579 *
580 * vconn_send will not block. If 'msg' cannot be immediately accepted for
581 * transmission, it returns EAGAIN immediately. */
582 int
583 vconn_send(struct vconn *vconn, struct ofpbuf *msg)
584 {
585 int retval = vconn_connect(vconn);
586 if (!retval) {
587 retval = do_send(vconn, msg);
588 }
589 return retval;
590 }
591
592 static int
593 do_send(struct vconn *vconn, struct ofpbuf *msg)
594 {
595 int retval;
596
597 assert(msg->size >= sizeof(struct ofp_header));
598 assert(((struct ofp_header *) msg->data)->length == htons(msg->size));
599 if (!VLOG_IS_DBG_ENABLED()) {
600 COVERAGE_INC(vconn_sent);
601 retval = (vconn->class->send)(vconn, msg);
602 } else {
603 char *s = ofp_to_string(msg->data, msg->size, 1);
604 retval = (vconn->class->send)(vconn, msg);
605 if (retval != EAGAIN) {
606 VLOG_DBG_RL(&ofmsg_rl, "%s: sent (%s): %s",
607 vconn->name, strerror(retval), s);
608 }
609 free(s);
610 }
611 return retval;
612 }
613
614 /* Same as vconn_send, except that it waits until 'msg' can be transmitted. */
615 int
616 vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
617 {
618 int retval;
619
620 fatal_signal_run();
621
622 while ((retval = vconn_send(vconn, msg)) == EAGAIN) {
623 vconn_run(vconn);
624 vconn_run_wait(vconn);
625 vconn_send_wait(vconn);
626 poll_block();
627 }
628 return retval;
629 }
630
631 /* Same as vconn_recv, except that it waits until a message is received. */
632 int
633 vconn_recv_block(struct vconn *vconn, struct ofpbuf **msgp)
634 {
635 int retval;
636
637 fatal_signal_run();
638
639 while ((retval = vconn_recv(vconn, msgp)) == EAGAIN) {
640 vconn_run(vconn);
641 vconn_run_wait(vconn);
642 vconn_recv_wait(vconn);
643 poll_block();
644 }
645 return retval;
646 }
647
648 /* Waits until a message with a transaction ID matching 'xid' is recived on
649 * 'vconn'. Returns 0 if successful, in which case the reply is stored in
650 * '*replyp' for the caller to examine and free. Otherwise returns a positive
651 * errno value, or EOF, and sets '*replyp' to null.
652 *
653 * 'request' is always destroyed, regardless of the return value. */
654 int
655 vconn_recv_xid(struct vconn *vconn, ovs_be32 xid, struct ofpbuf **replyp)
656 {
657 for (;;) {
658 ovs_be32 recv_xid;
659 struct ofpbuf *reply;
660 int error;
661
662 error = vconn_recv_block(vconn, &reply);
663 if (error) {
664 *replyp = NULL;
665 return error;
666 }
667 recv_xid = ((struct ofp_header *) reply->data)->xid;
668 if (xid == recv_xid) {
669 *replyp = reply;
670 return 0;
671 }
672
673 VLOG_DBG_RL(&bad_ofmsg_rl, "%s: received reply with xid %08"PRIx32
674 " != expected %08"PRIx32,
675 vconn->name, ntohl(recv_xid), ntohl(xid));
676 ofpbuf_delete(reply);
677 }
678 }
679
680 /* Sends 'request' to 'vconn' and blocks until it receives a reply with a
681 * matching transaction ID. Returns 0 if successful, in which case the reply
682 * is stored in '*replyp' for the caller to examine and free. Otherwise
683 * returns a positive errno value, or EOF, and sets '*replyp' to null.
684 *
685 * 'request' should be an OpenFlow request that requires a reply. Otherwise,
686 * if there is no reply, this function can end up blocking forever (or until
687 * the peer drops the connection).
688 *
689 * 'request' is always destroyed, regardless of the return value. */
690 int
691 vconn_transact(struct vconn *vconn, struct ofpbuf *request,
692 struct ofpbuf **replyp)
693 {
694 ovs_be32 send_xid = ((struct ofp_header *) request->data)->xid;
695 int error;
696
697 *replyp = NULL;
698 error = vconn_send_block(vconn, request);
699 if (error) {
700 ofpbuf_delete(request);
701 }
702 return error ? error : vconn_recv_xid(vconn, send_xid, replyp);
703 }
704
705 /* Sends 'request' followed by a barrier request to 'vconn', then blocks until
706 * it receives a reply to the barrier. If successful, stores the reply to
707 * 'request' in '*replyp', if one was received, and otherwise NULL, then
708 * returns 0. Otherwise returns a positive errno value, or EOF, and sets
709 * '*replyp' to null.
710 *
711 * This function is useful for sending an OpenFlow request that doesn't
712 * ordinarily include a reply but might report an error in special
713 * circumstances.
714 *
715 * 'request' is always destroyed, regardless of the return value. */
716 int
717 vconn_transact_noreply(struct vconn *vconn, struct ofpbuf *request,
718 struct ofpbuf **replyp)
719 {
720 ovs_be32 request_xid;
721 ovs_be32 barrier_xid;
722 struct ofpbuf *barrier;
723 int error;
724
725 *replyp = NULL;
726
727 /* Send request. */
728 request_xid = ((struct ofp_header *) request->data)->xid;
729 error = vconn_send_block(vconn, request);
730 if (error) {
731 ofpbuf_delete(request);
732 return error;
733 }
734
735 /* Send barrier. */
736 make_openflow(sizeof(struct ofp_header), OFPT_BARRIER_REQUEST, &barrier);
737 barrier_xid = ((struct ofp_header *) barrier->data)->xid;
738 error = vconn_send_block(vconn, barrier);
739 if (error) {
740 ofpbuf_delete(barrier);
741 return error;
742 }
743
744 for (;;) {
745 struct ofpbuf *msg;
746 ovs_be32 msg_xid;
747 int error;
748
749 error = vconn_recv_block(vconn, &msg);
750 if (error) {
751 ofpbuf_delete(*replyp);
752 *replyp = NULL;
753 return error;
754 }
755
756 msg_xid = ((struct ofp_header *) msg->data)->xid;
757 if (msg_xid == request_xid) {
758 if (*replyp) {
759 VLOG_WARN_RL(&bad_ofmsg_rl, "%s: duplicate replies with "
760 "xid %08"PRIx32, vconn->name, ntohl(msg_xid));
761 ofpbuf_delete(*replyp);
762 }
763 *replyp = msg;
764 } else {
765 ofpbuf_delete(msg);
766 if (msg_xid == barrier_xid) {
767 return 0;
768 } else {
769 VLOG_DBG_RL(&bad_ofmsg_rl, "%s: reply with xid %08"PRIx32
770 " != expected %08"PRIx32" or %08"PRIx32,
771 vconn->name, ntohl(msg_xid),
772 ntohl(request_xid), ntohl(barrier_xid));
773 }
774 }
775 }
776 }
777
778 /* vconn_transact_noreply() for a list of "struct ofpbuf"s, sent one by one.
779 * All of the requests on 'requests' are always destroyed, regardless of the
780 * return value. */
781 int
782 vconn_transact_multiple_noreply(struct vconn *vconn, struct list *requests,
783 struct ofpbuf **replyp)
784 {
785 struct ofpbuf *request, *next;
786
787 LIST_FOR_EACH_SAFE (request, next, list_node, requests) {
788 int error;
789
790 list_remove(&request->list_node);
791
792 error = vconn_transact_noreply(vconn, request, replyp);
793 if (error || *replyp) {
794 ofpbuf_list_delete(requests);
795 return error;
796 }
797 }
798
799 *replyp = NULL;
800 return 0;
801 }
802
803 void
804 vconn_wait(struct vconn *vconn, enum vconn_wait_type wait)
805 {
806 assert(wait == WAIT_CONNECT || wait == WAIT_RECV || wait == WAIT_SEND);
807
808 switch (vconn->state) {
809 case VCS_CONNECTING:
810 wait = WAIT_CONNECT;
811 break;
812
813 case VCS_SEND_HELLO:
814 case VCS_SEND_ERROR:
815 wait = WAIT_SEND;
816 break;
817
818 case VCS_RECV_HELLO:
819 wait = WAIT_RECV;
820 break;
821
822 case VCS_CONNECTED:
823 break;
824
825 case VCS_DISCONNECTED:
826 poll_immediate_wake();
827 return;
828 }
829 (vconn->class->wait)(vconn, wait);
830 }
831
832 void
833 vconn_connect_wait(struct vconn *vconn)
834 {
835 vconn_wait(vconn, WAIT_CONNECT);
836 }
837
838 void
839 vconn_recv_wait(struct vconn *vconn)
840 {
841 vconn_wait(vconn, WAIT_RECV);
842 }
843
844 void
845 vconn_send_wait(struct vconn *vconn)
846 {
847 vconn_wait(vconn, WAIT_SEND);
848 }
849
850 /* Given 'name', a connection name in the form "TYPE:ARGS", stores the class
851 * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
852 * a null pointer into '*classp' if 'name' is in the wrong form or if no such
853 * class exists. */
854 static int
855 pvconn_lookup_class(const char *name, struct pvconn_class **classp)
856 {
857 size_t prefix_len;
858
859 prefix_len = strcspn(name, ":");
860 if (name[prefix_len] != '\0') {
861 size_t i;
862
863 for (i = 0; i < ARRAY_SIZE(pvconn_classes); i++) {
864 struct pvconn_class *class = pvconn_classes[i];
865 if (strlen(class->name) == prefix_len
866 && !memcmp(class->name, name, prefix_len)) {
867 *classp = class;
868 return 0;
869 }
870 }
871 }
872
873 *classp = NULL;
874 return EAFNOSUPPORT;
875 }
876
877 /* Returns 0 if 'name' is a connection name in the form "TYPE:ARGS" and TYPE is
878 * a supported connection type, otherwise EAFNOSUPPORT. */
879 int
880 pvconn_verify_name(const char *name)
881 {
882 struct pvconn_class *class;
883 return pvconn_lookup_class(name, &class);
884 }
885
886 /* Attempts to start listening for OpenFlow connections. 'name' is a
887 * connection name in the form "TYPE:ARGS", where TYPE is an passive vconn
888 * class's name and ARGS are vconn class-specific.
889 *
890 * Returns 0 if successful, otherwise a positive errno value. If successful,
891 * stores a pointer to the new connection in '*pvconnp', otherwise a null
892 * pointer. */
893 int
894 pvconn_open(const char *name, struct pvconn **pvconnp)
895 {
896 struct pvconn_class *class;
897 struct pvconn *pvconn;
898 char *suffix_copy;
899 int error;
900
901 check_vconn_classes();
902
903 /* Look up the class. */
904 error = pvconn_lookup_class(name, &class);
905 if (!class) {
906 goto error;
907 }
908
909 /* Call class's "open" function. */
910 suffix_copy = xstrdup(strchr(name, ':') + 1);
911 error = class->listen(name, suffix_copy, &pvconn);
912 free(suffix_copy);
913 if (error) {
914 goto error;
915 }
916
917 /* Success. */
918 *pvconnp = pvconn;
919 return 0;
920
921 error:
922 *pvconnp = NULL;
923 return error;
924 }
925
926 /* Returns the name that was used to open 'pvconn'. The caller must not
927 * modify or free the name. */
928 const char *
929 pvconn_get_name(const struct pvconn *pvconn)
930 {
931 return pvconn->name;
932 }
933
934 /* Closes 'pvconn'. */
935 void
936 pvconn_close(struct pvconn *pvconn)
937 {
938 if (pvconn != NULL) {
939 char *name = pvconn->name;
940 (pvconn->class->close)(pvconn);
941 free(name);
942 }
943 }
944
945 /* Tries to accept a new connection on 'pvconn'. If successful, stores the new
946 * connection in '*new_vconn' and returns 0. Otherwise, returns a positive
947 * errno value.
948 *
949 * The new vconn will automatically negotiate an OpenFlow protocol version
950 * acceptable to both peers on the connection. The version negotiated will be
951 * no lower than 'min_version' and no higher than OFP_VERSION.
952 *
953 * pvconn_accept() will not block waiting for a connection. If no connection
954 * is ready to be accepted, it returns EAGAIN immediately. */
955 int
956 pvconn_accept(struct pvconn *pvconn, int min_version, struct vconn **new_vconn)
957 {
958 int retval = (pvconn->class->accept)(pvconn, new_vconn);
959 if (retval) {
960 *new_vconn = NULL;
961 } else {
962 assert((*new_vconn)->state != VCS_CONNECTING
963 || (*new_vconn)->class->connect);
964 (*new_vconn)->min_version = min_version;
965 }
966 return retval;
967 }
968
969 void
970 pvconn_wait(struct pvconn *pvconn)
971 {
972 (pvconn->class->wait)(pvconn);
973 }
974
975 /* Initializes 'vconn' as a new vconn named 'name', implemented via 'class'.
976 * The initial connection status, supplied as 'connect_status', is interpreted
977 * as follows:
978 *
979 * - 0: 'vconn' is connected. Its 'send' and 'recv' functions may be
980 * called in the normal fashion.
981 *
982 * - EAGAIN: 'vconn' is trying to complete a connection. Its 'connect'
983 * function should be called to complete the connection.
984 *
985 * - Other positive errno values indicate that the connection failed with
986 * the specified error.
987 *
988 * After calling this function, vconn_close() must be used to destroy 'vconn',
989 * otherwise resources will be leaked.
990 *
991 * The caller retains ownership of 'name'. */
992 void
993 vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status,
994 const char *name)
995 {
996 vconn->class = class;
997 vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING
998 : !connect_status ? VCS_SEND_HELLO
999 : VCS_DISCONNECTED);
1000 vconn->error = connect_status;
1001 vconn->version = -1;
1002 vconn->min_version = -1;
1003 vconn->remote_ip = 0;
1004 vconn->remote_port = 0;
1005 vconn->local_ip = 0;
1006 vconn->local_port = 0;
1007 vconn->name = xstrdup(name);
1008 assert(vconn->state != VCS_CONNECTING || class->connect);
1009 }
1010
1011 void
1012 vconn_set_remote_ip(struct vconn *vconn, ovs_be32 ip)
1013 {
1014 vconn->remote_ip = ip;
1015 }
1016
1017 void
1018 vconn_set_remote_port(struct vconn *vconn, ovs_be16 port)
1019 {
1020 vconn->remote_port = port;
1021 }
1022
1023 void
1024 vconn_set_local_ip(struct vconn *vconn, ovs_be32 ip)
1025 {
1026 vconn->local_ip = ip;
1027 }
1028
1029 void
1030 vconn_set_local_port(struct vconn *vconn, ovs_be16 port)
1031 {
1032 vconn->local_port = port;
1033 }
1034
1035 void
1036 pvconn_init(struct pvconn *pvconn, struct pvconn_class *class,
1037 const char *name)
1038 {
1039 pvconn->class = class;
1040 pvconn->name = xstrdup(name);
1041 }