[ipxe-devel] [PATCH] [netdevice] Make MTU configurable, obey DHCP option 26

Ladi Prosek lprosek at redhat.com
Mon Nov 21 10:27:41 UTC 2016


On Wed, Nov 16, 2016 at 2:21 AM, Dan Callaghan <dcallagh at redhat.com> wrote:
> iPXE is already assuming a conservative MTU in the TCP transmission code
> path (tcp_xmit_win() is using TCP_PATH_MTU, which is calculated assuming
> a network-layer MTU of 1280).
>
> However, MTU is also used to determine the TCP Maximum Segment Size.
> Currently tcpip_mtu() is assuming the network layer can receive full
> length packets (1500 in the case of IPv4 over Ethernet). In some
> scenarios this is not a valid assumption, for example when the network
> is Ethernet encapsulated in something else. This is common in OpenStack
> virtualised networks.
>
> In those cases the administrator may need to configure a lower MTU than
> the default, either explicitly or using DHCP option 26.
>
> Signed-off-by: Dan Callaghan <dcallagh at redhat.com>
> ---
>  src/include/ipxe/dhcp.h      |  3 +++
>  src/include/ipxe/netdevice.h |  1 +
>  src/include/ipxe/settings.h  |  2 ++
>  src/net/netdev_settings.c    |  6 ++++++
>  src/net/netdevice.c          | 22 ++++++++++++++++++++++
>  src/net/tcpip.c              |  3 +--
>  src/net/udp/dhcp.c           |  6 +++---
>  7 files changed, 38 insertions(+), 5 deletions(-)
>
> diff --git a/src/include/ipxe/dhcp.h b/src/include/ipxe/dhcp.h
> index b699b31..189468a 100644
> --- a/src/include/ipxe/dhcp.h
> +++ b/src/include/ipxe/dhcp.h
> @@ -83,6 +83,9 @@ struct dhcp_packet;
>  /** Root path */
>  #define DHCP_ROOT_PATH 17
>
> +/** MTU */
> +#define DHCP_MTU 26
> +
>  /** Vendor encapsulated options */
>  #define DHCP_VENDOR_ENCAP 43
>
> diff --git a/src/include/ipxe/netdevice.h b/src/include/ipxe/netdevice.h
> index a1d207f..4fb45c7 100644
> --- a/src/include/ipxe/netdevice.h
> +++ b/src/include/ipxe/netdevice.h
> @@ -680,6 +680,7 @@ netdev_rx_frozen ( struct net_device *netdev ) {
>         return ( netdev->state & NETDEV_RX_FROZEN );
>  }
>
> +extern size_t netdev_mtu ( struct net_device *netdev );
>  extern void netdev_rx_freeze ( struct net_device *netdev );
>  extern void netdev_rx_unfreeze ( struct net_device *netdev );
>  extern void netdev_link_err ( struct net_device *netdev, int rc );
> diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h
> index 341fc3c..2d8f241 100644
> --- a/src/include/ipxe/settings.h
> +++ b/src/include/ipxe/settings.h
> @@ -466,6 +466,8 @@ mac_setting __setting ( SETTING_NETDEV, mac );
>  extern const struct setting
>  busid_setting __setting ( SETTING_NETDEV, busid );
>  extern const struct setting
> +mtu_setting __setting ( SETTING_NETDEV, mtu );
> +extern const struct setting
>  user_class_setting __setting ( SETTING_HOST_EXTRA, user-class );
>  extern const struct setting
>  manufacturer_setting __setting ( SETTING_HOST_EXTRA, manufacturer );
> diff --git a/src/net/netdev_settings.c b/src/net/netdev_settings.c
> index 7d893a1..73d1d67 100644
> --- a/src/net/netdev_settings.c
> +++ b/src/net/netdev_settings.c
> @@ -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 = "Network-layer Maximum Transmission Unit (MTU)",
> +       .type = &setting_type_uint16,
> +       .tag = DHCP_MTU,
> +};
>
>  /**
>   * Store MAC address setting
> diff --git a/src/net/netdevice.c b/src/net/netdevice.c
> index 9df2119..8e6e7f8 100644
> --- a/src/net/netdevice.c
> +++ b/src/net/netdevice.c
> @@ -127,6 +127,28 @@ static void netdev_notify ( struct net_device *netdev ) {
>  }
>
>  /**
> + * Returns the network-layer Maximum Transmission Unit
> + *
> + * This is configurable at runtime with the "mtu" setting, either explicitly or
> + * through DHCP option 26. Otherwise uses the value determined by the driver
> + * (if any) or the protocol default.
> + *
> + * @v                  Network device
> + * @ret                Computed network-layer MTU
> + */
> +size_t netdev_mtu ( struct net_device *netdev ) {
> +       unsigned long mtu;
> +
> +       /* Use MTU from settings if one is set */
> +       if ( fetch_uint_setting ( netdev_settings ( netdev ), &mtu_setting,
> +                                 &mtu ) >= 0 )
> +               return mtu;
> +
> +       /* Use default */
> +       return ( netdev->max_pkt_len - netdev->ll_protocol->ll_header_len );
> +}
> +
> +/**
>   * Freeze network device receive queue processing
>   *
>   * @v netdev           Network device
> diff --git a/src/net/tcpip.c b/src/net/tcpip.c
> index c9e4ee7..9c439a5 100644
> --- a/src/net/tcpip.c
> +++ b/src/net/tcpip.c
> @@ -144,8 +144,7 @@ size_t tcpip_mtu ( struct sockaddr_tcpip *st_dest ) {
>                 return 0;
>
>         /* Calculate MTU */
> -       mtu = ( netdev->max_pkt_len - netdev->ll_protocol->ll_header_len -
> -               tcpip_net->header_len );
> +       mtu = ( netdev_mtu ( netdev ) - tcpip_net->header_len );

Is this the only place that consumes max_pkt_len and should be
modified to take the new setting? For example, the two occurrences in
interface/efi/efi_snp.c look like they might be affected. Or if it's
really IP only, would it make more sense for the setting to be
SETTING_IP / SETTING_IP_EXTRA?

Thanks!
Ladi

>         return mtu;
>  }
> diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
> index b9c1fd9..95f8082 100644
> --- a/src/net/udp/dhcp.c
> +++ b/src/net/udp/dhcp.c
> @@ -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
> --
> 2.7.4
>
> _______________________________________________
> ipxe-devel mailing list
> ipxe-devel at lists.ipxe.org
> https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel



More information about the ipxe-devel mailing list