[ovs-dev,3/3] OVN: use send_event action to report 'empty_lb_rule' events
diff mbox series

Message ID ee8505b3fd9c49b2a0bf5e5253f94cc9c1ceaea4.1560527377.git.lorenzo.bianconi@redhat.com
State Superseded
Headers show
Series
  • OVN: add Controller Events
Related show

Commit Message

Lorenzo Bianconi June 14, 2019, 3:53 p.m. UTC
Add northd logical flows in order to reports that the controller
received an IP packet for LB rule witn no backends.
This configuration is used by OpenShift to spin up a idle POD

Signed-off-by: Mark Michelson <mmichels@redhat.com>
Co-authored-by: Mark Michelson <mmichels@redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 ovn/northd/ovn-northd.c | 33 ++++++++++++++++++++
 ovn/ovn-nb.xml          |  5 +++
 tests/ovn.at            | 68 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)

Comments

Ben Pfaff July 5, 2019, 10:33 p.m. UTC | #1
On Fri, Jun 14, 2019 at 05:53:23PM +0200, Lorenzo Bianconi wrote:
> Add northd logical flows in order to reports that the controller
> received an IP packet for LB rule witn no backends.
> This configuration is used by OpenShift to spin up a idle POD
> 
> Signed-off-by: Mark Michelson <mmichels@redhat.com>
> Co-authored-by: Mark Michelson <mmichels@redhat.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>

In build_pre_lb(), instead of
            if (controller_event_en && !strlen(node->value)) {
please write
            if (controller_event_en && !node->value[0]) {
to avoid unnecessary work.

You can leave out the "ip &&" clauses because ip4 or ip6 implies them:
+                if (addr_family == AF_INET) {
+                    ds_put_format(&match, "ip && ip4.dst == %s && %s",
+                                  ip_address, lb->protocol);
+                } else {
+                    ds_put_format(&match, "ip && ip6.dst == %s && %s",
+                                  ip_address, lb->protocol);
+                }

Thanks,

Ben.

Patch
diff mbox series

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 0b0a96a3a..6cd607674 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -70,6 +70,8 @@  static const char *unixctl_path;
 static struct hmap macam = HMAP_INITIALIZER(&macam);
 static struct eth_addr mac_prefix;
 
+static bool controller_event_en;
+
 #define MAX_OVN_TAGS 4096
 
 /* Pipeline stages. */
@@ -3571,6 +3573,34 @@  build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)
                 sset_add(&all_ips, ip_address);
             }
 
+            if (controller_event_en && !strlen(node->value)) {
+                struct ds match = DS_EMPTY_INITIALIZER;
+                char *action;
+
+                if (addr_family == AF_INET) {
+                    ds_put_format(&match, "ip && ip4.dst == %s && %s",
+                                  ip_address, lb->protocol);
+                } else {
+                    ds_put_format(&match, "ip && ip6.dst == %s && %s",
+                                  ip_address, lb->protocol);
+                }
+                if (port) {
+                    ds_put_format(&match, " && %s.dst == %u", lb->protocol,
+                                  port);
+                }
+                action = xasprintf("trigger_event(event = \"%s\", "
+                               "vip = \"%s\", protocol = \"%s\", "
+                               "load_balancer = \"" UUID_FMT "\");",
+                               event_to_string(OVN_EVENT_EMPTY_LB_BACKENDS),
+                               node->key, lb->protocol,
+                               UUID_ARGS(&lb->header_.uuid));
+                ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_LB, 120,
+                              ds_cstr(&match), action);
+                ds_destroy(&match);
+                free(action);
+                continue;
+            }
+
             free(ip_address);
 
             /* Ignore L4 port information in the key because fragmented packets
@@ -8044,6 +8074,9 @@  ovnnb_db_run(struct northd_context *ctx,
         smap_destroy(&options);
     }
 
+    controller_event_en = smap_get_bool(&nb->options,
+                                        "controller_event", false);
+
     cleanup_macam(&macam);
 }
 
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index 318379c1f..3d0249a73 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -107,6 +107,11 @@ 
         Configure a given OUI to be used as prefix when L2 address is
         dynamically assigned, e.g. <code>00:11:22</code>
       </column>
+
+      <column name="options" key="controller_event" type='{"type": "boolean"}'>
+        Value used to enable/disable ovn-controller event reporting to the CMS.
+        Please see the <ref table="Controller_Event"/> table in SBDB.
+      </column>
     </group>
 
     <group title="Connection Options">
diff --git a/tests/ovn.at b/tests/ovn.at
index cbfa702c7..aae92b5b3 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -14027,3 +14027,71 @@  ovn-hv4-0
 
 OVN_CLEANUP([hv1], [hv2], [hv3])
 AT_CLEANUP
+
+AT_SETUP([ovn -- controller event])
+AT_KEYWORDS([ovn_controller_event])
+ovn_start
+
+# Create hypervisors hv[12].
+# Add vif1[12] to hv1, vif2[12] to hv2
+# Add all of the vifs to a single logical switch sw0.
+
+net_add n1
+ovn-nbctl ls-add sw0
+for i in 1 2; do
+    sim_add hv$i
+    as hv$i
+    ovs-vsctl add-br br-phys
+    ovn_attach n1 br-phys 192.168.0.$i
+
+    for j in 1 2; do
+        ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
+                lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
+
+        ovs-vsctl -- add-port br-int vif$i$j -- \
+                set interface vif$i$j \
+                external-ids:iface-id=sw0-p$i$j \
+                options:tx_pcap=hv$i/vif$i$j-tx.pcap \
+                options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
+                ofport-request=$i$j
+    done
+done
+
+ovn-nbctl --wait=hv set NB_Global . options:controller_event=true
+ovn-nbctl lb-add lb0 192.168.1.100:80 ""
+ovn-nbctl ls-lb-add sw0 lb0
+uuid_lb=$(ovn-nbctl --bare --columns=_uuid find load_balancer name=lb0)
+
+OVN_POPULATE_ARP
+ovn-nbctl --timeout=3 --wait=hv sync
+ovn-sbctl lflow-list
+as hv1 ovs-ofctl dump-flows br-int
+
+packet="inport==\"sw0-p11\" && eth.src==00:00:00:00:00:11 && eth.dst==00:00:00:00:00:21 &&
+       ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==192.168.1.100 &&
+       tcp && tcp.src==10000 && tcp.dst==80"
+as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
+
+ovn-sbctl list controller_event
+uuid=$(ovn-sbctl list controller_event | awk '/_uuid/{print $3}')
+AT_CHECK([ovn-sbctl get controller_event $uuid event_type], [0], [dnl
+empty_lb_backends
+])
+AT_CHECK([ovn-sbctl get controller_event $uuid event_info:vip], [0], [dnl
+"192.168.1.100:80"
+])
+AT_CHECK([ovn-sbctl get controller_event $uuid event_info:protocol], [0], [dnl
+tcp
+])
+AT_CHECK_UNQUOTED([ovn-sbctl get controller_event $uuid event_info:load_balancer], [0], [dnl
+"$uuid_lb"
+])
+AT_CHECK([ovn-sbctl get controller_event $uuid handled], [0], [dnl
+false
+])
+AT_CHECK([ovn-sbctl get controller_event $uuid seq_num], [0], [dnl
+1
+])
+
+OVN_CLEANUP([hv1], [hv2])
+AT_CLEANUP