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