I’m trying to understand whether DHCP is supported (or can easily be supported) 
for vtep port types.  The use case I am driving towards is to support DHCP/PXE 
booting for hardware over vxlan overlay network via a TOR switch.  I believe 
this could work using Neutron DHCP Agent but we’ve hit scaling issues in that 
area so we’re attempting to use OVN DHCP server if possible.

In the NB DB, the vtep port is added to the ironic provisioning network with 
both the IP/MAC set.


$ ovn-nbctl show
…
switch 99a907e0-7525-4d4e-a029-fddaafeff3e5 
(neutron-a2d49759-d8fa-43a3-8620-35201420f72b) (aka Ironic Provisioning)
    port provnet-2fd9fb49-7e68-4f86-8690-aec776e9f128
        type: localnet
        addresses: ["unknown"]
    port 2ebf0521-3f7e-44b6-848f-82a0214e3c25
        type: localport
        addresses: ["fa:16:3e:7f:e9:56 10.90.100.1"]
    port 23af2a74-0333-4600-9e11-e99bff860999
        type: vtep
        addresses: ["0c:c4:7a:ac:75:4e 10.90.100.32"]


In the SB database, I see the port binding under the data-switch-01 chassis:

$ ovn-sbctl show
Chassis compute-test
    hostname: compute-test
    Encap vxlan
        ip: "10.40.0.1"
        options: {csum="true"}
    Port_Binding "04901637-9467-4f01-b16b-e22de768a1b8"
Chassis data-switch-01
    Encap vxlan
        ip: "17.17.17.17"
        options: {csum="false"}
    Port_Binding "23af2a74-0333-4600-9e11-e99bff860999"
Chassis controller-test
    hostname: controller-test
    Encap geneve
        ip: "10.40.0.3"
        options: {csum="true"}
    Encap vxlan
        ip: "10.40.0.3"
        options: {csum="true"}
    Port_Binding cr-lrp-876f85ad-0a6f-4668-8736-e122fedc32c2



In the logical flow list, it appears that the DHCP responses are added:

  table=19(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.90.100.1 
&& arp.op == 1), action=(eth.dst = eth.src; eth.src = fa:16:3e:7f:e9:56; arp.op 
= 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = fa:16:3e:7f:e9:56; arp.tpa = 
arp.spa; arp.spa = 10.90.100.1; ou
tport = inport; flags.loopback = 1; output;)
  table=19(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.90.100.32 
&& arp.op == 1), action=(eth.dst = eth.src; eth.src = 0c:c4:7a:ac:75:4e; arp.op 
= 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 0c:c4:7a:ac:75:4e; arp.tpa = 
arp.spa; arp.spa = 10.90.100.32;
outport = inport; flags.loopback = 1; output;)
  table=19(ls_in_arp_rsp      ), priority=0    , match=(1), action=(next;)
  table=20(ls_in_dhcp_options ), priority=100  , match=(inport == 
"23af2a74-0333-4600-9e11-e99bff860999" && eth.src == 0c:c4:7a:ac:75:4e && 
ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 
67), action=(reg0[3] = put_dhcp_opts(offerip = 10.90
.100.32, bootfile_name = http://192.168.3.3:8089/boot.ipxe, bootfile_name_alt = 
"snponly.efi", classless_static_route = {169.254.169.254/32,10.90.100.1}, 
dns_server = {127.0.0.53}, lease_time = 43200, mtu = 1500, netmask = 
255.255.0.0, next_server = 192.168.3.3, server_
id = 10.90.100.1, tftp_server = "192.168.3.3", tftp_server_address = 
192.168.3.3); next;)
table=20(ls_in_dhcp_options ), priority=100  , match=(inport == 
"23af2a74-0333-4600-9e11-e99bff860999" && eth.src == 0c:c4:7a:ac:75:4e && 
ip4.src == 10.90.100.32 && ip4.dst == {10.90.100.1, 255.255.255.255} && udp.src 
== 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_
opts(offerip = 10.90.100.32, bootfile_name = http://192.168.3.3:8089/boot.ipxe, 
bootfile_name_alt = "snponly.efi", classless_static_route = 
{169.254.169.254/32,10.90.100.1}, dns_server = {127.0.0.53}, lease_time = 
43200, mtu = 1500, netmask = 255.255.0.0, next_server =
192.168.3.3, server_id = 10.90.100.1, tftp_server = "192.168.3.3", 
tftp_server_address = 192.168.3.3); next;)
  table=20(ls_in_dhcp_options ), priority=0    , match=(1), action=(next;)
  table=21(ls_in_dhcp_response), priority=100  , match=(inport == 
"23af2a74-0333-4


But when I packet capture I see the DHCP requests but no responses are sent.  
Using OVN-trace, it doesn’t appear that we’re hitting the appropriate flow to 
generate the DHCP response:

---
# ovn-trace 99a907e0-7525-4d4e-a029-fddaafeff3e5 'inport == 
"23af2a74-0333-4600-9e11-e99bff860999" && eth.src == 0c:c4:7a:ac:75:4e && 
ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 
67'
# 
udp,reg14=0x3,vlan_tci=0x0000,dl_src=0c:c4:7a:ac:75:4e,dl_dst=00:00:00:00:00:00,nw_src=0.0.0.0,nw_dst=255.255.255.255,nw_tos=0,nw_ecn=0,nw_ttl=0,nw_frag=no,tp_src=68,tp_dst=67

ingress(dp="Ironic Provisioning", inport="23af2a")
--------------------------------------------------
0. ls_in_check_port_sec (northd.c:5680): inport == "23af2a", priority 70, uuid 
aaeb17c1
    reg0[14] = 1;
    next(16);
16. ls_in_hairpin (northd.c:7637): reg0[14] == 1, priority 1000, uuid bee04e33
    next(25);
25. ls_in_l2_lkup (northd.c:8326): 1, priority 0, uuid f7842991
    outport = get_fdb(eth.dst);
    next;
26. ls_in_l2_unknown (northd.c:8330): outport == "none", priority 50, uuid 
da5c2086
    outport = "_MC_unknown";
    output;

multicast(dp="Ironic Provisioning", mcgroup="_MC_unknown")
----------------------------------------------------------

    egress(dp="Ironic Provisioning", inport="23af2a", outport="port_a")
    -------------------------------------------------------------------
         0. ls_out_pre_acl (northd.c:5904): ip, priority 100, uuid 87214ca2
            reg0[0] = 1;
            next;
         2. ls_out_pre_stateful (northd.c:6116): reg0[0] == 1, priority 100, 
uuid 00a32995
            ct_next;

        ct_next(ct_state=est|trk /* default (use --ct to customize) */)
        ---------------------------------------------------------------
         3. ls_out_acl_hint (northd.c:6201): !ct.new && ct.est && !ct.rpl && 
ct_label.blocked == 0, priority 4, uuid c617b2cb
            reg0[8] = 1;
            reg0[10] = 1;
            next;
         8. ls_out_check_port_sec (northd.c:5757): 1, priority 0, uuid 2816b94d
            reg0[15] = check_out_port_sec();
            next;
         9. ls_out_apply_port_sec (northd.c:5762): 1, priority 0, uuid 74fbe3e4
            output;
            /* output to "port_a", type "" */

    egress(dp="Ironic Provisioning", inport="23af2a", outport="provnet-2fd9fb")
    ---------------------------------------------------------------------------
         0. ls_out_pre_acl (northd.c:5790): ip && outport == "provnet-2fd9fb", 
priority 110, uuid 35b95f2e
            next;
         1. ls_out_pre_lb (northd.c:5790): ip && outport == "provnet-2fd9fb", 
priority 110, uuid 27a6943d
            next;
         2. ls_out_pre_stateful (northd.c:6116): reg0[0] == 1, priority 100, 
uuid 00a32995
            ct_next;

        ct_next(ct_state=est|trk /* default (use --ct to customize) */)
        ---------------------------------------------------------------
         3. ls_out_acl_hint (northd.c:6201): !ct.new && ct.est && !ct.rpl && 
ct_label.blocked == 0, priority 4, uuid c617b2cb
            reg0[8] = 1;
            reg0[10] = 1;
            next;
         8. ls_out_check_port_sec (northd.c:5757): 1, priority 0, uuid 2816b94d
            reg0[15] = check_out_port_sec();
            next;
         9. ls_out_apply_port_sec (northd.c:5762): 1, priority 0, uuid 74fbe3e4
            output;
            /* output to "provnet-2fd9fb", type "localnet" */


One theory I have is that it CANNOT work this way because without an “external” 
port there’s no OVS which would actually handle the flow at the datapath layer. 
 I figured it was worth a shot to send an email to see if this is the case and 
whether there is any potential workaround for having OVN generate the DHCP 
responses.

Appreciate any guidance.

-Austin



Juniper Business Use Only
_______________________________________________
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss

Reply via email to