diff options
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r-- | net/batman-adv/hard-interface.c | 41 |
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 | ||
267 | int batadv_hardif_min_mtu(struct net_device *soft_iface) | 267 | int 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 | |||
293 | out: | 303 | out: |
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. */ |
298 | void batadv_update_min_mtu(struct net_device *soft_iface) | 308 | void 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 | ||
307 | static void | 318 | static void |