aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/hard-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r--net/batman-adv/hard-interface.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c5f871f218c6..c60d3ed40257 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -266,16 +266,9 @@ static void batadv_check_known_mac_addr(const struct net_device *net_dev)
266 266
267int batadv_hardif_min_mtu(struct net_device *soft_iface) 267int batadv_hardif_min_mtu(struct net_device *soft_iface)
268{ 268{
269 const struct batadv_priv *bat_priv = netdev_priv(soft_iface); 269 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
270 const struct batadv_hard_iface *hard_iface; 270 const struct batadv_hard_iface *hard_iface;
271 /* allow big frames if all devices are capable to do so
272 * (have MTU > 1500 + batadv_max_header_len())
273 */
274 int min_mtu = ETH_DATA_LEN; 271 int min_mtu = ETH_DATA_LEN;
275 int max_header_len = batadv_max_header_len();
276
277 if (atomic_read(&bat_priv->fragmentation))
278 goto out;
279 272
280 rcu_read_lock(); 273 rcu_read_lock();
281 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 274 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
@@ -286,22 +279,40 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface)
286 if (hard_iface->soft_iface != soft_iface) 279 if (hard_iface->soft_iface != soft_iface)
287 continue; 280 continue;
288 281
289 min_mtu = min_t(int, hard_iface->net_dev->mtu - max_header_len, 282 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
290 min_mtu);
291 } 283 }
292 rcu_read_unlock(); 284 rcu_read_unlock();
285
286 atomic_set(&bat_priv->packet_size_max, min_mtu);
287
288 if (atomic_read(&bat_priv->fragmentation) == 0)
289 goto out;
290
291 /* with fragmentation enabled the maximum size of internally generated
292 * packets such as translation table exchanges or tvlv containers, etc
293 * has to be calculated
294 */
295 min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
296 min_mtu -= sizeof(struct batadv_frag_packet);
297 min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
298 atomic_set(&bat_priv->packet_size_max, min_mtu);
299
300 /* with fragmentation enabled we can fragment external packets easily */
301 min_mtu = min_t(int, min_mtu, ETH_DATA_LEN);
302
293out: 303out:
294 return min_mtu; 304 return min_mtu - batadv_max_header_len();
295} 305}
296 306
297/* adjusts the MTU if a new interface with a smaller MTU appeared. */ 307/* adjusts the MTU if a new interface with a smaller MTU appeared. */
298void batadv_update_min_mtu(struct net_device *soft_iface) 308void batadv_update_min_mtu(struct net_device *soft_iface)
299{ 309{
300 int min_mtu; 310 soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
301 311
302 min_mtu = batadv_hardif_min_mtu(soft_iface); 312 /* Check if the local translate table should be cleaned up to match a
303 if (soft_iface->mtu != min_mtu) 313 * new (and smaller) MTU.
304 soft_iface->mtu = min_mtu; 314 */
315 batadv_tt_local_resize_to_mtu(soft_iface);
305} 316}
306 317
307static void 318static void