diff options
author | Michael Brown | 2007-01-04 04:42:28 +0100 |
---|---|---|
committer | Michael Brown | 2007-01-04 04:42:28 +0100 |
commit | 7fafa8925800f3b6caf4983efd731b0c680caa49 (patch) | |
tree | 97d46520e772119f21f034a166b0319064888853 /src/net/udp/dhcp.c | |
parent | Added missing #include (diff) | |
download | ipxe-7fafa8925800f3b6caf4983efd731b0c680caa49.tar.gz ipxe-7fafa8925800f3b6caf4983efd731b0c680caa49.tar.xz ipxe-7fafa8925800f3b6caf4983efd731b0c680caa49.zip |
A DHCP session holds a persistent reference to a network device
Diffstat (limited to 'src/net/udp/dhcp.c')
-rw-r--r-- | src/net/udp/dhcp.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index f8107777..59dc8071 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -498,6 +498,7 @@ udp_to_dhcp ( struct udp_connection *conn ) { * @v rc Return status code */ static void dhcp_done ( struct dhcp_session *dhcp, int rc ) { + /* Free up options if we failed */ if ( rc != 0 ) { if ( dhcp->options ) { @@ -506,9 +507,15 @@ static void dhcp_done ( struct dhcp_session *dhcp, int rc ) { } } + /* Stop retry timer */ + stop_timer ( &dhcp->timer ); + /* Close UDP connection */ udp_close ( &dhcp->udp ); + /* Release reference on net device */ + ref_del ( &dhcp->netdev_ref ); + /* Mark async operation as complete */ async_done ( &dhcp->aop, rc ); } @@ -690,6 +697,19 @@ static struct udp_operations dhcp_udp_operations = { }; /** + * Forget reference to net_device + * + * @v ref Persistent reference + */ +static void dhcp_forget_netdev ( struct reference *ref ) { + struct dhcp_session *dhcp + = container_of ( ref, struct dhcp_session, netdev_ref ); + + /* Kill DHCP session immediately */ + dhcp_done ( dhcp, -ENETUNREACH ); +} + +/** * Initiate DHCP on a network interface * * @v dhcp DHCP session @@ -714,6 +734,10 @@ struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) { goto out; } + /* Add persistent reference to net device */ + dhcp->netdev_ref.forget = dhcp_forget_netdev; + ref_add ( &dhcp->netdev_ref, &dhcp->netdev->references ); + /* Proof of concept: just send a single DHCPDISCOVER */ dhcp_send_request ( dhcp ); |