[ovs-dev] [PATCH 1/2] cfm: Scope CFM packets to key zero.

Ethan Jackson ethan at nicira.com
Sat Oct 13 02:40:22 UTC 2012


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 <ethan at nicira.com>
---
 lib/cfm.c         |  5 ++++-
 lib/cfm.h         |  2 ++
 vswitchd/bridge.c | 12 ++++++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/lib/cfm.c b/lib/cfm.c
index fc999ab..b71c242 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 de4c299..8bb6778 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 d161c4c..5908e10 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");
-- 
1.7.12




More information about the dev mailing list