diff options
author | Ben Pfaff <blp@ovn.org> | 2016-12-12 09:16:18 -0800 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-12-12 09:16:18 -0800 |
commit | 1585ff634569ea37f92061b33733fd9a24c9b92a (patch) | |
tree | 1c9739134156f9c41f26f4b34128961bbec5bac3 /ovn | |
parent | c431227e33503421d3412bd33415750b6010730d (diff) | |
download | openvswitch-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.c | 63 |
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: |