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