Skip to content

Commit

Permalink
[netdevice] Allow MTU to be changed at runtime
Browse files Browse the repository at this point in the history
Provide a settings applicator to modify netdev->max_pkt_len in
response to changes to the "mtu" setting (DHCP option 26).

Note that as with MAC address changes, drivers are permitted to
completely ignore any changes in the MTU value.  The net result will
be that iPXE effectively uses the smaller of either the hardware
default MTU or the software configured MTU.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jan 23, 2017
1 parent 4e85b27 commit 16aed6e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/include/ipxe/dhcp.h
Expand Up @@ -83,6 +83,9 @@ struct dhcp_packet;
/** Root path */
#define DHCP_ROOT_PATH 17

/** Maximum transmission unit */
#define DHCP_MTU 26

/** Vendor encapsulated options */
#define DHCP_VENDOR_ENCAP 43

Expand Down
61 changes: 61 additions & 0 deletions src/net/netdev_settings.c
Expand Up @@ -70,6 +70,12 @@ const struct setting ifname_setting __setting ( SETTING_NETDEV, ifname ) = {
.description = "Interface name",
.type = &setting_type_string,
};
const struct setting mtu_setting __setting ( SETTING_NETDEV, mtu ) = {
.name = "mtu",
.description = "MTU",
.type = &setting_type_int16,
.tag = DHCP_MTU,
};

/**
* Store MAC address setting
Expand Down Expand Up @@ -377,3 +383,58 @@ static void netdev_redirect_settings_init ( void ) {
struct init_fn netdev_redirect_settings_init_fn __init_fn ( INIT_LATE ) = {
.initialise = netdev_redirect_settings_init,
};

/**
* Apply network device settings
*
* @ret rc Return status code
*/
static int apply_netdev_settings ( void ) {
struct net_device *netdev;
struct settings *settings;
struct ll_protocol *ll_protocol;
size_t old_max_pkt_len;
size_t mtu;
int rc;

/* Process settings for each network device */
for_each_netdev ( netdev ) {

/* Get network device settings */
settings = netdev_settings ( netdev );

/* Get MTU */
mtu = fetch_uintz_setting ( settings, &mtu_setting );

/* Do nothing unless MTU is specified */
if ( ! mtu )
continue;

/* Update maximum packet length */
ll_protocol = netdev->ll_protocol;
old_max_pkt_len = netdev->max_pkt_len;
netdev->max_pkt_len = ( mtu + ll_protocol->ll_header_len );
if ( netdev->max_pkt_len != old_max_pkt_len ) {
DBGC ( netdev, "NETDEV %s MTU is %zd\n",
netdev->name, mtu );
}

/* Close and reopen network device if MTU has increased */
if ( netdev_is_open ( netdev ) &&
( netdev->max_pkt_len > old_max_pkt_len ) ) {
netdev_close ( netdev );
if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
DBGC ( netdev, "NETDEV %s could not reopen: "
"%s\n", netdev->name, strerror ( rc ) );
return rc;
}
}
}

return 0;
}

/** Network device settings applicator */
struct settings_applicator netdev_applicator __settings_applicator = {
.apply = apply_netdev_settings,
};
6 changes: 3 additions & 3 deletions src/net/udp/dhcp.c
Expand Up @@ -91,9 +91,9 @@ static uint8_t dhcp_request_options_data[] = {
DHCP_PARAMETER_REQUEST_LIST,
DHCP_OPTION ( DHCP_SUBNET_MASK, DHCP_ROUTERS, DHCP_DNS_SERVERS,
DHCP_LOG_SERVERS, DHCP_HOST_NAME, DHCP_DOMAIN_NAME,
DHCP_ROOT_PATH, DHCP_VENDOR_ENCAP, DHCP_VENDOR_CLASS_ID,
DHCP_TFTP_SERVER_NAME, DHCP_BOOTFILE_NAME,
DHCP_DOMAIN_SEARCH,
DHCP_ROOT_PATH, DHCP_MTU, DHCP_VENDOR_ENCAP,
DHCP_VENDOR_CLASS_ID, DHCP_TFTP_SERVER_NAME,
DHCP_BOOTFILE_NAME, DHCP_DOMAIN_SEARCH,
128, 129, 130, 131, 132, 133, 134, 135, /* for PXE */
DHCP_EB_ENCAP, DHCP_ISCSI_INITIATOR_IQN ),
DHCP_END
Expand Down

0 comments on commit 16aed6e

Please sign in to comment.