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