git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
lacp: Make the LACP module thread safe.
[sliver-openvswitch.git]
/
lib
/
cfm.c
diff --git
a/lib/cfm.c
b/lib/cfm.c
index
64ad18c
..
a76a3ec
100644
(file)
--- a/
lib/cfm.c
+++ b/
lib/cfm.c
@@
-61,6
+61,8
@@
static const uint8_t eth_addr_ccm_x[6] = {
#define CCM_OPCODE 1 /* CFM message opcode meaning CCM. */
#define CCM_RDI_MASK 0x80
#define CFM_HEALTH_INTERVAL 6
#define CCM_OPCODE 1 /* CFM message opcode meaning CCM. */
#define CCM_RDI_MASK 0x80
#define CFM_HEALTH_INTERVAL 6
+
+OVS_PACKED(
struct ccm {
uint8_t mdlevel_version; /* MD Level and Version */
uint8_t opcode;
struct ccm {
uint8_t mdlevel_version; /* MD Level and Version */
uint8_t opcode;
@@
-78,7
+80,7
@@
struct ccm {
/* TLV space. */
uint8_t end_tlv;
/* TLV space. */
uint8_t end_tlv;
-}
__attribute__((packed)
);
+});
BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm));
struct cfm {
BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm));
struct cfm {
@@
-125,6
+127,8
@@
struct cfm {
int health_interval; /* Number of fault_intervals since health was
recomputed. */
long long int last_tx; /* Last CCM transmission time. */
int health_interval; /* Number of fault_intervals since health was
recomputed. */
long long int last_tx; /* Last CCM transmission time. */
+
+ int ref_cnt;
};
/* Remote MPs represent foreign network entities that are configured to have
};
/* Remote MPs represent foreign network entities that are configured to have
@@
-318,11
+322,12
@@
cfm_create(const struct netdev *netdev)
cfm->fault_override = -1;
cfm->health = -1;
cfm->last_tx = 0;
cfm->fault_override = -1;
cfm->health = -1;
cfm->last_tx = 0;
+ cfm->ref_cnt = 1;
return cfm;
}
void
return cfm;
}
void
-cfm_
destroy
(struct cfm *cfm)
+cfm_
unref
(struct cfm *cfm)
{
struct remote_mp *rmp, *rmp_next;
{
struct remote_mp *rmp, *rmp_next;
@@
-330,6
+335,11
@@
cfm_destroy(struct cfm *cfm)
return;
}
return;
}
+ ovs_assert(cfm->ref_cnt);
+ if (--cfm->ref_cnt) {
+ return;
+ }
+
HMAP_FOR_EACH_SAFE (rmp, rmp_next, node, &cfm->remote_mps) {
hmap_remove(&cfm->remote_mps, &rmp->node);
free(rmp);
HMAP_FOR_EACH_SAFE (rmp, rmp_next, node, &cfm->remote_mps) {
hmap_remove(&cfm->remote_mps, &rmp->node);
free(rmp);
@@
-342,6
+352,17
@@
cfm_destroy(struct cfm *cfm)
free(cfm);
}
free(cfm);
}
+struct cfm *
+cfm_ref(const struct cfm *cfm_)
+{
+ struct cfm *cfm = CONST_CAST(struct cfm *, cfm_);
+ if (cfm) {
+ ovs_assert(cfm->ref_cnt > 0);
+ cfm->ref_cnt++;
+ }
+ return cfm;
+}
+
/* Should be run periodically to update fault statistics messages. */
void
cfm_run(struct cfm *cfm)
/* Should be run periodically to update fault statistics messages. */
void
cfm_run(struct cfm *cfm)
@@
-577,10
+598,16
@@
cfm_set_netdev(struct cfm *cfm, const struct netdev *netdev)
}
}
}
}
-/* Returns true if 'cfm' should process packets from 'flow'. */
+/* Returns true if 'cfm' should process packets from 'flow'. Sets
+ * fields in 'wc' that were used to make the determination. */
bool
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)
{
{
+ memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
+ if (cfm->check_tnl_key) {
+ memset(&wc->masks.tunnel.tun_id, 0xff, sizeof wc->masks.tunnel.tun_id);
+ }
return (ntohs(flow->dl_type) == ETH_TYPE_CFM
&& eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))
&& (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0)));
return (ntohs(flow->dl_type) == ETH_TYPE_CFM
&& eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))
&& (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0)));