This commit adds a new module ofproto-dpif-monitor in ofproto directory. This module is in charge of all monitoring logics, including bfd and cfm. Accordingly, the bfd and cfm references are removed from ofproto-dpif and ofproto-dpif-xlate modules. And they will invoke the corresponding functions in ofproto-dpif-monitor module for bfd/cfm configuration.
Signed-off-by: Alex Wang <[email protected]> --- ofproto/automake.mk | 2 + ofproto/ofproto-dpif-monitor.c | 397 ++++++++++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-monitor.h | 60 ++++++ ofproto/ofproto-dpif-xlate.c | 27 +-- ofproto/ofproto-dpif-xlate.h | 4 +- ofproto/ofproto-dpif.c | 160 +++------------- ofproto/ofproto-dpif.h | 2 + tests/bfd.at | 261 -------------------------- 8 files changed, 497 insertions(+), 416 deletions(-) create mode 100644 ofproto/ofproto-dpif-monitor.c create mode 100644 ofproto/ofproto-dpif-monitor.h diff --git a/ofproto/automake.mk b/ofproto/automake.mk index 47ca1b8..432f083 100644 --- a/ofproto/automake.mk +++ b/ofproto/automake.mk @@ -28,6 +28,8 @@ ofproto_libofproto_a_SOURCES = \ ofproto/ofproto-dpif-ipfix.h \ ofproto/ofproto-dpif-mirror.c \ ofproto/ofproto-dpif-mirror.h \ + ofproto/ofproto-dpif-monitor.c \ + ofproto/ofproto-dpif-monitor.h \ ofproto/ofproto-dpif-sflow.c \ ofproto/ofproto-dpif-sflow.h \ ofproto/ofproto-dpif-upcall.c \ diff --git a/ofproto/ofproto-dpif-monitor.c b/ofproto/ofproto-dpif-monitor.c new file mode 100644 index 0000000..8f18440 --- /dev/null +++ b/ofproto/ofproto-dpif-monitor.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * + * 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. + */ + +#include <config.h> +#include "ofproto-dpif-monitor.h" + +#include <errno.h> +#include "bfd.h" +#include "cfm.h" +#include "hash.h" +#include "hmap.h" +#include "ofpbuf.h" +#include "ofproto.h" +#include "ofproto-dpif.h" +#include "util.h" +#include "vlog.h" + +VLOG_DEFINE_THIS_MODULE(ofproto_dpif_monitor); + +/* Monitor struct. */ +struct monitor { + struct hmap hmap; /* hmap that contains all port monitors. */ +}; + +/* Monitored port. It has reference to bfd/cfm struct of the port. */ +struct mport { + struct hmap_node hmap_node; /* In monitor's hmap. */ + + /* Reference to bfd/cfm structs. */ + struct cfm *cfm; + struct bfd *bfd; + + /* Related to sending control packets. */ + const struct ofport_dpif *ofport; + uint8_t *hw_addr; +}; + +static struct monitor monitor; + +static void ofproto_dpif_monitor_init(void); + +static struct mport *mport_create(const struct ofport_dpif *); +static void mport_check_delete(struct mport *); +static void mport_delete(struct mport *); +static struct mport *mport_find(const struct ofport_dpif *); + +/* Initializes the monitor struct. */ +static void +ofproto_dpif_monitor_init(void) { + hmap_init(&monitor.hmap); +} + + +/* Creates a new mport and inserts it into monitor->hmap. */ +static struct mport * +mport_create(const struct ofport_dpif *ofport) +{ + struct mport *mport; + + mport = xmalloc(sizeof *mport); + mport->ofport = ofport; + mport->bfd = NULL; + mport->cfm = NULL; + mport->hw_addr = NULL; + hmap_insert(&monitor.hmap, &mport->hmap_node, hash_pointer(ofport, 0)); + return mport; +} + +/* Checkes 'mport', if both bfd and cfm are NULL, deletes the 'mport'. */ +static void +mport_check_delete(struct mport *mport) +{ + if (!mport) { + return; + } + + if (!mport->bfd && !mport->cfm) { + mport_delete(mport); + } +} + +/* Removes 'mport' from monitor's hmap and frees it. */ +static void +mport_delete(struct mport *mport) +{ + hmap_remove(&monitor.hmap, &mport->hmap_node); + free(mport); +} + +/* Tries finding and returning the 'mport' from the monitor's hash map. + * If there is no such 'mport', returns NULL. */ +static struct mport * +mport_find(const struct ofport_dpif *ofport) +{ + struct mport *mport = NULL; + struct mport *node; + + HMAP_FOR_EACH_WITH_HASH (node, hmap_node, hash_pointer(ofport, 0), + &monitor.hmap) { + if (node->ofport == ofport) { + mport = node; + break; + } + } + return mport; +} + + +/* Checks bfd and cfm status to determine if the port is capable of + * forwarding data traffic. If bfd and cfm are not configured, + * return true. */ +bool +ofproto_dpif_monitor_check_alive(const struct ofport_dpif *ofport) +{ + struct mport *mport = mport_find(ofport); + bool cfm_enable = false; + bool bfd_enable = false; + + if (!mport) { + return true; + } + + if (mport->cfm) { + int cfm_opup = cfm_get_opup(mport->cfm); + + cfm_enable = !cfm_get_fault(mport->cfm); + + if (cfm_opup >= 0) { + cfm_enable = cfm_enable && cfm_opup; + } + } + if (mport->bfd) { + bfd_enable = bfd_forwarding(mport->bfd); + } + return cfm_enable || bfd_enable; +} + +/* Checks if the bfd flow should be processed. */ +bool +ofproto_dpif_monitor_should_process_bfd(const struct ofport_dpif *ofport, + const struct flow *flow, + struct flow_wildcards *wc) +{ + struct mport *mport = mport_find(ofport); + + if (mport && mport->bfd) { + return bfd_should_process_flow(mport->bfd, flow, wc); + } + return false; +} + +/* Checks if the cfm flow should be processed. */ +bool +ofproto_dpif_monitor_should_process_cfm(const struct ofport_dpif *ofport, + const struct flow *flow, + struct flow_wildcards *wc) +{ + struct mport *mport = mport_find(ofport); + + if (mport && mport->cfm) { + return cfm_should_process_flow(mport->cfm, flow, wc); + } + return false; +} + +/* Processes the bfd flow. */ +void +ofproto_dpif_monitor_process_bfd(const struct ofport_dpif *ofport, + const struct flow *flow, + const struct ofpbuf *packet) +{ + struct mport *mport = mport_find(ofport); + if (mport) { + bfd_process_packet(mport->bfd, flow, packet); + } +} + +/* Processes the CFM control packet. */ +void +ofproto_dpif_monitor_process_cfm(const struct ofport_dpif *ofport, + const struct ofpbuf *packet) +{ + struct mport *mport = mport_find(ofport); + if (mport) { + cfm_process_heartbeat(mport->cfm, packet); + } +} + +/* Starts the monitor, makes sure the init() function is called only once. */ +void +ofproto_dpif_monitor_start(void) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + + if (ovsthread_once_start(&once)) { + ofproto_dpif_monitor_init(); + ovsthread_once_done(&once); + } +} + +/* Sets bfd on ofport. Returns 1 if new bfd struct is created or deleted, + * and 0 if bfd is reconfigured. */ +int +ofproto_dpif_monitor_set_bfd(const struct ofport_dpif *ofport, + const struct smap *cfg, + struct netdev *netdev, uint8_t *hw_addr) +{ + struct mport *mport = mport_find(ofport); + struct bfd *old_bfd, *new_bfd; + int retval = 0; + + old_bfd = mport ? mport->bfd : NULL; + new_bfd = bfd_configure(old_bfd, netdev_get_name(netdev), cfg, netdev); + + if (old_bfd != new_bfd) { + if (!old_bfd) { + /* New bfd struct created. */ + if (!mport) { + mport = mport_create(ofport); + mport->hw_addr = hw_addr; + } + mport->bfd = new_bfd; + } else { + /* bfd struct deleted. */ + mport->bfd = new_bfd; + mport_check_delete(mport); + } + retval = 1; + } + + return retval; +} + +/* Sets cfm on ofport. Returns 1 if new cfm struct is created or deleted, + * 0 if cfm is reconfigured or -EINVAL if there is an error. */ +int +ofproto_dpif_monitor_set_cfm(const struct ofport_dpif *ofport, + const struct cfm_settings *s, + struct netdev *netdev, uint8_t *hw_addr) +{ + struct mport *mport = mport_find(ofport); + int retval = 0; + + if (s) { + if (!mport) { + mport = mport_create(ofport); + mport->hw_addr = hw_addr; + } + if (!mport->cfm) { + mport->cfm = cfm_create(netdev); + retval = 1; + } + if (cfm_configure(mport->cfm, s)) { + return retval; + } + } + + /* If reaches here, either 's' is NULL or cfm_configure() + * returns false. */ + if (mport) { + cfm_unref(mport->cfm); + mport->cfm = NULL; + mport_check_delete(mport); + } + + retval = -EINVAL; + return retval; +} + +/* Extracts the bfd status and stores it in 'smap'. */ +int +ofproto_dpif_monitor_get_bfd_status(const struct ofport_dpif *ofport, + struct smap *smap) +{ + struct mport *mport = mport_find(ofport); + + if (!mport || !mport->bfd) { + return ENOENT; + } + bfd_get_status(mport->bfd, smap); + + return 0; +} + +/* Extracts the cfm status and stores it in 'status'. */ +bool +ofproto_dpif_monitor_get_cfm_status(const struct ofport_dpif *ofport, + struct ofproto_cfm_status *status) +{ + struct mport *mport = mport_find(ofport); + + if (!mport || !mport->cfm) { + return false; + } + status->faults = cfm_get_fault(mport->cfm); + status->remote_opstate = cfm_get_opup(mport->cfm); + status->health = cfm_get_health(mport->cfm); + cfm_get_remote_mpids(mport->cfm, &status->rmps, &status->n_rmps); + return true; +} + + +/* Updates the netdev and hw_addr. */ +void +ofproto_dpif_monitor_set_netdev(const struct ofport_dpif *ofport, + struct netdev *netdev, + uint8_t *hw_addr) +{ + struct mport *mport = mport_find(ofport); + + if (!mport) { + return; + } else { + mport->hw_addr = hw_addr; + if (mport->bfd) { + bfd_set_netdev(mport->bfd, netdev); + } + if (mport->cfm) { + cfm_set_netdev(mport->cfm, netdev); + } + } +} + +/* Checks the sending of control packets on all mports. Sends the control + * packets if needed. */ +void +ofproto_dpif_monitor_run_fast(void) +{ + struct mport *mport; + + HMAP_FOR_EACH (mport, hmap_node, &monitor.hmap) { + if (mport->cfm && cfm_should_send_ccm(mport->cfm)) { + struct ofpbuf packet; + + ofpbuf_init(&packet, 0); + cfm_compose_ccm(mport->cfm, &packet, mport->hw_addr); + ofproto_dpif_send_packet(mport->ofport, &packet); + ofpbuf_uninit(&packet); + } + + if (mport->bfd && bfd_should_send_packet(mport->bfd)) { + struct ofpbuf packet; + + ofpbuf_init(&packet, 0); + bfd_put_packet(mport->bfd, &packet, mport->hw_addr); + ofproto_dpif_send_packet(mport->ofport, &packet); + ofpbuf_uninit(&packet); + } + } +} + +/* Executes bfd_run(), cfm_run() on all mports. */ +void +ofproto_dpif_monitor_run(void) +{ + struct mport *mport; + + HMAP_FOR_EACH (mport, hmap_node, &monitor.hmap) { + if (mport->cfm) { + cfm_run(mport->cfm); + } + + if (mport->bfd) { + bfd_run(mport->bfd); + } + } +} + +/* Executes the bfd_wait() and cfm_wait() functions on all mports. */ +void +ofproto_dpif_monitor_wait(void) +{ + struct mport *mport; + + HMAP_FOR_EACH (mport, hmap_node, &monitor.hmap) { + if (mport->cfm) { + cfm_wait(mport->cfm); + } + + if (mport->bfd) { + bfd_wait(mport->bfd); + } + } +} diff --git a/ofproto/ofproto-dpif-monitor.h b/ofproto/ofproto-dpif-monitor.h new file mode 100644 index 0000000..169973e --- /dev/null +++ b/ofproto/ofproto-dpif-monitor.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * + * 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 OFPROTO_DPIF_MONITOR_H +#define OFPROTO_DPIF_MONITOR_H 1 + +#include "ofp-util.h" + +struct bfd; +struct cfm; +struct cfm_settings; +struct flow; +struct ofpbuf; +struct ofproto_cfm_status; +struct ofport_dpif; + +void ofproto_dpif_monitor_start(void); +void ofproto_dpif_monitor_run(void); +void ofproto_dpif_monitor_run_fast(void); +void ofproto_dpif_monitor_wait(void); + +bool ofproto_dpif_monitor_check_alive(const struct ofport_dpif *ofport); + +void ofproto_dpif_monitor_process_bfd(const struct ofport_dpif *ofport, + const struct flow *flow, + const struct ofpbuf *packet); +void ofproto_dpif_monitor_process_cfm(const struct ofport_dpif *ofport, + const struct ofpbuf *packet); +bool ofproto_dpif_monitor_should_process_bfd(const struct ofport_dpif *ofport, + const struct flow *flow, + struct flow_wildcards *wc); +bool ofproto_dpif_monitor_should_process_cfm(const struct ofport_dpif *ofport, + const struct flow *flow, + struct flow_wildcards *wc); + +int ofproto_dpif_monitor_get_bfd_status(const struct ofport_dpif *, + struct smap *); +bool ofproto_dpif_monitor_get_cfm_status(const struct ofport_dpif *, + struct ofproto_cfm_status *); +int ofproto_dpif_monitor_set_bfd(const struct ofport_dpif *, + const struct smap *, + struct netdev *, uint8_t *); +int ofproto_dpif_monitor_set_cfm(const struct ofport_dpif *, + const struct cfm_settings *, + struct netdev *, uint8_t *); +void ofproto_dpif_monitor_set_netdev(const struct ofport_dpif *, + struct netdev *, + uint8_t *); +#endif /* ofproto-dpif-monitor.h */ diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index a5b6814..5d9297e 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -18,12 +18,10 @@ #include <errno.h> -#include "bfd.h" #include "bitmap.h" #include "bond.h" #include "bundle.h" #include "byte-order.h" -#include "cfm.h" #include "connmgr.h" #include "coverage.h" #include "dpif.h" @@ -42,6 +40,7 @@ #include "ofp-actions.h" #include "ofproto/ofproto-dpif-ipfix.h" #include "ofproto/ofproto-dpif-mirror.h" +#include "ofproto/ofproto-dpif-monitor.h" #include "ofproto/ofproto-dpif-sflow.h" #include "ofproto/ofproto-dpif.h" #include "ofproto/ofproto-provider.h" @@ -128,9 +127,6 @@ struct xport { bool may_enable; /* May be enabled in bonds. */ bool is_tunnel; /* Is a tunnel port. */ - - struct cfm *cfm; /* CFM handle or null. */ - struct bfd *bfd; /* BFD handle or null. */ }; struct xlate_ctx { @@ -368,7 +364,6 @@ void xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle, struct ofport_dpif *ofport, ofp_port_t ofp_port, odp_port_t odp_port, const struct netdev *netdev, - const struct cfm *cfm, const struct bfd *bfd, struct ofport_dpif *peer, int stp_port_no, const struct ofproto_port_queue *qdscp_list, size_t n_qdscp, enum ofputil_port_config config, bool is_tunnel, @@ -402,16 +397,6 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle, xport->netdev = netdev_ref(netdev); } - if (xport->cfm != cfm) { - cfm_unref(xport->cfm); - xport->cfm = cfm_ref(cfm); - } - - if (xport->bfd != bfd) { - bfd_unref(xport->bfd); - xport->bfd = bfd_ref(bfd); - } - if (xport->peer) { xport->peer->peer = NULL; } @@ -471,8 +456,6 @@ xlate_ofport_remove(struct ofport_dpif *ofport) hmap_remove(&xport->xbridge->xports, &xport->ofp_node); netdev_close(xport->netdev); - cfm_unref(xport->cfm); - bfd_unref(xport->bfd); free(xport); } @@ -1493,14 +1476,14 @@ process_special(struct xlate_ctx *ctx, const struct flow *flow, if (!xport) { return 0; - } else if (xport->cfm && cfm_should_process_flow(xport->cfm, flow, wc)) { + } else if (ofproto_dpif_monitor_should_process_cfm(xport->ofport, flow, wc)) { if (packet) { - cfm_process_heartbeat(xport->cfm, packet); + ofproto_dpif_monitor_process_cfm(xport->ofport, packet); } return SLOW_CFM; - } else if (xport->bfd && bfd_should_process_flow(xport->bfd, flow, wc)) { + } else if (ofproto_dpif_monitor_should_process_bfd(xport->ofport, flow, wc)) { if (packet) { - bfd_process_packet(xport->bfd, flow, packet); + ofproto_dpif_monitor_process_bfd(xport->ofport, flow, packet); } return SLOW_BFD; } else if (xport->xbundle && xport->xbundle->lacp diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index a54a9e4..8768ad3 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -24,7 +24,6 @@ #include "ofproto.h" #include "stp.h" -struct bfd; struct bond; struct dpif; struct lacp; @@ -133,8 +132,7 @@ void xlate_bundle_remove(struct ofbundle *) OVS_REQ_WRLOCK(xlate_rwlock); void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *, struct ofport_dpif *, ofp_port_t, odp_port_t, - const struct netdev *, const struct cfm *, - const struct bfd *, struct ofport_dpif *peer, + const struct netdev *, struct ofport_dpif *peer, int stp_port_no, const struct ofproto_port_queue *qdscp, size_t n_qdscp, enum ofputil_port_config, bool is_tunnel, bool may_enable) OVS_REQ_WRLOCK(xlate_rwlock); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 80874b8..ee107a9 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -21,13 +21,11 @@ #include <errno.h> -#include "bfd.h" #include "bond.h" #include "bundle.h" #include "byte-order.h" #include "connmgr.h" #include "coverage.h" -#include "cfm.h" #include "dpif.h" #include "dynamic-string.h" #include "fail-open.h" @@ -52,6 +50,7 @@ #include "ofproto-dpif-governor.h" #include "ofproto-dpif-ipfix.h" #include "ofproto-dpif-mirror.h" +#include "ofproto-dpif-monitor.h" #include "ofproto-dpif-sflow.h" #include "ofproto-dpif-upcall.h" #include "ofproto-dpif-xlate.h" @@ -304,8 +303,6 @@ struct ofport_dpif { odp_port_t odp_port; struct ofbundle *bundle; /* Bundle that contains this port, if any. */ struct list bundle_node; /* In struct ofbundle's "ports" list. */ - struct cfm *cfm; /* Connectivity Fault Management, if any. */ - struct bfd *bfd; /* BFD, if any. */ bool may_enable; /* May be enabled in bonds. */ bool is_tunnel; /* This port is a tunnel. */ long long int carrier_seq; /* Carrier status changes. */ @@ -360,8 +357,6 @@ ofport_dpif_cast(const struct ofport *ofport) } static void port_run(struct ofport_dpif *); -static void port_run_fast(struct ofport_dpif *); -static void port_wait(struct ofport_dpif *); static int set_bfd(struct ofport *, const struct smap *); static int set_cfm(struct ofport *, const struct cfm_settings *); static void ofport_update_peer(struct ofport_dpif *); @@ -540,9 +535,6 @@ static int expire(struct dpif_backer *); /* NetFlow. */ static void send_netflow_active_timeouts(struct ofproto_dpif *); -/* Utilities. */ -static int send_packet(const struct ofport_dpif *, struct ofpbuf *packet); - /* Global variables. */ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -816,8 +808,7 @@ type_run(const char *type) : -1; xlate_ofport_set(ofproto, ofport->bundle, ofport, ofport->up.ofp_port, ofport->odp_port, - ofport->up.netdev, ofport->cfm, - ofport->bfd, ofport->peer, stp_port, + ofport->up.netdev, ofport->peer, stp_port, ofport->qdscp, ofport->n_qdscp, ofport->up.pp.config, ofport->is_tunnel, ofport->may_enable); @@ -1244,6 +1235,8 @@ construct(struct ofproto *ofproto_) return error; } + ofproto_dpif_monitor_start(); + max_ports = dpif_get_max_ports(ofproto->backer->dpif); ofproto_init_max_ports(ofproto_, MIN(max_ports, ofp_to_u16(OFPP_MAX))); @@ -1452,7 +1445,6 @@ run_fast(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct ofputil_packet_in *pin, *next_pin; - struct ofport_dpif *ofport; struct list pins; /* Do not perform any periodic activity required by 'ofproto' while @@ -1468,10 +1460,7 @@ run_fast(struct ofproto *ofproto_) free(CONST_CAST(void *, pin->packet)); free(pin); } - - HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { - port_run_fast(ofport); - } + ofproto_dpif_monitor_run_fast(); return 0; } @@ -1514,6 +1503,8 @@ run(struct ofproto *ofproto_) dpif_ipfix_run(ofproto->ipfix); } + ofproto_dpif_monitor_run_fast(); + ofproto_dpif_monitor_run(); HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { port_run(ofport); } @@ -1558,7 +1549,6 @@ static void wait(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); - struct ofport_dpif *ofport; struct ofbundle *bundle; if (ofproto_get_flow_restore_wait()) { @@ -1571,9 +1561,8 @@ wait(struct ofproto *ofproto_) if (ofproto->ipfix) { dpif_ipfix_wait(ofproto->ipfix); } - HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { - port_wait(ofport); - } + + ofproto_dpif_monitor_wait(); HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { bundle_wait(bundle); } @@ -1708,8 +1697,6 @@ port_construct(struct ofport *port_) ofproto->backer->need_revalidate = REV_RECONFIGURE; port->bundle = NULL; - port->cfm = NULL; - port->bfd = NULL; port->may_enable = true; port->stp_port = NULL; port->stp_state = STP_DISABLED; @@ -1828,13 +1815,7 @@ port_modified(struct ofport *port_) bond_slave_set_netdev(port->bundle->bond, port, port->up.netdev); } - if (port->cfm) { - cfm_set_netdev(port->cfm, port->up.netdev); - } - - if (port->bfd) { - bfd_set_netdev(port->bfd, port->up.netdev); - } + ofproto_dpif_monitor_set_netdev(port, port->up.netdev, port->up.pp.hw_addr); if (port->is_tunnel && tnl_port_reconfigure(port, port->up.netdev, port->odp_port)) { @@ -1926,27 +1907,17 @@ static int set_cfm(struct ofport *ofport_, const struct cfm_settings *s) { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport_->ofproto); int error; - if (!s) { + error = ofproto_dpif_monitor_set_cfm(ofport, s, ofport->up.netdev, + ofport->up.pp.hw_addr); + if (error > 0) { error = 0; - } else { - if (!ofport->cfm) { - struct ofproto_dpif *ofproto; - - ofproto = ofproto_dpif_cast(ofport->up.ofproto); - ofproto->backer->need_revalidate = REV_RECONFIGURE; - ofport->cfm = cfm_create(ofport->up.netdev); - } - - if (cfm_configure(ofport->cfm, s)) { - return 0; - } - - error = EINVAL; + ofproto->backer->need_revalidate = REV_RECONFIGURE; + } else if (error < 0) { + error = -error; } - cfm_unref(ofport->cfm); - ofport->cfm = NULL; return error; } @@ -1956,15 +1927,7 @@ get_cfm_status(const struct ofport *ofport_, { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); - if (ofport->cfm) { - status->faults = cfm_get_fault(ofport->cfm); - status->remote_opstate = cfm_get_opup(ofport->cfm); - status->health = cfm_get_health(ofport->cfm); - cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps); - return true; - } else { - return false; - } + return ofproto_dpif_monitor_get_cfm_status(ofport, status); } static int @@ -1972,15 +1935,14 @@ set_bfd(struct ofport *ofport_, const struct smap *cfg) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport_->ofproto); struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); - struct bfd *old; + int error; - old = ofport->bfd; - ofport->bfd = bfd_configure(old, netdev_get_name(ofport->up.netdev), - cfg, ofport->up.netdev); - if (ofport->bfd != old) { + error = ofproto_dpif_monitor_set_bfd(ofport, cfg, ofport->up.netdev, + ofport->up.pp.hw_addr); + if (error > 0) { + error = 0; ofproto->backer->need_revalidate = REV_RECONFIGURE; } - return 0; } @@ -1989,12 +1951,7 @@ get_bfd_status(struct ofport *ofport_, struct smap *smap) { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); - if (ofport->bfd) { - bfd_get_status(ofport->bfd, smap); - return 0; - } else { - return ENOENT; - } + return ofproto_dpif_monitor_get_bfd_status(ofport, smap); } /* Spanning Tree. */ @@ -2018,7 +1975,7 @@ send_bpdu_cb(struct ofpbuf *pkt, int port_num, void *ofproto_) VLOG_WARN_RL(&rl, "%s: cannot send BPDU on port %d " "with unknown MAC", ofproto->up.name, port_num); } else { - send_packet(ofport, pkt); + ofproto_dpif_send_packet(ofport, pkt); } } ofpbuf_delete(pkt); @@ -2614,7 +2571,7 @@ send_pdu_cb(void *port_, const void *pdu, size_t pdu_size) pdu_size); memcpy(packet_pdu, pdu, pdu_size); - send_packet(port, &packet); + ofproto_dpif_send_packet(port, &packet); ofpbuf_uninit(&packet); } else { VLOG_ERR_RL(&rl, "port %s: cannot obtain Ethernet address of iface " @@ -2651,7 +2608,7 @@ bundle_send_learning_packets(struct ofbundle *bundle) LIST_FOR_EACH (learning_packet, list_node, &packets) { int ret; - ret = send_packet(learning_packet->private_p, learning_packet); + ret = ofproto_dpif_send_packet(learning_packet->private_p, learning_packet); if (ret) { error = ret; n_errors++; @@ -2866,59 +2823,15 @@ ofport_update_peer(struct ofport_dpif *ofport) } static void -port_run_fast(struct ofport_dpif *ofport) -{ - if (ofport->cfm && cfm_should_send_ccm(ofport->cfm)) { - struct ofpbuf packet; - - ofpbuf_init(&packet, 0); - cfm_compose_ccm(ofport->cfm, &packet, ofport->up.pp.hw_addr); - send_packet(ofport, &packet); - ofpbuf_uninit(&packet); - } - - if (ofport->bfd && bfd_should_send_packet(ofport->bfd)) { - struct ofpbuf packet; - - ofpbuf_init(&packet, 0); - bfd_put_packet(ofport->bfd, &packet, ofport->up.pp.hw_addr); - send_packet(ofport, &packet); - ofpbuf_uninit(&packet); - } -} - -static void port_run(struct ofport_dpif *ofport) { long long int carrier_seq = netdev_get_carrier_resets(ofport->up.netdev); bool carrier_changed = carrier_seq != ofport->carrier_seq; bool enable = netdev_get_carrier(ofport->up.netdev); - bool cfm_enable = false; - bool bfd_enable = false; ofport->carrier_seq = carrier_seq; - port_run_fast(ofport); - - if (ofport->cfm) { - int cfm_opup = cfm_get_opup(ofport->cfm); - - cfm_run(ofport->cfm); - cfm_enable = !cfm_get_fault(ofport->cfm); - - if (cfm_opup >= 0) { - cfm_enable = cfm_enable && cfm_opup; - } - } - - if (ofport->bfd) { - bfd_run(ofport->bfd); - bfd_enable = bfd_forwarding(ofport->bfd); - } - - if (ofport->bfd || ofport->cfm) { - enable = enable && (cfm_enable || bfd_enable); - } + enable = enable && ofproto_dpif_monitor_check_alive(ofport); if (ofport->bundle) { enable = enable && lacp_slave_may_enable(ofport->bundle->lacp, ofport); @@ -2926,7 +2839,6 @@ port_run(struct ofport_dpif *ofport) lacp_slave_carrier_changed(ofport->bundle->lacp, ofport); } } - if (ofport->may_enable != enable) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto); ofproto->backer->need_revalidate = REV_PORT_TOGGLED; @@ -2935,18 +2847,6 @@ port_run(struct ofport_dpif *ofport) ofport->may_enable = enable; } -static void -port_wait(struct ofport_dpif *ofport) -{ - if (ofport->cfm) { - cfm_wait(ofport->cfm); - } - - if (ofport->bfd) { - bfd_wait(ofport->bfd); - } -} - static int port_query_by_name(const struct ofproto *ofproto_, const char *devname, struct ofproto_port *ofproto_port) @@ -4945,8 +4845,8 @@ rule_modify_actions(struct rule *rule_, bool reset_counters) /* Sends 'packet' out 'ofport'. * May modify 'packet'. * Returns 0 if successful, otherwise a positive errno value. */ -static int -send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) +int +ofproto_dpif_send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto); uint64_t odp_actions_stub[1024 / 8]; diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 14a9669..8727551 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -95,6 +95,8 @@ bool vsp_adjust_flow(const struct ofproto_dpif *, struct flow *); void ofproto_dpif_send_packet_in(struct ofproto_dpif *, struct ofputil_packet_in *pin); +int ofproto_dpif_send_packet(const struct ofport_dpif *ofport, + struct ofpbuf *packet); void ofproto_dpif_flow_mod(struct ofproto_dpif *, struct ofputil_flow_mod *); struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); diff --git a/tests/bfd.at b/tests/bfd.at index 0b2b7cc..db6c6f5 100644 --- a/tests/bfd.at +++ b/tests/bfd.at @@ -248,267 +248,6 @@ This flow is handled by the userspace slow path because it: OVS_VSWITCHD_STOP AT_CLEANUP -# Tests below are for bfd decay features. -AT_SETUP([bfd - bfd decay]) -OVS_VSWITCHD_START([add-br br1 -- set bridge br1 datapath-type=dummy -- \ - add-port br1 p1 -- set Interface p1 type=patch \ - options:peer=p0 ofport_request=2 -- \ - add-port br0 p0 -- set Interface p0 type=patch \ - options:peer=p1 ofport_request=1 -- \ - set Interface p0 bfd:enable=true bfd:min_tx=300 bfd:min_rx=300 bfd:decay_min_rx=3000 -- \ - set Interface p1 bfd:enable=true bfd:min_tx=500 bfd:min_rx=500]) - -ovs-appctl time/stop - -# wait for local session state to go from down to up. -for i in `seq 0 1`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [init], [No Diagnostic]) - - -# Test-1 BFD decay: decay to decay_min_rx -# bfd:decay_min_rx is set to 3000ms after the local state of p0 goes up, -# so for the first 2500ms, there should be no change. -for i in `seq 0 4`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) - -# advance the clock by 500ms. -ovs-appctl time/warp 500 -# now at 3000ms, min_rx should decay to 3000ms and there should be -# poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) - -# since the tx_min of p0 is still 500ms, after 500ms from decay, -# the control message will be sent from p0 to p1, and p1 'flag' -# will go back to none. -ovs-appctl time/warp 500 -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - -# the rx_min of p0 is 3000ms now, and p1 will send next control message -# 3000ms after decay. so, advance clock by 2500ms to make that happen. -for i in `seq 0 4`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) -# End of Test-1 ############################################################### - - -# Test-2 BFD decay: go back to cfg_min_rx when there is traffic -# receive packet at 1/100ms rate for 3000ms. -for i in `seq 0 30` -do - ovs-appctl time/warp 100 - AT_CHECK([ovs-ofctl packet-out br1 3 2 "90e2ba01475000101856b2e80806000108000604000100101856b2e80202020300000000000002020202"], - [0], [stdout], []) -done -# after a decay interval (3000ms), the p0 min_rx will go back to -# cfg_min_rx. there should be poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) - -# 500ms later, both direction will send control messages, -# and their 'flag' will go back to none. -ovs-appctl time/warp 500 -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) -# End of Test-2 ############################################################### - - -# Test-3 BFD decay: go back to cfg_min_rx when decay_min_rx is changed -# advance the clock by 2500ms to 3000m after restore of -# min_rx. p0 is decayed, and there should be the poll sequence flags. -for i in `seq 0 4`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) - -# advance the clock, to make 'flag' go back to none. -for i in `seq 0 5`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - -# change decay_min_rx to 1000ms. -# for decay_min_rx < 2000ms, the decay detection time is set to 2000ms. -# this should firstly reset the min_rx and start poll sequence. -AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=1000]) -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) - -# for the following 1500ms, there should be no decay, -# since the decay_detect_time is set to 2000ms. -for i in `seq 0 2` -do - ovs-appctl time/warp 500 - BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) - BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) -done - -ovs-appctl time/warp 500 -# at 2000ms, decay should happen and there should be the poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [1000ms], [1000ms], [500ms]) -# advance the clock, so 'flag' go back to none. -for i in `seq 0 4`; do ovs-appctl time/warp 500; done -# End of Test-3 ############################################################### - - -# Test-4 BFD decay: set min_rx to 800ms. -# this should firstly reset the min_rx and then re-decay to 1000ms. -AT_CHECK([ovs-vsctl set Interface p0 bfd:min_rx=800]) -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [800ms], [800ms], [500ms]) - -# for the following 1600ms, there should be no decay, -# since the decay detection time is set to 2000ms. -for i in `seq 0 1` -do - ovs-appctl time/warp 800 - BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) - BFD_CHECK_RX([p0], [800ms], [800ms], [500ms]) -done - -ovs-appctl time/warp 400 -# at 2000ms, decay should happen and there should be the poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [1000ms], [1000ms], [500ms]) -# advance the clock, so 'flag' go back to none. -for i in `seq 0 4`; do ovs-appctl time/warp 500; done -# End of Test-4 ############################################################### - - -# Test-5 BFD decay: set min_rx to 300ms and decay_min_rx to 5000ms together. -AT_CHECK([ovs-vsctl set Interface p0 bfd:min_rx=300 bfd:decay_min_rx=5000]) -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) - -# for decay_min_rx > 2000ms, the decay detection time is set to -# decay_min_rx (5000ms). -# for the following 4500ms, there should be no decay, -# since the decay detection time is set to 5000ms. -for i in `seq 0 8` -do - ovs-appctl time/warp 500 - BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) - BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) -done - -ovs-appctl time/warp 500 -# at 5000ms, decay should happen and there should be the poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [5000ms], [5000ms], [500ms]) -# advance the clock, to make 'flag' go back to none. -for i in `seq 0 9`; do ovs-appctl time/warp 500; done -# End of Test-5 ############################################################### - - -# Test-6 BFD decay: set decay_min_rx to 0 to disable bfd decay. -AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=0]) -# min_rx is reset, and there should be the poll sequence flags. -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) -for i in `seq 0 20` -do - ovs-appctl time/warp 500 - BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) - BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) -done -# End of Test-6 ################################################################ - - -# Test-7 BFD decay: rmt_min_tx is greater than decay_min_rx -AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=3000 -- set interface p1 bfd:min_tx=5000]) -# there will be poll sequences from both sides. and it is hard to determine the -# order. so just skip 10000ms and check the RX/TX. at that time, p0 should be in decay already. -for i in `seq 0 19`; do echo $i; ovs-appctl bfd/show; ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [5000ms]) -BFD_CHECK_RX([p0], [5000ms], [3000ms], [500ms]) -# then, there should be no change of status, -for i in `seq 0 9` -do - ovs-appctl time/warp 500 - BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) - BFD_CHECK_TX([p0], [500ms], [300ms], [5000ms]) - BFD_CHECK_RX([p0], [5000ms], [3000ms], [500ms]) -done -# reset the p1's min_tx to 500ms. -AT_CHECK([ovs-vsctl set Interface p1 bfd:min_tx=500]) -# check the poll sequence. since p0 has been in decay, now the RX will show 3000ms. -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [final], [up], [No Diagnostic]) -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) -# advance the clock by 3000ms, at that time, p1 will send the control packets. -# then there will be no poll flags. -for i in `seq 0 5`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) -# End of Test-7 ############################################################### - - -# Test-8 BFD decay: state up->down->up. -# turn bfd off on p1 -AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=false]) - -# check the state change of bfd on p0. After 9000 ms (3 min_rx intervals) -for i in `seq 0 8`; do ovs-appctl time/warp 1000; done -BFD_CHECK([p0], [false], [false], [none], [down], [Control Detection Time Expired], [none], [down], [No Diagnostic]) -BFD_CHECK_TX([p0], [1000ms], [1000ms], [0ms]) -BFD_CHECK_RX([p0], [300ms], [300ms], [1ms]) - -# resume the bfd on p1. the bfd should not go to decay mode direclty. -AT_CHECK([ovs-vsctl set Interface p1 bfd:enable=true]) -for i in `seq 0 1`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [none], [up], [No Diagnostic]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms]) - -# since the decay_min_rx is still 3000ms, so after 3000ms, there should be the decay and poll sequence. -for i in `seq 0 5`; do ovs-appctl time/warp 500; done -BFD_CHECK([p0], [true], [false], [none], [up], [Control Detection Time Expired], [final], [up], [No Diagnostic]) -BFD_CHECK([p1], [true], [false], [none], [up], [No Diagnostic], [poll], [up], [Control Detection Time Expired]) -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms]) -BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms]) -# End of Test-8 ################################################################ - -OVS_VSWITCHD_STOP -AT_CLEANUP - # Tests below are for bfd forwarding_if_rx feature. # forwarding_if_rx Test1: bfd is enabled on one end of link. AT_SETUP([bfd - bfd forwarding_if_rx 1]) -- 1.7.9.5 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
