summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2016-12-12 09:16:18 -0800
committerBen Pfaff <blp@ovn.org>2016-12-12 09:16:18 -0800
commit1585ff634569ea37f92061b33733fd9a24c9b92a (patch)
tree1c9739134156f9c41f26f4b34128961bbec5bac3 /ovn
parentc431227e33503421d3412bd33415750b6010730d (diff)
downloadopenvswitch-1585ff634569ea37f92061b33733fd9a24c9b92a.tar.gz
ovn-trace: Implement DHCP option support.
The put_dhcp_opts(v6) logical action didn't really work because ovn-trace didn't handle DHCP options. This fixes the problem. This also makes the put_dhcp_opts(v6) logical provide useful tracing output showing what's happening and the assumptions. Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Numan Siddique <nusiddiq@redhat.com>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/utilities/ovn-trace.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c
index 04aa5326d..71798f8b8 100644
--- a/ovn/utilities/ovn-trace.c
+++ b/ovn/utilities/ovn-trace.c
@@ -33,6 +33,7 @@
#include "ovn/lex.h"
#include "ovn/lib/logical-fields.h"
#include "ovn/lib/ovn-sb-idl.h"
+#include "ovn/lib/ovn-dhcp.h"
#include "ovn/lib/ovn-util.h"
#include "ovsdb-idl.h"
#include "poll-loop.h"
@@ -338,6 +339,10 @@ static struct shash symtab;
/* Address sets. */
static struct shash address_sets;
+/* DHCP options. */
+static struct hmap dhcp_opts; /* Contains "struct dhcp_opts_map"s. */
+static struct hmap dhcpv6_opts; /* Contains "struct dhcp_opts_map"s. */
+
static struct ovntrace_datapath *
ovntrace_datapath_find_by_sb_uuid(const struct uuid *sb_uuid)
{
@@ -608,7 +613,8 @@ read_flows(void)
struct ovnact_parse_params pp = {
.symtab = &symtab,
- .dhcp_opts = NULL /* XXX */,
+ .dhcp_opts = &dhcp_opts,
+ .dhcpv6_opts = &dhcpv6_opts,
.n_tables = 16,
.cur_ltable = sblf->table_id,
};
@@ -666,6 +672,23 @@ read_flows(void)
}
static void
+read_dhcp_opts(void)
+{
+ hmap_init(&dhcp_opts);
+ const struct sbrec_dhcp_options *sdo;
+ SBREC_DHCP_OPTIONS_FOR_EACH (sdo, ovnsb_idl) {
+ dhcp_opt_add(&dhcp_opts, sdo->name, sdo->code, sdo->type);
+ }
+
+
+ hmap_init(&dhcpv6_opts);
+ const struct sbrec_dhcpv6_options *sdo6;
+ SBREC_DHCPV6_OPTIONS_FOR_EACH(sdo6, ovnsb_idl) {
+ dhcp_opt_add(&dhcpv6_opts, sdo6->name, sdo6->code, sdo6->type);
+ }
+}
+
+static void
read_mac_bindings(void)
{
const struct sbrec_mac_binding *sbmb;
@@ -713,6 +736,7 @@ read_db(void)
read_ports();
read_mcgroups();
read_address_sets();
+ read_dhcp_opts();
read_flows();
read_mac_bindings();
}
@@ -1209,8 +1233,37 @@ execute_get_mac_bind(const struct ovnact_get_mac_bind *bind,
static void
execute_put_dhcp_opts(const struct ovnact_put_dhcp_opts *pdo,
- struct flow *uflow)
+ const char *name, struct flow *uflow,
+ struct ovs_list *super)
{
+ ovntrace_node_append(
+ super, OVNTRACE_NODE_ERROR,
+ "/* We assume that this packet is DHCPDISCOVER or DHCPREQUEST. */");
+
+ /* Format the put_dhcp_opts action. */
+ struct ds s = DS_EMPTY_INITIALIZER;
+ for (const struct ovnact_dhcp_option *o = pdo->options;
+ o < &pdo->options[pdo->n_options]; o++) {
+ if (o != pdo->options) {
+ ds_put_cstr(&s, ", ");
+ }
+ ds_put_format(&s, "%s = ", o->option->name);
+ expr_constant_set_format(&o->value, &s);
+ }
+ ovntrace_node_append(super, OVNTRACE_NODE_MODIFY, "%s(%s)",
+ name, ds_cstr(&s));
+ ds_destroy(&s);
+
+ struct mf_subfield dst = expr_resolve_field(&pdo->dst);
+ if (!mf_is_register(dst.field->id)) {
+ /* Format assignment. */
+ struct ds s = DS_EMPTY_INITIALIZER;
+ expr_field_format(&pdo->dst, &s);
+ ovntrace_node_append(super, OVNTRACE_NODE_MODIFY,
+ "%s = 1", ds_cstr(&s));
+ ds_destroy(&s);
+ }
+
struct mf_subfield sf = expr_resolve_field(&pdo->dst);
union mf_subvalue sv = { .u8_val = 1 };
mf_write_subfield_flow(&sf, &sv, uflow);
@@ -1304,11 +1357,13 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len,
break;
case OVNACT_PUT_DHCPV4_OPTS:
- execute_put_dhcp_opts(ovnact_get_PUT_DHCPV4_OPTS(a), uflow);
+ execute_put_dhcp_opts(ovnact_get_PUT_DHCPV4_OPTS(a),
+ "put_dhcp_opts", uflow, super);
break;
case OVNACT_PUT_DHCPV6_OPTS:
- execute_put_dhcp_opts(ovnact_get_PUT_DHCPV6_OPTS(a), uflow);
+ execute_put_dhcp_opts(ovnact_get_PUT_DHCPV6_OPTS(a),
+ "put_dhcpv6_opts", uflow, super);
break;
case OVNACT_SET_QUEUE: