static struct hmap macam = HMAP_INITIALIZER(&macam);
static struct eth_addr mac_prefix;
+static bool controller_event_en;
+
#define MAX_OVN_TAGS 4096
\f
/* Pipeline stages. */
sset_add(&all_ips, ip_address);
}
+ if (controller_event_en && !node->value[0]) {
+ struct ds match = DS_EMPTY_INITIALIZER;
+ char *action;
+
+ if (addr_family == AF_INET) {
+ ds_put_format(&match, "ip4.dst == %s && %s",
+ ip_address, lb->protocol);
+ } else {
+ ds_put_format(&match, "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
smap_destroy(&options);
}
+ controller_event_en = smap_get_bool(&nb->options,
+ "controller_event", false);
+
cleanup_macam(&macam);
}
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 set by the CMS to enable/disable ovn-controller event reporting.
+ Traffic into OVS can raise a 'controller' event that results in a
+ Controller_Event being written to the <ref table="Controller_Event"/>
+ table in SBDB. When the CMS has seen the event and taken appropriate
+ action, it can remove the correponding row in
+ <ref table="Controller_Event"/> table.
+ The intention is for a CMS to see the events and take some sort of
+ action. Please see the <ref table="Controller_Event"/> table in SBDB.
+ </column>
</group>
<group title="Connection Options">
])
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 seq_num], [0], [dnl
+1
+])
+
+OVN_CLEANUP([hv1], [hv2])
+AT_CLEANUP