BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm));
struct cfm {
- uint16_t mpid;
- struct list list_node; /* Node in all_cfms list. */
+ char *name; /* Name of this CFM object. */
+ struct hmap_node hmap_node; /* Node in all_cfms list. */
+ uint16_t mpid;
bool fault; /* Indicates connectivity fault. */
bool recv_fault; /* Indicates an inability to receive CCMs. */
- char *name; /* Name of this CFM object. */
uint32_t seq; /* The sequence number of our last CCM. */
uint8_t ccm_interval; /* The CCM transmission interval. */
};
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
-static struct list all_cfms = LIST_INITIALIZER(&all_cfms);
+static struct hmap all_cfms = HMAP_INITIALIZER(&all_cfms);
static void cfm_unixctl_show(struct unixctl_conn *, const char *args,
void *aux);
unixctl_command_register("cfm/show", cfm_unixctl_show, NULL);
}
-/* Allocates a 'cfm' object. This object should have its 'mpid', 'maid',
- * 'eth_src', and 'interval' filled out. cfm_configure() should be called
- * whenever changes are made to 'cfm', and before cfm_run() is called for the
- * first time. */
+/* Allocates a 'cfm' object called 'name'. 'cfm' should be initialized by
+ * cfm_configure() before use. */
struct cfm *
-cfm_create(void)
+cfm_create(const char *name)
{
struct cfm *cfm;
cfm = xzalloc(sizeof *cfm);
+ cfm->name = xstrdup(name);
hmap_init(&cfm->remote_mps);
cfm_generate_maid(cfm);
- list_push_back(&all_cfms, &cfm->list_node);
+ hmap_insert(&all_cfms, &cfm->hmap_node, hash_string(cfm->name, 0));
return cfm;
}
}
hmap_destroy(&cfm->remote_mps);
- list_remove(&cfm->list_node);
+ hmap_remove(&all_cfms, &cfm->hmap_node);
+ free(cfm->name);
free(cfm);
}
cfm->mpid = s->mpid;
interval = ms_to_ccm_interval(s->interval);
- if (!cfm->name || strcmp(s->name, cfm->name)) {
- free(cfm->name);
- cfm->name = xstrdup(s->name);
- }
-
if (interval != cfm->ccm_interval) {
cfm->ccm_interval = interval;
cfm->ccm_interval_ms = ccm_interval_to_ms(interval);
{
struct cfm *cfm;
- LIST_FOR_EACH (cfm, list_node, &all_cfms) {
- if (cfm->name && !strcmp(cfm->name, name)) {
+ HMAP_FOR_EACH_WITH_HASH (cfm, hmap_node, hash_string(name, 0), &all_cfms) {
+ if (!strcmp(cfm->name, name)) {
return cfm;
}
}
struct cfm_settings {
uint16_t mpid; /* The MPID of this CFM. */
int interval; /* The requested transmission interval. */
- const char *name; /* Name of this CFM object. */
const uint16_t *remote_mpids; /* Array of remote MPIDs */
size_t n_remote_mpids; /* Number of MPIDs in 'remote_mpids'. */
};
void cfm_init(void);
-struct cfm *cfm_create(void);
+struct cfm *cfm_create(const char *name);
void cfm_destroy(struct cfm *);
void cfm_run(struct cfm *);
bool cfm_should_send_ccm(struct cfm *);