[ovs-dev] [PATCH RFC ovn 1/3] northd: Use thread-local storage for logical flow matches.
Mark Michelson
mmichels at redhat.com
Wed Jun 16 17:56:09 UTC 2021
For this commit, only the most trivial dynamic string matches have been
replaced with a thread-local buffer. This prevents a great deal of
memory allocations and frees.
Follow-up commits will take care of some of the more complex uses of
dynamic string matches.
Signed-off-by: Mark Michelson <mmichels at redhat.com>
---
northd/ovn-northd.c | 376 +++++++++++++++++++++-----------------------
1 file changed, 180 insertions(+), 196 deletions(-)
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index d872f6a3c..6b51d12de 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -56,6 +56,7 @@
#include "util.h"
#include "uuid.h"
#include "openvswitch/vlog.h"
+#include "ovs-thread.h"
VLOG_DEFINE_THIS_MODULE(ovn_northd);
@@ -4083,6 +4084,16 @@ static bool use_parallel_build = true;
static struct hashrow_locks lflow_locks;
+DEFINE_STATIC_PER_THREAD_DATA(struct ds, match, DS_EMPTY_INITIALIZER);
+
+static struct ds *
+match_get_clear(void)
+{
+ struct ds *match = match_get();
+ ds_clear(match);
+ return match;
+}
+
/* Adds a row with the specified contents to the Logical_Flow table.
* Version to use when locking is required.
*/
@@ -4338,21 +4349,21 @@ static void
build_port_security_nd(struct ovn_port *op, struct hmap *lflows,
const struct ovsdb_idl_row *stage_hint)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t i = 0; i < op->n_ps_addrs; i++) {
struct lport_addresses *ps = &op->ps_addrs[i];
bool no_ip = !(ps->n_ipv4_addrs || ps->n_ipv6_addrs);
- ds_clear(&match);
+ ds_clear(match);
if (ps->n_ipv4_addrs || no_ip) {
- ds_put_format(&match,
+ ds_put_format(match,
"inport == %s && eth.src == %s && arp.sha == %s",
op->json_key, ps->ea_s, ps->ea_s);
if (ps->n_ipv4_addrs) {
- ds_put_cstr(&match, " && arp.spa == {");
+ ds_put_cstr(match, " && arp.spa == {");
for (size_t j = 0; j < ps->n_ipv4_addrs; j++) {
/* When the netmask is applied, if the host portion is
* non-zero, the host can only use the specified
@@ -4360,38 +4371,37 @@ build_port_security_nd(struct ovn_port *op, struct hmap *lflows,
* to use any address in the subnet. */
if (ps->ipv4_addrs[j].plen == 32
|| ps->ipv4_addrs[j].addr & ~ps->ipv4_addrs[j].mask) {
- ds_put_cstr(&match, ps->ipv4_addrs[j].addr_s);
+ ds_put_cstr(match, ps->ipv4_addrs[j].addr_s);
} else {
- ds_put_format(&match, "%s/%d",
+ ds_put_format(match, "%s/%d",
ps->ipv4_addrs[j].network_s,
ps->ipv4_addrs[j].plen);
}
- ds_put_cstr(&match, ", ");
+ ds_put_cstr(match, ", ");
}
- ds_chomp(&match, ' ');
- ds_chomp(&match, ',');
- ds_put_cstr(&match, "}");
+ ds_chomp(match, ' ');
+ ds_chomp(match, ',');
+ ds_put_cstr(match, "}");
}
ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND,
- 90, ds_cstr(&match), "next;", stage_hint);
+ 90, ds_cstr(match), "next;", stage_hint);
}
if (ps->n_ipv6_addrs || no_ip) {
- ds_clear(&match);
- ds_put_format(&match, "inport == %s && eth.src == %s",
+ ds_clear(match);
+ ds_put_format(match, "inport == %s && eth.src == %s",
op->json_key, ps->ea_s);
- build_port_security_ipv6_nd_flow(&match, ps->ea, ps->ipv6_addrs,
+ build_port_security_ipv6_nd_flow(match, ps->ea, ps->ipv6_addrs,
ps->n_ipv6_addrs);
ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND,
- 90, ds_cstr(&match), "next;", stage_hint);
+ 90, ds_cstr(match), "next;", stage_hint);
}
}
- ds_clear(&match);
- ds_put_format(&match, "inport == %s && (arp || nd)", op->json_key);
+ ds_clear(match);
+ ds_put_format(match, "inport == %s && (arp || nd)", op->json_key);
ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND, 80,
- ds_cstr(&match), "drop;", stage_hint);
- ds_destroy(&match);
+ ds_cstr(match), "drop;", stage_hint);
}
/**
@@ -4432,7 +4442,7 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
}
if (ps->n_ipv4_addrs) {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
if (pipeline == P_IN) {
/* Permit use of the unspecified address for DHCP discovery */
struct ds dhcp_match = DS_EMPTY_INITIALIZER;
@@ -4446,11 +4456,11 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
ds_cstr(&dhcp_match), "next;",
stage_hint);
ds_destroy(&dhcp_match);
- ds_put_format(&match, "inport == %s && eth.src == %s"
+ ds_put_format(match, "inport == %s && eth.src == %s"
" && ip4.src == {", op->json_key,
ps->ea_s);
} else {
- ds_put_format(&match, "outport == %s && eth.dst == %s"
+ ds_put_format(match, "outport == %s && eth.dst == %s"
" && ip4.dst == {255.255.255.255, 224.0.0.0/4, ",
op->json_key, ps->ea_s);
}
@@ -4464,33 +4474,32 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
*/
if (ps->ipv4_addrs[j].plen == 32
|| ps->ipv4_addrs[j].addr & ~mask) {
- ds_put_format(&match, "%s", ps->ipv4_addrs[j].addr_s);
+ ds_put_format(match, "%s", ps->ipv4_addrs[j].addr_s);
if (pipeline == P_OUT && ps->ipv4_addrs[j].plen != 32) {
/* Host is also allowed to receive packets to the
* broadcast address in the specified subnet. */
- ds_put_format(&match, ", %s",
+ ds_put_format(match, ", %s",
ps->ipv4_addrs[j].bcast_s);
}
} else {
/* host portion is zero */
- ds_put_format(&match, "%s/%d", ps->ipv4_addrs[j].network_s,
+ ds_put_format(match, "%s/%d", ps->ipv4_addrs[j].network_s,
ps->ipv4_addrs[j].plen);
}
- ds_put_cstr(&match, ", ");
+ ds_put_cstr(match, ", ");
}
/* Replace ", " by "}". */
- ds_chomp(&match, ' ');
- ds_chomp(&match, ',');
- ds_put_cstr(&match, "}");
+ ds_chomp(match, ' ');
+ ds_chomp(match, ',');
+ ds_put_cstr(match, "}");
ovn_lflow_add_with_hint(lflows, op->od, stage, 90,
- ds_cstr(&match), "next;",
+ ds_cstr(match), "next;",
stage_hint);
- ds_destroy(&match);
}
if (ps->n_ipv6_addrs) {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
if (pipeline == P_IN) {
/* Permit use of unspecified address for duplicate address
* detection */
@@ -4506,15 +4515,14 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op,
stage_hint);
ds_destroy(&dad_match);
}
- ds_put_format(&match, "%s == %s && %s == %s",
+ ds_put_format(match, "%s == %s && %s == %s",
port_direction, op->json_key,
pipeline == P_IN ? "eth.src" : "eth.dst", ps->ea_s);
- build_port_security_ipv6_flow(pipeline, &match, ps->ea,
+ build_port_security_ipv6_flow(pipeline, match, ps->ea,
ps->ipv6_addrs, ps->n_ipv6_addrs);
ovn_lflow_add_with_hint(lflows, op->od, stage, 90,
- ds_cstr(&match), "next;",
+ ds_cstr(match), "next;",
stage_hint);
- ds_destroy(&match);
}
char *match = xasprintf("%s == %s && %s == %s && ip",
@@ -5122,19 +5130,19 @@ build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
}
bool ipv4 = IN6_IS_ADDR_V4MAPPED(&lb_vip->vip);
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
char *meter = "", *action;
if (meter_groups && shash_find(meter_groups, "event-elb")) {
meter = "event-elb";
}
- ds_put_format(&match, "ip%s.dst == %s && %s",
+ ds_put_format(match, "ip%s.dst == %s && %s",
ipv4 ? "4": "6", lb_vip->vip_str, lb->protocol);
char *vip = lb_vip->vip_str;
if (lb_vip->vip_port) {
- ds_put_format(&match, " && %s.dst == %u", lb->protocol,
+ ds_put_format(match, " && %s.dst == %u", lb->protocol,
lb_vip->vip_port);
vip = xasprintf("%s%s%s:%u", ipv4 ? "" : "[", lb_vip->vip_str,
ipv4 ? "" : "]", lb_vip->vip_port);
@@ -5147,9 +5155,8 @@ build_empty_lb_event_flow(struct ovn_datapath *od, struct hmap *lflows,
event_to_string(OVN_EVENT_EMPTY_LB_BACKENDS),
meter, vip, lb->protocol,
UUID_ARGS(&lb->header_.uuid));
- ovn_lflow_add_with_hint(lflows, od, pl, 130, ds_cstr(&match), action,
+ ovn_lflow_add_with_hint(lflows, od, pl, 130, ds_cstr(match), action,
&lb->header_);
- ds_destroy(&match);
if (lb_vip->vip_port) {
free(vip);
}
@@ -5270,32 +5277,31 @@ build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows)
const char *lb_protocols[] = {"tcp", "udp", "sctp"};
struct ds actions = DS_EMPTY_INITIALIZER;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t i = 0; i < ARRAY_SIZE(lb_protocols); i++) {
- ds_clear(&match);
+ ds_clear(match);
ds_clear(&actions);
- ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip4 && %s",
+ ds_put_format(match, REGBIT_CONNTRACK_NAT" == 1 && ip4 && %s",
lb_protocols[i]);
ds_put_format(&actions, REG_ORIG_DIP_IPV4 " = ip4.dst; "
REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
lb_protocols[i]);
ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120,
- ds_cstr(&match), ds_cstr(&actions));
+ ds_cstr(match), ds_cstr(&actions));
- ds_clear(&match);
+ ds_clear(match);
ds_clear(&actions);
- ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip6 && %s",
+ ds_put_format(match, REGBIT_CONNTRACK_NAT" == 1 && ip6 && %s",
lb_protocols[i]);
ds_put_format(&actions, REG_ORIG_DIP_IPV6 " = ip6.dst; "
REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
lb_protocols[i]);
ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120,
- ds_cstr(&match), ds_cstr(&actions));
+ ds_cstr(match), ds_cstr(&actions));
}
ds_destroy(&actions);
- ds_destroy(&match);
ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 110,
REGBIT_CONNTRACK_NAT" == 1", "ct_lb;");
@@ -5559,7 +5565,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
&acl->header_);
ds_destroy(&actions);
} else {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
/* Commit the connection tracking entry if it's a new
@@ -5574,14 +5580,14 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
* by ct_commit in the "stateful" stage) to indicate that the
* connection should be allowed to resume.
*/
- ds_put_format(&match, REGBIT_ACL_HINT_ALLOW_NEW " == 1 && (%s)",
+ ds_put_format(match, REGBIT_ACL_HINT_ALLOW_NEW " == 1 && (%s)",
acl->match);
ds_put_cstr(&actions, REGBIT_CONNTRACK_COMMIT" = 1; ");
build_acl_log(&actions, acl, meter_groups);
ds_put_cstr(&actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage,
acl->priority + OVN_ACL_PRI_OFFSET,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&actions),
&acl->header_);
@@ -5591,24 +5597,23 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
* proceed to the next table. We use this to ensure that this
* connection is still allowed by the currently defined
* policy. Match untracked packets too. */
- ds_clear(&match);
+ ds_clear(match);
ds_clear(&actions);
- ds_put_format(&match, REGBIT_ACL_HINT_ALLOW " == 1 && (%s)",
+ ds_put_format(match, REGBIT_ACL_HINT_ALLOW " == 1 && (%s)",
acl->match);
build_acl_log(&actions, acl, meter_groups);
ds_put_cstr(&actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage,
acl->priority + OVN_ACL_PRI_OFFSET,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&acl->header_);
- ds_destroy(&match);
ds_destroy(&actions);
}
} else if (!strcmp(acl->action, "drop")
|| !strcmp(acl->action, "reject")) {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
/* The implementation of "drop" differs if stateful ACLs are in
@@ -5618,17 +5623,17 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
if (has_stateful) {
/* If the packet is not tracked or not part of an established
* connection, then we can simply reject/drop it. */
- ds_put_cstr(&match, REGBIT_ACL_HINT_DROP " == 1");
+ ds_put_cstr(match, REGBIT_ACL_HINT_DROP " == 1");
if (!strcmp(acl->action, "reject")) {
- build_reject_acl_rules(od, lflows, stage, acl, &match,
+ build_reject_acl_rules(od, lflows, stage, acl, match,
&actions, &acl->header_, meter_groups);
} else {
- ds_put_format(&match, " && (%s)", acl->match);
+ ds_put_format(match, " && (%s)", acl->match);
build_acl_log(&actions, acl, meter_groups);
ds_put_cstr(&actions, "/* drop */");
ovn_lflow_add_with_hint(lflows, od, stage,
acl->priority + OVN_ACL_PRI_OFFSET,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&acl->header_);
}
/* For an existing connection without ct_label set, we've
@@ -5642,20 +5647,20 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
* ct_commit() to the "stateful" stage, but since we're
* rejecting/dropping the packet, we go ahead and do it here.
*/
- ds_clear(&match);
+ ds_clear(match);
ds_clear(&actions);
- ds_put_cstr(&match, REGBIT_ACL_HINT_BLOCK " == 1");
+ ds_put_cstr(match, REGBIT_ACL_HINT_BLOCK " == 1");
ds_put_cstr(&actions, "ct_commit { ct_label.blocked = 1; }; ");
if (!strcmp(acl->action, "reject")) {
- build_reject_acl_rules(od, lflows, stage, acl, &match,
+ build_reject_acl_rules(od, lflows, stage, acl, match,
&actions, &acl->header_, meter_groups);
} else {
- ds_put_format(&match, " && (%s)", acl->match);
+ ds_put_format(match, " && (%s)", acl->match);
build_acl_log(&actions, acl, meter_groups);
ds_put_cstr(&actions, "/* drop */");
ovn_lflow_add_with_hint(lflows, od, stage,
acl->priority + OVN_ACL_PRI_OFFSET,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&acl->header_);
}
} else {
@@ -5663,7 +5668,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
* so a "reject/drop" ACL is simply the "reject/drop"
* logical flow action in all cases. */
if (!strcmp(acl->action, "reject")) {
- build_reject_acl_rules(od, lflows, stage, acl, &match,
+ build_reject_acl_rules(od, lflows, stage, acl, match,
&actions, &acl->header_, meter_groups);
} else {
build_acl_log(&actions, acl, meter_groups);
@@ -5674,7 +5679,6 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
&acl->header_);
}
}
- ds_destroy(&match);
ds_destroy(&actions);
}
}
@@ -5889,17 +5893,16 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows,
const char *lease_time = smap_get(
&od->nbs->ports[i]->dhcpv4_options->options, "lease_time");
if (server_id && server_mac && lease_time) {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
const char *actions =
has_stateful ? "ct_commit; next;" : "next;";
- ds_put_format(&match, "outport == \"%s\" && eth.src == %s "
+ ds_put_format(match, "outport == \"%s\" && eth.src == %s "
"&& ip4.src == %s && udp && udp.src == 67 "
"&& udp.dst == 68", od->nbs->ports[i]->name,
server_mac, server_id);
ovn_lflow_add_with_hint(
- lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(&match),
+ lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(match),
actions, &od->nbs->ports[i]->dhcpv4_options->header_);
- ds_destroy(&match);
}
}
@@ -5916,17 +5919,16 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows,
char server_ip[INET6_ADDRSTRLEN + 1];
ipv6_string_mapped(server_ip, &lla);
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
const char *actions = has_stateful ? "ct_commit; next;" :
"next;";
- ds_put_format(&match, "outport == \"%s\" && eth.src == %s "
+ ds_put_format(match, "outport == \"%s\" && eth.src == %s "
"&& ip6.src == %s && udp && udp.src == 547 "
"&& udp.dst == 546", od->nbs->ports[i]->name,
server_mac, server_ip);
ovn_lflow_add_with_hint(
- lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(&match),
+ lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(match),
actions, &od->nbs->ports[i]->dhcpv6_options->header_);
- ds_destroy(&match);
}
}
}
@@ -6021,7 +6023,7 @@ build_lb_rules(struct ovn_datapath *od, struct hmap *lflows,
struct ovn_northd_lb *lb)
{
struct ds action = DS_EMPTY_INITIALIZER;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t i = 0; i < lb->n_vips; i++) {
struct ovn_lb_vip *lb_vip = &lb->vips[i];
@@ -6029,7 +6031,7 @@ build_lb_rules(struct ovn_datapath *od, struct hmap *lflows,
const char *ip_match = NULL;
ds_clear(&action);
- ds_clear(&match);
+ ds_clear(match);
/* Store the original destination IP to be used when generating
* hairpin flows.
@@ -6066,21 +6068,20 @@ build_lb_rules(struct ovn_datapath *od, struct hmap *lflows,
build_lb_vip_actions(lb_vip, lb_vip_nb, &action,
lb->selection_fields, true);
- ds_put_format(&match, "ct.new && %s.dst == %s", ip_match,
+ ds_put_format(match, "ct.new && %s.dst == %s", ip_match,
lb_vip->vip_str);
if (lb_vip->vip_port) {
- ds_put_format(&match, " && %s.dst == %d", proto, lb_vip->vip_port);
+ ds_put_format(match, " && %s.dst == %d", proto, lb_vip->vip_port);
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_STATEFUL, 120,
- ds_cstr(&match), ds_cstr(&action),
+ ds_cstr(match), ds_cstr(&action),
&lb->nlb->header_);
} else {
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_STATEFUL, 110,
- ds_cstr(&match), ds_cstr(&action),
+ ds_cstr(match), ds_cstr(&action),
&lb->nlb->header_);
}
}
ds_destroy(&action);
- ds_destroy(&match);
}
static void
@@ -6179,7 +6180,7 @@ build_fwd_group_lflows(struct ovn_datapath *od, struct hmap *lflows)
{
if (!(!od->nbs || !od->nbs->n_forwarding_groups)) {
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
struct ds group_ports = DS_EMPTY_INITIALIZER;
@@ -6191,7 +6192,7 @@ build_fwd_group_lflows(struct ovn_datapath *od, struct hmap *lflows)
}
/* ARP responder for the forwarding group's virtual IP */
- ds_put_format(&match, "arp.tpa == %s && arp.op == 1",
+ ds_put_format(match, "arp.tpa == %s && arp.op == 1",
fwd_group->vip);
ds_put_format(&actions,
"eth.dst = eth.src; "
@@ -6207,12 +6208,12 @@ build_fwd_group_lflows(struct ovn_datapath *od, struct hmap *lflows)
fwd_group->vmac, fwd_group->vmac, fwd_group->vip);
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_ARP_ND_RSP, 50,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&fwd_group->header_);
/* L2 lookup for the forwarding group's virtual MAC */
- ds_clear(&match);
- ds_put_format(&match, "eth.dst == %s", fwd_group->vmac);
+ ds_clear(match);
+ ds_put_format(match, "eth.dst == %s", fwd_group->vmac);
/* Create a comma separated string of child ports */
ds_clear(&group_ports);
@@ -6230,11 +6231,10 @@ build_fwd_group_lflows(struct ovn_datapath *od, struct hmap *lflows)
ds_clear(&actions);
ds_put_format(&actions, "fwd_group(%s);", ds_cstr(&group_ports));
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP, 50,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&fwd_group->header_);
}
- ds_destroy(&match);
ds_destroy(&actions);
ds_destroy(&group_ports);
}
@@ -6390,7 +6390,7 @@ build_lswitch_rport_arp_req_self_orig_flow(struct ovn_port *op,
{
struct sset all_eth_addrs = SSET_INITIALIZER(&all_eth_addrs);
struct ds eth_src = DS_EMPTY_INITIALIZER;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
sset_add(&all_eth_addrs, op->lrp_networks.ea_s);
@@ -6445,15 +6445,14 @@ build_lswitch_rport_arp_req_self_orig_flow(struct ovn_port *op,
ds_chomp(ð_src, ',');
ds_put_cstr(ð_src, "}");
- ds_put_format(&match, "eth.src == %s && (arp.op == 1 || nd_ns)",
+ ds_put_format(match, "eth.src == %s && (arp.op == 1 || nd_ns)",
ds_cstr(ð_src));
ovn_lflow_add_unique(lflows, od, S_SWITCH_IN_L2_LKUP, priority,
- ds_cstr(&match),
+ ds_cstr(match),
"outport = \""MC_FLOOD_L2"\"; output;");
sset_destroy(&all_eth_addrs);
ds_destroy(ð_src);
- ds_destroy(&match);
}
/*
@@ -6470,7 +6469,7 @@ build_lswitch_rport_arp_req_flow_for_ip(struct sset *ips,
struct hmap *lflows,
const struct ovsdb_idl_row *stage_hint)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
/* Packets received from VXLAN tunnels have already been through the
@@ -6478,22 +6477,22 @@ build_lswitch_rport_arp_req_flow_for_ip(struct sset *ips,
* multicast_group implementation (VXLAN packets skip table 32 which
* delivers to patch ports) but we're bypassing multicast_groups.
*/
- ds_put_cstr(&match, FLAGBIT_NOT_VXLAN " && ");
+ ds_put_cstr(match, FLAGBIT_NOT_VXLAN " && ");
if (addr_family == AF_INET) {
- ds_put_cstr(&match, "arp.op == 1 && arp.tpa == { ");
+ ds_put_cstr(match, "arp.op == 1 && arp.tpa == { ");
} else {
- ds_put_cstr(&match, "nd_ns && nd.target == { ");
+ ds_put_cstr(match, "nd_ns && nd.target == { ");
}
const char *ip_address;
SSET_FOR_EACH (ip_address, ips) {
- ds_put_format(&match, "%s, ", ip_address);
+ ds_put_format(match, "%s, ", ip_address);
}
- ds_chomp(&match, ' ');
- ds_chomp(&match, ',');
- ds_put_cstr(&match, "}");
+ ds_chomp(match, ' ');
+ ds_chomp(match, ',');
+ ds_put_cstr(match, "}");
/* Send a the packet to the router pipeline. If the switch has non-router
* ports then flood it there as well.
@@ -6503,16 +6502,15 @@ build_lswitch_rport_arp_req_flow_for_ip(struct sset *ips,
"outport = \""MC_FLOOD_L2"\"; output;",
patch_op->json_key);
ovn_lflow_add_unique_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP,
- priority, ds_cstr(&match),
+ priority, ds_cstr(match),
ds_cstr(&actions), stage_hint);
} else {
ds_put_format(&actions, "outport = %s; output;", patch_op->json_key);
ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP, priority,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
stage_hint);
}
- ds_destroy(&match);
ds_destroy(&actions);
}
@@ -6645,7 +6643,7 @@ build_dhcpv4_options_flows(struct ovn_port *op,
const char *json_key, bool is_external,
struct hmap *lflows)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t j = 0; j < lsp_addrs->n_ipv4_addrs; j++) {
struct ds options_action = DS_EMPTY_INITIALIZER;
@@ -6654,24 +6652,24 @@ build_dhcpv4_options_flows(struct ovn_port *op,
if (build_dhcpv4_action(
op, lsp_addrs->ipv4_addrs[j].addr,
&options_action, &response_action, &ipv4_addr_match)) {
- ds_clear(&match);
+ ds_clear(match);
ds_put_format(
- &match, "inport == %s && eth.src == %s && "
+ match, "inport == %s && eth.src == %s && "
"ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && "
"udp.src == 68 && udp.dst == 67",
json_key, lsp_addrs->ea_s);
if (is_external) {
- ds_put_format(&match, " && is_chassis_resident(%s)",
+ ds_put_format(match, " && is_chassis_resident(%s)",
op->json_key);
}
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&options_action),
&op->nbsp->dhcpv4_options->header_);
- ds_clear(&match);
+ ds_clear(match);
/* Allow ip4.src = OFFER_IP and
* ip4.dst = {SERVER_IP, 255.255.255.255} for the below
* cases
@@ -6681,38 +6679,38 @@ build_dhcpv4_options_flows(struct ovn_port *op,
* broadcasting the DHCPREQUEST.
*/
ds_put_format(
- &match, "inport == %s && eth.src == %s && "
+ match, "inport == %s && eth.src == %s && "
"%s && udp.src == 68 && udp.dst == 67",
json_key, lsp_addrs->ea_s, ds_cstr(&ipv4_addr_match));
if (is_external) {
- ds_put_format(&match, " && is_chassis_resident(%s)",
+ ds_put_format(match, " && is_chassis_resident(%s)",
op->json_key);
}
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&options_action),
&op->nbsp->dhcpv4_options->header_);
- ds_clear(&match);
+ ds_clear(match);
/* If REGBIT_DHCP_OPTS_RESULT is set, it means the
* put_dhcp_opts action is successful. */
ds_put_format(
- &match, "inport == %s && eth.src == %s && "
+ match, "inport == %s && eth.src == %s && "
"ip4 && udp.src == 68 && udp.dst == 67"
" && "REGBIT_DHCP_OPTS_RESULT,
json_key, lsp_addrs->ea_s);
if (is_external) {
- ds_put_format(&match, " && is_chassis_resident(%s)",
+ ds_put_format(match, " && is_chassis_resident(%s)",
op->json_key);
}
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_DHCP_RESPONSE, 100,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&response_action),
&op->nbsp->dhcpv4_options->header_);
ds_destroy(&options_action);
@@ -6721,7 +6719,6 @@ build_dhcpv4_options_flows(struct ovn_port *op,
break;
}
}
- ds_destroy(&match);
}
static void
@@ -6730,7 +6727,7 @@ build_dhcpv6_options_flows(struct ovn_port *op,
const char *json_key, bool is_external,
struct hmap *lflows)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t j = 0; j < lsp_addrs->n_ipv6_addrs; j++) {
struct ds options_action = DS_EMPTY_INITIALIZER;
@@ -6738,30 +6735,30 @@ build_dhcpv6_options_flows(struct ovn_port *op,
if (build_dhcpv6_action(
op, &lsp_addrs->ipv6_addrs[j].addr,
&options_action, &response_action)) {
- ds_clear(&match);
+ ds_clear(match);
ds_put_format(
- &match, "inport == %s && eth.src == %s"
+ match, "inport == %s && eth.src == %s"
" && ip6.dst == ff02::1:2 && udp.src == 546 &&"
" udp.dst == 547",
json_key, lsp_addrs->ea_s);
if (is_external) {
- ds_put_format(&match, " && is_chassis_resident(%s)",
+ ds_put_format(match, " && is_chassis_resident(%s)",
op->json_key);
}
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&options_action),
&op->nbsp->dhcpv6_options->header_);
/* If REGBIT_DHCP_OPTS_RESULT is set to 1, it means the
* put_dhcpv6_opts action is successful */
- ds_put_cstr(&match, " && "REGBIT_DHCP_OPTS_RESULT);
+ ds_put_cstr(match, " && "REGBIT_DHCP_OPTS_RESULT);
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_DHCP_RESPONSE, 100,
- ds_cstr(&match),
+ ds_cstr(match),
ds_cstr(&response_action),
&op->nbsp->dhcpv6_options->header_);
ds_destroy(&options_action);
@@ -6769,7 +6766,6 @@ build_dhcpv6_options_flows(struct ovn_port *op,
break;
}
}
- ds_destroy(&match);
}
static void
@@ -6777,16 +6773,16 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op,
const struct ovn_port *port,
struct hmap *lflows)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
for (size_t i = 0; i < op->n_lsp_addrs; i++) {
for (size_t j = 0; j < op->od->n_router_ports; j++) {
struct ovn_port *rp = op->od->router_ports[j];
for (size_t k = 0; k < rp->n_lsp_addrs; k++) {
for (size_t l = 0; l < rp->lsp_addrs[k].n_ipv4_addrs; l++) {
- ds_clear(&match);
+ ds_clear(match);
ds_put_format(
- &match, "inport == %s && eth.src == %s"
+ match, "inport == %s && eth.src == %s"
" && !is_chassis_resident(%s)"
" && arp.tpa == %s && arp.op == 1",
port->json_key,
@@ -6794,13 +6790,13 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op,
rp->lsp_addrs[k].ipv4_addrs[l].addr_s);
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_EXTERNAL_PORT,
- 100, ds_cstr(&match), "drop;",
+ 100, ds_cstr(match), "drop;",
&op->nbsp->header_);
}
for (size_t l = 0; l < rp->lsp_addrs[k].n_ipv6_addrs; l++) {
- ds_clear(&match);
+ ds_clear(match);
ds_put_format(
- &match, "inport == %s && eth.src == %s"
+ match, "inport == %s && eth.src == %s"
" && !is_chassis_resident(%s)"
" && nd_ns && ip6.dst == {%s, %s} && nd.target == %s",
port->json_key,
@@ -6810,13 +6806,13 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op,
rp->lsp_addrs[k].ipv6_addrs[l].addr_s);
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_EXTERNAL_PORT, 100,
- ds_cstr(&match), "drop;",
+ ds_cstr(match), "drop;",
&op->nbsp->header_);
}
- ds_clear(&match);
+ ds_clear(match);
ds_put_format(
- &match, "inport == %s && eth.src == %s"
+ match, "inport == %s && eth.src == %s"
" && eth.dst == %s"
" && !is_chassis_resident(%s)",
port->json_key,
@@ -6824,12 +6820,11 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op,
op->json_key);
ovn_lflow_add_with_hint(lflows, op->od,
S_SWITCH_IN_EXTERNAL_PORT,
- 100, ds_cstr(&match), "drop;",
+ 100, ds_cstr(match), "drop;",
&op->nbsp->header_);
}
}
}
- ds_destroy(&match);
}
static bool
@@ -6844,7 +6839,6 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *lflows)
/* This flow table structure is documented in ovn-northd(8), so please
* update ovn-northd.8.xml if you change anything. */
- struct ds match = DS_EMPTY_INITIALIZER;
struct ds actions = DS_EMPTY_INITIALIZER;
struct ovn_datapath *od;
@@ -6869,7 +6863,6 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *lflows)
"output;");
}
- ds_destroy(&match);
ds_destroy(&actions);
}
@@ -7870,7 +7863,7 @@ build_routing_policy_flow(struct hmap *lflows, struct ovn_datapath *od,
const struct nbrec_logical_router_policy *rule,
const struct ovsdb_idl_row *stage_hint)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
if (!strcmp(rule->action, "reroute")) {
@@ -7921,11 +7914,10 @@ build_routing_policy_flow(struct hmap *lflows, struct ovn_datapath *od,
}
ds_put_cstr(&actions, REG_ECMP_GROUP_ID" = 0; next;");
}
- ds_put_format(&match, "%s", rule->match);
+ ds_put_format(match, "%s", rule->match);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_POLICY, rule->priority,
- ds_cstr(&match), ds_cstr(&actions), stage_hint);
- ds_destroy(&match);
+ ds_cstr(match), ds_cstr(&actions), stage_hint);
ds_destroy(&actions);
}
@@ -7958,7 +7950,7 @@ build_ecmp_routing_policy_flows(struct hmap *lflows, struct ovn_datapath *od,
}
}
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
struct ds actions = DS_EMPTY_INITIALIZER;
for (size_t i = 0; i < rule->n_nexthops; i++) {
@@ -7999,12 +7991,12 @@ build_ecmp_routing_policy_flows(struct hmap *lflows, struct ovn_datapath *od,
out_port->lrp_networks.ea_s,
out_port->json_key);
- ds_clear(&match);
- ds_put_format(&match, REG_ECMP_GROUP_ID" == %"PRIu16" && "
+ ds_clear(match);
+ ds_put_format(match, REG_ECMP_GROUP_ID" == %"PRIu16" && "
REG_ECMP_MEMBER_ID" == %"PRIuSIZE,
ecmp_group_id, i + 1);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_POLICY_ECMP,
- 100, ds_cstr(&match),
+ 100, ds_cstr(match),
ds_cstr(&actions), &rule->header_);
}
@@ -8026,7 +8018,6 @@ build_ecmp_routing_policy_flows(struct hmap *lflows, struct ovn_datapath *od,
ds_cstr(&actions), &rule->header_);
cleanup:
- ds_destroy(&match);
ds_destroy(&actions);
}
@@ -8390,7 +8381,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
struct ds *route_match)
{
const struct nbrec_logical_router_static_route *st_route = route->route;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
struct ds ecmp_reply = DS_EMPTY_INITIALIZER;
char *cidr = normalize_v46_prefix(&route->prefix, route->plen);
@@ -8398,14 +8389,14 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
/* If symmetric ECMP replies are enabled, then packets that arrive over
* an ECMP route need to go through conntrack.
*/
- ds_put_format(&match, "inport == %s && ip%s.%s == %s",
+ ds_put_format(match, "inport == %s && ip%s.%s == %s",
out_port->json_key,
IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "4" : "6",
route->is_src_route ? "dst" : "src",
cidr);
free(cidr);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_DEFRAG, 100,
- ds_cstr(&match), "ct_next;",
+ ds_cstr(match), "ct_next;",
&st_route->header_);
/* And packets that go out over an ECMP route need conntrack */
@@ -8419,13 +8410,13 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
* NOTE: we purposely are not clearing match before this
* ds_put_cstr() call. The previous contents are needed.
*/
- ds_put_cstr(&match, " && (ct.new && !ct.est)");
+ ds_put_cstr(match, " && (ct.new && !ct.est)");
ds_put_format(&actions, "ct_commit { ct_label.ecmp_reply_eth = eth.src;"
" ct_label.ecmp_reply_port = %" PRId64 ";}; next;",
out_port->sb->tunnel_key);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&st_route->header_);
/* Bypass ECMP selection if we already have ct_label information
@@ -8433,8 +8424,8 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
*/
ds_put_format(&ecmp_reply, "ct.rpl && ct_label.ecmp_reply_port == %"
PRId64, out_port->sb->tunnel_key);
- ds_clear(&match);
- ds_put_format(&match, "%s && %s", ds_cstr(&ecmp_reply),
+ ds_clear(match);
+ ds_put_format(match, "%s && %s", ds_cstr(&ecmp_reply),
ds_cstr(route_match));
ds_clear(&actions);
ds_put_format(&actions, "ip.ttl--; flags.loopback = 1; "
@@ -8443,7 +8434,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "" : "xx",
port_ip, out_port->json_key);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, 300,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&st_route->header_);
/* Egress reply traffic for symmetric ECMP routes skips router policies. */
@@ -8456,7 +8447,6 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows,
200, ds_cstr(&ecmp_reply),
action, &st_route->header_);
- ds_destroy(&match);
ds_destroy(&actions);
ds_destroy(&ecmp_reply);
}
@@ -8497,7 +8487,7 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od,
ds_cstr(&route_match), ds_cstr(&actions));
/* Add per member flow */
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get();
struct sset visited_ports = SSET_INITIALIZER(&visited_ports);
LIST_FOR_EACH (er, list_node, &eg->route_list) {
const struct parsed_route *route_ = er->route;
@@ -8518,8 +8508,8 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od,
add_ecmp_symmetric_reply_flows(lflows, od, lrp_addr_s, out_port,
route_, &route_match);
}
- ds_clear(&match);
- ds_put_format(&match, REG_ECMP_GROUP_ID" == %"PRIu16" && "
+ ds_clear(match);
+ ds_put_format(match, REG_ECMP_GROUP_ID" == %"PRIu16" && "
REG_ECMP_MEMBER_ID" == %"PRIu16,
eg->id, er->id);
ds_clear(&actions);
@@ -8535,11 +8525,10 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od,
out_port->lrp_networks.ea_s,
out_port->json_key);
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING_ECMP, 100,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
&route->header_);
}
sset_destroy(&visited_ports);
- ds_destroy(&match);
ds_destroy(&route_match);
ds_destroy(&actions);
}
@@ -8552,7 +8541,7 @@ add_route(struct hmap *lflows, struct ovn_datapath *od,
bool is_discard_route)
{
bool is_ipv4 = strchr(network_s, '.') ? true : false;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
uint16_t priority;
const struct ovn_port *op_inport = NULL;
@@ -8565,7 +8554,7 @@ add_route(struct hmap *lflows, struct ovn_datapath *od,
}
}
build_route_match(op_inport, network_s, plen, is_src_route, is_ipv4,
- &match, &priority);
+ match, &priority);
struct ds common_actions = DS_EMPTY_INITIALIZER;
struct ds actions = DS_EMPTY_INITIALIZER;
@@ -8593,15 +8582,14 @@ add_route(struct hmap *lflows, struct ovn_datapath *od,
}
ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, priority,
- ds_cstr(&match), ds_cstr(&actions),
+ ds_cstr(match), ds_cstr(&actions),
stage_hint);
if (op && op->has_bfd) {
- ds_put_format(&match, " && udp.dst == 3784");
+ ds_put_format(match, " && udp.dst == 3784");
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_ROUTING,
- priority + 1, ds_cstr(&match),
+ priority + 1, ds_cstr(match),
ds_cstr(&common_actions), stage_hint);
}
- ds_destroy(&match);
ds_destroy(&common_actions);
ds_destroy(&actions);
}
@@ -9224,7 +9212,7 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
{
struct lport_addresses *ext_addrs = &nat_entry->ext_addrs;
const struct nbrec_nat *nat = nat_entry->nb;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
/* Mac address to use when replying to ARP/NS. */
const char *mac_s = REG_INPORT_ETH_ADDR;
@@ -9240,7 +9228,7 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
* resident, so that upstream MAC learning points to the
* correct chassis. Also need to avoid generation of
* multiple ARP responses from different chassis. */
- ds_put_format(&match, "is_chassis_resident(\"%s\")",
+ ds_put_format(match, "is_chassis_resident(\"%s\")",
nat->logical_port);
} else {
mac_s = REG_INPORT_ETH_ADDR;
@@ -9250,7 +9238,7 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
* Also need to avoid generation of multiple ARP responses
* from different chassis. */
if (op->od->l3redirect_port) {
- ds_put_format(&match, "is_chassis_resident(%s)",
+ ds_put_format(match, "is_chassis_resident(%s)",
op->od->l3redirect_port->json_key);
}
}
@@ -9262,7 +9250,7 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
build_lrouter_nd_flow(op->od, op, "nd_na",
ext_addrs->ipv6_addrs[0].addr_s,
ext_addrs->ipv6_addrs[0].sn_addr_s,
- mac_s, &match, false, 92,
+ mac_s, match, false, 92,
&nat->header_, lflows);
build_lrouter_nd_flow(op->od, op, "nd_na",
ext_addrs->ipv6_addrs[0].addr_s,
@@ -9272,15 +9260,13 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
} else {
build_lrouter_arp_flow(op->od, op,
ext_addrs->ipv4_addrs[0].addr_s,
- mac_s, &match, false, 92,
+ mac_s, match, false, 92,
&nat->header_, lflows);
build_lrouter_arp_flow(op->od, op,
ext_addrs->ipv4_addrs[0].addr_s,
mac_s, NULL, true, 91,
&nat->header_, lflows);
}
-
- ds_destroy(&match);
}
static void
@@ -9347,24 +9333,23 @@ build_lrouter_force_snat_flows(struct hmap *lflows, struct ovn_datapath *od,
const char *ip_version, const char *ip_addr,
const char *context)
{
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
struct ds actions = DS_EMPTY_INITIALIZER;
- ds_put_format(&match, "ip%s && ip%s.dst == %s",
+ ds_put_format(match, "ip%s && ip%s.dst == %s",
ip_version, ip_version, ip_addr);
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 110,
- ds_cstr(&match), "ct_snat;");
+ ds_cstr(match), "ct_snat;");
/* Higher priority rules to force SNAT with the IP addresses
* configured in the Gateway router. This only takes effect
* when the packet has already been DNATed or load balanced once. */
- ds_clear(&match);
- ds_put_format(&match, "flags.force_snat_for_%s == 1 && ip%s",
+ ds_clear(match);
+ ds_put_format(match, "flags.force_snat_for_%s == 1 && ip%s",
context, ip_version);
ds_put_format(&actions, "ct_snat(%s);", ip_addr);
ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 100,
- ds_cstr(&match), ds_cstr(&actions));
+ ds_cstr(match), ds_cstr(&actions));
- ds_destroy(&match);
ds_destroy(&actions);
}
@@ -9448,42 +9433,41 @@ build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op)
}
struct ds ip_list = DS_EMPTY_INITIALIZER;
- struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds *match = match_get_clear();
if (op->lrp_networks.n_ipv4_addrs) {
op_put_v4_networks(&ip_list, op, false);
- ds_put_format(&match, "ip4.src == %s && udp.dst == 3784",
+ ds_put_format(match, "ip4.src == %s && udp.dst == 3784",
ds_cstr(&ip_list));
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "next; ",
+ ds_cstr(match), "next; ",
&op->nbrp->header_);
- ds_clear(&match);
- ds_put_format(&match, "ip4.dst == %s && udp.dst == 3784",
+ ds_clear(match);
+ ds_put_format(match, "ip4.dst == %s && udp.dst == 3784",
ds_cstr(&ip_list));
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "handle_bfd_msg(); ",
+ ds_cstr(match), "handle_bfd_msg(); ",
&op->nbrp->header_);
}
if (op->lrp_networks.n_ipv6_addrs) {
ds_clear(&ip_list);
- ds_clear(&match);
+ ds_clear(match);
op_put_v6_networks(&ip_list, op);
- ds_put_format(&match, "ip6.src == %s && udp.dst == 3784",
+ ds_put_format(match, "ip6.src == %s && udp.dst == 3784",
ds_cstr(&ip_list));
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "next; ",
+ ds_cstr(match), "next; ",
&op->nbrp->header_);
- ds_clear(&match);
- ds_put_format(&match, "ip6.dst == %s && udp.dst == 3784",
+ ds_clear(match);
+ ds_put_format(match, "ip6.dst == %s && udp.dst == 3784",
ds_cstr(&ip_list));
ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "handle_bfd_msg(); ",
+ ds_cstr(match), "handle_bfd_msg(); ",
&op->nbrp->header_);
}
ds_destroy(&ip_list);
- ds_destroy(&match);
}
/* Logical router ingress Table 0: L2 Admission Control
--
2.31.1
More information about the dev
mailing list