Lines Matching +full:sub +full:- +full:message

1 // SPDX-License-Identifier: GPL-2.0
51 #include "hard-interface.h"
58 #include "translation-table.h"
64 * enum batadv_dup_status - duplicate status
86 * batadv_ring_buffer_set() - update the ring buffer with the given value
98 * batadv_ring_buffer_avg() - compute the average of all non-zero values stored
130 * batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
153 spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
155 kref_get(&orig_node->refcount);
156 hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
158 &orig_node->hash_entry);
186 neigh_node->orig_node = orig_neigh;
198 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
202 atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
204 hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
205 ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
207 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
208 return -ENOMEM;
211 hard_iface->bat_iv.ogm_buff = ogm_buff;
214 batadv_ogm_packet->packet_type = BATADV_IV_OGM;
215 batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
216 batadv_ogm_packet->ttl = 2;
217 batadv_ogm_packet->flags = BATADV_NO_FLAGS;
218 batadv_ogm_packet->reserved = 0;
219 batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
221 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
228 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
230 kfree(hard_iface->bat_iv.ogm_buff);
231 hard_iface->bat_iv.ogm_buff = NULL;
233 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
241 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
243 ogm_buff = hard_iface->bat_iv.ogm_buff;
248 ether_addr_copy(batadv_ogm_packet->orig,
249 hard_iface->net_dev->dev_addr);
250 ether_addr_copy(batadv_ogm_packet->prev_sender,
251 hard_iface->net_dev->dev_addr);
254 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
263 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
265 ogm_buff = hard_iface->bat_iv.ogm_buff;
270 batadv_ogm_packet->ttl = BATADV_TTL;
273 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
282 msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
297 int hop_penalty = atomic_read(&bat_priv->hop_penalty);
300 new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
307 * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
326 next_buff_pos += ntohs(ogm_packet->tvlv_len);
335 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
343 if (hard_iface->if_status != BATADV_IF_ACTIVE)
348 packet_pos = forw_packet->skb->data;
352 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
357 if (test_bit(packet_num, forw_packet->direct_link_flags) &&
358 forw_packet->if_incoming == hard_iface)
359 batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
361 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
363 if (packet_num > 0 || !forw_packet->own)
371 batadv_ogm_packet->orig,
372 ntohl(batadv_ogm_packet->seqno),
373 batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
374 str_on_off(batadv_ogm_packet->flags & BATADV_DIRECTLINK),
375 hard_iface->net_dev->name,
376 hard_iface->net_dev->dev_addr);
379 buff_pos += ntohs(batadv_ogm_packet->tvlv_len);
381 packet_pos = forw_packet->skb->data + buff_pos;
386 skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
390 skb->len + ETH_HLEN);
400 if (!forw_packet->if_incoming) {
401 pr_err("Error - can't forward packet: incoming iface not specified\n");
405 mesh_iface = forw_packet->if_incoming->mesh_iface;
407 if (WARN_ON(!forw_packet->if_outgoing))
410 if (forw_packet->if_outgoing->mesh_iface != mesh_iface) {
415 if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE)
419 batadv_iv_ogm_send_to_if(forw_packet, forw_packet->if_outgoing);
423 * batadv_iv_ogm_can_aggregate() - find out if an OGM can be aggregated on an
446 unsigned int aggregated_bytes = forw_packet->packet_len + packet_len;
448 u8 packet_num = forw_packet->num_packets;
453 batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
457 max_bytes = min_t(unsigned int, if_outgoing->net_dev->mtu,
463 * - the send time is within our MAX_AGGREGATION_MS time
464 * - the resulting packet won't be bigger than
466 * - the number of packets is lower than MAX_AGGREGATION_PACKETS
469 if (!time_before(send_time, forw_packet->send_time) ||
470 !time_after_eq(aggregation_end_time, forw_packet->send_time))
480 if (forw_packet->if_outgoing != if_outgoing)
484 * -> direct link packets are broadcasted on
486 * -> aggregate packet if the current packet is
498 !(batadv_ogm_packet->flags & BATADV_DIRECTLINK) &&
499 batadv_ogm_packet->ttl != 1 &&
501 /* own packets originating non-primary
504 (!forw_packet->own ||
505 forw_packet->if_incoming == primary_if)) {
511 * interface only - we still can aggregate
514 new_bat_ogm_packet->ttl == 1 &&
515 forw_packet->if_incoming == if_incoming &&
521 (batadv_ogm_packet->flags & BATADV_DIRECTLINK ||
522 (forw_packet->own &&
523 forw_packet->if_incoming != primary_if))) {
534 * batadv_iv_ogm_aggregate_new() - create a new aggregated packet and add this
542 * @own_packet: true if it is a self-generated ogm
551 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
556 atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
558 if (atomic_read(&bat_priv->aggregated_ogms))
577 forw_packet_aggr->skb->priority = TC_PRIO_CONTROL;
578 skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
580 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
581 forw_packet_aggr->packet_len = packet_len;
584 forw_packet_aggr->own = own_packet;
585 bitmap_zero(forw_packet_aggr->direct_link_flags,
587 forw_packet_aggr->send_time = send_time;
591 set_bit(0, forw_packet_aggr->direct_link_flags);
593 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
604 skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len);
605 forw_packet_aggr->packet_len += packet_len;
609 set_bit(forw_packet_aggr->num_packets,
610 forw_packet_aggr->direct_link_flags);
612 forw_packet_aggr->num_packets++;
616 * batadv_iv_ogm_queue_add() - queue up an OGM for transmission
622 * @own_packet: true if it is a self-generated ogm
632 /* _aggr -> pointer to the packet we want to aggregate with
633 * _pos -> pointer to the position in the queue
642 direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
646 spin_lock_bh(&bat_priv->forw_bat_list_lock);
648 if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
650 &bat_priv->forw_bat_list, list) {
663 /* nothing to aggregate with - either aggregation disabled or no
668 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
674 if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
684 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
696 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
699 if (batadv_ogm_packet->ttl <= 1) {
712 batadv_ogm_packet->flags |= BATADV_NOT_BEST_NEXT_HOP;
717 tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);
719 batadv_ogm_packet->ttl--;
720 ether_addr_copy(batadv_ogm_packet->prev_sender, ethhdr->h_source);
723 batadv_ogm_packet->tq = batadv_hop_penalty(batadv_ogm_packet->tq,
728 batadv_ogm_packet->tq, batadv_ogm_packet->ttl);
731 batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
733 batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
742 * batadv_iv_ogm_slide_own_bcast_window() - bitshift own OGM broadcast windows
749 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
750 struct batadv_hashtable *hash = bat_priv->orig_hash;
758 for (i = 0; i < hash->size; i++) {
759 head = &hash->table[i];
764 &orig_node->ifinfo_list,
766 if (orig_ifinfo->if_outgoing != hard_iface)
769 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
770 word = orig_ifinfo->bat_iv.bcast_own;
772 w = &orig_ifinfo->bat_iv.bcast_own_sum;
775 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
783 * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
788 struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
789 unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
792 int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
798 lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
810 if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
811 hard_iface->if_status = BATADV_IF_ACTIVE;
826 batadv_ogm_packet->tvlv_len = htons(tvlv_len);
829 seqno = (u32)atomic_read(&hard_iface->bat_iv.ogm_seqno);
830 batadv_ogm_packet->seqno = htonl(seqno);
831 atomic_inc(&hard_iface->bat_iv.ogm_seqno);
850 netdev_for_each_lower_private_rcu(hard_iface->mesh_iface, tmp_hard_iface, iter) {
851 if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
868 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
869 hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
872 mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
874 mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
878 * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over interface
897 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
898 sum = orig_ifinfo->bat_iv.bcast_own_sum;
899 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
907 * batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
943 &orig_node->neigh_list, list) {
944 neigh_addr = tmp_neigh_node->addr;
945 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
946 tmp_neigh_node->if_incoming == if_incoming &&
947 kref_get_unless_zero(&tmp_neigh_node->refcount)) {
963 spin_lock_bh(&tmp_neigh_node->ifinfo_lock);
964 batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
965 &neigh_ifinfo->bat_iv.tq_index, 0);
966 tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
967 neigh_ifinfo->bat_iv.tq_avg = tq_avg;
968 spin_unlock_bh(&tmp_neigh_node->ifinfo_lock);
977 orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
982 ethhdr->h_source,
990 "Updating existing last-hop neighbor of originator\n");
998 neigh_node->last_seen = jiffies;
1000 spin_lock_bh(&neigh_node->ifinfo_lock);
1001 batadv_ring_buffer_set(neigh_ifinfo->bat_iv.tq_recv,
1002 &neigh_ifinfo->bat_iv.tq_index,
1003 batadv_ogm_packet->tq);
1004 tq_avg = batadv_ring_buffer_avg(neigh_ifinfo->bat_iv.tq_recv);
1005 neigh_ifinfo->bat_iv.tq_avg = tq_avg;
1006 spin_unlock_bh(&neigh_node->ifinfo_lock);
1009 orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1010 neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1028 if (router_ifinfo->bat_iv.tq_avg > neigh_ifinfo->bat_iv.tq_avg)
1036 neigh_ifinfo->bat_iv.tq_avg == router_ifinfo->bat_iv.tq_avg) {
1037 sum_orig = batadv_iv_orig_ifinfo_sum(router->orig_node,
1038 router->if_incoming);
1039 sum_neigh = batadv_iv_orig_ifinfo_sum(neigh_node->orig_node,
1040 neigh_node->if_incoming);
1058 * batadv_iv_ogm_calc_tq() - calculate tq for current received ogm packet
1073 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1087 &orig_neigh_node->neigh_list, list) {
1088 if (!batadv_compare_eth(tmp_neigh_node->addr,
1089 orig_neigh_node->orig))
1092 if (tmp_neigh_node->if_incoming != if_incoming)
1095 if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
1105 orig_neigh_node->orig,
1114 neigh_node->last_seen = jiffies;
1116 orig_node->last_seen = jiffies;
1122 neigh_rq_count = neigh_ifinfo->bat_iv.real_packet_count;
1141 /* neigh_node->real_packet_count is never zero as we
1147 /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
1148 * affect the nearly-symmetric links only a little, but
1152 neigh_rq_inv = BATADV_TQ_LOCAL_WINDOW_SIZE - neigh_rq_count;
1159 tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
1160 tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
1171 combined_tq = batadv_ogm_packet->tq *
1178 batadv_ogm_packet->tq = combined_tq;
1182 orig_node->orig, orig_neigh_node->orig, total_count,
1184 tq_iface_hop_penalty, batadv_ogm_packet->tq,
1185 if_incoming->net_dev->name,
1186 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
1191 if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
1200 * batadv_iv_ogm_update_seqnos() - process a batman packet for all interfaces,
1215 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1225 u32 seqno = ntohl(batadv_ogm_packet->seqno);
1230 orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1240 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1241 seq_diff = seqno - orig_ifinfo->last_real_seqno;
1244 if (!hlist_empty(&orig_node->neigh_list) &&
1247 &orig_ifinfo->batman_seqno_reset, NULL)) {
1253 hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1259 neigh_addr = neigh_node->addr;
1260 is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
1261 orig_ifinfo->last_real_seqno,
1264 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
1265 neigh_node->if_incoming == if_incoming) {
1276 bitmap = neigh_ifinfo->bat_iv.real_bits;
1282 neigh_ifinfo->bat_iv.real_packet_count = packet_count;
1290 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
1291 orig_ifinfo->last_real_seqno, seqno);
1292 orig_ifinfo->last_real_seqno = seqno;
1296 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1303 * batadv_iv_ogm_process_per_outif() - process a batman iv OGM for an outgoing
1306 * @ogm_offset: offset from skb->data to start of ogm header
1317 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1343 ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
1347 if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
1353 ethhdr->h_source);
1357 if (ogm_packet->tq == 0) {
1365 ethhdr->h_source);
1367 hardif_neigh->last_seen = jiffies;
1372 router_router = batadv_orig_router_get(router->orig_node,
1377 if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
1378 (batadv_compare_eth(router->addr, ethhdr->h_source)))
1381 prev_sender = ogm_packet->prev_sender;
1384 (batadv_compare_eth(router->addr, prev_sender)) &&
1385 !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
1386 (batadv_compare_eth(router->addr, router_router->addr))) {
1389 ethhdr->h_source);
1403 ethhdr->h_source);
1425 * seqno and similar ttl as the non-duplicate
1431 sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
1432 similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;
1452 if (ogm_packet->ttl <= 2 &&
1502 * batadv_iv_ogm_process_reply() - Check OGM for direct reply and process it
1520 if (!(ogm_packet->flags & BATADV_DIRECTLINK))
1523 if (!batadv_compare_eth(if_incoming->net_dev->dev_addr,
1524 ogm_packet->orig))
1532 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1533 bit_pos = if_incoming_seqno - 2;
1534 bit_pos -= ntohl(ogm_packet->seqno);
1535 batadv_set_bit(orig_ifinfo->bat_iv.bcast_own, bit_pos);
1536 weight = &orig_ifinfo->bat_iv.bcast_own_sum;
1537 *weight = bitmap_weight(orig_ifinfo->bat_iv.bcast_own,
1539 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1545 * batadv_iv_ogm_process() - process an incoming batman iv OGM
1553 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1565 ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
1580 if (ogm_packet->packet_type != BATADV_IV_OGM)
1584 if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1586 if (ogm_packet->flags & BATADV_DIRECTLINK)
1593 ethhdr->h_source, if_incoming->net_dev->name,
1594 if_incoming->net_dev->dev_addr, ogm_packet->orig,
1595 ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
1596 ogm_packet->tq, ogm_packet->ttl,
1597 ogm_packet->version, has_directlink_flag);
1601 netdev_for_each_lower_private_rcu(if_incoming->mesh_iface, hard_iface, iter) {
1602 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1605 if (batadv_compare_eth(ethhdr->h_source,
1606 hard_iface->net_dev->dev_addr))
1609 if (batadv_compare_eth(ogm_packet->orig,
1610 hard_iface->net_dev->dev_addr))
1613 if (batadv_compare_eth(ogm_packet->prev_sender,
1614 hard_iface->net_dev->dev_addr))
1622 ethhdr->h_source);
1628 ethhdr->h_source);
1644 ethhdr->h_source);
1648 if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1651 ethhdr->h_source);
1655 orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
1663 netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
1664 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1667 if (!kref_get_unless_zero(&hard_iface->refcount))
1690 bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface);
1692 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
1702 * only re-schedule if this is the "original" copy, e.g. the OGM of the
1707 if (forw_packet->own &&
1708 forw_packet->if_incoming == forw_packet->if_outgoing)
1709 batadv_iv_ogm_schedule(forw_packet->if_incoming);
1714 &bat_priv->forw_bat_list_lock))
1721 struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
1735 if (bat_priv->algo_ops->iface.enable != batadv_iv_ogm_iface_enable)
1740 skb->len + ETH_HLEN);
1743 ogm_packet = (struct batadv_ogm_packet *)skb->data;
1751 ogm_offset += ntohs(ogm_packet->tvlv_len);
1753 packet_pos = skb->data + ogm_offset;
1769 * batadv_iv_ogm_neigh_get_tq_avg() - Get the TQ average for a neighbour on a
1788 *tq_avg = n_ifinfo->bat_iv.tq_avg;
1795 * batadv_iv_ogm_orig_dump_subentry() - Dump an originator subentry into a
1796 * message
1797 * @msg: Netlink message to dump into
1799 * @seq: Sequence number of netlink message
1820 last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
1826 if_outgoing != neigh_node->if_incoming)
1832 return -ENOBUFS;
1835 orig_node->orig) ||
1837 neigh_node->addr) ||
1839 neigh_node->if_incoming->net_dev->name) ||
1841 neigh_node->if_incoming->net_dev->ifindex) ||
1855 return -EMSGSIZE;
1859 * batadv_iv_ogm_orig_dump_entry() - Dump an originator entry into a message
1860 * @msg: Netlink message to dump into
1862 * @seq: Sequence number of netlink message
1866 * @sub_s: Number of sub entries to skip
1880 int sub = 0;
1895 hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
1896 if (sub++ < *sub_s)
1907 *sub_s = sub - 1;
1908 return -EMSGSIZE;
1920 * batadv_iv_ogm_orig_dump_bucket() - Dump an originator bucket into a
1921 * message
1922 * @msg: Netlink message to dump into
1924 * @seq: Sequence number of netlink message
1929 * @sub: Number of sub entries to be skipped
1937 struct hlist_head *head, int *idx_s, int *sub)
1949 sub)) {
1951 *idx_s = idx - 1;
1952 return -EMSGSIZE;
1958 *sub = 0;
1963 * batadv_iv_ogm_orig_dump() - Dump the originators into a message
1964 * @msg: Netlink message to dump into
1974 struct batadv_hashtable *hash = bat_priv->orig_hash;
1976 int bucket = cb->args[0];
1977 int idx = cb->args[1];
1978 int sub = cb->args[2];
1979 int portid = NETLINK_CB(cb->skb).portid;
1981 while (bucket < hash->size) {
1982 head = &hash->table[bucket];
1985 cb->nlh->nlmsg_seq,
1987 &idx, &sub))
1993 cb->args[0] = bucket;
1994 cb->args[1] = idx;
1995 cb->args[2] = sub;
1999 * batadv_iv_ogm_neigh_diff() - calculate tq difference of two neighbors
2030 tq1 = neigh1_ifinfo->bat_iv.tq_avg;
2031 tq2 = neigh2_ifinfo->bat_iv.tq_avg;
2032 *diff = (int)tq1 - (int)tq2;
2042 * batadv_iv_ogm_neigh_dump_neigh() - Dump a neighbour into a netlink message
2043 * @msg: Netlink message to dump into
2045 * @seq: Sequence number of netlink message
2057 last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
2062 return -ENOBUFS;
2065 hardif_neigh->addr) ||
2067 hardif_neigh->if_incoming->net_dev->name) ||
2069 hardif_neigh->if_incoming->net_dev->ifindex) ||
2079 return -EMSGSIZE;
2083 * batadv_iv_ogm_neigh_dump_hardif() - Dump the neighbours of a hard interface
2084 * into a message
2085 * @msg: Netlink message to dump into
2087 * @seq: Sequence number of netlink message
2106 &hard_iface->neigh_list, list) {
2112 *idx_s = idx - 1;
2113 return -EMSGSIZE;
2122 * batadv_iv_ogm_neigh_dump() - Dump the neighbours into a message
2123 * @msg: Netlink message to dump into
2136 int i_hardif_s = cb->args[0];
2137 int idx = cb->args[1];
2138 int portid = NETLINK_CB(cb->skb).portid;
2144 cb->nlh->nlmsg_seq,
2151 netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
2156 cb->nlh->nlmsg_seq,
2159 i_hardif--;
2166 cb->args[0] = i_hardif;
2167 cb->args[1] = idx;
2171 * batadv_iv_ogm_neigh_cmp() - compare the metrics of two neighbors
2197 * batadv_iv_ogm_neigh_is_sob() - check if neigh1 is similarly good or better
2221 ret = diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
2232 * batadv_iv_init_sel_class() - initialize GW selection class
2238 atomic_set(&bat_priv->gw.sel_class, 20);
2254 hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
2255 orig_node = gw_node->orig_node;
2265 if (!kref_get_unless_zero(&gw_node->refcount))
2268 tq_avg = router_ifinfo->bat_iv.tq_avg;
2270 switch (atomic_read(&bat_priv->gw.sel_class)) {
2273 tmp_gw_factor *= gw_node->bandwidth_down;
2282 kref_get(&curr_gw->refcount);
2287 * 3: fast-switch (use best statistic but change as
2289 * XX: late-switch (use best statistic but change as
2296 kref_get(&curr_gw->refcount);
2329 /* dynamic re-election is performed only on fast or late switch */
2330 if (atomic_read(&bat_priv->gw.sel_class) <= 2)
2355 gw_tq_avg = router_gw_ifinfo->bat_iv.tq_avg;
2356 orig_tq_avg = router_orig_ifinfo->bat_iv.tq_avg;
2365 if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
2366 (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
2384 * batadv_iv_gw_dump_entry() - Dump a gateway into a message
2385 * @msg: Netlink message to dump into
2404 router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
2414 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2418 ret = -ENOBUFS;
2424 ret = -EMSGSIZE;
2433 gw_node->orig_node->orig) ||
2434 nla_put_u8(msg, BATADV_ATTR_TQ, router_ifinfo->bat_iv.tq_avg) ||
2436 router->addr) ||
2438 router->if_incoming->net_dev->name) ||
2440 router->if_incoming->net_dev->ifindex) ||
2442 gw_node->bandwidth_down) ||
2444 gw_node->bandwidth_up)) {
2460 * batadv_iv_gw_dump() - Dump gateways into a message
2461 * @msg: Netlink message to dump into
2468 int portid = NETLINK_CB(cb->skb).portid;
2470 int idx_skip = cb->args[0];
2473 spin_lock_bh(&bat_priv->gw.list_lock);
2474 cb->seq = bat_priv->gw.generation << 1 | 1;
2476 hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
2482 idx_skip = idx - 1;
2489 spin_unlock_bh(&bat_priv->gw.list_lock);
2491 cb->args[0] = idx_skip;
2521 * batadv_iv_init() - B.A.T.M.A.N. IV initialization function