struct retry_timer link_block;
/** Maximum packet length
*
- * This length includes any link-layer headers.
+ * This is the maximum packet length (including any link-layer
+ * headers) supported by the hardware.
*/
size_t max_pkt_len;
+ /** Maximum transmission unit length
+ *
+ * This is the maximum transmission unit length (excluding any
+ * link-layer headers) configured for the link.
+ */
+ size_t mtu;
/** TX packet queue */
struct list_head tx_queue;
/** Deferred TX packet queue */
struct net_device *netdev;
struct settings *settings;
struct ll_protocol *ll_protocol;
- size_t old_max_pkt_len;
+ size_t max_mtu;
+ size_t old_mtu;
size_t mtu;
int rc;
if ( ! mtu )
continue;
- /* Update maximum packet length */
+ /* Limit MTU to maximum supported by hardware */
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 ) {
+ max_mtu = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
+ if ( mtu > max_mtu ) {
+ DBGC ( netdev, "NETDEV %s cannot support MTU %zd (max "
+ "%zd)\n", netdev->name, mtu, max_mtu );
+ mtu = max_mtu;
+ }
+
+ /* Update maximum packet length */
+ old_mtu = netdev->mtu;
+ netdev->mtu = mtu;
+ if ( mtu != old_mtu ) {
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 ) ) {
+ if ( netdev_is_open ( netdev ) && ( mtu > old_mtu ) ) {
netdev_close ( netdev );
if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
DBGC ( netdev, "NETDEV %s could not reopen: "
ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
}
+ /* Set MTU, if not already set */
+ if ( ! netdev->mtu ) {
+ netdev->mtu = ( netdev->max_pkt_len -
+ ll_protocol->ll_header_len );
+ }
+
/* Reject network devices that are already available via a
* different hardware device.
*/