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