/*
- * Copyright (c) 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 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.
static unixctl_cb_func cfm_unixctl_set_fault;
static uint64_t
-cfm_rx_packets(const struct cfm *cfm) OVS_REQ_WRLOCK(mutex)
+cfm_rx_packets(const struct cfm *cfm) OVS_REQUIRES(mutex)
{
struct netdev_stats stats;
}
static const uint8_t *
-cfm_ccm_addr(const struct cfm *cfm)
+cfm_ccm_addr(struct cfm *cfm)
{
bool extended;
atomic_read(&cfm->extended, &extended);
}
static void
-cfm_generate_maid(struct cfm *cfm) OVS_REQ_WRLOCK(mutex)
+cfm_generate_maid(struct cfm *cfm) OVS_REQUIRES(mutex)
{
const char *ovs_md_name = "ovs";
const char *ovs_ma_name = "ovs";
}
static long long int
-cfm_fault_interval(struct cfm *cfm) OVS_REQ_WRLOCK(mutex)
+cfm_fault_interval(struct cfm *cfm) OVS_REQUIRES(mutex)
{
/* 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
}
static struct remote_mp *
-lookup_remote_mp(const struct cfm *cfm, uint64_t mpid) OVS_REQ_WRLOCK(mutex)
+lookup_remote_mp(const struct cfm *cfm, uint64_t mpid) OVS_REQUIRES(mutex)
{
struct remote_mp *rmp;
struct remote_mp *rmp, *rmp_next;
bool old_cfm_fault = cfm->fault;
bool demand_override;
+ bool rmp_set_opup = false;
+ bool rmp_set_opdown = false;
cfm->fault = cfm->recv_fault;
cfm->recv_fault = 0;
cfm->rmps_array = xmalloc(hmap_count(&cfm->remote_mps) *
sizeof *cfm->rmps_array);
- cfm->remote_opup = true;
if (cfm->health_interval == CFM_HEALTH_INTERVAL) {
/* Calculate the cfm health of the interface. If the number of
* remote_mpids of a cfm interface is > 1, the cfm health is
} else {
rmp->recv = false;
- if (!rmp->opup) {
- cfm->remote_opup = rmp->opup;
+ if (rmp->opup) {
+ rmp_set_opup = true;
+ } else {
+ rmp_set_opdown = true;
}
cfm->rmps_array[cfm->rmps_array_len++] = rmp->mpid;
}
}
+ if (rmp_set_opdown) {
+ cfm->remote_opup = false;
+ }
+ else if (rmp_set_opup) {
+ cfm->remote_opup = true;
+ }
+
if (hmap_is_empty(&cfm->remote_mps)) {
cfm->fault |= CFM_FAULT_RECV;
}
/* Returns true if 'cfm' should process packets from 'flow'. Sets
* fields in 'wc' that were used to make the determination. */
bool
-cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow,
+cfm_should_process_flow(const struct cfm *cfm_, const struct flow *flow,
struct flow_wildcards *wc)
{
+ struct cfm *cfm = CONST_CAST(struct cfm *, cfm_);
bool check_tnl_key;
atomic_read(&cfm->check_tnl_key, &check_tnl_key);
}
static int
-cfm_get_fault__(const struct cfm *cfm) OVS_REQ_WRLOCK(mutex)
+cfm_get_fault__(const struct cfm *cfm) OVS_REQUIRES(mutex)
{
if (cfm->fault_override >= 0) {
return cfm->fault_override ? CFM_FAULT_OVERRIDE : 0;
* '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) OVS_EXCLUDED(mutex)
+cfm_get_opup(const struct cfm *cfm_) OVS_EXCLUDED(mutex)
{
+ struct cfm *cfm = CONST_CAST(struct cfm *, cfm_);
bool extended;
int opup;
}
static struct cfm *
-cfm_find(const char *name) OVS_REQ_WRLOCK(&mutex)
+cfm_find(const char *name) OVS_REQUIRES(mutex)
{
struct cfm *cfm;
}
static void
-cfm_print_details(struct ds *ds, const struct cfm *cfm) OVS_REQ_WRLOCK(&mutex)
+cfm_print_details(struct ds *ds, struct cfm *cfm) OVS_REQUIRES(mutex)
{
struct remote_mp *rmp;
bool extended;
void *aux OVS_UNUSED) OVS_EXCLUDED(mutex)
{
struct ds ds = DS_EMPTY_INITIALIZER;
- const struct cfm *cfm;
+ struct cfm *cfm;
ovs_mutex_lock(&mutex);
if (argc > 1) {