2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include "openflow/openflow.h"
28 #include "poll-loop.h"
35 VLOG_DEFINE_THIS_MODULE(rconn
);
37 COVERAGE_DEFINE(rconn_discarded
);
38 COVERAGE_DEFINE(rconn_overflow
);
39 COVERAGE_DEFINE(rconn_queued
);
40 COVERAGE_DEFINE(rconn_sent
);
44 STATE(BACKOFF, 1 << 1) \
45 STATE(CONNECTING, 1 << 2) \
46 STATE(ACTIVE, 1 << 3) \
49 #define STATE(NAME, VALUE) S_##NAME = VALUE,
55 state_name(enum state state
)
58 #define STATE(NAME, VALUE) case S_##NAME: return #NAME;
65 /* A reliable connection to an OpenFlow switch or controller.
67 * See the large comment in rconn.h for more information. */
69 struct ovs_mutex mutex
;
75 char *name
; /* Human-readable descriptive name. */
76 char *target
; /* vconn name, passed to vconn_open(). */
79 struct list txq
; /* Contains "struct ofpbuf"s. */
83 time_t backoff_deadline
;
84 time_t last_connected
;
85 time_t last_disconnected
;
86 unsigned int packets_sent
;
90 /* In S_ACTIVE and S_IDLE, probably_admitted reports whether we believe
91 * that the peer has made a (positive) admission control decision on our
92 * connection. If we have not yet been (probably) admitted, then the
93 * connection does not reset the timer used for deciding whether the switch
94 * should go into fail-open mode.
96 * last_admitted reports the last time we believe such a positive admission
97 * control decision was made. */
98 bool probably_admitted
;
101 /* These values are simply for statistics reporting, not used directly by
102 * anything internal to the rconn (or ofproto for that matter). */
103 unsigned int packets_received
;
104 unsigned int n_attempted_connections
, n_successful_connections
;
105 time_t creation_time
;
106 unsigned long int total_time_connected
;
108 /* Throughout this file, "probe" is shorthand for "inactivity probe". When
109 * no activity has been observed from the peer for a while, we send out an
110 * echo request as an inactivity probe packet. We should receive back a
113 * "Activity" is defined as either receiving an OpenFlow message from the
114 * peer or successfully sending a message that had been in 'txq'. */
115 int probe_interval
; /* Secs of inactivity before sending probe. */
116 time_t last_activity
; /* Last time we saw some activity. */
120 /* Messages sent or received are copied to the monitor connections. */
121 #define MAX_MONITORS 8
122 struct vconn
*monitors
[8];
125 uint32_t allowed_versions
;
128 uint32_t rconn_get_allowed_versions(const struct rconn
*rconn
)
130 return rconn
->allowed_versions
;
133 static unsigned int elapsed_in_this_state(const struct rconn
*rc
)
134 OVS_REQUIRES(rc
->mutex
);
135 static unsigned int timeout(const struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
136 static bool timed_out(const struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
137 static void state_transition(struct rconn
*rc
, enum state
)
138 OVS_REQUIRES(rc
->mutex
);
139 static void rconn_set_target__(struct rconn
*rc
,
140 const char *target
, const char *name
)
141 OVS_REQUIRES(rc
->mutex
);
142 static int rconn_send__(struct rconn
*rc
, struct ofpbuf
*,
143 struct rconn_packet_counter
*)
144 OVS_REQUIRES(rc
->mutex
);
145 static int try_send(struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
146 static void reconnect(struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
147 static void report_error(struct rconn
*rc
, int error
) OVS_REQUIRES(rc
->mutex
);
148 static void rconn_disconnect__(struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
149 static void disconnect(struct rconn
*rc
, int error
) OVS_REQUIRES(rc
->mutex
);
150 static void flush_queue(struct rconn
*rc
) OVS_REQUIRES(rc
->mutex
);
151 static void close_monitor(struct rconn
*rc
, size_t idx
, int retval
)
152 OVS_REQUIRES(rc
->mutex
);
153 static void copy_to_monitor(struct rconn
*, const struct ofpbuf
*);
154 static bool is_connected_state(enum state
);
155 static bool is_admitted_msg(const struct ofpbuf
*);
156 static bool rconn_logging_connection_attempts__(const struct rconn
*rc
)
157 OVS_REQUIRES(rc
->mutex
);
158 static int rconn_get_version__(const struct rconn
*rconn
)
159 OVS_REQUIRES(rconn
->mutex
);
161 /* The following prototypes duplicate those in rconn.h, but there we weren't
162 * able to add the OVS_EXCLUDED annotations because the definition of struct
163 * rconn was not visible. */
165 void rconn_set_max_backoff(struct rconn
*rc
, int max_backoff
)
166 OVS_EXCLUDED(rc
->mutex
);
167 void rconn_connect(struct rconn
*rc
, const char *target
, const char *name
)
168 OVS_EXCLUDED(rc
->mutex
);
169 void rconn_connect_unreliably(struct rconn
*rc
,
170 struct vconn
*vconn
, const char *name
)
171 OVS_EXCLUDED(rc
->mutex
);
172 void rconn_reconnect(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
173 void rconn_disconnect(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
174 void rconn_run(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
175 void rconn_run_wait(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
176 struct ofpbuf
*rconn_recv(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
177 void rconn_recv_wait(struct rconn
*rc
) OVS_EXCLUDED(rc
->mutex
);
178 int rconn_send(struct rconn
*rc
, struct ofpbuf
*b
,
179 struct rconn_packet_counter
*counter
)
180 OVS_EXCLUDED(rc
->mutex
);
181 int rconn_send_with_limit(struct rconn
*rc
, struct ofpbuf
*b
,
182 struct rconn_packet_counter
*counter
,
184 OVS_EXCLUDED(rc
->mutex
);
185 void rconn_add_monitor(struct rconn
*rc
, struct vconn
*vconn
)
186 OVS_EXCLUDED(rc
->mutex
);
187 void rconn_set_name(struct rconn
*rc
, const char *new_name
)
188 OVS_EXCLUDED(rc
->mutex
);
189 bool rconn_is_admitted(const struct rconn
*rconn
) OVS_EXCLUDED(rconn
->mutex
);
190 int rconn_failure_duration(const struct rconn
*rconn
)
191 OVS_EXCLUDED(rconn
->mutex
);
192 ovs_be16
rconn_get_local_port(const struct rconn
*rconn
)
193 OVS_EXCLUDED(rconn
->mutex
);
194 int rconn_get_version(const struct rconn
*rconn
) OVS_EXCLUDED(rconn
->mutex
);
195 unsigned int rconn_count_txqlen(const struct rconn
*rc
)
196 OVS_EXCLUDED(rc
->mutex
);
199 /* Creates and returns a new rconn.
201 * 'probe_interval' is a number of seconds. If the interval passes once
202 * without an OpenFlow message being received from the peer, the rconn sends
203 * out an "echo request" message. If the interval passes again without a
204 * message being received, the rconn disconnects and re-connects to the peer.
205 * Setting 'probe_interval' to 0 disables this behavior.
207 * 'max_backoff' is the maximum number of seconds between attempts to connect
208 * to the peer. The actual interval starts at 1 second and doubles on each
209 * failure until it reaches 'max_backoff'. If 0 is specified, the default of
212 * The new rconn is initially unconnected. Use rconn_connect() or
213 * rconn_connect_unreliably() to connect it.
215 * Connections made by the rconn will automatically negotiate an OpenFlow
216 * protocol version acceptable to both peers on the connection. The version
217 * negotiated will be one of those in the 'allowed_versions' bitmap: version
218 * 'x' is allowed if allowed_versions & (1 << x) is nonzero. (The underlying
219 * vconn will treat an 'allowed_versions' of 0 as OFPUTIL_DEFAULT_VERSIONS.)
222 rconn_create(int probe_interval
, int max_backoff
, uint8_t dscp
,
223 uint32_t allowed_versions
)
225 struct rconn
*rc
= xzalloc(sizeof *rc
);
227 ovs_mutex_init(&rc
->mutex
);
230 rc
->state_entered
= time_now();
233 rc
->name
= xstrdup("void");
234 rc
->target
= xstrdup("void");
235 rc
->reliable
= false;
240 rc
->max_backoff
= max_backoff
? max_backoff
: 8;
241 rc
->backoff_deadline
= TIME_MIN
;
242 rc
->last_connected
= TIME_MIN
;
243 rc
->last_disconnected
= TIME_MIN
;
246 rc
->packets_sent
= 0;
248 rc
->probably_admitted
= false;
249 rc
->last_admitted
= time_now();
251 rc
->packets_received
= 0;
252 rc
->n_attempted_connections
= 0;
253 rc
->n_successful_connections
= 0;
254 rc
->creation_time
= time_now();
255 rc
->total_time_connected
= 0;
257 rc
->last_activity
= time_now();
259 rconn_set_probe_interval(rc
, probe_interval
);
260 rconn_set_dscp(rc
, dscp
);
263 rc
->allowed_versions
= allowed_versions
;
269 rconn_set_max_backoff(struct rconn
*rc
, int max_backoff
)
270 OVS_EXCLUDED(rc
->mutex
)
272 ovs_mutex_lock(&rc
->mutex
);
273 rc
->max_backoff
= MAX(1, max_backoff
);
274 if (rc
->state
== S_BACKOFF
&& rc
->backoff
> max_backoff
) {
275 rc
->backoff
= max_backoff
;
276 if (rc
->backoff_deadline
> time_now() + max_backoff
) {
277 rc
->backoff_deadline
= time_now() + max_backoff
;
280 ovs_mutex_unlock(&rc
->mutex
);
284 rconn_get_max_backoff(const struct rconn
*rc
)
286 return rc
->max_backoff
;
290 rconn_set_dscp(struct rconn
*rc
, uint8_t dscp
)
296 rconn_get_dscp(const struct rconn
*rc
)
302 rconn_set_probe_interval(struct rconn
*rc
, int probe_interval
)
304 rc
->probe_interval
= probe_interval
? MAX(5, probe_interval
) : 0;
308 rconn_get_probe_interval(const struct rconn
*rc
)
310 return rc
->probe_interval
;
313 /* Drops any existing connection on 'rc', then sets up 'rc' to connect to
314 * 'target' and reconnect as needed. 'target' should be a remote OpenFlow
315 * target in a form acceptable to vconn_open().
317 * If 'name' is nonnull, then it is used in log messages in place of 'target'.
318 * It should presumably give more information to a human reader than 'target',
319 * but it need not be acceptable to vconn_open(). */
321 rconn_connect(struct rconn
*rc
, const char *target
, const char *name
)
322 OVS_EXCLUDED(rc
->mutex
)
324 ovs_mutex_lock(&rc
->mutex
);
325 rconn_disconnect__(rc
);
326 rconn_set_target__(rc
, target
, name
);
329 ovs_mutex_unlock(&rc
->mutex
);
332 /* Drops any existing connection on 'rc', then configures 'rc' to use
333 * 'vconn'. If the connection on 'vconn' drops, 'rc' will not reconnect on it
336 * By default, the target obtained from vconn_get_name(vconn) is used in log
337 * messages. If 'name' is nonnull, then it is used instead. It should
338 * presumably give more information to a human reader than the target, but it
339 * need not be acceptable to vconn_open(). */
341 rconn_connect_unreliably(struct rconn
*rc
,
342 struct vconn
*vconn
, const char *name
)
343 OVS_EXCLUDED(rc
->mutex
)
345 ovs_assert(vconn
!= NULL
);
347 ovs_mutex_lock(&rc
->mutex
);
348 rconn_disconnect__(rc
);
349 rconn_set_target__(rc
, vconn_get_name(vconn
), name
);
350 rc
->reliable
= false;
352 rc
->last_connected
= time_now();
353 state_transition(rc
, S_ACTIVE
);
354 ovs_mutex_unlock(&rc
->mutex
);
357 /* If 'rc' is connected, forces it to drop the connection and reconnect. */
359 rconn_reconnect(struct rconn
*rc
)
360 OVS_EXCLUDED(rc
->mutex
)
362 ovs_mutex_lock(&rc
->mutex
);
363 if (rc
->state
& (S_ACTIVE
| S_IDLE
)) {
364 VLOG_INFO("%s: disconnecting", rc
->name
);
367 ovs_mutex_unlock(&rc
->mutex
);
371 rconn_disconnect__(struct rconn
*rc
)
372 OVS_REQUIRES(rc
->mutex
)
374 if (rc
->state
!= S_VOID
) {
376 vconn_close(rc
->vconn
);
379 rconn_set_target__(rc
, "void", NULL
);
380 rc
->reliable
= false;
383 rc
->backoff_deadline
= TIME_MIN
;
385 state_transition(rc
, S_VOID
);
390 rconn_disconnect(struct rconn
*rc
)
391 OVS_EXCLUDED(rc
->mutex
)
393 ovs_mutex_lock(&rc
->mutex
);
394 rconn_disconnect__(rc
);
395 ovs_mutex_unlock(&rc
->mutex
);
398 /* Disconnects 'rc' and frees the underlying storage. */
400 rconn_destroy(struct rconn
*rc
)
405 ovs_mutex_lock(&rc
->mutex
);
408 vconn_close(rc
->vconn
);
410 ofpbuf_list_delete(&rc
->txq
);
411 for (i
= 0; i
< rc
->n_monitors
; i
++) {
412 vconn_close(rc
->monitors
[i
]);
414 ovs_mutex_unlock(&rc
->mutex
);
415 ovs_mutex_destroy(&rc
->mutex
);
422 timeout_VOID(const struct rconn
*rc OVS_UNUSED
)
423 OVS_REQUIRES(rc
->mutex
)
429 run_VOID(struct rconn
*rc OVS_UNUSED
)
430 OVS_REQUIRES(rc
->mutex
)
436 reconnect(struct rconn
*rc
)
437 OVS_REQUIRES(rc
->mutex
)
441 if (rconn_logging_connection_attempts__(rc
)) {
442 VLOG_INFO("%s: connecting...", rc
->name
);
444 rc
->n_attempted_connections
++;
445 retval
= vconn_open(rc
->target
, rc
->allowed_versions
, rc
->dscp
,
448 rc
->backoff_deadline
= time_now() + rc
->backoff
;
449 state_transition(rc
, S_CONNECTING
);
451 VLOG_WARN("%s: connection failed (%s)",
452 rc
->name
, ovs_strerror(retval
));
453 rc
->backoff_deadline
= TIME_MAX
; /* Prevent resetting backoff. */
454 disconnect(rc
, retval
);
459 timeout_BACKOFF(const struct rconn
*rc
)
460 OVS_REQUIRES(rc
->mutex
)
466 run_BACKOFF(struct rconn
*rc
)
467 OVS_REQUIRES(rc
->mutex
)
475 timeout_CONNECTING(const struct rconn
*rc
)
476 OVS_REQUIRES(rc
->mutex
)
478 return MAX(1, rc
->backoff
);
482 run_CONNECTING(struct rconn
*rc
)
483 OVS_REQUIRES(rc
->mutex
)
485 int retval
= vconn_connect(rc
->vconn
);
487 VLOG_INFO("%s: connected", rc
->name
);
488 rc
->n_successful_connections
++;
489 state_transition(rc
, S_ACTIVE
);
490 rc
->last_connected
= rc
->state_entered
;
491 } else if (retval
!= EAGAIN
) {
492 if (rconn_logging_connection_attempts__(rc
)) {
493 VLOG_INFO("%s: connection failed (%s)",
494 rc
->name
, ovs_strerror(retval
));
496 disconnect(rc
, retval
);
497 } else if (timed_out(rc
)) {
498 if (rconn_logging_connection_attempts__(rc
)) {
499 VLOG_INFO("%s: connection timed out", rc
->name
);
501 rc
->backoff_deadline
= TIME_MAX
; /* Prevent resetting backoff. */
502 disconnect(rc
, ETIMEDOUT
);
507 do_tx_work(struct rconn
*rc
)
508 OVS_REQUIRES(rc
->mutex
)
510 if (list_is_empty(&rc
->txq
)) {
513 while (!list_is_empty(&rc
->txq
)) {
514 int error
= try_send(rc
);
518 rc
->last_activity
= time_now();
520 if (list_is_empty(&rc
->txq
)) {
521 poll_immediate_wake();
526 timeout_ACTIVE(const struct rconn
*rc
)
527 OVS_REQUIRES(rc
->mutex
)
529 if (rc
->probe_interval
) {
530 unsigned int base
= MAX(rc
->last_activity
, rc
->state_entered
);
531 unsigned int arg
= base
+ rc
->probe_interval
- rc
->state_entered
;
538 run_ACTIVE(struct rconn
*rc
)
539 OVS_REQUIRES(rc
->mutex
)
542 unsigned int base
= MAX(rc
->last_activity
, rc
->state_entered
);
545 VLOG_DBG("%s: idle %u seconds, sending inactivity probe",
546 rc
->name
, (unsigned int) (time_now() - base
));
548 version
= rconn_get_version__(rc
);
549 ovs_assert(version
>= 0 && version
<= 0xff);
551 /* Ordering is important here: rconn_send() can transition to BACKOFF,
552 * and we don't want to transition back to IDLE if so, because then we
553 * can end up queuing a packet with vconn == NULL and then *boom*. */
554 state_transition(rc
, S_IDLE
);
555 rconn_send__(rc
, make_echo_request(version
), NULL
);
563 timeout_IDLE(const struct rconn
*rc
)
564 OVS_REQUIRES(rc
->mutex
)
566 return rc
->probe_interval
;
570 run_IDLE(struct rconn
*rc
)
571 OVS_REQUIRES(rc
->mutex
)
574 VLOG_ERR("%s: no response to inactivity probe after %u "
575 "seconds, disconnecting",
576 rc
->name
, elapsed_in_this_state(rc
));
577 disconnect(rc
, ETIMEDOUT
);
583 /* Performs whatever activities are necessary to maintain 'rc': if 'rc' is
584 * disconnected, attempts to (re)connect, backing off as necessary; if 'rc' is
585 * connected, attempts to send packets in the send queue, if any. */
587 rconn_run(struct rconn
*rc
)
588 OVS_EXCLUDED(rc
->mutex
)
593 ovs_mutex_lock(&rc
->mutex
);
597 vconn_run(rc
->vconn
);
599 error
= vconn_get_status(rc
->vconn
);
601 report_error(rc
, error
);
602 disconnect(rc
, error
);
605 for (i
= 0; i
< rc
->n_monitors
; ) {
609 vconn_run(rc
->monitors
[i
]);
611 /* Drain any stray message that came in on the monitor connection. */
612 retval
= vconn_recv(rc
->monitors
[i
], &msg
);
615 } else if (retval
!= EAGAIN
) {
616 close_monitor(rc
, i
, retval
);
623 old_state
= rc
->state
;
625 #define STATE(NAME, VALUE) case S_##NAME: run_##NAME(rc); break;
631 } while (rc
->state
!= old_state
);
632 ovs_mutex_unlock(&rc
->mutex
);
635 /* Causes the next call to poll_block() to wake up when rconn_run() should be
638 rconn_run_wait(struct rconn
*rc
)
639 OVS_EXCLUDED(rc
->mutex
)
644 ovs_mutex_lock(&rc
->mutex
);
646 vconn_run_wait(rc
->vconn
);
647 if ((rc
->state
& (S_ACTIVE
| S_IDLE
)) && !list_is_empty(&rc
->txq
)) {
648 vconn_wait(rc
->vconn
, WAIT_SEND
);
651 for (i
= 0; i
< rc
->n_monitors
; i
++) {
652 vconn_run_wait(rc
->monitors
[i
]);
653 vconn_recv_wait(rc
->monitors
[i
]);
657 if (timeo
!= UINT_MAX
) {
658 long long int expires
= sat_add(rc
->state_entered
, timeo
);
659 poll_timer_wait_until(expires
* 1000);
661 ovs_mutex_unlock(&rc
->mutex
);
664 /* Attempts to receive a packet from 'rc'. If successful, returns the packet;
665 * otherwise, returns a null pointer. The caller is responsible for freeing
666 * the packet (with ofpbuf_delete()). */
668 rconn_recv(struct rconn
*rc
)
669 OVS_EXCLUDED(rc
->mutex
)
671 struct ofpbuf
*buffer
= NULL
;
673 ovs_mutex_lock(&rc
->mutex
);
674 if (rc
->state
& (S_ACTIVE
| S_IDLE
)) {
675 int error
= vconn_recv(rc
->vconn
, &buffer
);
677 copy_to_monitor(rc
, buffer
);
678 if (rc
->probably_admitted
|| is_admitted_msg(buffer
)
679 || time_now() - rc
->last_connected
>= 30) {
680 rc
->probably_admitted
= true;
681 rc
->last_admitted
= time_now();
683 rc
->last_activity
= time_now();
684 rc
->packets_received
++;
685 if (rc
->state
== S_IDLE
) {
686 state_transition(rc
, S_ACTIVE
);
688 } else if (error
!= EAGAIN
) {
689 report_error(rc
, error
);
690 disconnect(rc
, error
);
693 ovs_mutex_unlock(&rc
->mutex
);
698 /* Causes the next call to poll_block() to wake up when a packet may be ready
699 * to be received by vconn_recv() on 'rc'. */
701 rconn_recv_wait(struct rconn
*rc
)
702 OVS_EXCLUDED(rc
->mutex
)
704 ovs_mutex_lock(&rc
->mutex
);
706 vconn_wait(rc
->vconn
, WAIT_RECV
);
708 ovs_mutex_unlock(&rc
->mutex
);
712 rconn_send__(struct rconn
*rc
, struct ofpbuf
*b
,
713 struct rconn_packet_counter
*counter
)
714 OVS_REQUIRES(rc
->mutex
)
716 if (rconn_is_connected(rc
)) {
717 COVERAGE_INC(rconn_queued
);
718 copy_to_monitor(rc
, b
);
721 rconn_packet_counter_inc(counter
, ofpbuf_size(b
));
724 /* Reuse 'frame' as a private pointer while 'b' is in txq. */
725 ofpbuf_set_frame(b
, counter
);
727 list_push_back(&rc
->txq
, &b
->list_node
);
729 /* If the queue was empty before we added 'b', try to send some
730 * packets. (But if the queue had packets in it, it's because the
731 * vconn is backlogged and there's no point in stuffing more into it
732 * now. We'll get back to that in rconn_run().) */
733 if (rc
->txq
.next
== &b
->list_node
) {
743 /* Sends 'b' on 'rc'. Returns 0 if successful, or ENOTCONN if 'rc' is not
744 * currently connected. Takes ownership of 'b'.
746 * If 'counter' is non-null, then 'counter' will be incremented while the
747 * packet is in flight, then decremented when it has been sent (or discarded
748 * due to disconnection). Because 'b' may be sent (or discarded) before this
749 * function returns, the caller may not be able to observe any change in
752 * There is no rconn_send_wait() function: an rconn has a send queue that it
753 * takes care of sending if you call rconn_run(), which will have the side
754 * effect of waking up poll_block(). */
756 rconn_send(struct rconn
*rc
, struct ofpbuf
*b
,
757 struct rconn_packet_counter
*counter
)
758 OVS_EXCLUDED(rc
->mutex
)
762 ovs_mutex_lock(&rc
->mutex
);
763 error
= rconn_send__(rc
, b
, counter
);
764 ovs_mutex_unlock(&rc
->mutex
);
769 /* Sends 'b' on 'rc'. Increments 'counter' while the packet is in flight; it
770 * will be decremented when it has been sent (or discarded due to
771 * disconnection). Returns 0 if successful, EAGAIN if 'counter->n' is already
772 * at least as large as 'queue_limit', or ENOTCONN if 'rc' is not currently
773 * connected. Regardless of return value, 'b' is destroyed.
775 * Because 'b' may be sent (or discarded) before this function returns, the
776 * caller may not be able to observe any change in 'counter'.
778 * There is no rconn_send_wait() function: an rconn has a send queue that it
779 * takes care of sending if you call rconn_run(), which will have the side
780 * effect of waking up poll_block(). */
782 rconn_send_with_limit(struct rconn
*rc
, struct ofpbuf
*b
,
783 struct rconn_packet_counter
*counter
, int queue_limit
)
784 OVS_EXCLUDED(rc
->mutex
)
788 ovs_mutex_lock(&rc
->mutex
);
789 if (rconn_packet_counter_n_packets(counter
) < queue_limit
) {
790 error
= rconn_send__(rc
, b
, counter
);
792 COVERAGE_INC(rconn_overflow
);
796 ovs_mutex_unlock(&rc
->mutex
);
801 /* Returns the total number of packets successfully sent on the underlying
802 * vconn. A packet is not counted as sent while it is still queued in the
803 * rconn, only when it has been successfuly passed to the vconn. */
805 rconn_packets_sent(const struct rconn
*rc
)
807 return rc
->packets_sent
;
810 /* Adds 'vconn' to 'rc' as a monitoring connection, to which all messages sent
811 * and received on 'rconn' will be copied. 'rc' takes ownership of 'vconn'. */
813 rconn_add_monitor(struct rconn
*rc
, struct vconn
*vconn
)
814 OVS_EXCLUDED(rc
->mutex
)
816 ovs_mutex_lock(&rc
->mutex
);
817 if (rc
->n_monitors
< ARRAY_SIZE(rc
->monitors
)) {
818 VLOG_INFO("new monitor connection from %s", vconn_get_name(vconn
));
819 rc
->monitors
[rc
->n_monitors
++] = vconn
;
821 VLOG_DBG("too many monitor connections, discarding %s",
822 vconn_get_name(vconn
));
825 ovs_mutex_unlock(&rc
->mutex
);
828 /* Returns 'rc''s name. This is a name for human consumption, appropriate for
829 * use in log messages. It is not necessarily a name that may be passed
830 * directly to, e.g., vconn_open(). */
832 rconn_get_name(const struct rconn
*rc
)
837 /* Sets 'rc''s name to 'new_name'. */
839 rconn_set_name(struct rconn
*rc
, const char *new_name
)
840 OVS_EXCLUDED(rc
->mutex
)
842 ovs_mutex_lock(&rc
->mutex
);
844 rc
->name
= xstrdup(new_name
);
845 ovs_mutex_unlock(&rc
->mutex
);
848 /* Returns 'rc''s target. This is intended to be a string that may be passed
849 * directly to, e.g., vconn_open(). */
851 rconn_get_target(const struct rconn
*rc
)
856 /* Returns true if 'rconn' is connected or in the process of reconnecting,
857 * false if 'rconn' is disconnected and will not reconnect on its own. */
859 rconn_is_alive(const struct rconn
*rconn
)
861 return rconn
->state
!= S_VOID
;
864 /* Returns true if 'rconn' is connected, false otherwise. */
866 rconn_is_connected(const struct rconn
*rconn
)
868 return is_connected_state(rconn
->state
);
872 rconn_is_admitted__(const struct rconn
*rconn
)
873 OVS_REQUIRES(rconn
->mutex
)
875 return (rconn_is_connected(rconn
)
876 && rconn
->last_admitted
>= rconn
->last_connected
);
879 /* Returns true if 'rconn' is connected and thought to have been accepted by
880 * the peer's admission-control policy. */
882 rconn_is_admitted(const struct rconn
*rconn
)
883 OVS_EXCLUDED(rconn
->mutex
)
887 ovs_mutex_lock(&rconn
->mutex
);
888 admitted
= rconn_is_admitted__(rconn
);
889 ovs_mutex_unlock(&rconn
->mutex
);
894 /* Returns 0 if 'rconn' is currently connected and considered to have been
895 * accepted by the peer's admission-control policy, otherwise the number of
896 * seconds since 'rconn' was last in such a state. */
898 rconn_failure_duration(const struct rconn
*rconn
)
899 OVS_EXCLUDED(rconn
->mutex
)
903 ovs_mutex_lock(&rconn
->mutex
);
904 duration
= (rconn_is_admitted__(rconn
)
906 : time_now() - rconn
->last_admitted
);
907 ovs_mutex_unlock(&rconn
->mutex
);
913 rconn_get_version__(const struct rconn
*rconn
)
914 OVS_REQUIRES(rconn
->mutex
)
916 return rconn
->vconn
? vconn_get_version(rconn
->vconn
) : -1;
919 /* Returns the OpenFlow version negotiated with the peer, or -1 if there is
920 * currently no connection or if version negotiation is not yet complete. */
922 rconn_get_version(const struct rconn
*rconn
)
923 OVS_EXCLUDED(rconn
->mutex
)
927 ovs_mutex_lock(&rconn
->mutex
);
928 version
= rconn_get_version__(rconn
);
929 ovs_mutex_unlock(&rconn
->mutex
);
934 /* Returns the total number of packets successfully received by the underlying
937 rconn_packets_received(const struct rconn
*rc
)
939 return rc
->packets_received
;
942 /* Returns a string representing the internal state of 'rc'. The caller must
943 * not modify or free the string. */
945 rconn_get_state(const struct rconn
*rc
)
947 return state_name(rc
->state
);
950 /* Returns the time at which the last successful connection was made by
951 * 'rc'. Returns TIME_MIN if never connected. */
953 rconn_get_last_connection(const struct rconn
*rc
)
955 return rc
->last_connected
;
958 /* Returns the time at which 'rc' was last disconnected. Returns TIME_MIN
959 * if never disconnected. */
961 rconn_get_last_disconnect(const struct rconn
*rc
)
963 return rc
->last_disconnected
;
966 /* Returns 'rc''s current connection sequence number, a number that changes
967 * every time that 'rconn' connects or disconnects. */
969 rconn_get_connection_seqno(const struct rconn
*rc
)
974 /* Returns a value that explains why 'rc' last disconnected:
976 * - 0 means that the last disconnection was caused by a call to
977 * rconn_disconnect(), or that 'rc' is new and has not yet completed its
978 * initial connection or connection attempt.
980 * - EOF means that the connection was closed in the normal way by the peer.
982 * - A positive integer is an errno value that represents the error.
985 rconn_get_last_error(const struct rconn
*rc
)
987 return rc
->last_error
;
990 /* Returns the number of messages queued for transmission on 'rc'. */
992 rconn_count_txqlen(const struct rconn
*rc
)
993 OVS_EXCLUDED(rc
->mutex
)
997 ovs_mutex_lock(&rc
->mutex
);
998 len
= list_size(&rc
->txq
);
999 ovs_mutex_unlock(&rc
->mutex
);
1004 struct rconn_packet_counter
*
1005 rconn_packet_counter_create(void)
1007 struct rconn_packet_counter
*c
= xzalloc(sizeof *c
);
1008 ovs_mutex_init(&c
->mutex
);
1009 ovs_mutex_lock(&c
->mutex
);
1011 ovs_mutex_unlock(&c
->mutex
);
1016 rconn_packet_counter_destroy(struct rconn_packet_counter
*c
)
1021 ovs_mutex_lock(&c
->mutex
);
1022 ovs_assert(c
->ref_cnt
> 0);
1023 dead
= !--c
->ref_cnt
&& !c
->n_packets
;
1024 ovs_mutex_unlock(&c
->mutex
);
1027 ovs_mutex_destroy(&c
->mutex
);
1034 rconn_packet_counter_inc(struct rconn_packet_counter
*c
, unsigned int n_bytes
)
1036 ovs_mutex_lock(&c
->mutex
);
1038 c
->n_bytes
+= n_bytes
;
1039 ovs_mutex_unlock(&c
->mutex
);
1043 rconn_packet_counter_dec(struct rconn_packet_counter
*c
, unsigned int n_bytes
)
1047 ovs_mutex_lock(&c
->mutex
);
1048 ovs_assert(c
->n_packets
> 0);
1049 ovs_assert(c
->n_packets
== 1
1050 ? c
->n_bytes
== n_bytes
1051 : c
->n_bytes
> n_bytes
);
1053 c
->n_bytes
-= n_bytes
;
1054 dead
= !c
->n_packets
&& !c
->ref_cnt
;
1055 ovs_mutex_unlock(&c
->mutex
);
1058 ovs_mutex_destroy(&c
->mutex
);
1064 rconn_packet_counter_n_packets(const struct rconn_packet_counter
*c
)
1068 ovs_mutex_lock(&c
->mutex
);
1070 ovs_mutex_unlock(&c
->mutex
);
1076 rconn_packet_counter_n_bytes(const struct rconn_packet_counter
*c
)
1080 ovs_mutex_lock(&c
->mutex
);
1082 ovs_mutex_unlock(&c
->mutex
);
1087 /* Set rc->target and rc->name to 'target' and 'name', respectively. If 'name'
1088 * is null, 'target' is used.
1090 * Also, clear out the cached IP address and port information, since changing
1091 * the target also likely changes these values. */
1093 rconn_set_target__(struct rconn
*rc
, const char *target
, const char *name
)
1094 OVS_REQUIRES(rc
->mutex
)
1097 rc
->name
= xstrdup(name
? name
: target
);
1099 rc
->target
= xstrdup(target
);
1102 /* Tries to send a packet from 'rc''s send buffer. Returns 0 if successful,
1103 * otherwise a positive errno value. */
1105 try_send(struct rconn
*rc
)
1106 OVS_REQUIRES(rc
->mutex
)
1108 struct ofpbuf
*msg
= ofpbuf_from_list(rc
->txq
.next
);
1109 unsigned int n_bytes
= ofpbuf_size(msg
);
1110 struct rconn_packet_counter
*counter
= msg
->frame
;
1113 /* Eagerly remove 'msg' from the txq. We can't remove it from the list
1114 * after sending, if sending is successful, because it is then owned by the
1115 * vconn, which might have freed it already. */
1116 list_remove(&msg
->list_node
);
1117 ofpbuf_set_frame(msg
, NULL
);
1119 retval
= vconn_send(rc
->vconn
, msg
);
1121 ofpbuf_set_frame(msg
, counter
);
1122 list_push_front(&rc
->txq
, &msg
->list_node
);
1123 if (retval
!= EAGAIN
) {
1124 report_error(rc
, retval
);
1125 disconnect(rc
, retval
);
1129 COVERAGE_INC(rconn_sent
);
1132 rconn_packet_counter_dec(counter
, n_bytes
);
1137 /* Reports that 'error' caused 'rc' to disconnect. 'error' may be a positive
1138 * errno value, or it may be EOF to indicate that the connection was closed
1141 report_error(struct rconn
*rc
, int error
)
1142 OVS_REQUIRES(rc
->mutex
)
1145 /* If 'rc' isn't reliable, then we don't really expect this connection
1146 * to last forever anyway (probably it's a connection that we received
1147 * via accept()), so use DBG level to avoid cluttering the logs. */
1148 enum vlog_level level
= rc
->reliable
? VLL_INFO
: VLL_DBG
;
1149 VLOG(level
, "%s: connection closed by peer", rc
->name
);
1151 VLOG_WARN("%s: connection dropped (%s)",
1152 rc
->name
, ovs_strerror(error
));
1156 /* Disconnects 'rc' and records 'error' as the error that caused 'rc''s last
1159 * - 0 means that this disconnection is due to a request by 'rc''s client,
1160 * not due to any kind of network error.
1162 * - EOF means that the connection was closed in the normal way by the peer.
1164 * - A positive integer is an errno value that represents the error.
1167 disconnect(struct rconn
*rc
, int error
)
1168 OVS_REQUIRES(rc
->mutex
)
1170 rc
->last_error
= error
;
1172 time_t now
= time_now();
1174 if (rc
->state
& (S_CONNECTING
| S_ACTIVE
| S_IDLE
)) {
1175 rc
->last_disconnected
= now
;
1176 vconn_close(rc
->vconn
);
1181 if (now
>= rc
->backoff_deadline
) {
1183 } else if (rc
->backoff
< rc
->max_backoff
/ 2) {
1184 rc
->backoff
= MAX(1, 2 * rc
->backoff
);
1185 VLOG_INFO("%s: waiting %d seconds before reconnect",
1186 rc
->name
, rc
->backoff
);
1188 if (rconn_logging_connection_attempts__(rc
)) {
1189 VLOG_INFO("%s: continuing to retry connections in the "
1190 "background but suppressing further logging",
1193 rc
->backoff
= rc
->max_backoff
;
1195 rc
->backoff_deadline
= now
+ rc
->backoff
;
1196 state_transition(rc
, S_BACKOFF
);
1198 rc
->last_disconnected
= time_now();
1199 rconn_disconnect__(rc
);
1203 /* Drops all the packets from 'rc''s send queue and decrements their queue
1206 flush_queue(struct rconn
*rc
)
1207 OVS_REQUIRES(rc
->mutex
)
1209 if (list_is_empty(&rc
->txq
)) {
1212 while (!list_is_empty(&rc
->txq
)) {
1213 struct ofpbuf
*b
= ofpbuf_from_list(list_pop_front(&rc
->txq
));
1214 struct rconn_packet_counter
*counter
= b
->frame
;
1216 rconn_packet_counter_dec(counter
, ofpbuf_size(b
));
1218 COVERAGE_INC(rconn_discarded
);
1221 poll_immediate_wake();
1225 elapsed_in_this_state(const struct rconn
*rc
)
1226 OVS_REQUIRES(rc
->mutex
)
1228 return time_now() - rc
->state_entered
;
1232 timeout(const struct rconn
*rc
)
1233 OVS_REQUIRES(rc
->mutex
)
1235 switch (rc
->state
) {
1236 #define STATE(NAME, VALUE) case S_##NAME: return timeout_##NAME(rc);
1245 timed_out(const struct rconn
*rc
)
1246 OVS_REQUIRES(rc
->mutex
)
1248 return time_now() >= sat_add(rc
->state_entered
, timeout(rc
));
1252 state_transition(struct rconn
*rc
, enum state state
)
1253 OVS_REQUIRES(rc
->mutex
)
1255 rc
->seqno
+= (rc
->state
== S_ACTIVE
) != (state
== S_ACTIVE
);
1256 if (is_connected_state(state
) && !is_connected_state(rc
->state
)) {
1257 rc
->probably_admitted
= false;
1259 if (rconn_is_connected(rc
)) {
1260 rc
->total_time_connected
+= elapsed_in_this_state(rc
);
1262 VLOG_DBG("%s: entering %s", rc
->name
, state_name(state
));
1264 rc
->state_entered
= time_now();
1268 close_monitor(struct rconn
*rc
, size_t idx
, int retval
)
1269 OVS_REQUIRES(rc
->mutex
)
1271 VLOG_DBG("%s: closing monitor connection to %s: %s",
1272 rconn_get_name(rc
), vconn_get_name(rc
->monitors
[idx
]),
1273 ovs_retval_to_string(retval
));
1274 rc
->monitors
[idx
] = rc
->monitors
[--rc
->n_monitors
];
1278 copy_to_monitor(struct rconn
*rc
, const struct ofpbuf
*b
)
1279 OVS_REQUIRES(rc
->mutex
)
1281 struct ofpbuf
*clone
= NULL
;
1285 for (i
= 0; i
< rc
->n_monitors
; ) {
1286 struct vconn
*vconn
= rc
->monitors
[i
];
1289 clone
= ofpbuf_clone(b
);
1291 retval
= vconn_send(vconn
, clone
);
1294 } else if (retval
!= EAGAIN
) {
1295 close_monitor(rc
, i
, retval
);
1300 ofpbuf_delete(clone
);
1304 is_connected_state(enum state state
)
1306 return (state
& (S_ACTIVE
| S_IDLE
)) != 0;
1309 /* When a switch initially connects to a controller, the controller may spend a
1310 * little time examining the switch, looking at, for example, its datapath ID,
1311 * before it decides whether it is willing to control that switch. At that
1312 * point, it either disconnects or starts controlling the switch.
1314 * This function returns a guess to its caller about whether 'b' is OpenFlow
1315 * message that indicates that the controller has decided to control the
1316 * switch. It returns false if the message is one that a controller typically
1317 * uses to determine whether a switch is admissible, true if the message is one
1318 * that would typically be used only after the controller has admitted the
1321 is_admitted_msg(const struct ofpbuf
*b
)
1326 error
= ofptype_decode(&type
, ofpbuf_data(b
));
1334 case OFPTYPE_ECHO_REQUEST
:
1335 case OFPTYPE_ECHO_REPLY
:
1336 case OFPTYPE_FEATURES_REQUEST
:
1337 case OFPTYPE_FEATURES_REPLY
:
1338 case OFPTYPE_GET_CONFIG_REQUEST
:
1339 case OFPTYPE_GET_CONFIG_REPLY
:
1340 case OFPTYPE_SET_CONFIG
:
1341 case OFPTYPE_QUEUE_GET_CONFIG_REQUEST
:
1342 case OFPTYPE_QUEUE_GET_CONFIG_REPLY
:
1343 case OFPTYPE_GET_ASYNC_REQUEST
:
1344 case OFPTYPE_GET_ASYNC_REPLY
:
1345 case OFPTYPE_GROUP_STATS_REQUEST
:
1346 case OFPTYPE_GROUP_STATS_REPLY
:
1347 case OFPTYPE_GROUP_DESC_STATS_REQUEST
:
1348 case OFPTYPE_GROUP_DESC_STATS_REPLY
:
1349 case OFPTYPE_GROUP_FEATURES_STATS_REQUEST
:
1350 case OFPTYPE_GROUP_FEATURES_STATS_REPLY
:
1351 case OFPTYPE_TABLE_FEATURES_STATS_REQUEST
:
1352 case OFPTYPE_TABLE_FEATURES_STATS_REPLY
:
1355 case OFPTYPE_PACKET_IN
:
1356 case OFPTYPE_FLOW_REMOVED
:
1357 case OFPTYPE_PORT_STATUS
:
1358 case OFPTYPE_PACKET_OUT
:
1359 case OFPTYPE_FLOW_MOD
:
1360 case OFPTYPE_GROUP_MOD
:
1361 case OFPTYPE_PORT_MOD
:
1362 case OFPTYPE_TABLE_MOD
:
1363 case OFPTYPE_METER_MOD
:
1364 case OFPTYPE_BARRIER_REQUEST
:
1365 case OFPTYPE_BARRIER_REPLY
:
1366 case OFPTYPE_DESC_STATS_REQUEST
:
1367 case OFPTYPE_DESC_STATS_REPLY
:
1368 case OFPTYPE_FLOW_STATS_REQUEST
:
1369 case OFPTYPE_FLOW_STATS_REPLY
:
1370 case OFPTYPE_AGGREGATE_STATS_REQUEST
:
1371 case OFPTYPE_AGGREGATE_STATS_REPLY
:
1372 case OFPTYPE_TABLE_STATS_REQUEST
:
1373 case OFPTYPE_TABLE_STATS_REPLY
:
1374 case OFPTYPE_PORT_STATS_REQUEST
:
1375 case OFPTYPE_PORT_STATS_REPLY
:
1376 case OFPTYPE_QUEUE_STATS_REQUEST
:
1377 case OFPTYPE_QUEUE_STATS_REPLY
:
1378 case OFPTYPE_PORT_DESC_STATS_REQUEST
:
1379 case OFPTYPE_PORT_DESC_STATS_REPLY
:
1380 case OFPTYPE_METER_STATS_REQUEST
:
1381 case OFPTYPE_METER_STATS_REPLY
:
1382 case OFPTYPE_METER_CONFIG_STATS_REQUEST
:
1383 case OFPTYPE_METER_CONFIG_STATS_REPLY
:
1384 case OFPTYPE_METER_FEATURES_STATS_REQUEST
:
1385 case OFPTYPE_METER_FEATURES_STATS_REPLY
:
1386 case OFPTYPE_ROLE_REQUEST
:
1387 case OFPTYPE_ROLE_REPLY
:
1388 case OFPTYPE_ROLE_STATUS
:
1389 case OFPTYPE_SET_FLOW_FORMAT
:
1390 case OFPTYPE_FLOW_MOD_TABLE_ID
:
1391 case OFPTYPE_SET_PACKET_IN_FORMAT
:
1392 case OFPTYPE_FLOW_AGE
:
1393 case OFPTYPE_SET_ASYNC_CONFIG
:
1394 case OFPTYPE_SET_CONTROLLER_ID
:
1395 case OFPTYPE_FLOW_MONITOR_STATS_REQUEST
:
1396 case OFPTYPE_FLOW_MONITOR_STATS_REPLY
:
1397 case OFPTYPE_FLOW_MONITOR_CANCEL
:
1398 case OFPTYPE_FLOW_MONITOR_PAUSED
:
1399 case OFPTYPE_FLOW_MONITOR_RESUMED
:
1405 /* Returns true if 'rc' is currently logging information about connection
1406 * attempts, false if logging should be suppressed because 'rc' hasn't
1407 * successuflly connected in too long. */
1409 rconn_logging_connection_attempts__(const struct rconn
*rc
)
1410 OVS_REQUIRES(rc
->mutex
)
1412 return rc
->backoff
< rc
->max_backoff
;