X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fcfm.c;h=a504714cf5540e89f69db34e113634504960e0d4;hb=76ea8efd442a403f8e874cd4103dafe2479b6a57;hp=f6cfb2e675ef2edfa5d2bf94cbf055e7312561a9;hpb=6fabb78d45211260c388979baab5b757ec76e33e;p=openvswitch diff --git a/lib/cfm.c b/lib/cfm.c index f6cfb2e6..a504714c 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -67,6 +67,20 @@ ccm_interval_to_ms(uint8_t interval) NOT_REACHED(); } +static long long int +cfm_fault_interval(struct cfm_internal *cfmi) +{ + /* According to the 802.1ag specification we should assume every other MP + * with the same MAID has the same transmission interval that we have. If + * an MP has a different interval, cfm_process_heartbeat will register it + * as a fault (likely due to a configuration error). Thus we can check all + * MPs at once making this quite a bit simpler. + * + * According to the specification we should check when (ccm_interval_ms * + * 3.5)ms have passed. */ + return (cfmi->ccm_interval_ms * 7) / 2; +} + static uint8_t ms_to_ccm_interval(int interval_ms) { @@ -156,25 +170,18 @@ cfm_run(struct cfm *cfm) { long long now = time_msec(); struct cfm_internal *cfmi = cfm_to_internal(cfm); - long long fault_interval; - /* According to the 802.1ag specification we should assume every other MP - * with the same MAID has the same transmission interval that we have. If - * an MP has a different interval, cfm_process_heartbeat will register it - * as a fault (likely due to a configuration error). Thus we can check all - * MPs at once making this quite a bit simpler. - * - * According to the specification we should check when (ccm_interval_ms * - * 3.5)ms have passed. */ - fault_interval = (cfmi->ccm_interval_ms * 7) / 2; if (timer_expired(&cfmi->fault_timer)) { bool fault; struct remote_mp *rmp; + long long int interval; - fault = now < cfmi->x_recv_time + fault_interval; + interval = cfm_fault_interval(cfmi); + fault = now < cfmi->x_recv_time + interval; HMAP_FOR_EACH (rmp, node, &cfm->remote_mps) { - if (timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) { + if (rmp->recv_time < timer_enabled_at(&cfmi->fault_timer, interval) + || timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) { rmp->fault = true; } @@ -184,7 +191,7 @@ cfm_run(struct cfm *cfm) } cfm->fault = fault; - timer_set_duration(&cfmi->fault_timer, fault_interval); + timer_set_duration(&cfmi->fault_timer, interval); } } @@ -230,19 +237,23 @@ cfm_wait(struct cfm *cfm) bool cfm_configure(struct cfm *cfm) { - struct cfm_internal *cfmi; + struct cfm_internal *cfmi = cfm_to_internal(cfm); + uint8_t interval; if (!cfm_is_valid_mpid(cfm->mpid) || !cfm->interval) { return false; } - cfmi = cfm_to_internal(cfm); - cfmi->ccm_interval = ms_to_ccm_interval(cfm->interval); - cfmi->ccm_interval_ms = ccm_interval_to_ms(cfmi->ccm_interval); + interval = ms_to_ccm_interval(cfm->interval); + + if (interval != cfmi->ccm_interval) { + cfmi->ccm_interval = interval; + cfmi->ccm_interval_ms = ccm_interval_to_ms(interval); + + timer_set_expired(&cfmi->tx_timer); + timer_set_duration(&cfmi->fault_timer, cfm_fault_interval(cfmi)); + } - /* Force a resend and check in case anything changed. */ - timer_set_expired(&cfmi->tx_timer); - timer_set_expired(&cfmi->fault_timer); return true; }