]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_update.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / eigrpd / eigrp_update.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * EIGRP Sending and Receiving EIGRP Update Packets.
4 * Copyright (C) 2013-2016
5 * Authors:
6 * Donnie Savage
7 * Jan Janovic
8 * Matej Perina
9 * Peter Orsag
10 * Peter Paluch
11 * Frantisek Gazo
12 * Tomas Hvorkovy
13 * Martin Kontsek
14 * Lukas Koribsky
15 */
16
17 #include <zebra.h>
18
19 #include "frrevent.h"
20 #include "memory.h"
21 #include "linklist.h"
22 #include "prefix.h"
23 #include "if.h"
24 #include "table.h"
25 #include "sockunion.h"
26 #include "stream.h"
27 #include "log.h"
28 #include "sockopt.h"
29 #include "checksum.h"
30 #include "md5.h"
31 #include "vty.h"
32 #include "plist.h"
33 #include "plist_int.h"
34 #include "routemap.h"
35 #include "vty.h"
36
37 #include "eigrpd/eigrp_types.h"
38 #include "eigrpd/eigrp_structs.h"
39 #include "eigrpd/eigrpd.h"
40 #include "eigrpd/eigrp_interface.h"
41 #include "eigrpd/eigrp_neighbor.h"
42 #include "eigrpd/eigrp_packet.h"
43 #include "eigrpd/eigrp_zebra.h"
44 #include "eigrpd/eigrp_vty.h"
45 #include "eigrpd/eigrp_dump.h"
46 #include "eigrpd/eigrp_macros.h"
47 #include "eigrpd/eigrp_topology.h"
48 #include "eigrpd/eigrp_fsm.h"
49 #include "eigrpd/eigrp_network.h"
50 #include "eigrpd/eigrp_metric.h"
51
52 bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei,
53 int in, struct prefix *prefix)
54 {
55 struct access_list *alist;
56 struct prefix_list *plist;
57
58 alist = eigrp->list[in];
59 if (alist && access_list_apply(alist, prefix) == FILTER_DENY)
60 return true;
61
62 plist = eigrp->prefix[in];
63 if (plist && prefix_list_apply(plist, prefix) == PREFIX_DENY)
64 return true;
65
66 alist = ei->list[in];
67 if (alist && access_list_apply(alist, prefix) == FILTER_DENY)
68 return true;
69
70 plist = ei->prefix[in];
71 if (plist && prefix_list_apply(plist, prefix) == PREFIX_DENY)
72 return true;
73
74 return false;
75 }
76
77 /**
78 * @fn remove_received_prefix_gr
79 *
80 * @param[in] nbr_prefixes List of neighbor prefixes
81 * @param[in] recv_prefix Prefix which needs to be removed from
82 * list
83 *
84 * @return void
85 *
86 * @par
87 * Function is used for removing received prefix
88 * from list of neighbor prefixes
89 */
90 static void
91 remove_received_prefix_gr(struct list *nbr_prefixes,
92 struct eigrp_prefix_descriptor *recv_prefix)
93 {
94 struct listnode *node1, *node11;
95 struct eigrp_prefix_descriptor *prefix = NULL;
96
97 /* iterate over all prefixes in list */
98 for (ALL_LIST_ELEMENTS(nbr_prefixes, node1, node11, prefix)) {
99 /* remove prefix from list if found */
100 if (prefix == recv_prefix) {
101 listnode_delete(nbr_prefixes, prefix);
102 }
103 }
104 }
105
106 /**
107 * @fn eigrp_update_receive_GR_ask
108 *
109 * @param[in] eigrp EIGRP process
110 * @param[in] nbr Neighbor update of who we
111 * received
112 * @param[in] nbr_prefixes Prefixes which weren't advertised
113 *
114 * @return void
115 *
116 * @par
117 * Function is used for notifying FSM about prefixes which
118 * weren't advertised by neighbor:
119 * We will send message to FSM with prefix delay set to infinity.
120 */
121 static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
122 struct eigrp_neighbor *nbr,
123 struct list *nbr_prefixes)
124 {
125 struct listnode *node1;
126 struct eigrp_prefix_descriptor *prefix;
127 struct eigrp_fsm_action_message fsm_msg;
128
129 /* iterate over all prefixes which weren't advertised by neighbor */
130 for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) {
131 zlog_debug("GR receive: Neighbor not advertised %pFX",
132 prefix->destination);
133
134 fsm_msg.metrics = prefix->reported_metric;
135 /* set delay to MAX */
136 fsm_msg.metrics.delay = EIGRP_MAX_METRIC;
137
138 struct eigrp_route_descriptor *entry =
139 eigrp_route_descriptor_lookup(prefix->entries, nbr);
140
141 fsm_msg.packet_type = EIGRP_OPC_UPDATE;
142 fsm_msg.eigrp = eigrp;
143 fsm_msg.data_type = EIGRP_INT;
144 fsm_msg.adv_router = nbr;
145 fsm_msg.entry = entry;
146 fsm_msg.prefix = prefix;
147
148 /* send message to FSM */
149 eigrp_fsm_event(&fsm_msg);
150 }
151 }
152
153 /*
154 * EIGRP UPDATE read function
155 */
156 void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
157 struct eigrp_header *eigrph, struct stream *s,
158 struct eigrp_interface *ei, int size)
159 {
160 struct eigrp_neighbor *nbr;
161 struct TLV_IPv4_Internal_type *tlv;
162 struct eigrp_prefix_descriptor *pe;
163 struct eigrp_route_descriptor *ne;
164 uint32_t flags;
165 uint16_t type;
166 uint16_t length;
167 uint8_t same;
168 struct prefix dest_addr;
169 uint8_t graceful_restart;
170 uint8_t graceful_restart_final;
171 struct list *nbr_prefixes = NULL;
172
173 /* increment statistics. */
174 ei->update_in++;
175
176 /* get neighbor struct */
177 nbr = eigrp_nbr_get(ei, eigrph, iph);
178
179 /* neighbor must be valid, eigrp_nbr_get creates if none existed */
180 assert(nbr);
181
182 flags = ntohl(eigrph->flags);
183
184 if (flags & EIGRP_CR_FLAG) {
185 return;
186 }
187
188 same = 0;
189 graceful_restart = 0;
190 graceful_restart_final = 0;
191 if ((nbr->recv_sequence_number) == (ntohl(eigrph->sequence)))
192 same = 1;
193
194 nbr->recv_sequence_number = ntohl(eigrph->sequence);
195 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
196 zlog_debug(
197 "Processing Update size[%u] int(%s) nbr(%pI4) seq [%u] flags [%0x]",
198 size,
199 ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id),
200 &nbr->src, nbr->recv_sequence_number, flags);
201
202
203 if ((flags == (EIGRP_INIT_FLAG + EIGRP_RS_FLAG + EIGRP_EOT_FLAG))
204 && (!same)) {
205 /* Graceful restart Update received with all routes */
206
207 zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart",
208 &nbr->src,
209 ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
210
211 /* get all prefixes from neighbor from topology table */
212 nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
213 graceful_restart = 1;
214 graceful_restart_final = 1;
215 } else if ((flags == (EIGRP_INIT_FLAG + EIGRP_RS_FLAG)) && (!same)) {
216 /* Graceful restart Update received, routes also in next packet
217 */
218
219 zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart",
220 &nbr->src,
221 ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
222
223 /* get all prefixes from neighbor from topology table */
224 nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
225 /* save prefixes to neighbor for later use */
226 nbr->nbr_gr_prefixes = nbr_prefixes;
227 graceful_restart = 1;
228 graceful_restart_final = 0;
229 } else if ((flags == (EIGRP_EOT_FLAG)) && (!same)) {
230 /* If there was INIT+RS Update packet before,
231 * consider this as GR EOT */
232
233 if (nbr->nbr_gr_prefixes != NULL) {
234 /* this is final packet of GR */
235 nbr_prefixes = nbr->nbr_gr_prefixes;
236 nbr->nbr_gr_prefixes = NULL;
237
238 graceful_restart = 1;
239 graceful_restart_final = 1;
240 }
241
242 } else if ((flags == (0)) && (!same)) {
243 /* If there was INIT+RS Update packet before,
244 * consider this as GR not final packet */
245
246 if (nbr->nbr_gr_prefixes != NULL) {
247 /* this is GR not final route packet */
248 nbr_prefixes = nbr->nbr_gr_prefixes;
249
250 graceful_restart = 1;
251 graceful_restart_final = 0;
252 }
253
254 } else if ((flags & EIGRP_INIT_FLAG)
255 && (!same)) { /* When in pending state, send INIT update only
256 if it wasn't
257 already sent before (only if init_sequence
258 is 0) */
259 if ((nbr->state == EIGRP_NEIGHBOR_PENDING)
260 && (nbr->init_sequence_number == 0))
261 eigrp_update_send_init(nbr);
262
263 if (nbr->state == EIGRP_NEIGHBOR_UP) {
264 eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
265 eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
266 nbr->recv_sequence_number = ntohl(eigrph->sequence);
267 zlog_info("Neighbor %pI4 (%s) is down: peer restarted",
268 &nbr->src,
269 ifindex2ifname(nbr->ei->ifp->ifindex,
270 eigrp->vrf_id));
271 eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
272 zlog_info(
273 "Neighbor %pI4 (%s) is pending: new adjacency",
274 &nbr->src,
275 ifindex2ifname(nbr->ei->ifp->ifindex,
276 eigrp->vrf_id));
277 eigrp_update_send_init(nbr);
278 }
279 }
280
281 /*If there is topology information*/
282 while (s->endp > s->getp) {
283 type = stream_getw(s);
284 switch (type) {
285 case EIGRP_TLV_IPv4_INT:
286 stream_set_getp(s, s->getp - sizeof(uint16_t));
287
288 tlv = eigrp_read_ipv4_tlv(s);
289
290 /*searching if destination exists */
291 dest_addr.family = AF_INET;
292 dest_addr.u.prefix4 = tlv->destination;
293 dest_addr.prefixlen = tlv->prefix_length;
294 struct eigrp_prefix_descriptor *dest =
295 eigrp_topology_table_lookup_ipv4(
296 eigrp->topology_table, &dest_addr);
297
298 /*if exists it comes to DUAL*/
299 if (dest != NULL) {
300 /* remove received prefix from neighbor prefix
301 * list if in GR */
302 if (graceful_restart)
303 remove_received_prefix_gr(nbr_prefixes,
304 dest);
305
306 struct eigrp_fsm_action_message msg;
307 struct eigrp_route_descriptor *entry =
308 eigrp_route_descriptor_lookup(
309 dest->entries, nbr);
310
311 msg.packet_type = EIGRP_OPC_UPDATE;
312 msg.eigrp = eigrp;
313 msg.data_type = EIGRP_INT;
314 msg.adv_router = nbr;
315 msg.metrics = tlv->metric;
316 msg.entry = entry;
317 msg.prefix = dest;
318 eigrp_fsm_event(&msg);
319 } else {
320 /*Here comes topology information save*/
321 pe = eigrp_prefix_descriptor_new();
322 pe->serno = eigrp->serno;
323 pe->destination =
324 (struct prefix *)prefix_ipv4_new();
325 prefix_copy(pe->destination, &dest_addr);
326 pe->af = AF_INET;
327 pe->state = EIGRP_FSM_STATE_PASSIVE;
328 pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;
329
330 ne = eigrp_route_descriptor_new();
331 ne->ei = ei;
332 ne->adv_router = nbr;
333 ne->reported_metric = tlv->metric;
334 ne->reported_distance = eigrp_calculate_metrics(
335 eigrp, tlv->metric);
336 /*
337 * Filtering
338 */
339 if (eigrp_update_prefix_apply(eigrp, ei,
340 EIGRP_FILTER_IN,
341 &dest_addr))
342 ne->reported_metric.delay =
343 EIGRP_MAX_METRIC;
344
345 ne->distance = eigrp_calculate_total_metrics(
346 eigrp, ne);
347
348 pe->fdistance = pe->distance = pe->rdistance =
349 ne->distance;
350 ne->prefix = pe;
351 ne->flags =
352 EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG;
353
354 eigrp_prefix_descriptor_add(
355 eigrp->topology_table, pe);
356 eigrp_route_descriptor_add(eigrp, pe, ne);
357 pe->distance = pe->fdistance = pe->rdistance =
358 ne->distance;
359 pe->reported_metric = ne->total_metric;
360 eigrp_topology_update_node_flags(eigrp, pe);
361
362 pe->req_action |= EIGRP_FSM_NEED_UPDATE;
363 listnode_add(
364 eigrp->topology_changes_internalIPV4,
365 pe);
366 }
367 eigrp_IPv4_InternalTLV_free(tlv);
368 break;
369
370 case EIGRP_TLV_IPv4_EXT:
371 /* DVS: processing of external routes needs packet and fsm work.
372 * for now, lets just not creash the box
373 */
374 default:
375 length = stream_getw(s);
376 // -2 for type, -2 for len
377 for (length -= 4; length; length--) {
378 (void)stream_getc(s);
379 }
380 }
381 }
382
383 /* ask about prefixes not present in GR update,
384 * if this is final GR packet */
385 if (graceful_restart_final) {
386 eigrp_update_receive_GR_ask(eigrp, nbr, nbr_prefixes);
387 }
388
389 /*
390 * We don't need to send separate Ack for INIT Update. INIT will be
391 * acked in EOT Update.
392 */
393 if ((nbr->state == EIGRP_NEIGHBOR_UP) && !(flags == EIGRP_INIT_FLAG)) {
394 eigrp_hello_send_ack(nbr);
395 }
396
397 eigrp_query_send_all(eigrp);
398 eigrp_update_send_all(eigrp, ei);
399
400 if (nbr_prefixes)
401 list_delete(&nbr_prefixes);
402 }
403
404 /*send EIGRP Update packet*/
405 void eigrp_update_send_init(struct eigrp_neighbor *nbr)
406 {
407 struct eigrp_packet *ep;
408 uint16_t length = EIGRP_HEADER_LEN;
409
410 ep = eigrp_packet_new(EIGRP_PACKET_MTU(nbr->ei->ifp->mtu), nbr);
411
412 /* Prepare EIGRP INIT UPDATE header */
413 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
414 zlog_debug("Enqueuing Update Init Seq [%u] Ack [%u]",
415 nbr->ei->eigrp->sequence_number,
416 nbr->recv_sequence_number);
417
418 eigrp_packet_header_init(
419 EIGRP_OPC_UPDATE, nbr->ei->eigrp, ep->s, EIGRP_INIT_FLAG,
420 nbr->ei->eigrp->sequence_number, nbr->recv_sequence_number);
421
422 // encode Authentication TLV, if needed
423 if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
424 && (nbr->ei->params.auth_keychain != NULL)) {
425 length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei);
426 eigrp_make_md5_digest(nbr->ei, ep->s,
427 EIGRP_AUTH_UPDATE_INIT_FLAG);
428 }
429
430 /* EIGRP Checksum */
431 eigrp_packet_checksum(nbr->ei, ep->s, length);
432
433 ep->length = length;
434 ep->dst.s_addr = nbr->src.s_addr;
435
436 /*This ack number we await from neighbor*/
437 nbr->init_sequence_number = nbr->ei->eigrp->sequence_number;
438 ep->sequence_number = nbr->ei->eigrp->sequence_number;
439 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
440 zlog_debug(
441 "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
442 ep->length, ep->sequence_number, &ep->dst);
443
444 /*Put packet to retransmission queue*/
445 eigrp_fifo_push(nbr->retrans_queue, ep);
446
447 if (nbr->retrans_queue->count == 1) {
448 eigrp_send_packet_reliably(nbr);
449 }
450 }
451
452 static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr,
453 struct eigrp_packet *ep,
454 uint32_t seq_no, int length)
455 {
456 if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
457 && (nbr->ei->params.auth_keychain != NULL)) {
458 eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
459 }
460
461 /* EIGRP Checksum */
462 eigrp_packet_checksum(nbr->ei, ep->s, length);
463
464 ep->length = length;
465 ep->dst.s_addr = nbr->src.s_addr;
466
467 /*This ack number we await from neighbor*/
468 ep->sequence_number = seq_no;
469
470 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
471 zlog_debug(
472 "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
473 ep->length, ep->sequence_number, &ep->dst);
474
475 /*Put packet to retransmission queue*/
476 eigrp_fifo_push(nbr->retrans_queue, ep);
477
478 if (nbr->retrans_queue->count == 1)
479 eigrp_send_packet_reliably(nbr);
480 }
481
482 static void eigrp_update_send_to_all_nbrs(struct eigrp_interface *ei,
483 struct eigrp_packet *ep)
484 {
485 struct listnode *node, *nnode;
486 struct eigrp_neighbor *nbr;
487 bool packet_sent = false;
488
489 for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
490 struct eigrp_packet *ep_dup;
491
492 if (nbr->state != EIGRP_NEIGHBOR_UP)
493 continue;
494
495 if (packet_sent)
496 ep_dup = eigrp_packet_duplicate(ep, NULL);
497 else
498 ep_dup = ep;
499
500 ep_dup->nbr = nbr;
501 packet_sent = true;
502 /*Put packet to retransmission queue*/
503 eigrp_fifo_push(nbr->retrans_queue, ep_dup);
504
505 if (nbr->retrans_queue->count == 1) {
506 eigrp_send_packet_reliably(nbr);
507 }
508 }
509
510 if (!packet_sent)
511 eigrp_packet_free(ep);
512 }
513
514 void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
515 {
516 struct eigrp_packet *ep;
517 uint16_t length = EIGRP_HEADER_LEN;
518 struct eigrp_route_descriptor *te;
519 struct eigrp_prefix_descriptor *pe;
520 struct listnode *node2, *nnode2;
521 struct eigrp_interface *ei = nbr->ei;
522 struct eigrp *eigrp = ei->eigrp;
523 struct prefix *dest_addr;
524 uint32_t seq_no = eigrp->sequence_number;
525 uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu);
526 struct route_node *rn;
527
528 ep = eigrp_packet_new(eigrp_mtu, nbr);
529
530 /* Prepare EIGRP EOT UPDATE header */
531 eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, EIGRP_EOT_FLAG,
532 seq_no, nbr->recv_sequence_number);
533
534 // encode Authentication TLV, if needed
535 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
536 && (ei->params.auth_keychain != NULL)) {
537 length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
538 }
539
540 for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
541 if (!rn->info)
542 continue;
543
544 pe = rn->info;
545 for (ALL_LIST_ELEMENTS(pe->entries, node2, nnode2, te)) {
546 if (eigrp_nbr_split_horizon_check(te, ei))
547 continue;
548
549 if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > eigrp_mtu) {
550 eigrp_update_place_on_nbr_queue(nbr, ep, seq_no,
551 length);
552 seq_no++;
553
554 length = EIGRP_HEADER_LEN;
555 ep = eigrp_packet_new(eigrp_mtu, nbr);
556 eigrp_packet_header_init(
557 EIGRP_OPC_UPDATE, nbr->ei->eigrp, ep->s,
558 EIGRP_EOT_FLAG, seq_no,
559 nbr->recv_sequence_number);
560
561 if ((ei->params.auth_type
562 == EIGRP_AUTH_TYPE_MD5)
563 && (ei->params.auth_keychain != NULL)) {
564 length +=
565 eigrp_add_authTLV_MD5_to_stream(
566 ep->s, ei);
567 }
568 }
569 /* Get destination address from prefix */
570 dest_addr = pe->destination;
571
572 /* Check if any list fits */
573 if (eigrp_update_prefix_apply(
574 eigrp, ei, EIGRP_FILTER_OUT, dest_addr))
575 continue;
576 else {
577 length += eigrp_add_internalTLV_to_stream(ep->s,
578 pe);
579 }
580 }
581 }
582
583 eigrp_update_place_on_nbr_queue(nbr, ep, seq_no, length);
584 eigrp->sequence_number = seq_no++;
585 }
586
587 void eigrp_update_send(struct eigrp_interface *ei)
588 {
589 struct eigrp_packet *ep;
590 struct listnode *node, *nnode;
591 struct eigrp_prefix_descriptor *pe;
592 uint8_t has_tlv;
593 struct eigrp *eigrp = ei->eigrp;
594 struct prefix *dest_addr;
595 uint32_t seq_no = eigrp->sequence_number;
596 uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu);
597
598 if (ei->nbrs->count == 0)
599 return;
600
601 uint16_t length = EIGRP_HEADER_LEN;
602
603 ep = eigrp_packet_new(eigrp_mtu, NULL);
604
605 /* Prepare EIGRP INIT UPDATE header */
606 eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, 0, seq_no, 0);
607
608 // encode Authentication TLV, if needed
609 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
610 && (ei->params.auth_keychain != NULL)) {
611 length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
612 }
613
614 has_tlv = 0;
615 for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node,
616 nnode, pe)) {
617 struct eigrp_route_descriptor *ne;
618
619 if (!(pe->req_action & EIGRP_FSM_NEED_UPDATE))
620 continue;
621
622 ne = listnode_head(pe->entries);
623 if (eigrp_nbr_split_horizon_check(ne, ei))
624 continue;
625
626 if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > eigrp_mtu) {
627 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
628 && (ei->params.auth_keychain != NULL)) {
629 eigrp_make_md5_digest(ei, ep->s,
630 EIGRP_AUTH_UPDATE_FLAG);
631 }
632
633 eigrp_packet_checksum(ei, ep->s, length);
634 ep->length = length;
635
636 ep->dst.s_addr = htonl(EIGRP_MULTICAST_ADDRESS);
637
638 ep->sequence_number = seq_no;
639 seq_no++;
640 eigrp_update_send_to_all_nbrs(ei, ep);
641
642 length = EIGRP_HEADER_LEN;
643 ep = eigrp_packet_new(eigrp_mtu, NULL);
644 eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s,
645 0, seq_no, 0);
646 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
647 && (ei->params.auth_keychain != NULL)) {
648 length += eigrp_add_authTLV_MD5_to_stream(ep->s,
649 ei);
650 }
651 has_tlv = 0;
652 }
653 /* Get destination address from prefix */
654 dest_addr = pe->destination;
655
656 if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
657 dest_addr)) {
658 // pe->reported_metric.delay = EIGRP_MAX_METRIC;
659 continue;
660 } else {
661 length += eigrp_add_internalTLV_to_stream(ep->s, pe);
662 has_tlv = 1;
663 }
664 }
665
666 if (!has_tlv) {
667 eigrp_packet_free(ep);
668 return;
669 }
670
671 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
672 && (ei->params.auth_keychain != NULL)) {
673 eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
674 }
675
676 /* EIGRP Checksum */
677 eigrp_packet_checksum(ei, ep->s, length);
678 ep->length = length;
679
680 ep->dst.s_addr = htonl(EIGRP_MULTICAST_ADDRESS);
681
682 /*This ack number we await from neighbor*/
683 ep->sequence_number = eigrp->sequence_number;
684
685 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
686 zlog_debug("Enqueuing Update length[%u] Seq [%u]", length,
687 ep->sequence_number);
688
689 eigrp_update_send_to_all_nbrs(ei, ep);
690 ei->eigrp->sequence_number = seq_no++;
691 }
692
693 void eigrp_update_send_all(struct eigrp *eigrp,
694 struct eigrp_interface *exception)
695 {
696 struct eigrp_interface *iface;
697 struct listnode *node, *node2, *nnode2;
698 struct eigrp_prefix_descriptor *pe;
699
700 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
701 if (iface != exception) {
702 eigrp_update_send(iface);
703 }
704 }
705
706 for (ALL_LIST_ELEMENTS(eigrp->topology_changes_internalIPV4, node2,
707 nnode2, pe)) {
708 if (pe->req_action & EIGRP_FSM_NEED_UPDATE) {
709 pe->req_action &= ~EIGRP_FSM_NEED_UPDATE;
710 listnode_delete(eigrp->topology_changes_internalIPV4,
711 pe);
712 }
713 }
714 }
715
716 /**
717 * @fn eigrp_update_send_GR_part
718 *
719 * @param[in] nbr contains neighbor who would receive
720 * Graceful
721 * restart
722 *
723 * @return void
724 *
725 * @par
726 * Function used for sending Graceful restart Update packet
727 * and if there are multiple chunks, send only one of them.
728 * It is called from thread. Do not call it directly.
729 *
730 * Uses nbr_gr_packet_type from neighbor.
731 */
732 static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
733 {
734 struct eigrp_packet *ep;
735 uint16_t length = EIGRP_HEADER_LEN;
736 struct eigrp_prefix_descriptor *pe;
737 struct prefix *dest_addr;
738 struct eigrp_interface *ei = nbr->ei;
739 struct eigrp *eigrp = ei->eigrp;
740 struct list *prefixes;
741 uint32_t flags;
742 unsigned int send_prefixes;
743 struct route_node *rn;
744
745 /* get prefixes to send to neighbor */
746 prefixes = nbr->nbr_gr_prefixes_send;
747
748 send_prefixes = 0;
749
750 /* if there already were last packet chunk, we won't continue */
751 if (nbr->nbr_gr_packet_type == EIGRP_PACKET_PART_LAST)
752 return;
753
754 /* if this is first packet chunk, we need to decide,
755 * if there will be one or more chunks */
756 if (nbr->nbr_gr_packet_type == EIGRP_PACKET_PART_FIRST) {
757 if (prefixes->count <= EIGRP_TLV_MAX_IPv4) {
758 /* there will be only one chunk */
759 flags = EIGRP_INIT_FLAG + EIGRP_RS_FLAG
760 + EIGRP_EOT_FLAG;
761 nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_LAST;
762 } else {
763 /* there will be more chunks */
764 flags = EIGRP_INIT_FLAG + EIGRP_RS_FLAG;
765 nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_NA;
766 }
767 } else {
768 /* this is not first chunk, and we need to decide,
769 * if there will be more chunks */
770 if (prefixes->count <= EIGRP_TLV_MAX_IPv4) {
771 /* this is last chunk */
772 flags = EIGRP_EOT_FLAG;
773 nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_LAST;
774 } else {
775 /* there will be more chunks */
776 flags = 0;
777 nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_NA;
778 }
779 }
780
781 ep = eigrp_packet_new(EIGRP_PACKET_MTU(ei->ifp->mtu), nbr);
782
783 /* Prepare EIGRP Graceful restart UPDATE header */
784 eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, flags,
785 eigrp->sequence_number,
786 nbr->recv_sequence_number);
787
788 // encode Authentication TLV, if needed
789 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
790 && (ei->params.auth_keychain != NULL)) {
791 length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
792 }
793
794 for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
795 if (!rn->info)
796 continue;
797
798 pe = rn->info;
799 /*
800 * Filtering
801 */
802 dest_addr = pe->destination;
803
804 if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
805 dest_addr)) {
806 /* do not send filtered route */
807 zlog_info("Filtered prefix %pI4 won't be sent out.",
808 &dest_addr->u.prefix4);
809 } else {
810 /* sending route which wasn't filtered */
811 length += eigrp_add_internalTLV_to_stream(ep->s, pe);
812 send_prefixes++;
813 }
814
815 /*
816 * This makes no sense, Filter out then filter in???
817 * Look into this more - DBS
818 */
819 if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN,
820 dest_addr)) {
821 /* do not send filtered route */
822 zlog_info("Filtered prefix %pI4 will be removed.",
823 &dest_addr->u.prefix4);
824
825 /* prepare message for FSM */
826 struct eigrp_fsm_action_message fsm_msg;
827
828 struct eigrp_route_descriptor *entry =
829 eigrp_route_descriptor_lookup(pe->entries, nbr);
830
831 fsm_msg.packet_type = EIGRP_OPC_UPDATE;
832 fsm_msg.eigrp = eigrp;
833 fsm_msg.data_type = EIGRP_INT;
834 fsm_msg.adv_router = nbr;
835 fsm_msg.metrics = pe->reported_metric;
836 /* Set delay to MAX */
837 fsm_msg.metrics.delay = EIGRP_MAX_METRIC;
838 fsm_msg.entry = entry;
839 fsm_msg.prefix = pe;
840
841 /* send message to FSM */
842 eigrp_fsm_event(&fsm_msg);
843 }
844
845 /* delete processed prefix from list */
846 listnode_delete(prefixes, pe);
847
848 /* if there are enough prefixes, send packet */
849 if (send_prefixes >= EIGRP_TLV_MAX_IPv4)
850 break;
851 }
852
853 /* compute Auth digest */
854 if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
855 && (ei->params.auth_keychain != NULL)) {
856 eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
857 }
858
859 /* EIGRP Checksum */
860 eigrp_packet_checksum(ei, ep->s, length);
861
862 ep->length = length;
863 ep->dst.s_addr = nbr->src.s_addr;
864
865 /*This ack number we await from neighbor*/
866 ep->sequence_number = eigrp->sequence_number;
867
868 if (IS_DEBUG_EIGRP_PACKET(0, RECV))
869 zlog_debug(
870 "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
871 ep->length, ep->sequence_number, &ep->dst);
872
873 /*Put packet to retransmission queue*/
874 eigrp_fifo_push(nbr->retrans_queue, ep);
875
876 if (nbr->retrans_queue->count == 1) {
877 eigrp_send_packet_reliably(nbr);
878 }
879 }
880
881 /**
882 * @fn eigrp_update_send_GR_thread
883 *
884 * @param[in] thread contains neighbor who would receive
885 * Graceful restart
886 *
887 * @return int always 0
888 *
889 * @par
890 * Function used for sending Graceful restart Update packet
891 * in thread, it is prepared for multiple chunks of packet.
892 *
893 * Uses nbr_gr_packet_type and t_nbr_send_gr from neighbor.
894 */
895 void eigrp_update_send_GR_thread(struct event *thread)
896 {
897 struct eigrp_neighbor *nbr;
898
899 /* get argument from thread */
900 nbr = EVENT_ARG(thread);
901 /* remove this thread pointer */
902
903 /* if there is packet waiting in queue,
904 * schedule this thread again with small delay */
905 if (nbr->retrans_queue->count > 0) {
906 event_add_timer_msec(master, eigrp_update_send_GR_thread, nbr,
907 10, &nbr->t_nbr_send_gr);
908 return;
909 }
910
911 /* send GR EIGRP packet chunk */
912 eigrp_update_send_GR_part(nbr);
913
914 /* if it wasn't last chunk, schedule this thread again */
915 if (nbr->nbr_gr_packet_type != EIGRP_PACKET_PART_LAST) {
916 event_execute(master, eigrp_update_send_GR_thread, nbr, 0);
917 }
918 }
919
920 /**
921 * @fn eigrp_update_send_GR
922 *
923 * @param[in] nbr Neighbor who would receive
924 * Graceful
925 * restart
926 * @param[in] gr_type Who executed Graceful restart
927 * @param[in] vty Virtual terminal for log output
928 *
929 * @return void
930 *
931 * @par
932 * Function used for sending Graceful restart Update packet:
933 * Creates Update packet with INIT, RS, EOT flags and include
934 * all route except those filtered
935 */
936 void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
937 struct vty *vty)
938 {
939 struct eigrp_prefix_descriptor *pe2;
940 struct list *prefixes;
941 struct route_node *rn;
942 struct eigrp_interface *ei = nbr->ei;
943 struct eigrp *eigrp = ei->eigrp;
944
945 if (gr_type == EIGRP_GR_FILTER) {
946 /* function was called after applying filtration */
947 zlog_info(
948 "Neighbor %pI4 (%s) is resync: route configuration changed",
949 &nbr->src,
950 ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
951 } else if (gr_type == EIGRP_GR_MANUAL) {
952 /* Graceful restart was called manually */
953 zlog_info("Neighbor %pI4 (%s) is resync: manually cleared",
954 &nbr->src,
955 ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
956
957 if (vty != NULL) {
958 vty_time_print(vty, 0);
959 vty_out(vty,
960 "Neighbor %pI4 (%s) is resync: manually cleared\n",
961 &nbr->src,
962 ifindex2ifname(ei->ifp->ifindex,
963 eigrp->vrf_id));
964 }
965 }
966
967 prefixes = list_new();
968 /* add all prefixes from topology table to list */
969 for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
970 if (!rn->info)
971 continue;
972
973 pe2 = rn->info;
974 listnode_add(prefixes, pe2);
975 }
976
977 /* save prefixes to neighbor */
978 nbr->nbr_gr_prefixes_send = prefixes;
979 /* indicate, that this is first GR Update packet chunk */
980 nbr->nbr_gr_packet_type = EIGRP_PACKET_PART_FIRST;
981 /* execute packet sending in thread */
982 event_execute(master, eigrp_update_send_GR_thread, nbr, 0);
983 }
984
985 /**
986 * @fn eigrp_update_send_interface_GR
987 *
988 * @param[in] ei Interface to neighbors of which
989 * the
990 * GR
991 * is sent
992 * @param[in] gr_type Who executed Graceful restart
993 * @param[in] vty Virtual terminal for log output
994 *
995 * @return void
996 *
997 * @par
998 * Function used for sending Graceful restart Update packet
999 * to all neighbors on specified interface.
1000 */
1001 void eigrp_update_send_interface_GR(struct eigrp_interface *ei,
1002 enum GR_type gr_type, struct vty *vty)
1003 {
1004 struct listnode *node;
1005 struct eigrp_neighbor *nbr;
1006
1007 /* iterate over all neighbors on eigrp interface */
1008 for (ALL_LIST_ELEMENTS_RO(ei->nbrs, node, nbr)) {
1009 /* send GR to neighbor */
1010 eigrp_update_send_GR(nbr, gr_type, vty);
1011 }
1012 }
1013
1014 /**
1015 * @fn eigrp_update_send_process_GR
1016 *
1017 * @param[in] eigrp EIGRP process
1018 * @param[in] gr_type Who executed Graceful restart
1019 * @param[in] vty Virtual terminal for log output
1020 *
1021 * @return void
1022 *
1023 * @par
1024 * Function used for sending Graceful restart Update packet
1025 * to all neighbors in eigrp process.
1026 */
1027 void eigrp_update_send_process_GR(struct eigrp *eigrp, enum GR_type gr_type,
1028 struct vty *vty)
1029 {
1030 struct listnode *node;
1031 struct eigrp_interface *ei;
1032
1033 /* iterate over all eigrp interfaces */
1034 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
1035 /* send GR to all neighbors on interface */
1036 eigrp_update_send_interface_GR(ei, gr_type, vty);
1037 }
1038 }