X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fcfm.c;h=d232b34f18211ae95a115fbf641463932e45222a;hb=f31282b9c152d5e993c8fe0068b7a4ed8c8d98c8;hp=65701781a3c8e734e4273ca31b22c4a667d80009;hpb=c3f72482ba4d375d2dd32de6f58ed4cdcef37ddd;p=sliver-openvswitch.git diff --git a/lib/cfm.c b/lib/cfm.c index 65701781a..d232b34f1 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -17,7 +17,6 @@ #include #include "cfm.h" -#include #include #include #include @@ -86,7 +85,9 @@ struct cfm { struct hmap_node hmap_node; /* Node in all_cfms list. */ uint64_t mpid; + bool check_tnl_key; /* Verify the tunnel key of inbound packets? */ bool extended; /* Extended mode. */ + bool booted; /* A full fault interval has occured. */ enum cfm_fault_reason fault; /* Connectivity fault status. */ enum cfm_fault_reason recv_fault; /* Bit mask of faults occuring on receive. */ @@ -188,7 +189,7 @@ cfm_generate_maid(struct cfm *cfm) md_len = strlen(ovs_md_name); ma_len = strlen(ovs_ma_name); - assert(md_len && ma_len && md_len + ma_len + 4 <= CCM_MAID_LEN); + ovs_assert(md_len && ma_len && md_len + ma_len + 4 <= CCM_MAID_LEN); cfm->maid[0] = 4; /* MD name string format. */ cfm->maid[1] = md_len; /* MD name size. */ @@ -366,7 +367,7 @@ cfm_run(struct cfm *cfm) cfm->health = (rmp->num_health_ccm * 100) / exp_ccm_recvd; cfm->health = MIN(cfm->health, 100); rmp->num_health_ccm = 0; - assert(cfm->health >= 0 && cfm->health <= 100); + ovs_assert(cfm->health >= 0 && cfm->health <= 100); } cfm->health_interval = 0; } @@ -407,6 +408,7 @@ cfm_run(struct cfm *cfm) ds_destroy(&ds); } + cfm->booted = true; timer_set_duration(&cfm->fault_timer, interval); VLOG_DBG("%s: new fault interval", cfm->name); } @@ -463,13 +465,13 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet, } if (cfm->ccm_interval == 0) { - assert(cfm->extended); + ovs_assert(cfm->extended); ccm->interval_ms_x = htons(cfm->ccm_interval_ms); } else { ccm->interval_ms_x = htons(0); } - if (hmap_is_empty(&cfm->remote_mps)) { + if (cfm->booted && hmap_is_empty(&cfm->remote_mps)) { ccm->flags |= CCM_RDI_MASK; } @@ -503,6 +505,7 @@ cfm_configure(struct cfm *cfm, const struct cfm_settings *s) } cfm->mpid = s->mpid; + cfm->check_tnl_key = s->check_tnl_key; cfm->extended = s->extended; cfm->opup = s->opup; interval = ms_to_ccm_interval(s->interval); @@ -531,7 +534,8 @@ bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow) { return (ntohs(flow->dl_type) == ETH_TYPE_CFM - && eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))); + && eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm)) + && (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0))); } /* Updates internal statistics relevant to packet 'p'. Should be called on @@ -682,12 +686,17 @@ cfm_get_health(const struct cfm *cfm) /* Gets the operational state of 'cfm'. 'cfm' is considered operationally down * if it has received a CCM with the operationally down bit set from any of its - * remote maintenance points. Returns true if 'cfm' is operationally up. False - * otherwise. */ -bool + * remote maintenance points. Returns 1 if 'cfm' is operationally up, 0 if + * 'cfm' is operationally down, or -1 if 'cfm' has no operational state + * (because it isn't in extended mode). */ +int cfm_get_opup(const struct cfm *cfm) { - return cfm->remote_opup; + if (cfm->extended) { + return cfm->remote_opup; + } else { + return -1; + } } /* Populates 'rmps' with an array of remote maintenance points reachable by