History

batman-adv: Introduce a configurable per interface hop penalty

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.

Linus Lüssing committed 6 years ago

Commit 3bda14d1 parent bccb48c6 files · +40 −13Browse files

Unified · Split

6 files
  1. include/uapi/linux/batman_adv.h +2 −1
  2. net/batman-adv/bat_iv_ogm.c +9 −8
  3. net/batman-adv/bat_v_ogm.c +10 −3
  4. net/batman-adv/hard-interface.c +2 −0
  5. net/batman-adv/netlink.c +11 −1
  6. net/batman-adv/types.h +6 −0
include/uapi/linux/batman_adv.h+2−1
@@ -427,7 +427,8 @@ enum batadv_nl_attrs { · 426 unmodified lines
427 427
428 /**428 /**
429 * @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied429 * @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 BATADV_ATTR_HOP_PENALTY,433 BATADV_ATTR_HOP_PENALTY,
433 434
net/batman-adv/bat_iv_ogm.c+9−8
@@ -1075,10 +1075,10 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, · 1074 unmodified lines
1075 struct batadv_neigh_ifinfo *neigh_ifinfo;1075 struct batadv_neigh_ifinfo *neigh_ifinfo;
1076 u8 total_count;1076 u8 total_count;
1077 u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;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 unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;1079 unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
1079 unsigned int tq_asym_penalty, inv_asym_penalty;1080 unsigned int tq_asym_penalty, inv_asym_penalty;
1080 unsigned int combined_tq;1081 unsigned int combined_tq;
1081 unsigned int tq_iface_penalty;
1082 bool ret = false;1082 bool ret = false;
1083 1083
1084 /* find corresponding one hop neighbor */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 inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;1157 inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
1158 inv_asym_penalty /= neigh_rq_max_cube;1158 inv_asym_penalty /= neigh_rq_max_cube;
1159 tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;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 /* penalize if the OGM is forwarded on the same interface. WiFi1162 /* penalize if the OGM is forwarded on the same interface. WiFi
1162 * interfaces and other half duplex devices suffer from throughput1163 * interfaces and other half duplex devices suffer from throughput
1163 * drops as they can't send and receive at the same time.1164 * drops as they can't send and receive at the same time.
1164 */1165 */
1165 tq_iface_penalty = BATADV_TQ_MAX_VALUE;
1166 if (if_outgoing && if_incoming == if_outgoing &&1166 if (if_outgoing && if_incoming == if_outgoing &&
1167 batadv_is_wifi_hardif(if_outgoing))1167 batadv_is_wifi_hardif(if_outgoing))
1168 tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE,1168 tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty,
1169 bat_priv);1169 bat_priv);
1170 1170
1171 combined_tq = batadv_ogm_packet->tq *1171 combined_tq = batadv_ogm_packet->tq *
1172 tq_own *1172 tq_own *
1173 tq_asym_penalty *1173 tq_asym_penalty *
1174 tq_iface_penalty;1174 tq_iface_hop_penalty;
1175 combined_tq /= BATADV_TQ_MAX_VALUE *1175 combined_tq /= BATADV_TQ_MAX_VALUE *
1176 BATADV_TQ_MAX_VALUE *1176 BATADV_TQ_MAX_VALUE *
1177 BATADV_TQ_MAX_VALUE;1177 BATADV_TQ_MAX_VALUE;
1178 batadv_ogm_packet->tq = combined_tq;1178 batadv_ogm_packet->tq = combined_tq;
1179 1179
1180 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,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 orig_node->orig, orig_neigh_node->orig, total_count,1182 orig_node->orig, orig_neigh_node->orig, total_count,
1183 neigh_rq_count, tq_own, tq_asym_penalty, tq_iface_penalty,1183 neigh_rq_count, tq_own, tq_asym_penalty,
1184 batadv_ogm_packet->tq, if_incoming->net_dev->name,1184 tq_iface_hop_penalty, batadv_ogm_packet->tq,
1185 if_incoming->net_dev->name,
1185 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");1186 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
1186 1187
1187 /* if link has the minimum required transmission quality1188 /* if link has the minimum required transmission quality
net/batman-adv/bat_v_ogm.c+10−3
@@ -455,15 +455,17 @@ unlock: · 454 unmodified lines
455 * @throughput: the current throughput455 * @throughput: the current throughput
456 *456 *
457 * Apply a penalty on the current throughput metric value based on the457 * Apply a penalty on the current throughput metric value based on the
458 * characteristic of the interface where the OGM has been received. The return458 * characteristic of the interface where the OGM has been received.
459 * value is computed as follows: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 * - throughput * 50% if the incoming and outgoing interface are the462 * - throughput * 50% if the incoming and outgoing interface are the
461 * same WiFi interface and the throughput is above463 * same WiFi interface and the throughput is above
462 * 1MBit/s464 * 1MBit/s
463 * - throughput if the outgoing interface is the default465 * - throughput if the outgoing interface is the default
464 * interface (i.e. this OGM is processed for the466 * interface (i.e. this OGM is processed for the
465 * internal table and not forwarded)467 * internal table and not forwarded)
466 * - throughput * hop penalty otherwise468 * - throughput * node hop penalty otherwise
467 *469 *
468 * Return: the penalised throughput metric.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 struct batadv_hard_iface *if_outgoing,474 struct batadv_hard_iface *if_outgoing,
473 u32 throughput)475 u32 throughput)
474{476{
477 int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
475 int hop_penalty = atomic_read(&bat_priv->hop_penalty);478 int hop_penalty = atomic_read(&bat_priv->hop_penalty);
476 int hop_penalty_max = BATADV_TQ_MAX_VALUE;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 /* Don't apply hop penalty in default originator table. */485 /* Don't apply hop penalty in default originator table. */
479 if (if_outgoing == BATADV_IF_DEFAULT)486 if (if_outgoing == BATADV_IF_DEFAULT)
480 return throughput;487 return throughput;
net/batman-adv/hard-interface.c+2−0
@@ -939,6 +939,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) · 938 unmodified lines
939 if (batadv_is_wifi_hardif(hard_iface))939 if (batadv_is_wifi_hardif(hard_iface))
940 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;940 hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
941 941
942 atomic_set(&hard_iface->hop_penalty, 0);
943
942 batadv_v_hardif_init(hard_iface);944 batadv_v_hardif_init(hard_iface);
943 945
944 batadv_check_known_mac_addr(hard_iface->net_dev);946 batadv_check_known_mac_addr(hard_iface->net_dev);
net/batman-adv/netlink.c+11−1
@@ -826,6 +826,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg, · 825 unmodified lines
826 goto nla_put_failure;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#ifdef CONFIG_BATMAN_ADV_BATMAN_V833#ifdef CONFIG_BATMAN_ADV_BATMAN_V
830 if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,834 if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
831 atomic_read(&hard_iface->bat_v.elp_interval)))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 struct batadv_hard_iface *hard_iface = info->user_ptr[1];925 struct batadv_hard_iface *hard_iface = info->user_ptr[1];
922 struct batadv_priv *bat_priv = info->user_ptr[0];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#ifdef CONFIG_BATMAN_ADV_BATMAN_V935#ifdef CONFIG_BATMAN_ADV_BATMAN_V
925 struct nlattr *attr;
926 936
927 if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {937 if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {
928 attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];938 attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];
net/batman-adv/types.h+6−0
@@ -208,6 +208,12 @@ struct batadv_hard_iface { · 207 unmodified lines
208 /** @rcu: struct used for freeing in an RCU-safe manner */208 /** @rcu: struct used for freeing in an RCU-safe manner */
209 struct rcu_head rcu;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 /** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */217 /** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */
212 struct batadv_hard_iface_bat_iv bat_iv;218 struct batadv_hard_iface_bat_iv bat_iv;
213 219