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