NetSim Source Code Help
Loading...
Searching...
No Matches
DIO.c
Go to the documentation of this file.
1/************************************************************************************
2* Copyright (C) 2020 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "RPL.h"
16#include "RPL_Message.h"
17
19{
22
23 if (!d2)
24 return FALSE;
25
26 if (!d1)
27 return true;
28
29 return memcmp(d1, d2, sizeof* d1);
30}
31
32static bool dio_pdu_changed(PRPL_NEIGHBOR neighbor, PRPL_CTRL_MSG dio_pdu)
33{
34 if (neighbor->lastDIOMSG == NULL)
35 {
36 return TRUE;
37 }
38 else
39 {
40 PRPL_CTRL_MSG msg = dio_pdu;
41 PRPL_DIO_BASE b = msg->Base;
42 PRPL_DIO_BASE lb = ((PRPL_CTRL_MSG)neighbor->lastDIOMSG)->Base;
43
44 bool base_changed = (IP_COMPARE(lb->DODAGID, b->DODAGID)) ||
45 (lb->Prf != b->Prf) ||
46 (lb->DTSN != b->DTSN) ||
47 (lb->Rank != b->Rank) ||
48 (lb->G != b->G) ||
49 (lb->MOP != b->MOP) ||
50 (lb->RPLInstanceID != b->RPLInstanceID) ||
52
53 bool dodag_config_changed = dio_pdu_dodag_config_changed(neighbor->lastDIOMSG,
54 msg);
55
56 return base_changed || dodag_config_changed;
57 }
58}
59
61{
62 PRPL_NODE rpl = GET_RPL_NODE(d);
63 /* forget about all DIO routes */
65
67 rpl->joined_dodag->pref_parent = NULL;
68
70
73 rpl->poison_count_so_far = 0;
74
76}
77
79{
80 PRPL_NODE rpl = GET_RPL_NODE(d);
81 NetSim_PACKET* root_packet = create_root_dio_message(d, time, FALSE, FALSE);
82 PRPL_CTRL_MSG root_dio_pdu = root_packet->pstruNetworkData->Packet_RoutingProtocol;
83 PRPL_CTRL_MSG best_dio_pdu = root_dio_pdu;
84 PRPL_DIO_BASE best_dio_base = root_dio_pdu->Base;
85 root_packet->pstruNetworkData->Packet_RoutingProtocol = NULL;
86 fn_NetSim_Packet_FreePacket(root_packet);
87
88 PRPL_NEIGHBOR old_pref_parent = rpl_node_is_joined(rpl) ? rpl->joined_dodag->pref_parent : NULL;
89
90 UINT16 i;
91 for (i = 0; i < rpl->neighbor_count; i++)
92 {
93 PRPL_NEIGHBOR neighbor = rpl->neighbor_list[i];
94
95 if (neighbor->lastDIOMSG == NULL)
96 { /* ignore neighbors who haven't sent any DIO */
97 continue;
98 }
99
101 if (dodag_config_suboption == NULL)
102 { /* ignore neighbors for whom no DODAG config info is available */
103 continue;
104 }
105 PRPL_DIO_BASE diobase = neighbor->lastDIOMSG->Base;
106
107 if (diobase->Rank >= INFINITE_RANK)
108 { /* ignore neighbors that started poisoning */
109 continue;
110 }
111
112 if (rpl_node_is_joined(rpl) &&
113 IP_COMPARE(diobase->DODAGID, rpl->joined_dodag->dodag_id) == 0 &&
114 diobase->Rank >= rpl->joined_dodag->rank)
115 { /* ignore neighbors of our DODAG with greater or equal rank */
116
117 continue;
118 }
119
120 if (!best_dio_base->G && diobase->G)
121 {
122 best_dio_pdu = neighbor->lastDIOMSG;
123 best_dio_base = best_dio_pdu->Base;
124 }
125 else if (best_dio_base->G == diobase->G)
126 {
127 if (best_dio_base->Prf < diobase->Prf)
128 {
129 best_dio_pdu = neighbor->lastDIOMSG;
130 best_dio_base = best_dio_pdu->Base;
131 }
132 else if (best_dio_base->Prf == diobase->Prf)
133 {
134 if (best_dio_base->DTSN < diobase->DTSN)
135 {
136 best_dio_pdu = neighbor->lastDIOMSG;
137 best_dio_base = best_dio_pdu->Base;
138 }
139 }
140 }
141 }
142
143 if (best_dio_pdu != root_dio_pdu)
144 {
145 rpl_dio_pdu_free(root_dio_pdu);
146
148 {
149 *same = (IP_COMPARE(rpl->joined_dodag->dodag_id, best_dio_base->DODAGID) == 0) &&
150 (rpl->joined_dodag->seq_num == best_dio_base->DTSN);
151 }
152 else
153 {
154 *same = FALSE;
155 }
156 return best_dio_pdu;
157 }
158 else
159 {
160 print_rpl_log("node '%d': no preferable DODAG iterations around", d);
161 /* give priority to the former parent, to follow him if necessary */
162
163 if (old_pref_parent != NULL &&
164 old_pref_parent->lastDIOMSG != NULL)
165 {
166 PRPL_DIO_BASE diobase = old_pref_parent->lastDIOMSG->Base;
167 if (diobase->G == best_dio_base->G &&
168 diobase->Prf == best_dio_base->Prf)
169 {
170 *same = ((IP_COMPARE(rpl->joined_dodag->dodag_id, diobase->DODAGID) == 0) &&
171 rpl->joined_dodag->seq_num == diobase->DTSN);
172
173 best_dio_pdu = old_pref_parent->lastDIOMSG;
174 best_dio_base = best_dio_pdu->Base;
175
176 rpl_dio_pdu_free(root_dio_pdu);
177 return best_dio_pdu;
178 }
179 }
180 else
181 {
182 rpl_dio_pdu_free(root_dio_pdu);
183
184 *same = rpl_node_is_root(rpl);
185 return NULL;
186 }
187 }
188 return NULL;
189}
190
192{
196 PRPL_NODE drpl = GET_RPL_NODE(d);
197 PRPL_NODE rrpl = GET_RPL_NODE(r);
198 PRPL_DIO_BASE diobase = dioPdu->Base;
199
200 PRPL_NEIGHBOR neighbor = rpl_find_neighbor(d, r);
201
202 if (dio_pdu_changed(neighbor, dioPdu))
203 {
204
205 /* ignore messages from members of our DODAG which are neither parents nor siblings and emit a greater rank than us */
206 if (rpl_node_is_joined(drpl))
207 {
208 if (IP_COMPARE(drpl->joined_dodag->dodag_id, diobase->DODAGID) == 0 &&
209 drpl->joined_dodag->rank < diobase->Rank &&
210 !rpl_node_has_parent(d, r) &&
212 {
213
214 neighbor->lastDIOMSG = NULL; /* make sure we "forgot" the last message for this neighbor */
215 return;
216 }
217 }
218 else if (rpl_node_is_root(drpl))
219 {
220 if (IP_COMPARE(drpl->root_info->dodag_id, diobase->DODAGID) == 0)
221 {
222
223 neighbor->lastDIOMSG = NULL; /* make sure we "forgot" the last message for this */
224 return;
225 }
226 }
227
228 print_rpl_log("node '%d': received a new/modified message from node '%d' with dodag_id = '%s'",
229 d, r, RPL_IP_TO_STR(diobase->DODAGID));
230
231
232 bool dodag_config_changed = dio_pdu_dodag_config_changed(neighbor->lastDIOMSG, dioPdu);
233
234 update_neighbor_dio_message(neighbor, dioPdu);
235
236 /*
237 * If we get poison from the preferred parent, we propagate the poisoning mechanism
238 */
239 if (rpl_node_is_joined(drpl))
240 {
241 if ((drpl->joined_dodag->pref_parent == neighbor) &&
242 (((PRPL_DIO_BASE)neighbor->lastDIOMSG->Base)->Rank == INFINITE_RANK))
243 {
245 return;
246 }
247 }
248 /* end of poisoning procedure */
249
250
251 bool same;
253
254 if (rpl_node_is_isolated(drpl))
255 {
256 if (preferred_dodag_pdu != NULL)
257 {
258 PRPL_DIO_BASE b = preferred_dodag_pdu->Base;
259 print_rpl_log("node '%d': was isolated, now found dodag_id = '%s'",
260 d, RPL_IP_TO_STR(b->DODAGID));
261 join_dodag_iteration(d, preferred_dodag_pdu);
263 }
264 else
265 {
266 /* don't start as root, since we were configured to start as isolated */
267 }
268 }
269 else if (rpl_node_is_root(drpl))
270 {
271 if (preferred_dodag_pdu != NULL)
272 {
273 PRPL_DIO_BASE b = preferred_dodag_pdu->Base;
274 print_rpl_log("node '%d': was root of dodag_id = '%s', now found a better one with dodag_id = '%s'",
275 d, drpl->root_info->dodag_id, b->DODAGID);
276
277 join_dodag_iteration(d, preferred_dodag_pdu);
279 }
280 else
281 {
282 /* we're already root */
283 }
284 }
285 else if (rpl_node_is_poisoning(drpl))
286 {
287 /* we ignore everything in this temporary state */
288 }
289 else if (rpl_node_is_joined(drpl))
290 {
291 if (!same)
292 {
293 if (preferred_dodag_pdu != NULL)
294 {
295 PRPL_DIO_BASE b = preferred_dodag_pdu->Base;
296 print_rpl_log("node '%d': was member of dodag_id = '%s', now found a better one with dodag_id = '%s'",
297 d, drpl->joined_dodag->dodag_id, b->DODAGID);
298
299 join_dodag_iteration(d, preferred_dodag_pdu);
301 }
302 else
303 {
304 print_rpl_log("node '%d': was member of dodag_id = '%s', now starting own root",
305 d, drpl->joined_dodag->dodag_id);
306 start_as_root(d);
307 }
308 }
309 else
310 {
311 PRPL_DIO_BASE dbase = neighbor->lastDIOMSG->Base;
312 /* a new member of our DODAG is a potential parent/sibling, need to reevaluate our neighbors */
313 if (IP_COMPARE(dbase->DODAGID, drpl->joined_dodag->dodag_id) == 0)
314 {
315 print_rpl_log("node '%d': '%d' sent a modified DIO message and is a member of dodag_id = '%s', reevaluating our neighbors",
316 d, r, RPL_IP_TO_STR(drpl->joined_dodag->dodag_id));
317
319 }
320 else
321 {
322 print_rpl_log("node '%d': remaining in dodag_id = '%s'", d, RPL_IP_TO_STR(drpl->joined_dodag->dodag_id));
323 }
324
325 /* consider dodag config updates, but only from parents */
326 if (dodag_config_changed && rpl_node_has_parent(d, r))
327 {
328 update_dodag_config(d, dioPdu);
329 }
330 }
331 }
332 else
333 { /* this should never happen */
334 fnNetSimError("node '%d': not root, not joined, not poisoning and not isolated either, what are we anyway?", d);
335 }
336 }
337}
338
339void rpl_dio_msg_copy(const NetSim_PACKET* destPacket, const NetSim_PACKET* srcPacket)
340{
343 destPacket->pstruNetworkData->Packet_RoutingProtocol = drpl;
344}
345
347{
349 rpl_dio_pdu_free(srpl);
351}
unsigned int NETSIM_ID
Definition: Animation.h:45
static bool dio_pdu_changed(PRPL_NEIGHBOR neighbor, PRPL_CTRL_MSG dio_pdu)
Definition: DIO.c:32
void rpl_dio_msg_copy(const NetSim_PACKET *destPacket, const NetSim_PACKET *srcPacket)
Definition: DIO.c:339
static bool dio_pdu_dodag_config_changed(PRPL_CTRL_MSG c1, PRPL_CTRL_MSG c2)
Definition: DIO.c:18
PRPL_CTRL_MSG get_preferred_dodag_dio_pdu(NETSIM_ID d, bool *same, double time)
Definition: DIO.c:78
void rpl_dio_msg_destroy(NetSim_PACKET *packet)
Definition: DIO.c:346
void start_dio_poisoning(NETSIM_ID d)
Definition: DIO.c:60
void rpl_process_dio_msg()
Definition: DIO.c:191
void update_dodag_config(NETSIM_ID node, PRPL_CTRL_MSG dio_pdu)
Definition: DODAG.c:112
void join_dodag_iteration(NETSIM_ID d, PRPL_CTRL_MSG dio_pdu)
Definition: DODAG.c:73
#define IP_COMPARE(ip1, ip2)
Definition: IP_Addressing.h:67
#define fnNetSimError(x,...)
Definition: Linux.h:56
#define TRUE
Definition: Linux.h:77
#define FALSE
Definition: Linux.h:76
#define UINT16
Definition: Linux.h:33
void forget_neighbor_messages(PRPL_NODE rpl)
Definition: Neighbor.c:107
void choose_parents_and_siblings(NETSIM_ID d)
Definition: Neighbor.c:189
PRPL_NEIGHBOR rpl_find_neighbor(NETSIM_ID d, NETSIM_ID r)
Definition: Neighbor.c:19
void update_neighbor_dio_message(PRPL_NEIGHBOR neighbor, PRPL_CTRL_MSG dio_pdu)
Definition: Neighbor.c:58
void rpl_node_remove_all_parents(NETSIM_ID d)
Definition: Neighbor.c:94
void start_as_root(NETSIM_ID d)
Definition: RPL.c:197
bool rpl_node_is_isolated(PRPL_NODE rpl)
void rpl_delete_all_route(NETSIM_ID d)
#define GET_RPL_NODE(d)
Definition: RPL.h:212
void * get_option_from_msg(PRPL_CTRL_MSG msg, RPL_OPTION_TYPE type)
Definition: RPL_Message.c:60
bool rpl_node_is_joined(PRPL_NODE r)
void rpl_dio_pdu_free(PRPL_CTRL_MSG dio)
Definition: RPL_Message.c:343
bool rpl_node_is_root(PRPL_NODE r)
void print_rpl_log(char *format,...)
#define INFINITE_RANK
Definition: RPL.h:81
#define rpl_node_has_sibling(node, sibling)
Definition: RPL.h:306
bool rpl_node_is_poisoning(PRPL_NODE r)
#define RPL_IP_TO_STR(ip)
Definition: RPL.h:316
void rpl_trickle_reset(NETSIM_ID nDevId)
Definition: Trickle.c:23
NetSim_PACKET * create_root_dio_message(NETSIM_ID ndevId, double time, bool include_dodag_config, bool include_seq_num)
Definition: RPL_Message.c:225
#define rpl_node_has_parent(node, parent)
Definition: RPL.h:300
PRPL_CTRL_MSG rpl_dio_pdu_duplicate(PRPL_CTRL_MSG dio)
Definition: RPL_Message.c:314
@ RPLOPTION_DODAGConfiguration
Definition: RPL_Message.h:45
#define GET_PRPL_CTRL_MSG(packet)
Definition: RPL_Message.h:83
struct stru_rpl_ctrl_message * PRPL_CTRL_MSG
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
#define fn_NetSim_Packet_FreePacket(pstruPacket)
Definition: main.h:177
struct stru_NetSim_Packet * pPacket
Definition: Stack.h:754
NETSIM_ID nDeviceId
Definition: Stack.h:750
struct stru_NetSim_Packet_NetworkLayer * pstruNetworkData
Definition: Packet.h:275
NETSIM_ID nTransmitterId
Definition: Packet.h:265
NETSIM_IPAddress DODAGID
Definition: RPL_Message.h:143
UINT16 rank
Definition: RPL.h:158
UINT16 lowest_rank
Definition: RPL.h:157
PRPL_NEIGHBOR pref_parent
Definition: RPL.h:164
DODAGID dodag_id
Definition: RPL.h:143
UINT8 seq_num
Definition: RPL.h:156
PRPL_CTRL_MSG lastDIOMSG
Definition: RPL.h:119
PRPL_DODAG joined_dodag
Definition: RPL.h:178
PRPL_ROOT root_info
Definition: RPL.h:177
UINT16 neighbor_count
Definition: RPL.h:200
PRPL_NEIGHBOR * neighbor_list
Definition: RPL.h:199
UINT8 poison_count_so_far
Definition: RPL.h:202
DODAGID dodag_id
Definition: RPL.h:124