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