mirror of
https://github.com/openvswitch/ovs
synced 2025-10-27 15:18:06 +00:00
cfm: Support random VLAN tag for CCM PDUs.
CCM PDUs may take a different path through the network depending on the VLAN tag they carry. In order to exercise these paths, it may be advantageous to use a random VLAN tag. Signed-off-by: Ethan Jackson <ethan@nicira.com>
This commit is contained in:
16
lib/cfm.c
16
lib/cfm.c
@@ -30,6 +30,7 @@
|
|||||||
#include "ofpbuf.h"
|
#include "ofpbuf.h"
|
||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "poll-loop.h"
|
#include "poll-loop.h"
|
||||||
|
#include "random.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "timeval.h"
|
#include "timeval.h"
|
||||||
#include "unixctl.h"
|
#include "unixctl.h"
|
||||||
@@ -96,7 +97,8 @@ struct cfm {
|
|||||||
uint32_t seq; /* The sequence number of our last CCM. */
|
uint32_t seq; /* The sequence number of our last CCM. */
|
||||||
uint8_t ccm_interval; /* The CCM transmission interval. */
|
uint8_t ccm_interval; /* The CCM transmission interval. */
|
||||||
int ccm_interval_ms; /* 'ccm_interval' in milliseconds. */
|
int ccm_interval_ms; /* 'ccm_interval' in milliseconds. */
|
||||||
uint16_t ccm_vlan; /* Vlan tag of CCM PDUs. */
|
uint16_t ccm_vlan; /* Vlan tag of CCM PDUs. CFM_RANDOM_VLAN if
|
||||||
|
random. */
|
||||||
uint8_t ccm_pcp; /* Priority of CCM PDUs. */
|
uint8_t ccm_pcp; /* Priority of CCM PDUs. */
|
||||||
uint8_t maid[CCM_MAID_LEN]; /* The MAID of this CFM. */
|
uint8_t maid[CCM_MAID_LEN]; /* The MAID of this CFM. */
|
||||||
|
|
||||||
@@ -391,13 +393,19 @@ void
|
|||||||
cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
|
cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
|
||||||
uint8_t eth_src[ETH_ADDR_LEN])
|
uint8_t eth_src[ETH_ADDR_LEN])
|
||||||
{
|
{
|
||||||
|
uint16_t ccm_vlan;
|
||||||
struct ccm *ccm;
|
struct ccm *ccm;
|
||||||
|
|
||||||
timer_set_duration(&cfm->tx_timer, cfm->ccm_interval_ms);
|
timer_set_duration(&cfm->tx_timer, cfm->ccm_interval_ms);
|
||||||
eth_compose(packet, cfm_ccm_addr(cfm), eth_src, ETH_TYPE_CFM, sizeof *ccm);
|
eth_compose(packet, cfm_ccm_addr(cfm), eth_src, ETH_TYPE_CFM, sizeof *ccm);
|
||||||
|
|
||||||
if (cfm->ccm_vlan || cfm->ccm_pcp) {
|
ccm_vlan = (cfm->ccm_vlan != CFM_RANDOM_VLAN
|
||||||
uint16_t tci = cfm->ccm_vlan | (cfm->ccm_pcp << VLAN_PCP_SHIFT);
|
? cfm->ccm_vlan
|
||||||
|
: random_uint16());
|
||||||
|
ccm_vlan = ccm_vlan & VLAN_VID_MASK;
|
||||||
|
|
||||||
|
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(tci));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +463,7 @@ cfm_configure(struct cfm *cfm, const struct cfm_settings *s)
|
|||||||
interval = ms_to_ccm_interval(s->interval);
|
interval = ms_to_ccm_interval(s->interval);
|
||||||
interval_ms = ccm_interval_to_ms(interval);
|
interval_ms = ccm_interval_to_ms(interval);
|
||||||
|
|
||||||
cfm->ccm_vlan = s->ccm_vlan & VLAN_VID_MASK;
|
cfm->ccm_vlan = s->ccm_vlan;
|
||||||
cfm->ccm_pcp = s->ccm_pcp & (VLAN_PCP_MASK >> VLAN_PCP_SHIFT);
|
cfm->ccm_pcp = s->ccm_pcp & (VLAN_PCP_MASK >> VLAN_PCP_SHIFT);
|
||||||
if (cfm->extended && interval_ms != s->interval) {
|
if (cfm->extended && interval_ms != s->interval) {
|
||||||
interval = 0;
|
interval = 0;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
struct flow;
|
struct flow;
|
||||||
struct ofpbuf;
|
struct ofpbuf;
|
||||||
|
|
||||||
|
#define CFM_RANDOM_VLAN UINT16_MAX
|
||||||
|
|
||||||
#define CFM_FAULT_REASONS \
|
#define CFM_FAULT_REASONS \
|
||||||
CFM_FAULT_REASON(RECV, recv) \
|
CFM_FAULT_REASON(RECV, recv) \
|
||||||
CFM_FAULT_REASON(RDI, rdi) \
|
CFM_FAULT_REASON(RDI, rdi) \
|
||||||
@@ -51,7 +53,8 @@ struct cfm_settings {
|
|||||||
int interval; /* The requested transmission interval. */
|
int interval; /* The requested transmission interval. */
|
||||||
bool extended; /* Run in extended mode. */
|
bool extended; /* Run in extended mode. */
|
||||||
bool opup; /* Operational State. */
|
bool opup; /* Operational State. */
|
||||||
uint16_t ccm_vlan; /* CCM Vlan tag. Zero if none. */
|
uint16_t ccm_vlan; /* CCM Vlan tag. Zero if none.
|
||||||
|
CFM_RANDOM_VLAN if random. */
|
||||||
uint8_t ccm_pcp; /* CCM Priority. Zero if none. */
|
uint8_t ccm_pcp; /* CCM Priority. Zero if none. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3226,6 +3226,7 @@ iface_configure_cfm(struct iface *iface)
|
|||||||
{
|
{
|
||||||
const struct ovsrec_interface *cfg = iface->cfg;
|
const struct ovsrec_interface *cfg = iface->cfg;
|
||||||
const char *extended_str, *opstate_str;
|
const char *extended_str, *opstate_str;
|
||||||
|
const char *cfm_ccm_vlan;
|
||||||
struct cfm_settings s;
|
struct cfm_settings s;
|
||||||
|
|
||||||
if (!cfg->n_cfm_mpid) {
|
if (!cfg->n_cfm_mpid) {
|
||||||
@@ -3236,14 +3237,22 @@ iface_configure_cfm(struct iface *iface)
|
|||||||
s.mpid = *cfg->cfm_mpid;
|
s.mpid = *cfg->cfm_mpid;
|
||||||
s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
|
s.interval = atoi(get_interface_other_config(iface->cfg, "cfm_interval",
|
||||||
"0"));
|
"0"));
|
||||||
s.ccm_vlan = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_vlan",
|
cfm_ccm_vlan = get_interface_other_config(iface->cfg, "cfm_ccm_vlan", "0");
|
||||||
"0"));
|
|
||||||
s.ccm_pcp = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_pcp",
|
s.ccm_pcp = atoi(get_interface_other_config(iface->cfg, "cfm_ccm_pcp",
|
||||||
"0"));
|
"0"));
|
||||||
if (s.interval <= 0) {
|
if (s.interval <= 0) {
|
||||||
s.interval = 1000;
|
s.interval = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp("random", cfm_ccm_vlan)) {
|
||||||
|
s.ccm_vlan = CFM_RANDOM_VLAN;
|
||||||
|
} else {
|
||||||
|
s.ccm_vlan = atoi(cfm_ccm_vlan);
|
||||||
|
if (s.ccm_vlan == CFM_RANDOM_VLAN) {
|
||||||
|
s.ccm_vlan = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extended_str = get_interface_other_config(iface->cfg, "cfm_extended",
|
extended_str = get_interface_other_config(iface->cfg, "cfm_extended",
|
||||||
"false");
|
"false");
|
||||||
s.extended = !strcasecmp("true", extended_str);
|
s.extended = !strcasecmp("true", extended_str);
|
||||||
|
|||||||
@@ -1766,7 +1766,8 @@
|
|||||||
<column name="other_config" key="cfm_ccm_vlan"
|
<column name="other_config" key="cfm_ccm_vlan"
|
||||||
type='{"type": "integer", "minInteger": 1, "maxInteger": 4095}'>
|
type='{"type": "integer", "minInteger": 1, "maxInteger": 4095}'>
|
||||||
When set, the CFM module will apply a VLAN tag to all CCMs it generates
|
When set, the CFM module will apply a VLAN tag to all CCMs it generates
|
||||||
with the given value.
|
with the given value. May be the string <code>random</code> in which
|
||||||
|
case each CCM will be tagged with a different randomly generated VLAN.
|
||||||
</column>
|
</column>
|
||||||
|
|
||||||
<column name="other_config" key="cfm_ccm_pcp"
|
<column name="other_config" key="cfm_ccm_pcp"
|
||||||
|
|||||||
Reference in New Issue
Block a user