diff mbox

[ovs-dev] ovn-northd: Add flows in DHCP_OPTIONS pipeline to support renew requests

Message ID 20170124185859.19365-1-nusiddiq@redhat.com
State Superseded
Headers show

Commit Message

Numan Siddique Jan. 24, 2017, 6:58 p.m. UTC
ovn-northd adds the flows to send the DHCPv4 packets to ovn-controller
only with the match ip4.src = 0.0.0.0 and ip4.dst = 255.255.255.255.

When a DHCPv4 lease is about to expire, before sending a DHCPDISCOVER
packet, the client can send a DHCPREQUEST packet to renew its ip
with ip4.src set to its offered ip and ip4.dst set to the DHCP server
ip or broadcast ip.

This patch supports this missing scenario by adding the necessary
flows in DHCP_OPTIONS ingress pipeline.

Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
---
 ovn/northd/ovn-northd.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

Comments

Russell Bryant Jan. 24, 2017, 8:10 p.m. UTC | #1
On Tue, Jan 24, 2017 at 1:58 PM, Numan Siddique <nusiddiq@redhat.com> wrote:

> ovn-northd adds the flows to send the DHCPv4 packets to ovn-controller
> only with the match ip4.src = 0.0.0.0 and ip4.dst = 255.255.255.255.
>
> When a DHCPv4 lease is about to expire, before sending a DHCPDISCOVER
> packet, the client can send a DHCPREQUEST packet to renew its ip
> with ip4.src set to its offered ip and ip4.dst set to the DHCP server
> ip or broadcast ip.
>
> This patch supports this missing scenario by adding the necessary
> flows in DHCP_OPTIONS ingress pipeline.
>
> Signed-off-by: Numan Siddique <nusiddiq@redhat.com>


Thanks for working on this, Numan!

I see some DHCP test cases in tests/ovn.at.  Could you look at extending
those to cover this case as well?

Thanks,
Numan Siddique Jan. 25, 2017, 7:56 a.m. UTC | #2
On Wed, Jan 25, 2017 at 1:40 AM, Russell Bryant <russell@ovn.org> wrote:

>
>
> On Tue, Jan 24, 2017 at 1:58 PM, Numan Siddique <nusiddiq@redhat.com>
> wrote:
>
>> ovn-northd adds the flows to send the DHCPv4 packets to ovn-controller
>> only with the match ip4.src = 0.0.0.0 and ip4.dst = 255.255.255.255.
>>
>> When a DHCPv4 lease is about to expire, before sending a DHCPDISCOVER
>> packet, the client can send a DHCPREQUEST packet to renew its ip
>> with ip4.src set to its offered ip and ip4.dst set to the DHCP server
>> ip or broadcast ip.
>>
>> This patch supports this missing scenario by adding the necessary
>> flows in DHCP_OPTIONS ingress pipeline.
>>
>> Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
>
>
> Thanks for working on this, Numan!
>
> I see some DHCP test cases in tests/ovn.at.  Could you look at extending
> those to cover this case as well?
>

​Thanks for the review. Done.​

​I just posted v2​

​Numan
​


> Thanks,
>
> --
> Russell Bryant
>
diff mbox

Patch

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 87c80d1..3b05470 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -2115,7 +2115,8 @@  lsp_is_up(const struct nbrec_logical_switch_port *lsp)
 
 static bool
 build_dhcpv4_action(struct ovn_port *op, ovs_be32 offer_ip,
-                    struct ds *options_action, struct ds *response_action)
+                    struct ds *options_action, struct ds *response_action,
+                    struct ds *ipv4_addr_match)
 {
     if (!op->nbsp->dhcpv4_options) {
         /* CMS has disabled native DHCPv4 for this lport. */
@@ -2185,6 +2186,9 @@  build_dhcpv4_action(struct ovn_port *op, ovs_be32 offer_ip,
                   "output;",
                   server_mac, IP_ARGS(offer_ip), server_ip);
 
+    ds_put_format(ipv4_addr_match,
+                  "ip4.src == "IP_FMT" && ip4.dst == {%s, 255.255.255.255}",
+                  IP_ARGS(offer_ip), server_ip);
     smap_destroy(&dhcpv4_options);
     return true;
 }
@@ -3085,9 +3089,10 @@  build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
             for (size_t j = 0; j < op->lsp_addrs[i].n_ipv4_addrs; j++) {
                 struct ds options_action = DS_EMPTY_INITIALIZER;
                 struct ds response_action = DS_EMPTY_INITIALIZER;
+                struct ds ipv4_addr_match = DS_EMPTY_INITIALIZER;
                 if (build_dhcpv4_action(
                         op, op->lsp_addrs[i].ipv4_addrs[j].addr,
-                        &options_action, &response_action)) {
+                        &options_action, &response_action, &ipv4_addr_match)) {
                     struct ds match = DS_EMPTY_INITIALIZER;
                     ds_put_format(
                         &match, "inport == %s && eth.src == %s && "
@@ -3098,15 +3103,39 @@  build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                     ovn_lflow_add(lflows, op->od, S_SWITCH_IN_DHCP_OPTIONS,
                                   100, ds_cstr(&match),
                                   ds_cstr(&options_action));
+                    ds_clear(&match);
+                    /* Allow ip4.src = OFFER_IP and
+                     * ip4.dst = {SERVER_IP, 255.255.255.255} for the below
+                     * cases
+                     *  -  When the client wants to renew the IP by sending
+                     *     the DHCPREQUEST to the server ip.
+                     *  -  When the client wants to renew the IP by
+                     *     broadcasting the DHCPREQUEST.
+                     */
+                    ds_put_format(
+                        &match, "inport == %s && eth.src == %s && "
+                        "%s && udp.src == 68 && udp.dst == 67", op->json_key,
+                        op->lsp_addrs[i].ea_s, ds_cstr(&ipv4_addr_match));
+
+                    ovn_lflow_add(lflows, op->od, S_SWITCH_IN_DHCP_OPTIONS,
+                                  100, ds_cstr(&match),
+                                  ds_cstr(&options_action));
+                    ds_clear(&match);
+
                     /* If REGBIT_DHCP_OPTS_RESULT is set, it means the
-                     * put_dhcp_opts action  is successful */
-                    ds_put_cstr(&match, " && "REGBIT_DHCP_OPTS_RESULT);
+                     * put_dhcp_opts action  is successful. */
+                    ds_put_format(
+                        &match, "inport == %s && eth.src == %s && "
+                        "ip4 && udp.src == 68 && udp.dst == 67"
+                        " && "REGBIT_DHCP_OPTS_RESULT, op->json_key,
+                        op->lsp_addrs[i].ea_s);
                     ovn_lflow_add(lflows, op->od, S_SWITCH_IN_DHCP_RESPONSE,
                                   100, ds_cstr(&match),
                                   ds_cstr(&response_action));
                     ds_destroy(&match);
                     ds_destroy(&options_action);
                     ds_destroy(&response_action);
+                    ds_destroy(&ipv4_addr_match);
                     break;
                 }
             }