X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fcfm.c;h=ff460195b0805eefd0d9c12daa4276695a58f297;hb=5382a3cf9be0632c83cff17f08c9b46036a8ad88;hp=9c65b3489ddae24897b49aa23369fa73b224ef4e;hpb=fb668e3a13eaa07bbb8bc50cbee1d201051b779c;p=sliver-openvswitch.git diff --git a/lib/cfm.c b/lib/cfm.c index 9c65b3489..ff460195b 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include #include "byte-order.h" +#include "connectivity.h" #include "dynamic-string.h" #include "flow.h" #include "hash.h" @@ -31,6 +32,7 @@ #include "packets.h" #include "poll-loop.h" #include "random.h" +#include "seq.h" #include "timer.h" #include "timeval.h" #include "unixctl.h" @@ -128,7 +130,7 @@ struct cfm { atomic_bool check_tnl_key; /* Verify the tunnel key of inbound packets? */ atomic_bool extended; /* Extended mode. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; uint64_t flap_count; /* Count the flaps since boot. */ }; @@ -234,7 +236,7 @@ static int ccm_interval_to_ms(uint8_t interval) { switch (interval) { - case 0: NOT_REACHED(); /* Explicitly not supported by 802.1ag. */ + case 0: OVS_NOT_REACHED(); /* Explicitly not supported by 802.1ag. */ case 1: return 3; /* Not recommended due to timer resolution. */ case 2: return 10; /* Not recommended due to timer resolution. */ case 3: return 100; @@ -242,10 +244,10 @@ ccm_interval_to_ms(uint8_t interval) case 5: return 10000; case 6: return 60000; case 7: return 600000; - default: NOT_REACHED(); /* Explicitly not supported by 802.1ag. */ + default: OVS_NOT_REACHED(); /* Explicitly not supported by 802.1ag. */ } - NOT_REACHED(); + OVS_NOT_REACHED(); } static long long int @@ -335,7 +337,7 @@ cfm_create(const struct netdev *netdev) OVS_EXCLUDED(mutex) cfm->flap_count = 0; atomic_init(&cfm->extended, false); atomic_init(&cfm->check_tnl_key, false); - atomic_init(&cfm->ref_cnt, 1); + ovs_refcount_init(&cfm->ref_cnt); ovs_mutex_lock(&mutex); cfm_generate_maid(cfm); @@ -348,15 +350,12 @@ void cfm_unref(struct cfm *cfm) OVS_EXCLUDED(mutex) { struct remote_mp *rmp, *rmp_next; - int orig; if (!cfm) { return; } - atomic_sub(&cfm->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig != 1) { + if (ovs_refcount_unref(&cfm->ref_cnt) != 1) { return; } @@ -372,6 +371,7 @@ cfm_unref(struct cfm *cfm) OVS_EXCLUDED(mutex) hmap_destroy(&cfm->remote_mps); netdev_close(cfm->netdev); free(cfm->rmps_array); + free(cfm); } @@ -380,9 +380,7 @@ cfm_ref(const struct cfm *cfm_) { struct cfm *cfm = CONST_CAST(struct cfm *, cfm_); if (cfm) { - int orig; - atomic_add(&cfm->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&cfm->ref_cnt); } return cfm; } @@ -395,7 +393,12 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) if (timer_expired(&cfm->fault_timer)) { long long int interval = cfm_fault_interval(cfm); struct remote_mp *rmp, *rmp_next; - bool old_cfm_fault = cfm->fault; + enum cfm_fault_reason old_cfm_fault = cfm->fault; + uint64_t old_flap_count = cfm->flap_count; + int old_health = cfm->health; + size_t old_rmps_array_len = cfm->rmps_array_len; + bool old_rmps_deleted = false; + bool old_rmp_opup = cfm->remote_opup; bool demand_override; bool rmp_set_opup = false; bool rmp_set_opdown = false; @@ -453,6 +456,7 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) " %lldms", cfm->name, rmp->mpid, time_msec() - rmp->last_rx); if (!demand_override) { + old_rmps_deleted = true; hmap_remove(&cfm->remote_mps, &rmp->node); free(rmp); } @@ -494,11 +498,21 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex) } /* If there is a flap, increments the counter. */ - if (old_cfm_fault == false || cfm->fault == false) { + if (old_cfm_fault == 0 || cfm->fault == 0) { cfm->flap_count++; } } + /* These variables represent the cfm session status, it is desirable + * to update them to database immediately after change. */ + if (old_health != cfm->health + || old_rmp_opup != cfm->remote_opup + || (old_rmps_array_len != cfm->rmps_array_len || old_rmps_deleted) + || old_cfm_fault != cfm->fault + || old_flap_count != cfm->flap_count) { + seq_change(connectivity_seq_get()); + } + cfm->booted = true; timer_set_duration(&cfm->fault_timer, interval); VLOG_DBG("%s: new fault interval", cfm->name); @@ -540,7 +554,7 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet, if (ccm_vlan || cfm->ccm_pcp) { uint16_t tci = ccm_vlan | (cfm->ccm_pcp << VLAN_PCP_SHIFT); - eth_push_vlan(packet, htons(tci)); + eth_push_vlan(packet, htons(ETH_TYPE_VLAN), htons(tci)); } ccm = packet->l3; @@ -1020,6 +1034,7 @@ cfm_unixctl_set_fault(struct unixctl_conn *conn, int argc, const char *argv[], } } + seq_change(connectivity_seq_get()); unixctl_command_reply(conn, "OK"); out: