aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/batman-adv/routing.c66
-rw-r--r--net/batman-adv/translation-table.c69
-rw-r--r--net/batman-adv/translation-table.h9
3 files changed, 70 insertions, 74 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 91a7860ecadd..19499281b695 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,65 +64,6 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
64 } 64 }
65} 65}
66 66
67static void update_transtable(struct bat_priv *bat_priv,
68 struct orig_node *orig_node,
69 const unsigned char *tt_buff,
70 uint8_t tt_num_changes, uint8_t ttvn,
71 uint16_t tt_crc)
72{
73 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
74 bool full_table = true;
75
76 /* the ttvn increased by one -> we can apply the attached changes */
77 if (ttvn - orig_ttvn == 1) {
78 /* the OGM could not contain the changes due to their size or
79 * because they have already been sent TT_OGM_APPEND_MAX times.
80 * In this case send a tt request */
81 if (!tt_num_changes) {
82 full_table = false;
83 goto request_table;
84 }
85
86 tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
87 (struct tt_change *)tt_buff);
88
89 /* Even if we received the precomputed crc with the OGM, we
90 * prefer to recompute it to spot any possible inconsistency
91 * in the global table */
92 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
93
94 /* The ttvn alone is not enough to guarantee consistency
95 * because a single value could represent different states
96 * (due to the wrap around). Thus a node has to check whether
97 * the resulting table (after applying the changes) is still
98 * consistent or not. E.g. a node could disconnect while its
99 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
100 * checking the CRC value is mandatory to detect the
101 * inconsistency */
102 if (orig_node->tt_crc != tt_crc)
103 goto request_table;
104
105 /* Roaming phase is over: tables are in sync again. I can
106 * unset the flag */
107 orig_node->tt_poss_change = false;
108 } else {
109 /* if we missed more than one change or our tables are not
110 * in sync anymore -> request fresh tt data */
111 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
112request_table:
113 bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
114 "Need to retrieve the correct information "
115 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
116 "%u num_changes: %u)\n", orig_node->orig, ttvn,
117 orig_ttvn, tt_crc, orig_node->tt_crc,
118 tt_num_changes);
119 send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
120 full_table);
121 return;
122 }
123 }
124}
125
126static void update_route(struct bat_priv *bat_priv, 67static void update_route(struct bat_priv *bat_priv,
127 struct orig_node *orig_node, 68 struct orig_node *orig_node,
128 struct neigh_node *neigh_node) 69 struct neigh_node *neigh_node)
@@ -499,10 +440,9 @@ update_tt:
499 if (((batman_packet->orig != ethhdr->h_source) && 440 if (((batman_packet->orig != ethhdr->h_source) &&
500 (batman_packet->ttl > 2)) || 441 (batman_packet->ttl > 2)) ||
501 (batman_packet->flags & PRIMARIES_FIRST_HOP)) 442 (batman_packet->flags & PRIMARIES_FIRST_HOP))
502 update_transtable(bat_priv, orig_node, tt_buff, 443 tt_update_orig(bat_priv, orig_node, tt_buff,
503 batman_packet->tt_num_changes, 444 batman_packet->tt_num_changes,
504 batman_packet->ttvn, 445 batman_packet->ttvn, batman_packet->tt_crc);
505 batman_packet->tt_crc);
506 446
507 if (orig_node->gw_flags != batman_packet->gw_flags) 447 if (orig_node->gw_flags != batman_packet->gw_flags)
508 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); 448 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index e8f849f6b5b7..cc53f78e448c 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1079,8 +1079,9 @@ out:
1079 return skb; 1079 return skb;
1080} 1080}
1081 1081
1082int send_tt_request(struct bat_priv *bat_priv, struct orig_node *dst_orig_node, 1082static int send_tt_request(struct bat_priv *bat_priv,
1083 uint8_t ttvn, uint16_t tt_crc, bool full_table) 1083 struct orig_node *dst_orig_node,
1084 uint8_t ttvn, uint16_t tt_crc, bool full_table)
1084{ 1085{
1085 struct sk_buff *skb = NULL; 1086 struct sk_buff *skb = NULL;
1086 struct tt_query_packet *tt_request; 1087 struct tt_query_packet *tt_request;
@@ -1455,9 +1456,10 @@ out:
1455 orig_node_free_ref(orig_node); 1456 orig_node_free_ref(orig_node);
1456} 1457}
1457 1458
1458void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node, 1459static void tt_update_changes(struct bat_priv *bat_priv,
1459 uint16_t tt_num_changes, uint8_t ttvn, 1460 struct orig_node *orig_node,
1460 struct tt_change *tt_change) 1461 uint16_t tt_num_changes, uint8_t ttvn,
1462 struct tt_change *tt_change)
1461{ 1463{
1462 _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes, 1464 _tt_update_changes(bat_priv, orig_node, tt_change, tt_num_changes,
1463 ttvn); 1465 ttvn);
@@ -1802,3 +1804,60 @@ out:
1802 tt_local_entry_free_ref(tt_local_entry); 1804 tt_local_entry_free_ref(tt_local_entry);
1803 return ret; 1805 return ret;
1804} 1806}
1807
1808void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
1809 const unsigned char *tt_buff, uint8_t tt_num_changes,
1810 uint8_t ttvn, uint16_t tt_crc)
1811{
1812 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1813 bool full_table = true;
1814
1815 /* the ttvn increased by one -> we can apply the attached changes */
1816 if (ttvn - orig_ttvn == 1) {
1817 /* the OGM could not contain the changes due to their size or
1818 * because they have already been sent TT_OGM_APPEND_MAX times.
1819 * In this case send a tt request */
1820 if (!tt_num_changes) {
1821 full_table = false;
1822 goto request_table;
1823 }
1824
1825 tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
1826 (struct tt_change *)tt_buff);
1827
1828 /* Even if we received the precomputed crc with the OGM, we
1829 * prefer to recompute it to spot any possible inconsistency
1830 * in the global table */
1831 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
1832
1833 /* The ttvn alone is not enough to guarantee consistency
1834 * because a single value could represent different states
1835 * (due to the wrap around). Thus a node has to check whether
1836 * the resulting table (after applying the changes) is still
1837 * consistent or not. E.g. a node could disconnect while its
1838 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
1839 * checking the CRC value is mandatory to detect the
1840 * inconsistency */
1841 if (orig_node->tt_crc != tt_crc)
1842 goto request_table;
1843
1844 /* Roaming phase is over: tables are in sync again. I can
1845 * unset the flag */
1846 orig_node->tt_poss_change = false;
1847 } else {
1848 /* if we missed more than one change or our tables are not
1849 * in sync anymore -> request fresh tt data */
1850 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
1851request_table:
1852 bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
1853 "Need to retrieve the correct information "
1854 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
1855 "%u num_changes: %u)\n", orig_node->orig, ttvn,
1856 orig_ttvn, tt_crc, orig_node->tt_crc,
1857 tt_num_changes);
1858 send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
1859 full_table);
1860 return;
1861 }
1862 }
1863}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index b47e8760b76b..30efd49881a3 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -49,14 +49,8 @@ void tt_save_orig_buffer(struct bat_priv *bat_priv, struct orig_node *orig_node,
49uint16_t tt_local_crc(struct bat_priv *bat_priv); 49uint16_t tt_local_crc(struct bat_priv *bat_priv);
50uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node); 50uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node);
51void tt_free(struct bat_priv *bat_priv); 51void tt_free(struct bat_priv *bat_priv);
52int send_tt_request(struct bat_priv *bat_priv,
53 struct orig_node *dst_orig_node, uint8_t ttvn,
54 uint16_t tt_crc, bool full_table);
55bool send_tt_response(struct bat_priv *bat_priv, 52bool send_tt_response(struct bat_priv *bat_priv,
56 struct tt_query_packet *tt_request); 53 struct tt_query_packet *tt_request);
57void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node,
58 uint16_t tt_num_changes, uint8_t ttvn,
59 struct tt_change *tt_change);
60bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); 54bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr);
61void handle_tt_response(struct bat_priv *bat_priv, 55void handle_tt_response(struct bat_priv *bat_priv,
62 struct tt_query_packet *tt_response); 56 struct tt_query_packet *tt_response);
@@ -64,5 +58,8 @@ void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
64 struct orig_node *orig_node); 58 struct orig_node *orig_node);
65void tt_commit_changes(struct bat_priv *bat_priv); 59void tt_commit_changes(struct bat_priv *bat_priv);
66bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); 60bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst);
61void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
62 const unsigned char *tt_buff, uint8_t tt_num_changes,
63 uint8_t ttvn, uint16_t tt_crc);
67 64
68#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ 65#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */