diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 154f255ba..66f3a5a38 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -409,6 +409,28 @@ void Interface::_release_dhcp_allocation(Dhcp_allocation &allocation) } +void Interface::_new_dhcp_allocation(Ethernet_frame ð, + Dhcp_packet &dhcp, + Dhcp_server &dhcp_srv) +{ + Dhcp_allocation &allocation = *new (_alloc) + Dhcp_allocation(*this, dhcp_srv.alloc_ip(), + dhcp.client_mac(), _timer, + _config().dhcp_offer_timeout()); + + _dhcp_allocations.insert(&allocation); + if (_config().verbose()) { + log("Offer IP allocation: ", allocation, + " at ", *this); + } + _send_dhcp_reply(dhcp_srv, eth.src(), + allocation.ip(), + Dhcp_packet::Message_type::OFFER, + dhcp.xid()); + return; +} + + void Interface::_handle_dhcp_request(Ethernet_frame ð, Genode::size_t eth_size, Dhcp_packet &dhcp) @@ -430,7 +452,11 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, case Dhcp_packet::Message_type::DISCOVER: if (allocation.bound()) { - throw Drop_packet_warn("DHCP DISCOVER from client expected to be in DHCP BOUND state"); + + _release_dhcp_allocation(allocation); + _destroy_dhcp_allocation(allocation); + _new_dhcp_allocation(eth, dhcp, dhcp_srv); + return; } else { allocation.lifetime(_config().dhcp_offer_timeout()); @@ -500,23 +526,10 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, switch (msg_type) { case Dhcp_packet::Message_type::DISCOVER: - { - Dhcp_allocation &allocation = *new (_alloc) - Dhcp_allocation(*this, dhcp_srv.alloc_ip(), - dhcp.client_mac(), _timer, - _config().dhcp_offer_timeout()); - _dhcp_allocations.insert(&allocation); - if (_config().verbose()) { - log("Offer IP allocation: ", allocation, - " at ", *this); - } - _send_dhcp_reply(dhcp_srv, eth.src(), - allocation.ip(), - Dhcp_packet::Message_type::OFFER, - dhcp.xid()); - return; - } + _new_dhcp_allocation(eth, dhcp, dhcp_srv); + return; + case Dhcp_packet::Message_type::REQUEST: throw Drop_packet_warn("DHCP REQUEST from client without offered/acked IP"); case Dhcp_packet::Message_type::DECLINE: throw Drop_packet_warn("DHCP DECLINE from client without offered/acked IP"); case Dhcp_packet::Message_type::RELEASE: throw Drop_packet_warn("DHCP RELEASE from client without offered/acked IP"); diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 1db1dedd7..26402158a 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -86,6 +86,10 @@ class Net::Interface void _release_dhcp_allocation(Dhcp_allocation &allocation); + void _new_dhcp_allocation(Ethernet_frame ð, + Dhcp_packet &dhcp, + Dhcp_server &dhcp_srv); + void _send_dhcp_reply(Dhcp_server const &dhcp_srv, Mac_address const &client_mac, Ipv4_address const &client_ip,