Configure or disable ovn-controller probe_timer on the fly. There are four sessions established from ovn-controller to the following: OVN Southbound — jsonrpc based Local vswitchd — jsonrpc based Local vswitchd — openflow based from ofctrl Local vswitchd — openflow based from pinctrl All of these sessions have their own probe_interval, and currently only one [SB] of them can be configured using ovn-vsctl command, and even that is not effective on the fly —in other words, ovn-controller has to be restarted to use that probe_timer value. With this patch, probe_timer for all those four connections can be changed [disabled with setting them to 0] and the changes take effect on the fly. Using NB database’s external-ids, these settings are stored, the following are the external-ids which are used and here is how to set them: ovs-vsctl --no-wait set open_vswitch . \ external-ids:ovn-sb-remote-probe-interval=7000 ovs-vsctl --no-wait set open_vswitch . \ external-ids:ovn-ovs-remote-probe-interval=8000 ovs-vsctl --no-wait set open_vswitch . \ external-ids:ovn-ofctrl-remote-probe-interval=9 ovs-vsctl --no-wait set open_vswitch . \ external-ids:ovn-pinctrl-remote-probe-interval=10 Signed-off-by: Nirapada Ghosh <ngh...@us.ibm.com>
diff --git a/lib/rconn.c b/lib/rconn.c index 6de4c63..1775729 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -461,6 +461,7 @@ reconnect(struct rconn *rc) if (!retval) { rc->backoff_deadline = time_now() + rc->backoff; state_transition(rc, S_CONNECTING); + VLOG_INFO("connected with probe-interval %d", rc->probe_interval); } else { VLOG_WARN("%s: connection failed (%s)", rc->name, ovs_strerror(retval)); diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c index 55ca98d..cd01d99 100644 --- a/ovn/controller/ofctrl.c +++ b/ovn/controller/ofctrl.c @@ -102,6 +102,18 @@ static void ovn_flow_table_destroy(struct hmap *flow_table); static void ofctrl_recv(const struct ofp_header *, enum ofptype); + +/* The following function sets the probe_timer value to the input argument, + * we need this function because current code uses swconn as a static + * global variable and that might change on the fly because of connect or + * reconnect. + */ +void +ofctrl_set_probe_timer(int probe_timer) +{ + rconn_set_probe_interval(swconn,probe_timer); +} + void ofctrl_init(void) { diff --git a/ovn/controller/ovn-controller.8.xml b/ovn/controller/ovn-controller.8.xml index 1ee3a6e..6fa3af7 100644 --- a/ovn/controller/ovn-controller.8.xml +++ b/ovn/controller/ovn-controller.8.xml @@ -78,9 +78,6 @@ <dt><code>external_ids:system-id</code></dt> <dd>The chassis name to use in the Chassis table.</dd> - <dt><code>external_ids:hostname</code></dt> - <dd>The hostname to use in the Chassis table.</dd> - <dt><code>external_ids:ovn-bridge</code></dt> <dd> The integration bridge to which logical ports are attached. The @@ -103,7 +100,7 @@ </p> </dd> - <dt><code>external_ids:ovn-remote-probe-interval</code></dt> + <dt><code>external_ids:ovn-sb-remote-probe-interval</code></dt> <dd> <p> The inactivity probe interval of the connection to the OVN database, @@ -116,6 +113,45 @@ at least 1000 ms. </p> </dd> + <dt><code>external_ids:ovn-ovs-remote-probe-interval</code></dt> + <dd> + <p> + The inactivity probe interval of the connection to the local OVSREC, + in milliseconds. + If the value is zero, it disables the connection keepalive feature. + </p> + + <p> + If the value is nonzero, then it will be forced to a value of + at least 1000 ms. + </p> + </dd> + + <dt><code>external_ids:ovn-ofctrl-remote-probe-interval</code></dt> + <dd> + <p> + The inactivity probe interval of the connection to the local openflow + switch, in seconds. + If the value is zero, it disables the connection keepalive feature. + </p> + <p> + If the value is nonzero, then it will be forced to a value of + at least 5 seconds. + </p> + </dd> + + <dt><code>external_ids:ovn-pinctrl-remote-probe-interval</code></dt> + <dd> + <p> + The inactivity probe interval of the connection to the local openflow + switch, in seconds. + If the value is zero, it disables the connection keepalive feature. + </p> + <p> + If the value is nonzero, then it will be forced to a value of + at least 5 seconds. + </p> + </dd> <dt><code>external_ids:ovn-encap-type</code></dt> <dd> diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 6027011..5ddbc08 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -52,16 +52,53 @@ VLOG_DEFINE_THIS_MODULE(main); +static void set_probe_timer_if_changed(const struct ovsrec_open_vswitch *cfg, + const struct ovsdb_idl *ovs_idl, + const struct ovsdb_idl *sb_idl); +static bool extract_probe_timer(const struct ovsrec_open_vswitch *cfg, + char *key_name, + int *ret_value_ptr); + static unixctl_cb_func ovn_controller_exit; static unixctl_cb_func ct_zone_list; #define DEFAULT_BRIDGE_NAME "br-int" +#define DEFAULT_PROBE_INTERVAL 5 static void parse_options(int argc, char *argv[]); OVS_NO_RETURN static void usage(void); static char *ovs_remote; +/* Given key_name, the following function retrieves probe_timer value from the + * configuration passed, this configuration comes from the "external-ids" + * which were configured via ovs-vsctl command. + * + * cfg: Holding the external-id values read from NB database. + * keyname: Name to extract the value for. + * ret_value_ptr: Pointer to integer location where the value read + * should be copied. + * The function returns true if success, keeps the original + * value of ret_value_ptr intact in case of a failure. + */ +static bool +extract_probe_timer(const struct ovsrec_open_vswitch *cfg, + char *key_name, + int *ret_value_ptr) +{ + const char *probe_interval= smap_get(&cfg->external_ids, key_name); + int ret_value_temp=0; /* Temporary location to hold the value, in case of + * failure, str_to_int() sets the ret_value_temp to 0, + * which is a valid value for us */ + if ((!probe_interval) || (!str_to_int(probe_interval, 10, &ret_value_temp))) { + VLOG_WARN("OVN OVSDB invalid remote probe interval:%s for %s", + probe_interval, key_name); + return false; + } + *ret_value_ptr = ret_value_temp; + return true; +} + const struct sbrec_chassis * get_chassis(struct ovsdb_idl *ovnsb_idl, const char *chassis_id) { @@ -198,30 +235,62 @@ get_ovnsb_remote(struct ovsdb_idl *ovs_idl) } } -/* Retrieves the OVN Southbound remote's json session probe interval from the - * "external-ids:ovn-remote-probe-interval" key in 'ovs_idl' and returns it. - * - * This function must be called after get_ovnsb_remote(). */ -static bool -get_ovnsb_remote_probe_interval(struct ovsdb_idl *ovs_idl, int *value) +/* If any of the probe timers is changed using ovs-vsctl command, this function + * will set those probe timers on the fly. + * cfg: Holding the external-id values read from southbound DB. + * ovs_idl: pointer to the ovs_idl connection to local vswitchd. + * sb_idl: pointer to the ovs_idl connection to OVN southbound. + */ +static void +set_probe_timer_if_changed(const struct ovsrec_open_vswitch *cfg, + const struct ovsdb_idl *ovs_idl, + const struct ovsdb_idl *sb_idl + ) { - const struct ovsrec_open_vswitch *cfg = ovsrec_open_vswitch_first(ovs_idl); - if (!cfg) { - return false; + static int probe_int_sb = DEFAULT_PROBE_INTERVAL * 1000, /* in ms */ + probe_int_ovs = DEFAULT_PROBE_INTERVAL * 1000, /* in ms */ + probe_int_ofctrl = DEFAULT_PROBE_INTERVAL, /* in seconds */ + probe_int_pinctrl = DEFAULT_PROBE_INTERVAL; /* in seconds */ + int probe_int_ovs_new = probe_int_ovs, + probe_int_sb_new = probe_int_sb, + probe_int_ofctrl_new = probe_int_ofctrl, + probe_int_pinctrl_new = probe_int_pinctrl; + + extract_probe_timer(cfg, "ovn-ovs-remote-probe-interval", + &probe_int_ovs_new); + if (probe_int_ovs_new != probe_int_ovs) { + ovsdb_idl_set_probe_interval(ovs_idl, probe_int_ovs_new); + VLOG_INFO("OVN OVS probe interval changed %d->%d ", + probe_int_ovs, + probe_int_ovs_new); + probe_int_ovs = probe_int_ovs_new; } - - const char *probe_interval = - smap_get(&cfg->external_ids, "ovn-remote-probe-interval"); - if (probe_interval) { - if (str_to_int(probe_interval, 10, value)) { - return true; - } - - VLOG_WARN("Invalid value for OVN remote probe interval: %s", - probe_interval); + extract_probe_timer(cfg, "ovn-sb-remote-probe-interval", &probe_int_sb_new); + if (probe_int_sb_new != probe_int_sb) { + ovsdb_idl_set_probe_interval(sb_idl, probe_int_sb_new); + VLOG_INFO("OVN SB probe interval changed %d->%d ", + probe_int_sb, + probe_int_sb_new); + probe_int_sb = probe_int_sb_new; + } + extract_probe_timer(cfg, "ovn-ofctrl-remote-probe-interval", + &probe_int_ofctrl_new); + if (probe_int_ofctrl_new != probe_int_ofctrl) { + ofctrl_set_probe_timer(probe_int_ofctrl_new); + VLOG_INFO("OVN OFCTRL probe interval changed %d->%d ", + probe_int_ofctrl, + probe_int_ofctrl_new); + probe_int_ofctrl = probe_int_ofctrl_new; + } + extract_probe_timer(cfg, "ovn-pinctrl-remote-probe-interval", + &probe_int_pinctrl_new); + if (probe_int_pinctrl_new != probe_int_pinctrl) { + pinctrl_set_probe_timer(probe_int_pinctrl_new); + VLOG_INFO("OVN PINCTRL probe interval changed %d->%d ", + probe_int_pinctrl, + probe_int_pinctrl_new); + probe_int_pinctrl = probe_int_pinctrl_new; } - - return false; } int @@ -287,10 +356,12 @@ main(int argc, char *argv[]) ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true)); ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl); - int probe_interval = 0; - if (get_ovnsb_remote_probe_interval(ovs_idl_loop.idl, &probe_interval)) { - ovsdb_idl_set_probe_interval(ovnsb_idl_loop.idl, probe_interval); + const struct ovsrec_open_vswitch *cfg = + ovsrec_open_vswitch_first(ovs_idl_loop.idl); + if (!cfg) { + return false; } + set_probe_timer_if_changed(cfg,ovs_idl_loop.idl,ovnsb_idl_loop.idl); /* Initialize connection tracking zones. */ struct simap ct_zones = SIMAP_INITIALIZER(&ct_zones); @@ -308,6 +379,7 @@ main(int argc, char *argv[]) .ovnsb_idl = ovnsb_idl_loop.idl, .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), }; + set_probe_timer_if_changed(cfg,ovs_idl_loop.idl,ovnsb_idl_loop.idl); /* Contains "struct local_datpath" nodes whose hash values are the * tunnel_key of datapaths with at least one local port binding. */ diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h index 9955097..7c71fab 100644 --- a/ovn/controller/ovn-controller.h +++ b/ovn/controller/ovn-controller.h @@ -62,6 +62,7 @@ enum chassis_tunnel_type { }; uint32_t get_tunnel_type(const char *name); - +void ofctrl_set_probe_timer(int probe_timer); +void pinctrl_set_probe_timer(int probe_timer); #endif /* ovn/ovn-controller.h */ diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index 3fcab99..b1b79b1 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -56,6 +56,17 @@ static void flush_put_arps(void); COVERAGE_DEFINE(pinctrl_drop_put_arp); +/* The following function sets the probe_timer value to the input argument, + * we need this function because current code uses swconn as a static + * global variable and that might change on the fly because of connect or + * reconnect. + */ +void +pinctrl_set_probe_timer(int probe_timer) +{ + rconn_set_probe_interval(swconn,probe_timer); +} + void pinctrl_init(void) { _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev