diff options
author | David S. Miller <davem@davemloft.net> | 2017-03-16 15:05:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-16 15:05:38 -0400 |
commit | b124f413323e90398b868a9848e63149d0fed8ce (patch) | |
tree | cefa770d1522702c92d94869fd51a22585357e9d /net | |
parent | 8f3dbfd79ed9ef9770305a7cc4e13dfd31ad2cd0 (diff) | |
parent | 1a9070ec91b37234fe915849b767c61584c64a44 (diff) |
Merge tag 'batadv-net-for-davem-20170316' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says:
====================
Here are two batman-adv bugfixes:
- Keep fragments equally sized, avoids some problems with too small fragments,
by Sven Eckelmann
- Initialize gateway class correctly when BATMAN V is compiled in,
by Sven Eckelmann
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 11 | ||||
-rw-r--r-- | net/batman-adv/bat_v.c | 14 | ||||
-rw-r--r-- | net/batman-adv/fragmentation.c | 20 | ||||
-rw-r--r-- | net/batman-adv/gateway_common.c | 5 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 1 | ||||
-rw-r--r-- | net/batman-adv/types.h | 2 |
6 files changed, 42 insertions, 11 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 7c3d994e90d8..71343d0fec94 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -2477,6 +2477,16 @@ static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface) | |||
2477 | batadv_iv_ogm_schedule(hard_iface); | 2477 | batadv_iv_ogm_schedule(hard_iface); |
2478 | } | 2478 | } |
2479 | 2479 | ||
2480 | /** | ||
2481 | * batadv_iv_init_sel_class - initialize GW selection class | ||
2482 | * @bat_priv: the bat priv with all the soft interface information | ||
2483 | */ | ||
2484 | static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv) | ||
2485 | { | ||
2486 | /* set default TQ difference threshold to 20 */ | ||
2487 | atomic_set(&bat_priv->gw.sel_class, 20); | ||
2488 | } | ||
2489 | |||
2480 | static struct batadv_gw_node * | 2490 | static struct batadv_gw_node * |
2481 | batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv) | 2491 | batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv) |
2482 | { | 2492 | { |
@@ -2823,6 +2833,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { | |||
2823 | .del_if = batadv_iv_ogm_orig_del_if, | 2833 | .del_if = batadv_iv_ogm_orig_del_if, |
2824 | }, | 2834 | }, |
2825 | .gw = { | 2835 | .gw = { |
2836 | .init_sel_class = batadv_iv_init_sel_class, | ||
2826 | .get_best_gw_node = batadv_iv_gw_get_best_gw_node, | 2837 | .get_best_gw_node = batadv_iv_gw_get_best_gw_node, |
2827 | .is_eligible = batadv_iv_gw_is_eligible, | 2838 | .is_eligible = batadv_iv_gw_is_eligible, |
2828 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS | 2839 | #ifdef CONFIG_BATMAN_ADV_DEBUGFS |
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 0acd081dd286..a36c8e7291d6 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c | |||
@@ -668,6 +668,16 @@ err_ifinfo1: | |||
668 | return ret; | 668 | return ret; |
669 | } | 669 | } |
670 | 670 | ||
671 | /** | ||
672 | * batadv_v_init_sel_class - initialize GW selection class | ||
673 | * @bat_priv: the bat priv with all the soft interface information | ||
674 | */ | ||
675 | static void batadv_v_init_sel_class(struct batadv_priv *bat_priv) | ||
676 | { | ||
677 | /* set default throughput difference threshold to 5Mbps */ | ||
678 | atomic_set(&bat_priv->gw.sel_class, 50); | ||
679 | } | ||
680 | |||
671 | static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv, | 681 | static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv, |
672 | char *buff, size_t count) | 682 | char *buff, size_t count) |
673 | { | 683 | { |
@@ -1052,6 +1062,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { | |||
1052 | .dump = batadv_v_orig_dump, | 1062 | .dump = batadv_v_orig_dump, |
1053 | }, | 1063 | }, |
1054 | .gw = { | 1064 | .gw = { |
1065 | .init_sel_class = batadv_v_init_sel_class, | ||
1055 | .store_sel_class = batadv_v_store_sel_class, | 1066 | .store_sel_class = batadv_v_store_sel_class, |
1056 | .show_sel_class = batadv_v_show_sel_class, | 1067 | .show_sel_class = batadv_v_show_sel_class, |
1057 | .get_best_gw_node = batadv_v_gw_get_best_gw_node, | 1068 | .get_best_gw_node = batadv_v_gw_get_best_gw_node, |
@@ -1092,9 +1103,6 @@ int batadv_v_mesh_init(struct batadv_priv *bat_priv) | |||
1092 | if (ret < 0) | 1103 | if (ret < 0) |
1093 | return ret; | 1104 | return ret; |
1094 | 1105 | ||
1095 | /* set default throughput difference threshold to 5Mbps */ | ||
1096 | atomic_set(&bat_priv->gw.sel_class, 50); | ||
1097 | |||
1098 | return 0; | 1106 | return 0; |
1099 | } | 1107 | } |
1100 | 1108 | ||
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 11a23fd6e1a0..8f964beaac28 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -404,7 +404,7 @@ out: | |||
404 | * batadv_frag_create - create a fragment from skb | 404 | * batadv_frag_create - create a fragment from skb |
405 | * @skb: skb to create fragment from | 405 | * @skb: skb to create fragment from |
406 | * @frag_head: header to use in new fragment | 406 | * @frag_head: header to use in new fragment |
407 | * @mtu: size of new fragment | 407 | * @fragment_size: size of new fragment |
408 | * | 408 | * |
409 | * Split the passed skb into two fragments: A new one with size matching the | 409 | * Split the passed skb into two fragments: A new one with size matching the |
410 | * passed mtu and the old one with the rest. The new skb contains data from the | 410 | * passed mtu and the old one with the rest. The new skb contains data from the |
@@ -414,11 +414,11 @@ out: | |||
414 | */ | 414 | */ |
415 | static struct sk_buff *batadv_frag_create(struct sk_buff *skb, | 415 | static struct sk_buff *batadv_frag_create(struct sk_buff *skb, |
416 | struct batadv_frag_packet *frag_head, | 416 | struct batadv_frag_packet *frag_head, |
417 | unsigned int mtu) | 417 | unsigned int fragment_size) |
418 | { | 418 | { |
419 | struct sk_buff *skb_fragment; | 419 | struct sk_buff *skb_fragment; |
420 | unsigned int header_size = sizeof(*frag_head); | 420 | unsigned int header_size = sizeof(*frag_head); |
421 | unsigned int fragment_size = mtu - header_size; | 421 | unsigned int mtu = fragment_size + header_size; |
422 | 422 | ||
423 | skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); | 423 | skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); |
424 | if (!skb_fragment) | 424 | if (!skb_fragment) |
@@ -456,7 +456,7 @@ int batadv_frag_send_packet(struct sk_buff *skb, | |||
456 | struct sk_buff *skb_fragment; | 456 | struct sk_buff *skb_fragment; |
457 | unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; | 457 | unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; |
458 | unsigned int header_size = sizeof(frag_header); | 458 | unsigned int header_size = sizeof(frag_header); |
459 | unsigned int max_fragment_size, max_packet_size; | 459 | unsigned int max_fragment_size, num_fragments; |
460 | int ret; | 460 | int ret; |
461 | 461 | ||
462 | /* To avoid merge and refragmentation at next-hops we never send | 462 | /* To avoid merge and refragmentation at next-hops we never send |
@@ -464,10 +464,15 @@ int batadv_frag_send_packet(struct sk_buff *skb, | |||
464 | */ | 464 | */ |
465 | mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE); | 465 | mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE); |
466 | max_fragment_size = mtu - header_size; | 466 | max_fragment_size = mtu - header_size; |
467 | max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; | 467 | |
468 | if (skb->len == 0 || max_fragment_size == 0) | ||
469 | return -EINVAL; | ||
470 | |||
471 | num_fragments = (skb->len - 1) / max_fragment_size + 1; | ||
472 | max_fragment_size = (skb->len - 1) / num_fragments + 1; | ||
468 | 473 | ||
469 | /* Don't even try to fragment, if we need more than 16 fragments */ | 474 | /* Don't even try to fragment, if we need more than 16 fragments */ |
470 | if (skb->len > max_packet_size) { | 475 | if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS) { |
471 | ret = -EAGAIN; | 476 | ret = -EAGAIN; |
472 | goto free_skb; | 477 | goto free_skb; |
473 | } | 478 | } |
@@ -507,7 +512,8 @@ int batadv_frag_send_packet(struct sk_buff *skb, | |||
507 | goto put_primary_if; | 512 | goto put_primary_if; |
508 | } | 513 | } |
509 | 514 | ||
510 | skb_fragment = batadv_frag_create(skb, &frag_header, mtu); | 515 | skb_fragment = batadv_frag_create(skb, &frag_header, |
516 | max_fragment_size); | ||
511 | if (!skb_fragment) { | 517 | if (!skb_fragment) { |
512 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
513 | goto put_primary_if; | 519 | goto put_primary_if; |
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 5db2e43e3775..33940c5c74a8 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c | |||
@@ -253,6 +253,11 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, | |||
253 | */ | 253 | */ |
254 | void batadv_gw_init(struct batadv_priv *bat_priv) | 254 | void batadv_gw_init(struct batadv_priv *bat_priv) |
255 | { | 255 | { |
256 | if (bat_priv->algo_ops->gw.init_sel_class) | ||
257 | bat_priv->algo_ops->gw.init_sel_class(bat_priv); | ||
258 | else | ||
259 | atomic_set(&bat_priv->gw.sel_class, 1); | ||
260 | |||
256 | batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, | 261 | batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, |
257 | NULL, BATADV_TVLV_GW, 1, | 262 | NULL, BATADV_TVLV_GW, 1, |
258 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); | 263 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 5d099b2e6cfc..d042c99af028 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -819,7 +819,6 @@ static int batadv_softif_init_late(struct net_device *dev) | |||
819 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); | 819 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); |
820 | #endif | 820 | #endif |
821 | atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); | 821 | atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); |
822 | atomic_set(&bat_priv->gw.sel_class, 20); | ||
823 | atomic_set(&bat_priv->gw.bandwidth_down, 100); | 822 | atomic_set(&bat_priv->gw.bandwidth_down, 100); |
824 | atomic_set(&bat_priv->gw.bandwidth_up, 20); | 823 | atomic_set(&bat_priv->gw.bandwidth_up, 20); |
825 | atomic_set(&bat_priv->orig_interval, 1000); | 824 | atomic_set(&bat_priv->orig_interval, 1000); |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 66b25e410a41..246f21b4973b 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -1489,6 +1489,7 @@ struct batadv_algo_orig_ops { | |||
1489 | 1489 | ||
1490 | /** | 1490 | /** |
1491 | * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific) | 1491 | * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific) |
1492 | * @init_sel_class: initialize GW selection class (optional) | ||
1492 | * @store_sel_class: parse and stores a new GW selection class (optional) | 1493 | * @store_sel_class: parse and stores a new GW selection class (optional) |
1493 | * @show_sel_class: prints the current GW selection class (optional) | 1494 | * @show_sel_class: prints the current GW selection class (optional) |
1494 | * @get_best_gw_node: select the best GW from the list of available nodes | 1495 | * @get_best_gw_node: select the best GW from the list of available nodes |
@@ -1499,6 +1500,7 @@ struct batadv_algo_orig_ops { | |||
1499 | * @dump: dump gateways to a netlink socket (optional) | 1500 | * @dump: dump gateways to a netlink socket (optional) |
1500 | */ | 1501 | */ |
1501 | struct batadv_algo_gw_ops { | 1502 | struct batadv_algo_gw_ops { |
1503 | void (*init_sel_class)(struct batadv_priv *bat_priv); | ||
1502 | ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff, | 1504 | ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff, |
1503 | size_t count); | 1505 | size_t count); |
1504 | ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff); | 1506 | ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff); |