From: Ethan Jackson Date: Fri, 12 Oct 2012 20:19:35 +0000 (-0700) Subject: cfm: Scope CFM packets to key zero. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b363bae4f802a07efec6e012075caf915e1e4fe5;p=openvswitch cfm: Scope CFM packets to key zero. Before this patch, when a tunnel is configured with key=flow, CFM didn't verify that incoming packets had the appropriate key of zero. This could cause the CFM module to consume packets which weren't actually intended for it. Bug #13542. Signed-off-by: Ethan Jackson --- diff --git a/lib/cfm.c b/lib/cfm.c index fc999ab2..b71c242a 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -86,6 +86,7 @@ struct cfm { struct hmap_node hmap_node; /* Node in all_cfms list. */ uint64_t mpid; + bool check_tnl_key; /* Verify the tunnel key of inbound packets? */ bool extended; /* Extended mode. */ bool booted; /* A full fault interval has occured. */ enum cfm_fault_reason fault; /* Connectivity fault status. */ @@ -505,6 +506,7 @@ cfm_configure(struct cfm *cfm, const struct cfm_settings *s) } cfm->mpid = s->mpid; + cfm->check_tnl_key = s->check_tnl_key; cfm->extended = s->extended; cfm->opup = s->opup; interval = ms_to_ccm_interval(s->interval); @@ -533,7 +535,8 @@ bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow) { return (ntohs(flow->dl_type) == ETH_TYPE_CFM - && eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))); + && eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm)) + && (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0))); } /* Updates internal statistics relevant to packet 'p'. Should be called on diff --git a/lib/cfm.h b/lib/cfm.h index de4c2992..8bb67784 100644 --- a/lib/cfm.h +++ b/lib/cfm.h @@ -57,6 +57,8 @@ struct cfm_settings { uint16_t ccm_vlan; /* CCM Vlan tag. Zero if none. CFM_RANDOM_VLAN if random. */ uint8_t ccm_pcp; /* CCM Priority. Zero if none. */ + + bool check_tnl_key; /* Verify inbound packet key? */ }; void cfm_init(void); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index b9df794d..a481f061 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -3312,12 +3312,24 @@ iface_configure_cfm(struct iface *iface) const char *opstate_str; const char *cfm_ccm_vlan; struct cfm_settings s; + struct smap netdev_args; if (!cfg->n_cfm_mpid) { ofproto_port_clear_cfm(iface->port->bridge->ofproto, iface->ofp_port); return; } + s.check_tnl_key = false; + smap_init(&netdev_args); + if (!netdev_get_config(iface->netdev, &netdev_args)) { + const char *key = smap_get(&netdev_args, "key"); + const char *in_key = smap_get(&netdev_args, "in_key"); + + s.check_tnl_key = (key && !strcmp(key, "flow")) + || (in_key && !strcmp(in_key, "flow")); + } + smap_destroy(&netdev_args); + s.mpid = *cfg->cfm_mpid; s.interval = smap_get_int(&iface->cfg->other_config, "cfm_interval", 0); cfm_ccm_vlan = smap_get(&iface->cfg->other_config, "cfm_ccm_vlan"); diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 464afa16..e9ea0c4c 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -1718,6 +1718,12 @@ faulted otherwise.

+

+ When operating over tunnels which have no in_key, or an + in_key of flow. CFM will only accept CCMs + with a tunnel key of zero. +

+ A Maintenance Point ID (MPID) uniquely identifies each endpoint within a Maintenance Association. The MPID is used to identify this endpoint @@ -1873,7 +1879,7 @@ When set, the CFM module will apply a VLAN tag to all CCMs it generates - with the given PCP value. The VLAN ID of the tag is governed by the + with the given PCP value, the VLAN ID of the tag is governed by the value of . If is unset, a VLAN ID of zero is used.