[ovs-dev] [PATCH v5 ovn 3/3] northd: add rate limiting support for SB controller events
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Tue Sep 3 14:22:53 UTC 2019
Introduce the capability to associate a meter to each controller event
type in order to not overload the pinctrl thread under heavy load.
Each event type relies on a meter with a defined name:
- empty_lb_backends: event-elb
Acked-by: Mark Michelson <mmichels at redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
northd/ovn-northd.8.xml | 5 ++++
northd/ovn-northd.c | 55 ++++++++++++++++++++++++++++++-----------
ovn-nb.xml | 8 ++++++
tests/ovn.at | 1 +
4 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 442e899bc..c0a54bcce 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -301,6 +301,11 @@
<code>Pre-stateful</code> to send IP packets to the connection tracker
for packet de-fragmentation before eventually advancing to ingress table
<code>LB</code>.
+ If controller_event has been enabled and load balancing rules with
+ empty backends have been added in <code>OVN_Northbound</code>, a 130 flow
+ is added to trigger ovn-controller events whenever the chassis receives a
+ packet for that particular VIP. If <code>event-elb</code> meter has been
+ previously created, it will be associated to the empty_lb logical flow
</p>
<h3>Ingress Table 5: Pre-stateful</h3>
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 679d36d88..df7a5eca9 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -4018,14 +4018,18 @@ static void
build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
struct smap_node *node, char *ip_address,
struct nbrec_load_balancer *lb, uint16_t port,
- int addr_family, int pl)
+ int addr_family, int pl, struct shash *meter_groups)
{
if (!controller_event_en || node->value[0]) {
return;
}
struct ds match = DS_EMPTY_INITIALIZER;
- char *action;
+ char *meter = "", *action;
+
+ if (meter_groups && shash_find(meter_groups, "event-elb")) {
+ meter = "event-elb";
+ }
if (addr_family == AF_INET) {
ds_put_format(&match, "ip4.dst == %s && %s",
@@ -4039,18 +4043,20 @@ build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
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));
+ "meter = \"%s\", vip = \"%s\", "
+ "protocol = \"%s\", "
+ "load_balancer = \"" UUID_FMT "\");",
+ event_to_string(OVN_EVENT_EMPTY_LB_BACKENDS),
+ meter, node->key, lb->protocol,
+ UUID_ARGS(&lb->header_.uuid));
ovn_lflow_add(lflows, od, pl, 130, ds_cstr(&match), action);
ds_destroy(&match);
free(action);
}
static void
-build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)
+build_pre_lb(struct ovn_datapath *od, struct hmap *lflows,
+ struct shash *meter_groups)
{
/* Do not send ND packets to conntrack */
ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_LB, 110,
@@ -4087,7 +4093,8 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows)
}
build_empty_lb_event_flow(od, lflows, node, ip_address, lb,
- port, addr_family, S_SWITCH_IN_PRE_LB);
+ port, addr_family, S_SWITCH_IN_PRE_LB,
+ meter_groups);
free(ip_address);
@@ -4907,7 +4914,8 @@ build_lrouter_groups(struct hmap *ports, struct ovs_list *lr_list)
static void
build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
struct hmap *port_groups, struct hmap *lflows,
- struct hmap *mcgroups, struct hmap *igmp_groups)
+ struct hmap *mcgroups, struct hmap *igmp_groups,
+ struct shash *meter_groups)
{
/* This flow table structure is documented in ovn-northd(8), so please
* update ovn-northd.8.xml if you change anything. */
@@ -4924,7 +4932,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
}
build_pre_acls(od, lflows);
- build_pre_lb(od, lflows);
+ build_pre_lb(od, lflows, meter_groups);
build_pre_stateful(od, lflows);
build_acls(od, lflows, port_groups);
build_qos(od, lflows);
@@ -8278,12 +8286,13 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
static void
build_lflows(struct northd_context *ctx, struct hmap *datapaths,
struct hmap *ports, struct hmap *port_groups,
- struct hmap *mcgroups, struct hmap *igmp_groups)
+ struct hmap *mcgroups, struct hmap *igmp_groups,
+ struct shash *meter_groups)
{
struct hmap lflows = HMAP_INITIALIZER(&lflows);
build_lswitch_flows(datapaths, ports, port_groups, &lflows, mcgroups,
- igmp_groups);
+ igmp_groups, meter_groups);
build_lrouter_flows(datapaths, ports, &lflows);
/* Push changes to the Logical_Flow table to database. */
@@ -8951,6 +8960,16 @@ build_mcast_groups(struct northd_context *ctx,
}
}
+static void
+build_meter_groups(struct northd_context *ctx,
+ struct shash *meter_groups)
+{
+ const struct nbrec_meter *nb_meter;
+ NBREC_METER_FOR_EACH (nb_meter, ctx->ovnnb_idl) {
+ shash_add(meter_groups, nb_meter->name, nb_meter);
+ }
+}
+
static void
ovnnb_db_run(struct northd_context *ctx,
struct ovsdb_idl_index *sbrec_chassis_by_name,
@@ -8964,6 +8983,7 @@ ovnnb_db_run(struct northd_context *ctx,
struct hmap port_groups;
struct hmap mcast_groups;
struct hmap igmp_groups;
+ struct shash meter_groups = SHASH_INITIALIZER(&meter_groups);
build_datapaths(ctx, datapaths, lr_list);
build_ports(ctx, sbrec_chassis_by_name, datapaths, ports);
@@ -8972,8 +8992,9 @@ ovnnb_db_run(struct northd_context *ctx,
build_lrouter_groups(ports, lr_list);
build_ip_mcast(ctx, datapaths);
build_mcast_groups(ctx, datapaths, ports, &mcast_groups, &igmp_groups);
+ build_meter_groups(ctx, &meter_groups);
build_lflows(ctx, datapaths, ports, &port_groups, &mcast_groups,
- &igmp_groups);
+ &igmp_groups, &meter_groups);
sync_address_sets(ctx);
sync_port_groups(ctx);
@@ -8994,6 +9015,12 @@ ovnnb_db_run(struct northd_context *ctx,
hmap_destroy(&mcast_groups);
hmap_destroy(&port_groups);
+ struct shash_node *node, *next;
+ SHASH_FOR_EACH_SAFE (node, next, &meter_groups) {
+ shash_delete(&meter_groups, node);
+ }
+ shash_destroy(&meter_groups);
+
/* Sync ipsec configuration.
* Copy nb_cfg from northbound to southbound database.
* Also set up to update sb_cfg once our southbound transaction commits. */
diff --git a/ovn-nb.xml b/ovn-nb.xml
index b99a808b8..442e5cb60 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -117,6 +117,14 @@
<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.
+ It is possible to associate a meter to each controller event type
+ in order to not overload the pinctrl thread under heavy load.
+ Each event type relies on a meter with a defined name:
+
+ <ul>
+ <li>empty_lb_backends: event-elb</li>
+ </ul>
+
</column>
</group>
diff --git a/tests/ovn.at b/tests/ovn.at
index 5352a750a..de1b3b3ba 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -14709,6 +14709,7 @@ 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-nbctl --wait=hv meter-add event-elb drop 100 pktps 10
OVN_POPULATE_ARP
ovn-nbctl --timeout=3 --wait=hv sync
--
2.21.0
More information about the dev
mailing list