]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_zebra.c
vtysh: Fix eigrp ordering in 'show run'
[mirror_frr.git] / eigrpd / eigrp_zebra.c
CommitLineData
7f57883e
DS
1/*
2 * Zebra connect library for EIGRP.
3 * Copyright (C) 2013-2014
4 * Authors:
5 * Donnie Savage
6 * Jan Janovic
7 * Matej Perina
8 * Peter Orsag
9 * Peter Paluch
10 *
11 * This file is part of GNU Zebra.
12 *
13 * GNU Zebra is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2, or (at your option) any
16 * later version.
17 *
18 * GNU Zebra is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Zebra; see the file COPYING. If not, write to the Free
25 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 * 02111-1307, USA.
27 */
28
29#include <zebra.h>
30
31#include "thread.h"
32#include "command.h"
33#include "network.h"
34#include "prefix.h"
35#include "routemap.h"
36#include "table.h"
37#include "stream.h"
38#include "memory.h"
39#include "zclient.h"
40#include "filter.h"
41#include "plist.h"
42#include "log.h"
43#include "nexthop.h"
44
45#include "eigrpd/eigrp_structs.h"
46#include "eigrpd/eigrpd.h"
47#include "eigrpd/eigrp_interface.h"
48#include "eigrpd/eigrp_neighbor.h"
49#include "eigrpd/eigrp_packet.h"
50#include "eigrpd/eigrp_zebra.h"
51#include "eigrpd/eigrp_vty.h"
52#include "eigrpd/eigrp_dump.h"
53#include "eigrpd/eigrp_network.h"
54#include "eigrpd/eigrp_topology.h"
55#include "eigrpd/eigrp_fsm.h"
56
57static int eigrp_interface_add (int , struct zclient *, zebra_size_t, vrf_id_t);
58static int eigrp_interface_delete (int , struct zclient *,
59 zebra_size_t, vrf_id_t);
60static int eigrp_interface_address_add (int, struct zclient *,
61 zebra_size_t, vrf_id_t vrf_id);
62static int eigrp_interface_address_delete (int, struct zclient *,
63 zebra_size_t, vrf_id_t vrf_id);
64static int eigrp_interface_state_up (int, struct zclient *,
65 zebra_size_t, vrf_id_t vrf_id);
66static int eigrp_interface_state_down (int, struct zclient *,
67 zebra_size_t, vrf_id_t vrf_id);
68static struct interface * zebra_interface_if_lookup (struct stream *);
69
70static int eigrp_zebra_read_ipv4 (int , struct zclient *,
71 zebra_size_t, vrf_id_t vrf_id);
72
73/* Zebra structure to hold current status. */
74struct zclient *zclient = NULL;
75
76/* For registering threads. */
77extern struct thread_master *master;
78struct in_addr router_id_zebra;
79
80/* Router-id update message from zebra. */
81static int
82eigrp_router_id_update_zebra (int command, struct zclient *zclient,
83 zebra_size_t length, vrf_id_t vrf_id)
84{
85 struct eigrp *eigrp;
86 struct prefix router_id;
87 zebra_router_id_update_read (zclient->ibuf,&router_id);
88
89 router_id_zebra = router_id.u.prefix4;
90
91 eigrp = eigrp_lookup ();
92
93 if (eigrp != NULL)
94 eigrp_router_id_update (eigrp);
95
96 return 0;
97}
98
99
100void
101eigrp_zebra_init (void)
102{
103 zclient = zclient_new (master);
104
105 zclient_init (zclient, ZEBRA_ROUTE_EIGRP, 0);
106 zclient->router_id_update = eigrp_router_id_update_zebra;
107 zclient->interface_add = eigrp_interface_add;
108 zclient->interface_delete = eigrp_interface_delete;
109 zclient->interface_up = eigrp_interface_state_up;
110 zclient->interface_down = eigrp_interface_state_down;
111 zclient->interface_address_add = eigrp_interface_address_add;
112 zclient->interface_address_delete = eigrp_interface_address_delete;
113 zclient->redistribute_route_ipv4_add = eigrp_zebra_read_ipv4;
114 zclient->redistribute_route_ipv4_del = eigrp_zebra_read_ipv4;
115}
116
117
118/* Zebra route add and delete treatment. */
119static int
120eigrp_zebra_read_ipv4 (int command, struct zclient *zclient,
121 zebra_size_t length, vrf_id_t vrf_id)
122{
123 struct stream *s;
124 struct zapi_ipv4 api;
125 struct prefix_ipv4 p;
126 struct eigrp *eigrp;
127
128 s = zclient->ibuf;
129
130 /* Type, flags, message. */
131 api.type = stream_getc (s);
132 api.instance = stream_getw (s);
133 api.flags = stream_getc (s);
134 api.message = stream_getc (s);
135
136 /* IPv4 prefix. */
137 memset (&p, 0, sizeof (struct prefix_ipv4));
138 p.family = AF_INET;
139 p.prefixlen = stream_getc (s);
140 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
141
142 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
143 return 0;
144
145 /* Nexthop, ifindex, distance, metric. */
146 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
147 {
148 api.nexthop_num = stream_getc (s);
149 stream_get_ipv4 (s);
150 }
151 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
152 {
153 api.ifindex_num = stream_getc (s);
154 /* XXX assert(api.ifindex_num == 1); */
155 stream_getl (s); /* ifindex, unused */
156 }
157 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
158 api.distance = stream_getc (s);
159 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
160 api.metric = stream_getl (s);
161
162 eigrp = eigrp_lookup ();
163 if (eigrp == NULL)
164 return 0;
165
166 if (command == ZEBRA_IPV4_ROUTE_ADD)
167 {
168
169 }
170 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
171 {
172
173 }
174
175 return 0;
176}
177
178/* Inteface addition message from zebra. */
179static int
180eigrp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
181 vrf_id_t vrf_id)
182{
183 struct interface *ifp;
184
185 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
186
187 assert (ifp->info);
188
189 if (!EIGRP_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
190 {
191 SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
192 IF_DEF_PARAMS (ifp)->type = eigrp_default_iftype (ifp);
193 }
194
195 eigrp_if_update (ifp);
196
197 return 0;
198}
199
200static int
201eigrp_interface_delete (int command, struct zclient *zclient,
202 zebra_size_t length, vrf_id_t vrf_id)
203{
204 struct interface *ifp;
205 struct stream *s;
206 struct route_node *rn;
207
208 s = zclient->ibuf;
209 /* zebra_interface_state_read () updates interface structure in iflist */
210 ifp = zebra_interface_state_read (s, vrf_id);
211
212 if (ifp == NULL)
213 return 0;
214
215 if (if_is_up (ifp))
216 zlog_warn ("Zebra: got delete of %s, but interface is still up",
217 ifp->name);
218
219 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
220 zlog_debug("Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
221 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
222
223 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
224 if (rn->info)
225 eigrp_if_free ((struct eigrp_interface *) rn->info, INTERFACE_DOWN_BY_ZEBRA);
226
227 ifp->ifindex = IFINDEX_INTERNAL;
228 return 0;
229}
230
231static int
232eigrp_interface_address_add (int command, struct zclient *zclient,
233 zebra_size_t length, vrf_id_t vrf_id)
234{
235 struct connected *c;
236
237 c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
238
239 if (c == NULL)
240 return 0;
241
242 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
243 {
244 char buf[128];
245 prefix2str (c->address, buf, sizeof (buf));
246 zlog_debug ("Zebra: interface %s address add %s", c->ifp->name, buf);
247 }
248
249 eigrp_if_update (c->ifp);
250
251 return 0;
252}
253
254static int
255eigrp_interface_address_delete (int command, struct zclient *zclient,
256 zebra_size_t length, vrf_id_t vrf_id)
257{
258 struct connected *c;
259 struct interface *ifp;
260 struct eigrp_interface *ei;
261 struct route_node *rn;
262 struct prefix p;
263
264 c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
265
266 if (c == NULL)
267 return 0;
268
269 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
270 {
271 char buf[128];
272 prefix2str (c->address, buf, sizeof (buf));
273 zlog_debug ("Zebra: interface %s address delete %s", c->ifp->name, buf);
274 }
275
276 ifp = c->ifp;
277 p = *c->address;
278 p.prefixlen = IPV4_MAX_PREFIXLEN;
279
280 rn = route_node_lookup (IF_OIFS (ifp), &p);
281 if (!rn)
282 {
283 connected_free (c);
284 return 0;
285 }
286
287 assert (rn->info);
288 ei = rn->info;
289
290 /* Call interface hook functions to clean up */
291 eigrp_if_free (ei, INTERFACE_DOWN_BY_ZEBRA);
292
293 connected_free (c);
294
295 return 0;
296}
297
298static int
299eigrp_interface_state_up (int command, struct zclient *zclient,
300 zebra_size_t length, vrf_id_t vrf_id)
301{
302 struct interface *ifp;
303 struct eigrp_interface *ei;
304 struct route_node *rn;
305
306 ifp = zebra_interface_if_lookup (zclient->ibuf);
307
308 if (ifp == NULL)
309 return 0;
310
311 /* Interface is already up. */
312 if (if_is_operative (ifp))
313 {
314 /* Temporarily keep ifp values. */
315 struct interface if_tmp;
316 memcpy (&if_tmp, ifp, sizeof (struct interface));
317
318 zebra_interface_if_set_value (zclient->ibuf, ifp);
319
320 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
321 zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
322
323 if (if_tmp.bandwidth != ifp->bandwidth)
324 {
325 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
326 zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
327 ifp->name, if_tmp.bandwidth, ifp->bandwidth);
328
329// eigrp_if_recalculate_output_cost (ifp);
330 }
331
332 if (if_tmp.mtu != ifp->mtu)
333 {
334 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
335 zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
336 ifp->name, if_tmp.mtu, ifp->mtu);
337
338 /* Must reset the interface (simulate down/up) when MTU changes. */
339 eigrp_if_reset (ifp);
340 }
341 return 0;
342 }
343
344 zebra_interface_if_set_value (zclient->ibuf, ifp);
345
346 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
347 zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
348
349 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
350 {
351 if ((ei = rn->info) == NULL)
352 continue;
353
354 eigrp_if_up (ei);
355 }
356
357 return 0;
358}
359
360static int
361eigrp_interface_state_down (int command, struct zclient *zclient,
362 zebra_size_t length, vrf_id_t vrf_id)
363{
364 struct interface *ifp;
365 struct eigrp_interface *ei;
366 struct route_node *node;
367
368 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
369
370 if (ifp == NULL)
371 return 0;
372
373 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
374 zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
375
376 for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
377 {
378 if ((ei = node->info) == NULL)
379 continue;
380 eigrp_if_down (ei);
381 }
382
383 return 0;
384}
385
386static struct interface *
387zebra_interface_if_lookup (struct stream *s)
388{
389 char ifname_tmp[INTERFACE_NAMSIZ];
390
391 /* Read interface name. */
392 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
393
394 /* And look it up. */
395 return if_lookup_by_name_len (ifname_tmp,
396 strnlen (ifname_tmp, INTERFACE_NAMSIZ));
397}
398
399void
400eigrp_zebra_route_add (struct prefix_ipv4 *p, struct eigrp_neighbor_entry *te)
401{
402 u_char message;
403 u_char flags;
404 int psize;
405 struct stream *s;
406
407 if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
408 {
409 message = 0;
410 flags = 0;
411
412 /* EIGRP pass nexthop and metric */
413 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
414 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
415
416 /* Distance value. */
417// distance = eigrp_distance_apply (p, er);
418// if (distance)
419// SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
420
421 /* Make packet. */
422 s = zclient->obuf;
423 stream_reset (s);
424
425 /* Put command, type, flags, message. */
426 zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
427 stream_putc (s, ZEBRA_ROUTE_EIGRP);
428 stream_putc (s, flags);
429 stream_putc (s, message);
430 stream_putw (s, SAFI_UNICAST);
431
432 /* Put prefix information. */
433 psize = PSIZE (p->prefixlen);
434 stream_putc (s, p->prefixlen);
435 stream_write (s, (u_char *) & p->prefix, psize);
436
437 /* Nexthop count. */
438 stream_putc (s, 1);
439
440 /* Nexthop, ifindex, distance and metric information. */
441 stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX);
442 stream_put_in_addr (s, &te->adv_router->src);
443 stream_putl (s, te->ei->ifp->ifindex);
444
445 if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
446 {
447 char buf[2][INET_ADDRSTRLEN];
448 zlog_debug ("Zebra: Route add %s/%d nexthop %s",
449 inet_ntop(AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
450 p->prefixlen,
451 inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
452 }
453
454 stream_putl (s, te->distance);
455 stream_putw_at (s, 0, stream_get_endp (s));
456
457 zclient_send_message (zclient);
458 }
459}
460
461void
462eigrp_zebra_route_delete (struct prefix_ipv4 *p, struct eigrp_neighbor_entry *te)
463{
464 u_char message;
465 u_char flags;
466 int psize;
467 struct stream *s;
468
469 if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
470 {
471 message = 0;
472 flags = 0;
473 /* Make packet. */
474 s = zclient->obuf;
475 stream_reset (s);
476
477 /* Put command, type, flags, message. */
478 zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT);
479 stream_putc (s, ZEBRA_ROUTE_EIGRP);
480 stream_putc (s, flags);
481 stream_putc (s, message);
482 stream_putw (s, SAFI_UNICAST);
483
484 /* Put prefix information. */
485 psize = PSIZE (p->prefixlen);
486 stream_putc (s, p->prefixlen);
487 stream_write (s, (u_char *) & p->prefix, psize);
488
489 /* Nexthop count. */
490 stream_putc (s, 1);
491
492 /* Nexthop, ifindex, distance and metric information. */
493 stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX);
494 stream_put_in_addr (s, &te->adv_router->src);
495 stream_putl (s, te->ei->ifp->ifindex);
496
497 if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
498 {
499 char buf[2][INET_ADDRSTRLEN];
500 zlog_debug ("Zebra: Route del %s/%d nexthop %s",
501 inet_ntop (AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
502 p->prefixlen,
503 inet_ntop (AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
504 }
505
506
507 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
508 {
509 stream_putl (s, te->distance);
510 }
511
512 stream_putw_at (s, 0, stream_get_endp (s));
513
514 zclient_send_message (zclient);
515 }
516}
517
518vrf_bitmap_t
519eigrp_is_type_redistributed (int type)
520{
521 return (DEFAULT_ROUTE_TYPE (type)) ?
522 zclient->default_information : zclient->redist[AFI_IP][type];
523}
524
525int
526eigrp_redistribute_set (struct eigrp *eigrp, int type, struct eigrp_metrics metric)
527{
528
529 if (eigrp_is_type_redistributed (type))
530 {
531 if (eigrp_metrics_is_same(&metric, &eigrp->dmetric[type]))
532 {
533 eigrp->dmetric[type] = metric;
534 }
535
536 eigrp_external_routes_refresh (eigrp, type);
537
538// if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE))
539// zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
540// eigrp_redist_string(type),
541// metric_type (eigrp, type), metric_value (eigrp, type));
542 return CMD_SUCCESS;
543 }
544
545 eigrp->dmetric[type] = metric;
546
547 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
548 AFI_IP, type, 0, VRF_DEFAULT);
549
550// if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
551// zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
552// ospf_redist_string(type),
553// metric_type (ospf, type), metric_value (ospf, type));
554
555 ++eigrp->redistribute;
556
557 return CMD_SUCCESS;
558}
559
560int
561eigrp_redistribute_unset (struct eigrp *eigrp, int type)
562{
563
564 if (eigrp_is_type_redistributed (type))
565 {
566 memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics));
567 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient,
568 AFI_IP, type, 0, VRF_DEFAULT);
569 --eigrp->redistribute;
570 }
571
572// if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
573// zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
574// ospf_redist_string(type),
575// metric_type (ospf, type), metric_value (ospf, type));
576
577 return CMD_SUCCESS;
578}
579