{"id":817000,"url":"http://patchwork.ozlabs.org/api/patches/817000/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/patch/20170921160826.24745-1-nusiddiq@redhat.com/","project":{"id":47,"url":"http://patchwork.ozlabs.org/api/projects/47/?format=json","name":"Open vSwitch","link_name":"openvswitch","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"git@github.com:openvswitch/ovs.git","webscm_url":"https://github.com/openvswitch/ovs","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170921160826.24745-1-nusiddiq@redhat.com>","list_archive_url":null,"date":"2017-09-21T16:08:26","name":"[ovs-dev,v8,1/4] ovn util: Refactor dhcp_opts_map to make it generic","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"a337cbb6e164844f3addacf66c9182e4e6d01126","submitter":{"id":67480,"url":"http://patchwork.ozlabs.org/api/people/67480/?format=json","name":"Numan Siddique","email":"nusiddiq@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/openvswitch/patch/20170921160826.24745-1-nusiddiq@redhat.com/mbox/","series":[{"id":4431,"url":"http://patchwork.ozlabs.org/api/series/4431/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/list/?series=4431","date":"2017-09-21T16:07:47","name":"ovn IPv6: Add Router Solicitation responder support and generate Neighbor Solicitation request for unknown MACs","version":8,"mbox":"http://patchwork.ozlabs.org/series/4431/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/817000/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/817000/checks/","tags":{},"related":[],"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","ovs-dev@mail.linuxfoundation.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=openvswitch.org\n\t(client-ip=140.211.169.12; helo=mail.linuxfoundation.org;\n\tenvelope-from=ovs-dev-bounces@openvswitch.org;\n\treceiver=<UNKNOWN>)","ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com","ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=nusiddiq@redhat.com"],"Received":["from mail.linuxfoundation.org (mail.linuxfoundation.org\n\t[140.211.169.12])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xyhPH2wMDz9t4B\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 02:08:51 +1000 (AEST)","from mail.linux-foundation.org (localhost [127.0.0.1])\n\tby mail.linuxfoundation.org (Postfix) with ESMTP id CD558B7D;\n\tThu, 21 Sep 2017 16:08:48 +0000 (UTC)","from smtp1.linuxfoundation.org (smtp1.linux-foundation.org\n\t[172.17.192.35])\n\tby mail.linuxfoundation.org (Postfix) with ESMTPS id 061F9A49\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 16:08:47 +0000 (UTC)","from mx1.redhat.com (mx1.redhat.com [209.132.183.28])\n\tby smtp1.linuxfoundation.org (Postfix) with ESMTPS id DDACA204\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 16:08:45 +0000 (UTC)","from smtp.corp.redhat.com\n\t(int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 59D60CD277\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 16:08:45 +0000 (UTC)","from numans.blr.redhat.com (ovpn-116-55.sin2.redhat.com\n\t[10.67.116.55])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id CF209614E6;\n\tThu, 21 Sep 2017 16:08:41 +0000 (UTC)"],"X-Greylist":["domain auto-whitelisted by SQLgrey-1.7.6","Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.38]);\n\tThu, 21 Sep 2017 16:08:45 +0000 (UTC)"],"DMARC-Filter":"OpenDMARC Filter v1.3.2 mx1.redhat.com 59D60CD277","From":"nusiddiq@redhat.com","To":"dev@openvswitch.org","Date":"Thu, 21 Sep 2017 21:38:26 +0530","Message-Id":"<20170921160826.24745-1-nusiddiq@redhat.com>","In-Reply-To":"<20170921160747.24602-1-nusiddiq@redhat.com>","References":"<20170921160747.24602-1-nusiddiq@redhat.com>","X-Scanned-By":"MIMEDefang 2.79 on 10.5.11.13","X-Spam-Status":"No, score=-5.0 required=5.0 tests=RCVD_IN_DNSWL_HI,\n\tRP_MATCHES_RCVD autolearn=disabled version=3.3.1","X-Spam-Checker-Version":"SpamAssassin 3.3.1 (2010-03-16) on\n\tsmtp1.linux-foundation.org","Subject":"[ovs-dev] [PATCH v8 1/4] ovn util: Refactor dhcp_opts_map to make\n\tit generic","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.12","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"ovs-dev-bounces@openvswitch.org","Errors-To":"ovs-dev-bounces@openvswitch.org"},"content":"From: Numan Siddique <nusiddiq@redhat.com>\n\nRenamed 'struct dhcp_opts_map' to 'struct gen_opts_map' and\nrenamed ovn-dhcp.h to ovn-l7.h. An upcoming commit to support IPv6\nRouter Advertisement, will make use of the refactored code to store\nthe IPv6 ND RA options in 'struct gen_opts_map'.\n\nSigned-off-by: Numan Siddique <nusiddiq@redhat.com>\nAcked-by: Miguel Angel Ajo <majopela@redhat.com>\n---\n include/ovn/actions.h            |  16 +++----\n ovn/controller/lflow.c           |   2 +-\n ovn/controller/pinctrl.c         |   2 +-\n ovn/lib/actions.c                | 100 ++++++++++++++++++++++-----------------\n ovn/lib/automake.mk              |   2 +-\n ovn/lib/{ovn-dhcp.h => ovn-l7.h} |  67 ++++++++++++++++++--------\n ovn/northd/ovn-northd.c          |  14 +++---\n ovn/utilities/ovn-trace.c        |  14 +++---\n tests/test-ovn.c                 |   3 +-\n 9 files changed, 129 insertions(+), 91 deletions(-)\n rename ovn/lib/{ovn-dhcp.h => ovn-l7.h} (78%)","diff":"diff --git a/include/ovn/actions.h b/include/ovn/actions.h\nindex 0a04af7aa..d13a3747b 100644\n--- a/include/ovn/actions.h\n+++ b/include/ovn/actions.h\n@@ -68,8 +68,8 @@ struct simap;\n     OVNACT(PUT_ARP,           ovnact_put_mac_bind)    \\\n     OVNACT(GET_ND,            ovnact_get_mac_bind)    \\\n     OVNACT(PUT_ND,            ovnact_put_mac_bind)    \\\n-    OVNACT(PUT_DHCPV4_OPTS,   ovnact_put_dhcp_opts)   \\\n-    OVNACT(PUT_DHCPV6_OPTS,   ovnact_put_dhcp_opts)   \\\n+    OVNACT(PUT_DHCPV4_OPTS,   ovnact_put_opts)        \\\n+    OVNACT(PUT_DHCPV6_OPTS,   ovnact_put_opts)        \\\n     OVNACT(SET_QUEUE,         ovnact_set_queue)       \\\n     OVNACT(DNS_LOOKUP,        ovnact_dns_lookup)      \\\n     OVNACT(LOG,               ovnact_log)\n@@ -234,16 +234,16 @@ struct ovnact_put_mac_bind {\n     struct expr_field mac;      /* 48-bit Ethernet address. */\n };\n \n-struct ovnact_dhcp_option {\n-    const struct dhcp_opts_map *option;\n+struct ovnact_gen_option {\n+    const struct gen_opts_map *option;\n     struct expr_constant_set value;\n };\n \n /* OVNACT_PUT_DHCPV4_OPTS, OVNACT_PUT_DHCPV6_OPTS. */\n-struct ovnact_put_dhcp_opts {\n+struct ovnact_put_opts {\n     struct ovnact ovnact;\n     struct expr_field dst;      /* 1-bit destination field. */\n-    struct ovnact_dhcp_option *options;\n+    struct ovnact_gen_option *options;\n     size_t n_options;\n };\n \n@@ -432,10 +432,10 @@ struct ovnact_parse_params {\n      * expr_parse()). */\n     const struct shash *symtab;\n \n-    /* hmap of 'struct dhcp_opts_map' to support 'put_dhcp_opts' action */\n+    /* hmap of 'struct gen_opts_map' to support 'put_dhcp_opts' action */\n     const struct hmap *dhcp_opts;\n \n-    /* hmap of 'struct dhcp_opts_map'  to support 'put_dhcpv6_opts' action */\n+    /* hmap of 'struct gen_opts_map'  to support 'put_dhcpv6_opts' action */\n     const struct hmap *dhcpv6_opts;\n \n     /* Each OVN flow exists in a logical table within a logical pipeline.\ndiff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c\nindex 20a18c259..6b6b91abc 100644\n--- a/ovn/controller/lflow.c\n+++ b/ovn/controller/lflow.c\n@@ -25,7 +25,7 @@\n #include \"ovn-controller.h\"\n #include \"ovn/actions.h\"\n #include \"ovn/expr.h\"\n-#include \"ovn/lib/ovn-dhcp.h\"\n+#include \"ovn/lib/ovn-l7.h\"\n #include \"ovn/lib/ovn-sb-idl.h\"\n #include \"packets.h\"\n #include \"physical.h\"\ndiff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c\nindex 469a35586..43e3cba23 100644\n--- a/ovn/controller/pinctrl.c\n+++ b/ovn/controller/pinctrl.c\n@@ -41,7 +41,7 @@\n #include \"ovn/lex.h\"\n #include \"ovn/lib/acl-log.h\"\n #include \"ovn/lib/logical-fields.h\"\n-#include \"ovn/lib/ovn-dhcp.h\"\n+#include \"ovn/lib/ovn-l7.h\"\n #include \"ovn/lib/ovn-util.h\"\n #include \"poll-loop.h\"\n #include \"rconn.h\"\ndiff --git a/ovn/lib/actions.c b/ovn/lib/actions.c\nindex d0d73b69c..b2559cd07 100644\n--- a/ovn/lib/actions.c\n+++ b/ovn/lib/actions.c\n@@ -20,7 +20,7 @@\n #include \"bitmap.h\"\n #include \"byte-order.h\"\n #include \"compiler.h\"\n-#include \"ovn-dhcp.h\"\n+#include \"ovn-l7.h\"\n #include \"hash.h\"\n #include \"logical-fields.h\"\n #include \"nx-match.h\"\n@@ -1374,19 +1374,17 @@ ovnact_put_mac_bind_free(struct ovnact_put_mac_bind *put_mac OVS_UNUSED)\n }\n \f\n static void\n-parse_dhcp_opt(struct action_context *ctx, struct ovnact_dhcp_option *o,\n-               bool v6)\n+parse_gen_opt(struct action_context *ctx, struct ovnact_gen_option *o,\n+              const struct hmap *gen_opts, const char *opts_type)\n {\n     if (ctx->lexer->token.type != LEX_T_ID) {\n         lexer_syntax_error(ctx->lexer, NULL);\n         return;\n     }\n \n-    const char *name = v6 ? \"DHCPv6\" : \"DHCPv4\";\n-    const struct hmap *map = v6 ? ctx->pp->dhcpv6_opts : ctx->pp->dhcp_opts;\n-    o->option = map ? dhcp_opts_find(map, ctx->lexer->token.s) : NULL;\n+    o->option = gen_opts ? gen_opts_find(gen_opts, ctx->lexer->token.s) : NULL;\n     if (!o->option) {\n-        lexer_syntax_error(ctx->lexer, \"expecting %s option name\", name);\n+        lexer_syntax_error(ctx->lexer, \"expecting %s option name\", opts_type);\n         return;\n     }\n     lexer_get(ctx->lexer);\n@@ -1403,22 +1401,22 @@ parse_dhcp_opt(struct action_context *ctx, struct ovnact_dhcp_option *o,\n     if (!strcmp(o->option->type, \"str\")) {\n         if (o->value.type != EXPR_C_STRING) {\n             lexer_error(ctx->lexer, \"%s option %s requires string value.\",\n-                        name, o->option->name);\n+                        opts_type, o->option->name);\n             return;\n         }\n     } else {\n         if (o->value.type != EXPR_C_INTEGER) {\n             lexer_error(ctx->lexer, \"%s option %s requires numeric value.\",\n-                        name, o->option->name);\n+                        opts_type, o->option->name);\n             return;\n         }\n     }\n }\n \n-static const struct ovnact_dhcp_option *\n-find_offerip(const struct ovnact_dhcp_option *options, size_t n)\n+static const struct ovnact_gen_option *\n+find_offerip(const struct ovnact_gen_option *options, size_t n)\n {\n-    for (const struct ovnact_dhcp_option *o = options; o < &options[n]; o++) {\n+    for (const struct ovnact_gen_option *o = options; o < &options[n]; o++) {\n         if (o->option->code == 0) {\n             return o;\n         }\n@@ -1427,21 +1425,18 @@ find_offerip(const struct ovnact_dhcp_option *options, size_t n)\n }\n \n static void\n-free_dhcp_options(struct ovnact_dhcp_option *options, size_t n)\n+free_gen_options(struct ovnact_gen_option *options, size_t n)\n {\n-    for (struct ovnact_dhcp_option *o = options; o < &options[n]; o++) {\n+    for (struct ovnact_gen_option *o = options; o < &options[n]; o++) {\n         expr_constant_set_destroy(&o->value);\n     }\n     free(options);\n }\n \n-/* Parses the \"put_dhcp_opts\" and \"put_dhcpv6_opts\" actions.\n- *\n- * The caller has already consumed \"<dst> =\", so this just parses the rest. */\n static void\n-parse_put_dhcp_opts(struct action_context *ctx,\n-                    const struct expr_field *dst,\n-                    struct ovnact_put_dhcp_opts *pdo)\n+parse_put_opts(struct action_context *ctx, const struct expr_field *dst,\n+               struct ovnact_put_opts *po, const struct hmap *gen_opts,\n+               const char *opts_type)\n {\n     lexer_get(ctx->lexer); /* Skip put_dhcp[v6]_opts. */\n     lexer_get(ctx->lexer); /* Skip '('. */\n@@ -1453,27 +1448,44 @@ parse_put_dhcp_opts(struct action_context *ctx,\n         free(error);\n         return;\n     }\n-    pdo->dst = *dst;\n+    po->dst = *dst;\n \n     size_t allocated_options = 0;\n     while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {\n-        if (pdo->n_options >= allocated_options) {\n-            pdo->options = x2nrealloc(pdo->options, &allocated_options,\n-                                      sizeof *pdo->options);\n+        if (po->n_options >= allocated_options) {\n+            po->options = x2nrealloc(po->options, &allocated_options,\n+                                     sizeof *po->options);\n         }\n \n-        struct ovnact_dhcp_option *o = &pdo->options[pdo->n_options++];\n+        struct ovnact_gen_option *o = &po->options[po->n_options++];\n         memset(o, 0, sizeof *o);\n-        parse_dhcp_opt(ctx, o, pdo->ovnact.type == OVNACT_PUT_DHCPV6_OPTS);\n+        parse_gen_opt(ctx, o, gen_opts, opts_type);\n         if (ctx->lexer->error) {\n             return;\n         }\n \n         lexer_match(ctx->lexer, LEX_T_COMMA);\n     }\n+}\n+\n+/* Parses the \"put_dhcp_opts\" and \"put_dhcpv6_opts\" actions.\n+ *\n+ * The caller has already consumed \"<dst> =\", so this just parses the rest. */\n+static void\n+parse_put_dhcp_opts(struct action_context *ctx,\n+                    const struct expr_field *dst,\n+                    struct ovnact_put_opts *po)\n+{\n+    const struct hmap *dhcp_opts =\n+        (po->ovnact.type == OVNACT_PUT_DHCPV6_OPTS) ?\n+            ctx->pp->dhcpv6_opts : ctx->pp->dhcp_opts;\n+    const char *opts_type =\n+        (po->ovnact.type == OVNACT_PUT_DHCPV6_OPTS) ? \"DHCPv6\" : \"DHCPv4\";\n+\n+    parse_put_opts(ctx, dst, po, dhcp_opts, opts_type);\n \n-    if (pdo->ovnact.type == OVNACT_PUT_DHCPV4_OPTS\n-        && !find_offerip(pdo->options, pdo->n_options)) {\n+    if (!ctx->lexer->error && po->ovnact.type == OVNACT_PUT_DHCPV4_OPTS\n+        && !find_offerip(po->options, po->n_options)) {\n         lexer_error(ctx->lexer,\n                     \"put_dhcp_opts requires offerip to be specified.\");\n         return;\n@@ -1481,12 +1493,12 @@ parse_put_dhcp_opts(struct action_context *ctx,\n }\n \n static void\n-format_put_dhcp_opts(const char *name,\n-                     const struct ovnact_put_dhcp_opts *pdo, struct ds *s)\n+format_put_opts(const char *name, const struct ovnact_put_opts *pdo,\n+                struct ds *s)\n {\n     expr_field_format(&pdo->dst, s);\n     ds_put_format(s, \" = %s(\", name);\n-    for (const struct ovnact_dhcp_option *o = pdo->options;\n+    for (const struct ovnact_gen_option *o = pdo->options;\n          o < &pdo->options[pdo->n_options]; o++) {\n         if (o != pdo->options) {\n             ds_put_cstr(s, \", \");\n@@ -1498,19 +1510,19 @@ format_put_dhcp_opts(const char *name,\n }\n \n static void\n-format_PUT_DHCPV4_OPTS(const struct ovnact_put_dhcp_opts *pdo, struct ds *s)\n+format_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo, struct ds *s)\n {\n-    format_put_dhcp_opts(\"put_dhcp_opts\", pdo, s);\n+    format_put_opts(\"put_dhcp_opts\", pdo, s);\n }\n \n static void\n-format_PUT_DHCPV6_OPTS(const struct ovnact_put_dhcp_opts *pdo, struct ds *s)\n+format_PUT_DHCPV6_OPTS(const struct ovnact_put_opts *pdo, struct ds *s)\n {\n-    format_put_dhcp_opts(\"put_dhcpv6_opts\", pdo, s);\n+    format_put_opts(\"put_dhcpv6_opts\", pdo, s);\n }\n \n static void\n-encode_put_dhcpv4_option(const struct ovnact_dhcp_option *o,\n+encode_put_dhcpv4_option(const struct ovnact_gen_option *o,\n                          struct ofpbuf *ofpacts)\n {\n     uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2);\n@@ -1586,7 +1598,7 @@ encode_put_dhcpv4_option(const struct ovnact_dhcp_option *o,\n }\n \n static void\n-encode_put_dhcpv6_option(const struct ovnact_dhcp_option *o,\n+encode_put_dhcpv6_option(const struct ovnact_gen_option *o,\n                          struct ofpbuf *ofpacts)\n {\n     struct dhcp_opt6_header *opt = ofpbuf_put_uninit(ofpacts, sizeof *opt);\n@@ -1614,7 +1626,7 @@ encode_put_dhcpv6_option(const struct ovnact_dhcp_option *o,\n }\n \n static void\n-encode_PUT_DHCPV4_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n+encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,\n                        const struct ovnact_encode_params *ep OVS_UNUSED,\n                        struct ofpbuf *ofpacts)\n {\n@@ -1629,12 +1641,12 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n     /* Encode the offerip option first, because it's a special case and needs\n      * to be first in the actual DHCP response, and then encode the rest\n      * (skipping offerip the second time around). */\n-    const struct ovnact_dhcp_option *offerip_opt = find_offerip(\n+    const struct ovnact_gen_option *offerip_opt = find_offerip(\n         pdo->options, pdo->n_options);\n     ovs_be32 offerip = offerip_opt->value.values[0].value.ipv4;\n     ofpbuf_put(ofpacts, &offerip, sizeof offerip);\n \n-    for (const struct ovnact_dhcp_option *o = pdo->options;\n+    for (const struct ovnact_gen_option *o = pdo->options;\n          o < &pdo->options[pdo->n_options]; o++) {\n         if (o != offerip_opt) {\n             encode_put_dhcpv4_option(o, ofpacts);\n@@ -1645,7 +1657,7 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n }\n \n static void\n-encode_PUT_DHCPV6_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n+encode_PUT_DHCPV6_OPTS(const struct ovnact_put_opts *pdo,\n                        const struct ovnact_encode_params *ep OVS_UNUSED,\n                        struct ofpbuf *ofpacts)\n {\n@@ -1657,7 +1669,7 @@ encode_PUT_DHCPV6_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n     ovs_be32 ofs = htonl(dst.ofs);\n     ofpbuf_put(ofpacts, &ofs, sizeof ofs);\n \n-    for (const struct ovnact_dhcp_option *o = pdo->options;\n+    for (const struct ovnact_gen_option *o = pdo->options;\n          o < &pdo->options[pdo->n_options]; o++) {\n         encode_put_dhcpv6_option(o, ofpacts);\n     }\n@@ -1666,9 +1678,9 @@ encode_PUT_DHCPV6_OPTS(const struct ovnact_put_dhcp_opts *pdo,\n }\n \n static void\n-ovnact_put_dhcp_opts_free(struct ovnact_put_dhcp_opts *pdo)\n+ovnact_put_opts_free(struct ovnact_put_opts *pdo)\n {\n-    free_dhcp_options(pdo->options, pdo->n_options);\n+    free_gen_options(pdo->options, pdo->n_options);\n }\n \n static void\ndiff --git a/ovn/lib/automake.mk b/ovn/lib/automake.mk\nindex d9ed050f3..dae06a5c1 100644\n--- a/ovn/lib/automake.mk\n+++ b/ovn/lib/automake.mk\n@@ -11,7 +11,7 @@ ovn_lib_libovn_la_SOURCES = \\\n \tovn/lib/chassis-index.h \\\n \tovn/lib/expr.c \\\n \tovn/lib/lex.c \\\n-\tovn/lib/ovn-dhcp.h \\\n+\tovn/lib/ovn-l7.h \\\n \tovn/lib/ovn-util.c \\\n \tovn/lib/ovn-util.h \\\n \tovn/lib/logical-fields.c \\\ndiff --git a/ovn/lib/ovn-dhcp.h b/ovn/lib/ovn-l7.h\nsimilarity index 78%\nrename from ovn/lib/ovn-dhcp.h\nrename to ovn/lib/ovn-l7.h\nindex d5561edfa..40bd75461 100644\n--- a/ovn/lib/ovn-dhcp.h\n+++ b/ovn/lib/ovn-l7.h\n@@ -21,7 +21,8 @@\n #include \"openvswitch/hmap.h\"\n #include \"hash.h\"\n \n-struct dhcp_opts_map {\n+/* Generic options map which is used to store dhcpv4 opts and dhcpv6 opts. */\n+struct gen_opts_map {\n     struct hmap_node hmap_node;\n     char *name;\n     char *type;\n@@ -68,45 +69,69 @@ struct dhcp_opts_map {\n #define DHCP_OPT_T2 DHCP_OPTION(\"T2\", 59, \"uint32\")\n \n static inline uint32_t\n-dhcp_opt_hash(char *opt_name)\n+gen_opt_hash(char *opt_name)\n {\n     return hash_string(opt_name, 0);\n }\n \n-static inline struct dhcp_opts_map *\n-dhcp_opts_find(const struct hmap *dhcp_opts, char *opt_name)\n+static inline uint32_t\n+dhcp_opt_hash(char *opt_name)\n {\n-    struct dhcp_opts_map *dhcp_opt;\n-    HMAP_FOR_EACH_WITH_HASH (dhcp_opt, hmap_node, dhcp_opt_hash(opt_name),\n-                             dhcp_opts) {\n-        if (!strcmp(dhcp_opt->name, opt_name)) {\n-            return dhcp_opt;\n+    return gen_opt_hash(opt_name);\n+}\n+\n+static inline struct gen_opts_map *\n+gen_opts_find(const struct hmap *gen_opts, char *opt_name)\n+{\n+    struct gen_opts_map *gen_opt;\n+    HMAP_FOR_EACH_WITH_HASH (gen_opt, hmap_node, gen_opt_hash(opt_name),\n+                             gen_opts) {\n+        if (!strcmp(gen_opt->name, opt_name)) {\n+            return gen_opt;\n         }\n     }\n \n     return NULL;\n }\n \n+static inline struct gen_opts_map *\n+dhcp_opts_find(const struct hmap *dhcp_opts, char *opt_name)\n+{\n+    return gen_opts_find(dhcp_opts, opt_name);\n+}\n+\n+static inline void\n+gen_opt_add(struct hmap *gen_opts, char *opt_name, size_t code, char *type)\n+{\n+    struct gen_opts_map *gen_opt = xzalloc(sizeof *gen_opt);\n+    gen_opt->name = xstrdup(opt_name);\n+    gen_opt->code = code;\n+    gen_opt->type = xstrdup(type);\n+    hmap_insert(gen_opts, &gen_opt->hmap_node, gen_opt_hash(opt_name));\n+}\n+\n static inline void\n dhcp_opt_add(struct hmap *dhcp_opts, char *opt_name, size_t code, char *type)\n {\n-    struct dhcp_opts_map *dhcp_opt = xzalloc(sizeof *dhcp_opt);\n-    dhcp_opt->name = xstrdup(opt_name);\n-    dhcp_opt->code = code;\n-    dhcp_opt->type = xstrdup(type);\n-    hmap_insert(dhcp_opts, &dhcp_opt->hmap_node, dhcp_opt_hash(opt_name));\n+    gen_opt_add(dhcp_opts, opt_name, code, type);\n }\n \n static inline void\n-dhcp_opts_destroy(struct hmap *dhcp_opts)\n+gen_opts_destroy(struct hmap *gen_opts)\n {\n-    struct dhcp_opts_map *dhcp_opt;\n-    HMAP_FOR_EACH_POP(dhcp_opt, hmap_node, dhcp_opts) {\n-        free(dhcp_opt->name);\n-        free(dhcp_opt->type);\n-        free(dhcp_opt);\n+    struct gen_opts_map *gen_opt;\n+    HMAP_FOR_EACH_POP (gen_opt, hmap_node, gen_opts) {\n+        free(gen_opt->name);\n+        free(gen_opt->type);\n+        free(gen_opt);\n     }\n-    hmap_destroy(dhcp_opts);\n+    hmap_destroy(gen_opts);\n+}\n+\n+static inline void\n+dhcp_opts_destroy(struct hmap *dhcp_opts)\n+{\n+    gen_opts_destroy(dhcp_opts);\n }\n \n /* Used in the OpenFlow PACKET_IN userdata */\ndiff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c\nindex 2db238073..75f2c6607 100644\n--- a/ovn/northd/ovn-northd.c\n+++ b/ovn/northd/ovn-northd.c\n@@ -30,7 +30,7 @@\n #include \"ovn/lex.h\"\n #include \"ovn/lib/chassis-index.h\"\n #include \"ovn/lib/logical-fields.h\"\n-#include \"ovn/lib/ovn-dhcp.h\"\n+#include \"ovn/lib/ovn-l7.h\"\n #include \"ovn/lib/ovn-nb-idl.h\"\n #include \"ovn/lib/ovn-sb-idl.h\"\n #include \"ovn/lib/ovn-util.h\"\n@@ -5995,7 +5995,7 @@ update_logical_port_status(struct northd_context *ctx)\n     hmap_destroy(&lports_hmap);\n }\n \n-static struct dhcp_opts_map supported_dhcp_opts[] = {\n+static struct gen_opts_map supported_dhcp_opts[] = {\n     OFFERIP,\n     DHCP_OPT_NETMASK,\n     DHCP_OPT_ROUTER,\n@@ -6022,7 +6022,7 @@ static struct dhcp_opts_map supported_dhcp_opts[] = {\n     DHCP_OPT_T2\n };\n \n-static struct dhcp_opts_map supported_dhcpv6_opts[] = {\n+static struct gen_opts_map supported_dhcpv6_opts[] = {\n     DHCPV6_OPT_IA_ADDR,\n     DHCPV6_OPT_SERVER_ID,\n     DHCPV6_OPT_DOMAIN_SEARCH,\n@@ -6041,7 +6041,7 @@ check_and_add_supported_dhcp_opts_to_sb_db(struct northd_context *ctx)\n \n     const struct sbrec_dhcp_options *opt_row, *opt_row_next;\n     SBREC_DHCP_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, ctx->ovnsb_idl) {\n-        struct dhcp_opts_map *dhcp_opt =\n+        struct gen_opts_map *dhcp_opt =\n             dhcp_opts_find(&dhcp_opts_to_add, opt_row->name);\n         if (dhcp_opt) {\n             hmap_remove(&dhcp_opts_to_add, &dhcp_opt->hmap_node);\n@@ -6050,7 +6050,7 @@ check_and_add_supported_dhcp_opts_to_sb_db(struct northd_context *ctx)\n         }\n     }\n \n-    struct dhcp_opts_map *opt;\n+    struct gen_opts_map *opt;\n     HMAP_FOR_EACH (opt, hmap_node, &dhcp_opts_to_add) {\n         struct sbrec_dhcp_options *sbrec_dhcp_option =\n             sbrec_dhcp_options_insert(ctx->ovnsb_txn);\n@@ -6074,7 +6074,7 @@ check_and_add_supported_dhcpv6_opts_to_sb_db(struct northd_context *ctx)\n \n     const struct sbrec_dhcpv6_options *opt_row, *opt_row_next;\n     SBREC_DHCPV6_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, ctx->ovnsb_idl) {\n-        struct dhcp_opts_map *dhcp_opt =\n+        struct gen_opts_map *dhcp_opt =\n             dhcp_opts_find(&dhcpv6_opts_to_add, opt_row->name);\n         if (dhcp_opt) {\n             hmap_remove(&dhcpv6_opts_to_add, &dhcp_opt->hmap_node);\n@@ -6083,7 +6083,7 @@ check_and_add_supported_dhcpv6_opts_to_sb_db(struct northd_context *ctx)\n         }\n     }\n \n-    struct dhcp_opts_map *opt;\n+    struct gen_opts_map *opt;\n     HMAP_FOR_EACH(opt, hmap_node, &dhcpv6_opts_to_add) {\n         struct sbrec_dhcpv6_options *sbrec_dhcpv6_option =\n             sbrec_dhcpv6_options_insert(ctx->ovnsb_txn);\ndiff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c\nindex 59083eebe..d9465c90c 100644\n--- a/ovn/utilities/ovn-trace.c\n+++ b/ovn/utilities/ovn-trace.c\n@@ -36,8 +36,8 @@\n #include \"ovn/lex.h\"\n #include \"ovn/lib/acl-log.h\"\n #include \"ovn/lib/logical-fields.h\"\n+#include \"ovn/lib/ovn-l7.h\"\n #include \"ovn/lib/ovn-sb-idl.h\"\n-#include \"ovn/lib/ovn-dhcp.h\"\n #include \"ovn/lib/ovn-util.h\"\n #include \"ovsdb-idl.h\"\n #include \"poll-loop.h\"\n@@ -418,8 +418,8 @@ static struct shash symtab;\n static struct shash address_sets;\n \n /* DHCP options. */\n-static struct hmap dhcp_opts;   /* Contains \"struct dhcp_opts_map\"s. */\n-static struct hmap dhcpv6_opts; /* Contains \"struct dhcp_opts_map\"s. */\n+static struct hmap dhcp_opts;   /* Contains \"struct gen_opts_map\"s. */\n+static struct hmap dhcpv6_opts; /* Contains \"struct gen_opts_map\"s. */\n \n static struct ovntrace_datapath *\n ovntrace_datapath_find_by_sb_uuid(const struct uuid *sb_uuid)\n@@ -867,7 +867,7 @@ read_flows(void)\n }\n \n static void\n-read_dhcp_opts(void)\n+read_gen_opts(void)\n {\n     hmap_init(&dhcp_opts);\n     const struct sbrec_dhcp_options *sdo;\n@@ -931,7 +931,7 @@ read_db(void)\n     read_ports();\n     read_mcgroups();\n     read_address_sets();\n-    read_dhcp_opts();\n+    read_gen_opts();\n     read_flows();\n     read_mac_bindings();\n }\n@@ -1541,7 +1541,7 @@ execute_get_mac_bind(const struct ovnact_get_mac_bind *bind,\n }\n \n static void\n-execute_put_dhcp_opts(const struct ovnact_put_dhcp_opts *pdo,\n+execute_put_dhcp_opts(const struct ovnact_put_opts *pdo,\n                       const char *name, struct flow *uflow,\n                       struct ovs_list *super)\n {\n@@ -1551,7 +1551,7 @@ execute_put_dhcp_opts(const struct ovnact_put_dhcp_opts *pdo,\n \n     /* Format the put_dhcp_opts action. */\n     struct ds s = DS_EMPTY_INITIALIZER;\n-    for (const struct ovnact_dhcp_option *o = pdo->options;\n+    for (const struct ovnact_gen_option *o = pdo->options;\n          o < &pdo->options[pdo->n_options]; o++) {\n         if (o != pdo->options) {\n             ds_put_cstr(&s, \", \");\ndiff --git a/tests/test-ovn.c b/tests/test-ovn.c\nindex 4beb2b8d6..67221ea50 100644\n--- a/tests/test-ovn.c\n+++ b/tests/test-ovn.c\n@@ -18,6 +18,7 @@\n #include <errno.h>\n #include <getopt.h>\n #include <sys/wait.h>\n+\n #include \"command-line.h\"\n #include \"dp-packet.h\"\n #include \"fatal-signal.h\"\n@@ -31,7 +32,7 @@\n #include \"ovn/expr.h\"\n #include \"ovn/lex.h\"\n #include \"ovn/lib/logical-fields.h\"\n-#include \"ovn/lib/ovn-dhcp.h\"\n+#include \"ovn/lib/ovn-l7.h\"\n #include \"ovs-thread.h\"\n #include \"ovstest.h\"\n #include \"openvswitch/shash.h\"\n","prefixes":["ovs-dev","v8","1/4"]}