BFD: Add check_tnl_key feature to BFD code.
authorPavithra Ramesh <paramesh@vmware.com>
Tue, 16 Jul 2013 09:58:42 +0000 (09:58 +0000)
committerEthan Jackson <ethan@nicira.com>
Tue, 16 Jul 2013 02:22:54 +0000 (19:22 -0700)
This change adds the check_tnl_key functionality for BFD.
When the feature is enabled, BFD will only accept control
packets with a tunnel key of 0.

Signed-off-by: Pavithra Ramesh <paramesh@vmware.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
lib/bfd.c
lib/bfd.h
ofproto/ofproto-dpif-xlate.c
vswitchd/vswitch.xml

index aa1a3f7..a06611a 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -58,10 +58,6 @@ VLOG_DEFINE_THIS_MODULE(bfd);
  *
  * - Set TOS/PCP on inner BFD frame, and outer tunnel header when encapped.
  *
- * - CFM "check_tnl_key" option equivalent.
- *
- * - CFM "fault override" equivalent.
- *
  * - Sending BFD messages should be in its own thread/process.
  *
  * - Scale testing.  How does it operate when there are large number of bfd
@@ -182,6 +178,7 @@ struct bfd {
 
     int ref_cnt;
     int forwarding_override;      /* Manual override of 'forwarding' status. */
+    bool check_tnl_key;           /* Verify tunnel key of inbound packets? */
 };
 
 static bool bfd_in_poll(const struct bfd *);
@@ -287,6 +284,7 @@ bfd_configure(struct bfd *bfd, const char *name,
         bfd_set_state(bfd, STATE_DOWN, DIAG_NONE);
     }
 
+    bfd->check_tnl_key = smap_get_bool(cfg, "check_tnl_key", false);
     min_tx = smap_get_int(cfg, "min_tx", 100);
     min_tx = MAX(min_tx, 100);
     if (bfd->cfg_min_tx != min_tx) {
@@ -449,13 +447,18 @@ bfd_put_packet(struct bfd *bfd, struct ofpbuf *p,
 }
 
 bool
-bfd_should_process_flow(const struct flow *flow, struct flow_wildcards *wc)
+bfd_should_process_flow(const struct bfd *bfd, const struct flow *flow,
+                        struct flow_wildcards *wc)
 {
     memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
     memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
+    if (bfd->check_tnl_key) {
+        memset(&wc->masks.tunnel.tun_id, 0xff, sizeof wc->masks.tunnel.tun_id);
+    }
     return (flow->dl_type == htons(ETH_TYPE_IP)
             && flow->nw_proto == IPPROTO_UDP
-            && flow->tp_dst == htons(3784));
+            && flow->tp_dst == htons(3784)
+            && (!bfd->check_tnl_key || flow->tunnel.tun_id == htonl(0)));
 }
 
 void
index ab854d8..67d012e 100644 (file)
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -34,7 +34,8 @@ bool bfd_should_send_packet(const struct bfd *);
 void bfd_put_packet(struct bfd *bfd, struct ofpbuf *packet,
                     uint8_t eth_src[6]);
 
-bool bfd_should_process_flow(const struct flow *, struct flow_wildcards *);
+bool bfd_should_process_flow(const struct bfd *, const struct flow *,
+                             struct flow_wildcards *);
 void bfd_process_packet(struct bfd *, const struct flow *,
                         const struct ofpbuf *);
 
index 84677a1..0507f8e 100644 (file)
@@ -1193,7 +1193,7 @@ process_special(struct xlate_ctx *ctx, const struct flow *flow,
             cfm_process_heartbeat(xport->cfm, packet);
         }
         return SLOW_CFM;
-    } else if (xport->bfd && bfd_should_process_flow(flow, wc)) {
+    } else if (xport->bfd && bfd_should_process_flow(xport->bfd, flow, wc)) {
         if (packet) {
             bfd_process_packet(xport->bfd, flow, packet);
         }
index 3385912..957b02c 100644 (file)
           <code>false</code>.
       </column>
 
+      <column name="bfd" key="check_tnl_key" type='{"type": "boolean"}'>
+          When set to true, Check Tunnel Key will make BFD only accept control
+          messages with an <code>in_key</code> of zero. Defaults to
+          <code>false</code>.
+      </column>
+
       <column name="bfd_status" key="state"
           type='{"type": "string",
           "enum": ["set", ["admin_down", "down", "init", "up"]]}'>