RFC2131.txt: xid 4 Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server. The 'xid' field is used by the client to match incoming DHCP messages with pending requests. A DHCP client MUST choose 'xid's in such a way as to minimize the chance of using an 'xid' identical to one used by another client. For example, a client may choose a different, random initial 'xid' each time the client is rebooted, and subsequently use sequential 'xid's until the next reboot. Selecting a new 'xid' for each retransmission is an implementation decision. A client may choose to reuse the same 'xid' or select a new 'xid' for each retransmitted message. This patch generates random id when start dhcp, and record it to netdev struct. Signed-off-by: Amos Kong <akong@xxxxxxxxxx> CC: Eduardo Habkost <ehabkost@xxxxxxxxxx> CC: Marty Connor <mdc@xxxxxxxxxxxxx> --- src/include/gpxe/netdevice.h | 3 +++ src/net/udp/dhcp.c | 23 ++++------------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h index 97bf168..7272cf8 100644 --- a/src/include/gpxe/netdevice.h +++ b/src/include/gpxe/netdevice.h @@ -294,6 +294,9 @@ struct net_device { /** Link-layer broadcast address */ const uint8_t *ll_broadcast; + /* DHCP Transaction ID */ + uint32_t xid; + /** Current device state * * This is the bitwise-OR of zero or more NETDEV_XXX constants. diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 4bfcb80..51b7150 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -136,23 +136,6 @@ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) { } } -/** - * Calculate DHCP transaction ID for a network device - * - * @v netdev Network device - * @ret xid DHCP XID - * - * Extract the least significant bits of the hardware address for use - * as the transaction ID. - */ -static uint32_t dhcp_xid ( struct net_device *netdev ) { - uint32_t xid; - - memcpy ( &xid, ( netdev->ll_addr + netdev->ll_protocol->ll_addr_len - - sizeof ( xid ) ), sizeof ( xid ) ); - return xid; -} - /**************************************************************************** * * DHCP session @@ -1070,7 +1053,7 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt, /* Initialise DHCP packet content */ memset ( dhcphdr, 0, max_len ); - dhcphdr->xid = dhcp_xid ( netdev ); + dhcphdr->xid = netdev->xid; dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE ); dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto ); dhcphdr->op = dhcp_op[msgtype]; @@ -1313,7 +1296,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer, &server_id, sizeof ( server_id ) ); /* Check for matching transaction ID */ - if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) { + if ( dhcphdr->xid != dhcp->netdev->xid ) { + DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction " "ID\n", dhcp, dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ), @@ -1442,6 +1426,7 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { dhcp = zalloc ( sizeof ( *dhcp ) ); if ( ! dhcp ) return -ENOMEM; + netdev->xid = random(); ref_init ( &dhcp->refcnt, dhcp_free ); job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt ); xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html