}
 
 /* Needs rtnl lock */
-static struct rmnet_port*
+struct rmnet_port*
 rmnet_get_port_rtnl(const struct net_device *real_dev)
 {
        return rtnl_dereference(real_dev->rx_handler_data);
                netdev_dbg(real_dev, "Kernel unregister\n");
                rmnet_force_unassociate_device(real_dev);
                break;
-
+       case NETDEV_CHANGEMTU:
+               if (rmnet_vnd_validate_real_dev_mtu(real_dev))
+                       return NOTIFY_BAD;
+               break;
        default:
                break;
        }
 
        if (data[IFLA_RMNET_FLAGS]) {
                struct ifla_rmnet_flags *flags;
+               u32 old_data_format;
 
+               old_data_format = port->data_format;
                flags = nla_data(data[IFLA_RMNET_FLAGS]);
                port->data_format = flags->flags & flags->mask;
+
+               if (rmnet_vnd_update_dev_mtu(port, real_dev)) {
+                       port->data_format = old_data_format;
+                       NL_SET_ERR_MSG_MOD(extack, "Invalid MTU on real dev");
+                       return -EINVAL;
+               }
        }
 
        return 0;
 
        return NETDEV_TX_OK;
 }
 
+static int rmnet_vnd_headroom(struct rmnet_port *port)
+{
+       u32 headroom;
+
+       headroom = sizeof(struct rmnet_map_header);
+
+       if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4)
+               headroom += sizeof(struct rmnet_map_ul_csum_header);
+
+       return headroom;
+}
+
 static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
 {
-       if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE)
+       struct rmnet_priv *priv = netdev_priv(rmnet_dev);
+       struct rmnet_port *port;
+       u32 headroom;
+
+       port = rmnet_get_port_rtnl(priv->real_dev);
+
+       headroom = rmnet_vnd_headroom(port);
+
+       if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE ||
+           new_mtu > (priv->real_dev->mtu - headroom))
                return -EINVAL;
 
        rmnet_dev->mtu = new_mtu;
 
 {
        struct rmnet_priv *priv = netdev_priv(rmnet_dev);
+       u32 headroom;
        int rc;
 
        if (rmnet_get_endpoint(port, id)) {
 
        priv->real_dev = real_dev;
 
+       headroom = rmnet_vnd_headroom(port);
+
+       if (rmnet_vnd_change_mtu(rmnet_dev, real_dev->mtu - headroom)) {
+               NL_SET_ERR_MSG_MOD(extack, "Invalid MTU on real dev");
+               return -EINVAL;
+       }
+
        rc = register_netdevice(rmnet_dev);
        if (!rc) {
                ep->egress_dev = rmnet_dev;
 
        return 0;
 }
+
+int rmnet_vnd_validate_real_dev_mtu(struct net_device *real_dev)
+{
+       struct hlist_node *tmp_ep;
+       struct rmnet_endpoint *ep;
+       struct rmnet_port *port;
+       unsigned long bkt_ep;
+       u32 headroom;
+
+       port = rmnet_get_port_rtnl(real_dev);
+
+       headroom = rmnet_vnd_headroom(port);
+
+       hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
+               if (ep->egress_dev->mtu > (real_dev->mtu - headroom))
+                       return -1;
+       }
+
+       return 0;
+}
+
+int rmnet_vnd_update_dev_mtu(struct rmnet_port *port,
+                            struct net_device *real_dev)
+{
+       struct hlist_node *tmp_ep;
+       struct rmnet_endpoint *ep;
+       unsigned long bkt_ep;
+       u32 headroom;
+
+       headroom = rmnet_vnd_headroom(port);
+
+       hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
+               if (ep->egress_dev->mtu <= (real_dev->mtu - headroom))
+                       continue;
+
+               if (rmnet_vnd_change_mtu(ep->egress_dev,
+                                        real_dev->mtu - headroom))
+                       return -1;
+       }
+
+       return 0;
+}
\ No newline at end of file