diff options
-rw-r--r-- | net/batman-adv/routing.c | 66 | ||||
-rw-r--r-- | net/batman-adv/translation-table.c | 69 | ||||
-rw-r--r-- | net/batman-adv/translation-table.h | 9 |
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 | ||
67 | static 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) { | ||
112 | request_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 | |||
126 | static void update_route(struct bat_priv *bat_priv, | 67 | static 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 | ||
1082 | int send_tt_request(struct bat_priv *bat_priv, struct orig_node *dst_orig_node, | 1082 | static 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 | ||
1458 | void tt_update_changes(struct bat_priv *bat_priv, struct orig_node *orig_node, | 1459 | static 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 | |||
1808 | void 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) { | ||
1851 | request_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, | |||
49 | uint16_t tt_local_crc(struct bat_priv *bat_priv); | 49 | uint16_t tt_local_crc(struct bat_priv *bat_priv); |
50 | uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node); | 50 | uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node); |
51 | void tt_free(struct bat_priv *bat_priv); | 51 | void tt_free(struct bat_priv *bat_priv); |
52 | int 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); | ||
55 | bool send_tt_response(struct bat_priv *bat_priv, | 52 | bool send_tt_response(struct bat_priv *bat_priv, |
56 | struct tt_query_packet *tt_request); | 53 | struct tt_query_packet *tt_request); |
57 | void 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); | ||
60 | bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); | 54 | bool is_my_client(struct bat_priv *bat_priv, const uint8_t *addr); |
61 | void handle_tt_response(struct bat_priv *bat_priv, | 55 | void 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); |
65 | void tt_commit_changes(struct bat_priv *bat_priv); | 59 | void tt_commit_changes(struct bat_priv *bat_priv); |
66 | bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); | 60 | bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); |
61 | void 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_ */ |