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