]> git.proxmox.com Git - ovs.git/commitdiff
ofproto: Add support to watch controller port liveness in fast-failover group
authorVishal Deep Ajmera <vishal.deep.ajmera@ericsson.com>
Mon, 3 Feb 2020 10:32:46 +0000 (11:32 +0100)
committerBen Pfaff <blp@ovn.org>
Fri, 6 Mar 2020 21:25:23 +0000 (13:25 -0800)
Currently fast-failover group does not support checking liveness of controller
port (OFPP_CONTROLLER). However this feature can be useful for selecting
alternate pipeline when controller connection itself is down for e.g.
by using local DHCP server to reply for any DHCP request originating from VMs.

This patch adds the support for watching controller port liveness in fast-
failover group. Controller port is considered live when atleast one
of-connection is alive.

Example usage:

ovs-ofctl add-group br-int 'group_id=1234,type=ff,
          bucket=watch_port:CONTROLLER,actions:<A>,
          bucket=watch_port:1,actions:<B>

Signed-off-by: Vishal Deep Ajmera <vishal.deep.ajmera@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
NEWS
lib/ofp-group.c
ofproto/ofproto-dpif-xlate.c
ofproto/ofproto-dpif.c
ofproto/ofproto-dpif.h
ofproto/ofproto.c

diff --git a/NEWS b/NEWS
index 8710a02338b691a7a7f8209f423f7a2f1299d339..872e1863ce872bfa167e6d3e59b57618f5390177 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Post-v2.13.0
    - OpenFlow:
      * The OpenFlow ofp_desc/serial_num may now be configured by setting the
        value of other-config:dp-sn in the Bridge table.
+     * Added support to watch CONTROLLER port status in fast failover group.
    - DPDK:
      * Deprecated DPDK pdump packet capture support removed.
      * Deprecated DPDK ring ports (dpdkr) are no longer supported.
index b675e802c3171af3196babe90a2459fd584e5999..bf0f8af544c9a18c3a368253a63a045eb365aec3 100644 (file)
@@ -660,7 +660,8 @@ parse_bucket_str(struct ofputil_bucket *bucket, char *str_,
         } else if (!strcasecmp(key, "watch_port")) {
             if (!ofputil_port_from_string(value, port_map, &bucket->watch_port)
                 || (ofp_to_u16(bucket->watch_port) >= ofp_to_u16(OFPP_MAX)
-                    && bucket->watch_port != OFPP_ANY)) {
+                    && bucket->watch_port != OFPP_ANY
+                    && bucket->watch_port != OFPP_CONTROLLER)) {
                 error = xasprintf("%s: invalid watch_port", value);
             }
         } else if (!strcasecmp(key, "watch_group")) {
index 0b45ecf3d4dadd2ce412a7f5174a9ed339da2f24..adf57a5e8929951c7a1c7d0bbcaafc56adec5002 100644 (file)
@@ -1888,9 +1888,12 @@ bucket_is_alive(const struct xlate_ctx *ctx,
 
     return (!ofputil_bucket_has_liveness(bucket)
             || (bucket->watch_port != OFPP_ANY
+               && bucket->watch_port != OFPP_CONTROLLER
                && odp_port_is_alive(ctx, bucket->watch_port))
             || (bucket->watch_group != OFPG_ANY
-               && group_is_alive(ctx, bucket->watch_group, depth + 1)));
+               && group_is_alive(ctx, bucket->watch_group, depth + 1))
+            || (bucket->watch_port == OFPP_CONTROLLER
+               && ofproto_is_alive(&ctx->xbridge->ofproto->up)));
 }
 
 static void
index d56cece95e909423932fe43cd38e5b4c3c5dcfd0..d21874b466f8987d000e9a6c29332976ec706bd9 100644 (file)
@@ -1800,6 +1800,7 @@ run(struct ofproto *ofproto_)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     uint64_t new_seq, new_dump_seq;
+    bool is_connected;
 
     if (mbridge_need_revalidate(ofproto->mbridge)) {
         ofproto->backer->need_revalidate = REV_RECONFIGURE;
@@ -1868,6 +1869,15 @@ run(struct ofproto *ofproto_)
         ofproto->backer->need_revalidate = REV_MCAST_SNOOPING;
     }
 
+    /* Check if controller connection is toggled. */
+    is_connected = ofproto_is_alive(&ofproto->up);
+    if (ofproto->is_controller_connected != is_connected) {
+        ofproto->is_controller_connected = is_connected;
+        /* Trigger revalidation as fast failover group monitoring
+         * controller port may need to check liveness again. */
+        ofproto->backer->need_revalidate = REV_RECONFIGURE;
+    }
+
     new_dump_seq = seq_read(udpif_dump_seq(ofproto->backer->udpif));
     if (ofproto->dump_seq != new_dump_seq) {
         struct rule *rule, *next_rule;
index c9d5df34b0e40dd502988f3a2181f265c0982a39..aee61d61d8edaf6eff6c2add17c6702bdcffeee2 100644 (file)
@@ -342,6 +342,9 @@ struct ofproto_dpif {
     struct guarded_list ams;      /* Contains "struct ofproto_async_msgs"s. */
     struct seq *ams_seq;          /* For notifying 'ams' reception. */
     uint64_t ams_seqno;
+
+    bool is_controller_connected; /* True if any controller admitted this
+                                   * switch connection. */
 };
 
 struct ofproto_dpif *ofproto_dpif_lookup_by_name(const char *name);
index e2591287dfd888936995b04729598ccd597addfb..0fbd6c380288558615a982a7659c1d1f85cdb21b 100644 (file)
@@ -1906,7 +1906,8 @@ ofproto_wait(struct ofproto *p)
 bool
 ofproto_is_alive(const struct ofproto *p)
 {
-    return connmgr_has_controllers(p->connmgr);
+    return (connmgr_has_controllers(p->connmgr)
+            && connmgr_is_any_controller_admitted(p->connmgr));
 }
 
 /* Adds some memory usage statistics for 'ofproto' into 'usage', for use with