diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-06-20 11:56:43 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-06-20 12:01:50 +0100 |
commit | c0942408b7ab30745952e801381e931b1b947e1f (patch) | |
tree | b7a3ec2291d7904a97f232d8be350521c08d066c | |
parent | b9ef880c8d50ccb89aef7e820aa737f66b63fd90 (diff) | |
download | ipxe-c0942408b7ab30745952e801381e931b1b947e1f.tar.gz |
[dhcp] Request broadcast responses when we already have an IPv4 address
FCoE requires the use of multiple local unicast link-layer addresses.
To avoid the complexity of managing multiple addresses, iPXE operates
in promiscuous mode. As a consequence, any unicast packets with
non-matching IPv4 addresses are rejected at the IPv4 layer (rather
than at the link layer).
This can cause problems when issuing a second DHCP request: if the
address chosen by the DHCP server does not match the existing address,
then the DHCP response will itself be rejected.
Fix by requesting a broadcast response from the DHCP server if the
network interface already has any IPv4 addresses.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/include/ipxe/ip.h | 2 | ||||
-rw-r--r-- | src/net/ipv4.c | 2 | ||||
-rw-r--r-- | src/net/udp/dhcp.c | 7 |
3 files changed, 10 insertions, 1 deletions
diff --git a/src/include/ipxe/ip.h b/src/include/ipxe/ip.h index 4366d9ab..ca508e27 100644 --- a/src/include/ipxe/ip.h +++ b/src/include/ipxe/ip.h @@ -86,4 +86,6 @@ extern struct list_head ipv4_miniroutes; extern struct net_protocol ipv4_protocol __net_protocol; +extern int ipv4_has_any_addr ( struct net_device *netdev ); + #endif /* _IPXE_IP_H */ diff --git a/src/net/ipv4.c b/src/net/ipv4.c index 08249d41..791d4195 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -408,7 +408,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, * @v netdev Network device * @ret has_any_addr Network device has any IPv4 address */ -static int ipv4_has_any_addr ( struct net_device *netdev ) { +int ipv4_has_any_addr ( struct net_device *netdev ) { struct ipv4_miniroute *miniroute; list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) { diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 10482e94..9a231840 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -941,6 +941,13 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt, &dhcphdr->flags ); memcpy ( dhcphdr->options, options, options_len ); + /* If the network device already has an IPv4 address then + * unicast responses from the DHCP server may be rejected, so + * request broadcast responses. + */ + if ( ipv4_has_any_addr ( netdev ) ) + dhcphdr->flags |= htons ( BOOTP_FL_BROADCAST ); + /* Initialise DHCP packet structure */ memset ( dhcppkt, 0, sizeof ( *dhcppkt ) ); dhcppkt_init ( dhcppkt, data, max_len ); |