In some setups multiple hard interfaces with similar link qualities or throughput values are available. But people have expressed the desire to consider one of them as a backup only. Some creative solutions are currently in use: Such people are configuring multiple batman-adv mesh/soft interfaces, wire them together with some veth pairs and then tune the hop penalty to achieve an effect similar to a tunable per interface hop penalty. This patch introduces a new, configurable, per hard interface hop penalty to simplify such setups.
Unified · Split
| @@ -427,7 +427,8 @@ enum batadv_nl_attrs { · 426 unmodified lines | ||
| 427 | 427 | |
| 428 | 428 | /** |
| 429 | 429 | * @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied |
| 430 | − * to an originator message's tq-field on every hop. | |
| 430 | + * to an originator message's tq-field on every hop and/or per | |
| 431 | + * hard interface | |
| 431 | 432 | */ |
| 432 | 433 | BATADV_ATTR_HOP_PENALTY, |
| 433 | 434 | |
| @@ -1075,10 +1075,10 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, · 1074 unmodified lines | ||
| 1075 | 1075 | struct batadv_neigh_ifinfo *neigh_ifinfo; |
| 1076 | 1076 | u8 total_count; |
| 1077 | 1077 | u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; |
| 1078 | + unsigned int tq_iface_hop_penalty = BATADV_TQ_MAX_VALUE; | |
| 1078 | 1079 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; |
| 1079 | 1080 | unsigned int tq_asym_penalty, inv_asym_penalty; |
| 1080 | 1081 | unsigned int combined_tq; |
| 1081 | − unsigned int tq_iface_penalty; | |
| 1082 | 1082 | bool ret = false; |
| 1083 | 1083 | |
| 1084 | 1084 | /* find corresponding one hop neighbor */ |
| @@ -1157,31 +1157,32 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, · 72 unmodified lines | ||
| 1157 | 1157 | inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube; |
| 1158 | 1158 | inv_asym_penalty /= neigh_rq_max_cube; |
| 1159 | 1159 | tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty; |
| 1160 | + tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty); | |
| 1160 | 1161 | |
| 1161 | 1162 | /* penalize if the OGM is forwarded on the same interface. WiFi |
| 1162 | 1163 | * interfaces and other half duplex devices suffer from throughput |
| 1163 | 1164 | * drops as they can't send and receive at the same time. |
| 1164 | 1165 | */ |
| 1165 | − tq_iface_penalty = BATADV_TQ_MAX_VALUE; | |
| 1166 | 1166 | if (if_outgoing && if_incoming == if_outgoing && |
| 1167 | 1167 | batadv_is_wifi_hardif(if_outgoing)) |
| 1168 | − tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE, | |
| 1169 | − bat_priv); | |
| 1168 | + tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty, | |
| 1169 | + bat_priv); | |
| 1170 | 1170 | |
| 1171 | 1171 | combined_tq = batadv_ogm_packet->tq * |
| 1172 | 1172 | tq_own * |
| 1173 | 1173 | tq_asym_penalty * |
| 1174 | − tq_iface_penalty; | |
| 1174 | + tq_iface_hop_penalty; | |
| 1175 | 1175 | combined_tq /= BATADV_TQ_MAX_VALUE * |
| 1176 | 1176 | BATADV_TQ_MAX_VALUE * |
| 1177 | 1177 | BATADV_TQ_MAX_VALUE; |
| 1178 | 1178 | batadv_ogm_packet->tq = combined_tq; |
| 1179 | 1179 | |
| 1180 | 1180 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
| 1181 | − "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n", | |
| 1181 | + "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_hop_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n", | |
| 1182 | 1182 | orig_node->orig, orig_neigh_node->orig, total_count, |
| 1183 | − neigh_rq_count, tq_own, tq_asym_penalty, tq_iface_penalty, | |
| 1184 | − batadv_ogm_packet->tq, if_incoming->net_dev->name, | |
| 1183 | + neigh_rq_count, tq_own, tq_asym_penalty, | |
| 1184 | + tq_iface_hop_penalty, batadv_ogm_packet->tq, | |
| 1185 | + if_incoming->net_dev->name, | |
| 1185 | 1186 | if_outgoing ? if_outgoing->net_dev->name : "DEFAULT"); |
| 1186 | 1187 | |
| 1187 | 1188 | /* if link has the minimum required transmission quality |
| @@ -455,15 +455,17 @@ unlock: · 454 unmodified lines | ||
| 455 | 455 | * @throughput: the current throughput |
| 456 | 456 | * |
| 457 | 457 | * Apply a penalty on the current throughput metric value based on the |
| 458 | − * characteristic of the interface where the OGM has been received. The return | |
| 459 | − * value is computed as follows: | |
| 458 | + * characteristic of the interface where the OGM has been received. | |
| 459 | + * | |
| 460 | + * Initially the per hardif hop penalty is applied to the throughput. After | |
| 461 | + * that the return value is then computed as follows: | |
| 460 | 462 | * - throughput * 50% if the incoming and outgoing interface are the |
| 461 | 463 | * same WiFi interface and the throughput is above |
| 462 | 464 | * 1MBit/s |
| 463 | 465 | * - throughput if the outgoing interface is the default |
| 464 | 466 | * interface (i.e. this OGM is processed for the |
| 465 | 467 | * internal table and not forwarded) |
| 466 | − * - throughput * hop penalty otherwise | |
| 468 | + * - throughput * node hop penalty otherwise | |
| 467 | 469 | * |
| 468 | 470 | * Return: the penalised throughput metric. |
| 469 | 471 | */ |
| @@ -472,9 +474,14 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, · 2 unmodified lines | ||
| 472 | 474 | struct batadv_hard_iface *if_outgoing, |
| 473 | 475 | u32 throughput) |
| 474 | 476 | { |
| 477 | + int if_hop_penalty = atomic_read(&if_incoming->hop_penalty); | |
| 475 | 478 | int hop_penalty = atomic_read(&bat_priv->hop_penalty); |
| 476 | 479 | int hop_penalty_max = BATADV_TQ_MAX_VALUE; |
| 477 | 480 | |
| 481 | + /* Apply per hardif hop penalty */ | |
| 482 | + throughput = throughput * (hop_penalty_max - if_hop_penalty) / | |
| 483 | + hop_penalty_max; | |
| 484 | + | |
| 478 | 485 | /* Don't apply hop penalty in default originator table. */ |
| 479 | 486 | if (if_outgoing == BATADV_IF_DEFAULT) |
| 480 | 487 | return throughput; |
| @@ -939,6 +939,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) · 938 unmodified lines | ||
| 939 | 939 | if (batadv_is_wifi_hardif(hard_iface)) |
| 940 | 940 | hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; |
| 941 | 941 | |
| 942 | + atomic_set(&hard_iface->hop_penalty, 0); | |
| 943 | + | |
| 942 | 944 | batadv_v_hardif_init(hard_iface); |
| 943 | 945 | |
| 944 | 946 | batadv_check_known_mac_addr(hard_iface->net_dev); |
| @@ -826,6 +826,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg, · 825 unmodified lines | ||
| 826 | 826 | goto nla_put_failure; |
| 827 | 827 | } |
| 828 | 828 | |
| 829 | + if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY, | |
| 830 | + atomic_read(&hard_iface->hop_penalty))) | |
| 831 | + goto nla_put_failure; | |
| 832 | + | |
| 829 | 833 | #ifdef CONFIG_BATMAN_ADV_BATMAN_V |
| 830 | 834 | if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, |
| 831 | 835 | atomic_read(&hard_iface->bat_v.elp_interval))) |
| @@ -920,9 +924,15 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb, · 88 unmodified lines | ||
| 920 | 924 | { |
| 921 | 925 | struct batadv_hard_iface *hard_iface = info->user_ptr[1]; |
| 922 | 926 | struct batadv_priv *bat_priv = info->user_ptr[0]; |
| 927 | + struct nlattr *attr; | |
| 928 | + | |
| 929 | + if (info->attrs[BATADV_ATTR_HOP_PENALTY]) { | |
| 930 | + attr = info->attrs[BATADV_ATTR_HOP_PENALTY]; | |
| 931 | + | |
| 932 | + atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr)); | |
| 933 | + } | |
| 923 | 934 | |
| 924 | 935 | #ifdef CONFIG_BATMAN_ADV_BATMAN_V |
| 925 | − struct nlattr *attr; | |
| 926 | 936 | |
| 927 | 937 | if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) { |
| 928 | 938 | attr = info->attrs[BATADV_ATTR_ELP_INTERVAL]; |
| @@ -208,6 +208,12 @@ struct batadv_hard_iface { · 207 unmodified lines | ||
| 208 | 208 | /** @rcu: struct used for freeing in an RCU-safe manner */ |
| 209 | 209 | struct rcu_head rcu; |
| 210 | 210 | |
| 211 | + /** | |
| 212 | + * @hop_penalty: penalty which will be applied to the tq-field | |
| 213 | + * of an OGM received via this interface | |
| 214 | + */ | |
| 215 | + atomic_t hop_penalty; | |
| 216 | + | |
| 211 | 217 | /** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */ |
| 212 | 218 | struct batadv_hard_iface_bat_iv bat_iv; |
| 213 | 219 | |