The ovn-controller registers a flow in table 33 (LOCAL_OUTPUT) to
send a packet matching the DHCP discover/request structure to
a specific controller id, that the ovn pinctrl has registered on
it's ofconn.

Signed-off-by: Babu Shanmugam <bscha...@redhat.com>
Signed-off-by: Numan Siddique <nusid...@redhat.com>
Co-Authored-by: Numan Siddique <nusid...@redhat.com>
---
 lib/ofp-util.c            | 14 ++++++++++++++
 lib/ofp-util.h            |  3 +++
 ovn/controller/physical.c | 27 ++++++++++++++++++++++++---
 ovn/controller/pinctrl.c  |  6 ++++++
 ovn/controller/pinctrl.h  |  2 ++
 5 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 342be54..7cfa06b 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -1544,6 +1544,20 @@ ofputil_make_set_packet_in_format(enum ofp_version ofp_version,
     return msg;
 }

+struct ofpbuf *
+ofputil_make_set_controller_id(enum ofp_version ofp_version,
+                               uint16_t controller_id)
+{
+    struct nx_controller_id *cid;
+    struct ofpbuf *msg;
+
+    msg = ofpraw_alloc(OFPRAW_NXT_SET_CONTROLLER_ID, ofp_version, 0);
+    cid = ofpbuf_put_zeros(msg, sizeof *cid);
+    cid->controller_id = htons(controller_id);
+
+    return msg;
+}
+
/* Returns an OpenFlow message that can be used to turn the flow_mod_table_id
  * extension on or off (according to 'flow_mod_table_id'). */
 struct ofpbuf *
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 8914342..5373d86 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -237,6 +237,9 @@ int ofputil_packet_in_format_from_string(const char *);
 const char *ofputil_packet_in_format_to_string(enum nx_packet_in_format);
 struct ofpbuf *ofputil_make_set_packet_in_format(enum ofp_version,
enum nx_packet_in_format);
+struct ofpbuf *
+ofputil_make_set_controller_id(enum ofp_version ofp_version,
+                               uint16_t controller_id);

 /* NXT_FLOW_MOD_TABLE_ID extension. */
 struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id);
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 5821c11..44f72dc 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -18,6 +18,7 @@
 #include "lflow.h"
 #include "match.h"
 #include "ofctrl.h"
+#include "pinctrl.h"
 #include "ofp-actions.h"
 #include "ofpbuf.h"
 #include "ovn-controller.h"
@@ -396,17 +397,37 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
                                 tag ? 150 : 100, &match, &ofpacts);
             }

-            /* Table 33, priority 100.
-             * =======================
+            /* Table 33, priority 100 and 150
+             * ==============================
              *
              * Implements output to local hypervisor.  Each flow matches a
* logical output port on the local hypervisor, and resubmits to
-             * table 34.
+             * table 34.
+             * Also, send the DHCP traffic to the controller as packet-in
              */

             match_init_catchall(&match);
             ofpbuf_clear(&ofpacts);

+ match_set_metadata(&match, htonll(binding->datapath->tunnel_key));
+            match_set_dl_type(&match, htons(ETH_TYPE_IP));
+            match_set_nw_proto(&match, IPPROTO_UDP);
+            match_set_nw_src(&match, htonl(INADDR_ANY));
+            match_set_nw_dst(&match, htonl(INADDR_BROADCAST));
+            match_set_tp_src(&match, htons(68));
+            match_set_tp_dst(&match, htons(67));
+
+            struct ofpact_controller *controller =
+                ofpact_put_CONTROLLER(&ofpacts);
+            controller->max_len = UINT16_MAX;
+            controller->controller_id = OVN_PACKET_IN_CONTROLLER_ID;
+            controller->reason = OFPR_ACTION;
+            ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 150, &match,
+                            &ofpacts);
+
+            match_init_catchall(&match);
+            ofpbuf_clear(&ofpacts);
+
             /* Match MFF_LOG_DATAPATH, MFF_LOG_OUTPORT. */
match_set_metadata(&match, htonll(binding->datapath->tunnel_key));
             match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0,
diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index 2fb8ab3..1ea683b 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -98,6 +98,7 @@ pinctrl_recv(struct controller_ctx *ctx, const struct ofp_header *oh,
     } else if (type == OFPTYPE_GET_CONFIG_REPLY) {
         struct ofpbuf rq_buf;
         struct ofpbuf *spif;
+        struct ofpbuf *scid;
         struct ofp_switch_config *config_, config;

         ofpbuf_use_const(&rq_buf, oh, ntohs(oh->length));
@@ -105,9 +106,14 @@ pinctrl_recv(struct controller_ctx *ctx, const struct ofp_header *oh,
         config = *config_;
         config.miss_send_len = htons(UINT16_MAX);
         set_switch_config(swconn, &config);
+
spif = ofputil_make_set_packet_in_format(rconn_get_version(swconn),
                                                  NXPIF_NXM);
         queue_msg(spif);
+
+        scid = ofputil_make_set_controller_id(rconn_get_version(swconn),
+ OVN_PACKET_IN_CONTROLLER_ID);
+        queue_msg(scid);
     } else if (type == OFPTYPE_PACKET_IN) {
         process_packet_in(ctx, oh);
} else if (type != OFPTYPE_ECHO_REPLY && type != OFPTYPE_BARRIER_REPLY) {
diff --git a/ovn/controller/pinctrl.h b/ovn/controller/pinctrl.h
index 65d5dfe..c51e31e 100644
--- a/ovn/controller/pinctrl.h
+++ b/ovn/controller/pinctrl.h
@@ -21,6 +21,8 @@

 #include "meta-flow.h"

+#define OVN_PACKET_IN_CONTROLLER_ID (UINT16_MAX)
+
 struct ovsrec_bridge;
 struct controller_ctx;

--
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to