mirror of
https://github.com/openvswitch/ovs
synced 2025-10-23 14:57:06 +00:00
When the switch is configured to connect to a controller that accepts connections, waits a few seconds, and then disconnects without setting up flows, currently this causes "fail-open" to flush the flow table and stop setting up new flows during the connection duration. This is OK if it happens once, but it can easily happen every 8 seconds with typical backoff settings, and that isn't so great. This commit changes fail-open to only flush the flow table once the switch appears to have been admitted by the controller, which prevents these frequent network interruptions. Thanks to Jesse Gross for especially valuable feedback. QA notes: Behavior in fail-open and especially behavior with a controller that rejects the switch after it connects needs to be re-tested. The ovs-controller --mute switch added by this commit is one simple way to create such a controller. CC: Peter Balland <peter@nicira.com> Bug #1695. Bug #2055.
110 lines
4.2 KiB
C
110 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2008, 2009 Nicira Networks.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef RCONN_H
|
|
#define RCONN_H 1
|
|
|
|
#include "queue.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
|
|
/* A wrapper around vconn that provides queuing and optionally reliability.
|
|
*
|
|
* An rconn maintains a message transmission queue of bounded length specified
|
|
* by the caller. The rconn does not guarantee reliable delivery of
|
|
* queued messages: all queued messages are dropped when reconnection becomes
|
|
* necessary.
|
|
*
|
|
* An rconn optionally provides reliable communication, in this sense: the
|
|
* rconn will re-connect, with exponential backoff, when the underlying vconn
|
|
* disconnects.
|
|
*/
|
|
|
|
struct vconn;
|
|
struct rconn_packet_counter;
|
|
|
|
struct rconn *rconn_new(const char *name,
|
|
int inactivity_probe_interval, int max_backoff);
|
|
struct rconn *rconn_new_from_vconn(const char *name, struct vconn *);
|
|
struct rconn *rconn_create(int inactivity_probe_interval, int max_backoff);
|
|
|
|
void rconn_set_max_backoff(struct rconn *, int max_backoff);
|
|
int rconn_get_max_backoff(const struct rconn *);
|
|
void rconn_set_probe_interval(struct rconn *, int inactivity_probe_interval);
|
|
int rconn_get_probe_interval(const struct rconn *);
|
|
|
|
int rconn_connect(struct rconn *, const char *name);
|
|
void rconn_connect_unreliably(struct rconn *,
|
|
const char *name, struct vconn *vconn);
|
|
void rconn_reconnect(struct rconn *);
|
|
void rconn_disconnect(struct rconn *);
|
|
void rconn_destroy(struct rconn *);
|
|
|
|
void rconn_run(struct rconn *);
|
|
void rconn_run_wait(struct rconn *);
|
|
struct ofpbuf *rconn_recv(struct rconn *);
|
|
void rconn_recv_wait(struct rconn *);
|
|
int rconn_send(struct rconn *, struct ofpbuf *, struct rconn_packet_counter *);
|
|
int rconn_send_with_limit(struct rconn *, struct ofpbuf *,
|
|
struct rconn_packet_counter *, int queue_limit);
|
|
unsigned int rconn_packets_sent(const struct rconn *);
|
|
unsigned int rconn_packets_received(const struct rconn *);
|
|
|
|
void rconn_add_monitor(struct rconn *, struct vconn *);
|
|
|
|
const char *rconn_get_name(const struct rconn *);
|
|
bool rconn_is_alive(const struct rconn *);
|
|
bool rconn_is_connected(const struct rconn *);
|
|
bool rconn_is_admitted(const struct rconn *);
|
|
int rconn_failure_duration(const struct rconn *);
|
|
bool rconn_is_connectivity_questionable(struct rconn *);
|
|
|
|
uint32_t rconn_get_remote_ip(const struct rconn *);
|
|
uint16_t rconn_get_remote_port(const struct rconn *);
|
|
uint32_t rconn_get_local_ip(const struct rconn *);
|
|
uint16_t rconn_get_local_port(const struct rconn *);
|
|
|
|
const char *rconn_get_state(const struct rconn *);
|
|
unsigned int rconn_get_attempted_connections(const struct rconn *);
|
|
unsigned int rconn_get_successful_connections(const struct rconn *);
|
|
time_t rconn_get_last_connection(const struct rconn *);
|
|
time_t rconn_get_last_received(const struct rconn *);
|
|
time_t rconn_get_creation_time(const struct rconn *);
|
|
unsigned long int rconn_get_total_time_connected(const struct rconn *);
|
|
int rconn_get_backoff(const struct rconn *);
|
|
unsigned int rconn_get_state_elapsed(const struct rconn *);
|
|
unsigned int rconn_get_connection_seqno(const struct rconn *);
|
|
|
|
/* Counts the number of packets queued into an rconn by a given source. */
|
|
struct rconn_packet_counter {
|
|
int n; /* Number of packets queued. */
|
|
int ref_cnt; /* Number of owners. */
|
|
};
|
|
|
|
struct rconn_packet_counter *rconn_packet_counter_create(void);
|
|
void rconn_packet_counter_destroy(struct rconn_packet_counter *);
|
|
void rconn_packet_counter_inc(struct rconn_packet_counter *);
|
|
void rconn_packet_counter_dec(struct rconn_packet_counter *);
|
|
|
|
static inline int
|
|
rconn_packet_counter_read(const struct rconn_packet_counter *counter)
|
|
{
|
|
return counter->n;
|
|
}
|
|
|
|
#endif /* rconn.h */
|