2 * Zebra connect library for EIGRP.
3 * Copyright (C) 2013-2014
11 * This file is part of GNU Zebra.
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
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.
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
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"
57 static int eigrp_interface_add (int , struct zclient
*, zebra_size_t
, vrf_id_t
);
58 static int eigrp_interface_delete (int , struct zclient
*,
59 zebra_size_t
, vrf_id_t
);
60 static int eigrp_interface_address_add (int, struct zclient
*,
61 zebra_size_t
, vrf_id_t vrf_id
);
62 static int eigrp_interface_address_delete (int, struct zclient
*,
63 zebra_size_t
, vrf_id_t vrf_id
);
64 static int eigrp_interface_state_up (int, struct zclient
*,
65 zebra_size_t
, vrf_id_t vrf_id
);
66 static int eigrp_interface_state_down (int, struct zclient
*,
67 zebra_size_t
, vrf_id_t vrf_id
);
68 static struct interface
* zebra_interface_if_lookup (struct stream
*);
70 static int eigrp_zebra_read_ipv4 (int , struct zclient
*,
71 zebra_size_t
, vrf_id_t vrf_id
);
73 /* Zebra structure to hold current status. */
74 struct zclient
*zclient
= NULL
;
76 /* For registering threads. */
77 extern struct thread_master
*master
;
78 struct in_addr router_id_zebra
;
80 /* Router-id update message from zebra. */
82 eigrp_router_id_update_zebra (int command
, struct zclient
*zclient
,
83 zebra_size_t length
, vrf_id_t vrf_id
)
86 struct prefix router_id
;
87 zebra_router_id_update_read (zclient
->ibuf
,&router_id
);
89 router_id_zebra
= router_id
.u
.prefix4
;
91 eigrp
= eigrp_lookup ();
94 eigrp_router_id_update (eigrp
);
101 eigrp_zebra_init (void)
103 zclient
= zclient_new (master
);
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
;
118 /* Zebra route add and delete treatment. */
120 eigrp_zebra_read_ipv4 (int command
, struct zclient
*zclient
,
121 zebra_size_t length
, vrf_id_t vrf_id
)
124 struct zapi_ipv4 api
;
125 struct prefix_ipv4 p
;
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
);
137 memset (&p
, 0, sizeof (struct prefix_ipv4
));
139 p
.prefixlen
= stream_getc (s
);
140 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
142 if (IPV4_NET127(ntohl(p
.prefix
.s_addr
)))
145 /* Nexthop, ifindex, distance, metric. */
146 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
148 api
.nexthop_num
= stream_getc (s
);
151 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
153 api
.ifindex_num
= stream_getc (s
);
154 /* XXX assert(api.ifindex_num == 1); */
155 stream_getl (s
); /* ifindex, unused */
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
);
162 eigrp
= eigrp_lookup ();
166 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
170 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
178 /* Inteface addition message from zebra. */
180 eigrp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
,
183 struct interface
*ifp
;
185 ifp
= zebra_interface_add_read (zclient
->ibuf
, vrf_id
);
189 if (!EIGRP_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp
), type
))
191 SET_IF_PARAM (IF_DEF_PARAMS (ifp
), type
);
192 IF_DEF_PARAMS (ifp
)->type
= eigrp_default_iftype (ifp
);
195 eigrp_if_update (ifp
);
201 eigrp_interface_delete (int command
, struct zclient
*zclient
,
202 zebra_size_t length
, vrf_id_t vrf_id
)
204 struct interface
*ifp
;
206 struct route_node
*rn
;
209 /* zebra_interface_state_read () updates interface structure in iflist */
210 ifp
= zebra_interface_state_read (s
, vrf_id
);
216 zlog_warn ("Zebra: got delete of %s, but interface is still up",
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
);
223 for (rn
= route_top (IF_OIFS (ifp
)); rn
; rn
= route_next (rn
))
225 eigrp_if_free ((struct eigrp_interface
*) rn
->info
, INTERFACE_DOWN_BY_ZEBRA
);
227 ifp
->ifindex
= IFINDEX_INTERNAL
;
232 eigrp_interface_address_add (int command
, struct zclient
*zclient
,
233 zebra_size_t length
, vrf_id_t vrf_id
)
237 c
= zebra_interface_address_read (command
, zclient
->ibuf
, vrf_id
);
242 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_INTERFACE
))
245 prefix2str (c
->address
, buf
, sizeof (buf
));
246 zlog_debug ("Zebra: interface %s address add %s", c
->ifp
->name
, buf
);
249 eigrp_if_update (c
->ifp
);
255 eigrp_interface_address_delete (int command
, struct zclient
*zclient
,
256 zebra_size_t length
, vrf_id_t vrf_id
)
259 struct interface
*ifp
;
260 struct eigrp_interface
*ei
;
261 struct route_node
*rn
;
264 c
= zebra_interface_address_read (command
, zclient
->ibuf
, vrf_id
);
269 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_INTERFACE
))
272 prefix2str (c
->address
, buf
, sizeof (buf
));
273 zlog_debug ("Zebra: interface %s address delete %s", c
->ifp
->name
, buf
);
278 p
.prefixlen
= IPV4_MAX_PREFIXLEN
;
280 rn
= route_node_lookup (IF_OIFS (ifp
), &p
);
290 /* Call interface hook functions to clean up */
291 eigrp_if_free (ei
, INTERFACE_DOWN_BY_ZEBRA
);
299 eigrp_interface_state_up (int command
, struct zclient
*zclient
,
300 zebra_size_t length
, vrf_id_t vrf_id
)
302 struct interface
*ifp
;
303 struct eigrp_interface
*ei
;
304 struct route_node
*rn
;
306 ifp
= zebra_interface_if_lookup (zclient
->ibuf
);
311 /* Interface is already up. */
312 if (if_is_operative (ifp
))
314 /* Temporarily keep ifp values. */
315 struct interface if_tmp
;
316 memcpy (&if_tmp
, ifp
, sizeof (struct interface
));
318 zebra_interface_if_set_value (zclient
->ibuf
, ifp
);
320 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_INTERFACE
))
321 zlog_debug ("Zebra: Interface[%s] state update.", ifp
->name
);
323 if (if_tmp
.bandwidth
!= ifp
->bandwidth
)
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
);
329 // eigrp_if_recalculate_output_cost (ifp);
332 if (if_tmp
.mtu
!= ifp
->mtu
)
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
);
338 /* Must reset the interface (simulate down/up) when MTU changes. */
339 eigrp_if_reset (ifp
);
344 zebra_interface_if_set_value (zclient
->ibuf
, ifp
);
346 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_INTERFACE
))
347 zlog_debug ("Zebra: Interface[%s] state change to up.", ifp
->name
);
349 for (rn
= route_top (IF_OIFS (ifp
)); rn
; rn
= route_next (rn
))
351 if ((ei
= rn
->info
) == NULL
)
361 eigrp_interface_state_down (int command
, struct zclient
*zclient
,
362 zebra_size_t length
, vrf_id_t vrf_id
)
364 struct interface
*ifp
;
365 struct eigrp_interface
*ei
;
366 struct route_node
*node
;
368 ifp
= zebra_interface_state_read (zclient
->ibuf
, vrf_id
);
373 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_INTERFACE
))
374 zlog_debug ("Zebra: Interface[%s] state change to down.", ifp
->name
);
376 for (node
= route_top (IF_OIFS (ifp
)); node
; node
= route_next (node
))
378 if ((ei
= node
->info
) == NULL
)
386 static struct interface
*
387 zebra_interface_if_lookup (struct stream
*s
)
389 char ifname_tmp
[INTERFACE_NAMSIZ
];
391 /* Read interface name. */
392 stream_get (ifname_tmp
, s
, INTERFACE_NAMSIZ
);
394 /* And look it up. */
395 return if_lookup_by_name_len (ifname_tmp
,
396 strnlen (ifname_tmp
, INTERFACE_NAMSIZ
));
400 eigrp_zebra_route_add (struct prefix_ipv4
*p
, struct eigrp_neighbor_entry
*te
)
407 if (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_EIGRP
])
412 /* EIGRP pass nexthop and metric */
413 SET_FLAG (message
, ZAPI_MESSAGE_NEXTHOP
);
414 SET_FLAG (message
, ZAPI_MESSAGE_METRIC
);
416 /* Distance value. */
417 // distance = eigrp_distance_apply (p, er);
419 // SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
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
);
432 /* Put prefix information. */
433 psize
= PSIZE (p
->prefixlen
);
434 stream_putc (s
, p
->prefixlen
);
435 stream_write (s
, (u_char
*) & p
->prefix
, psize
);
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
);
445 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_REDISTRIBUTE
))
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])),
451 inet_ntop(AF_INET
, 0 /*&p->nexthop*/, buf
[1], sizeof (buf
[1])));
454 stream_putl (s
, te
->distance
);
455 stream_putw_at (s
, 0, stream_get_endp (s
));
457 zclient_send_message (zclient
);
462 eigrp_zebra_route_delete (struct prefix_ipv4
*p
, struct eigrp_neighbor_entry
*te
)
469 if (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_EIGRP
])
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
);
484 /* Put prefix information. */
485 psize
= PSIZE (p
->prefixlen
);
486 stream_putc (s
, p
->prefixlen
);
487 stream_write (s
, (u_char
*) & p
->prefix
, psize
);
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
);
497 if (IS_DEBUG_EIGRP (zebra
, ZEBRA_REDISTRIBUTE
))
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])),
503 inet_ntop (AF_INET
, 0 /*&p->nexthop*/, buf
[1], sizeof (buf
[1])));
507 if (CHECK_FLAG (message
, ZAPI_MESSAGE_METRIC
))
509 stream_putl (s
, te
->distance
);
512 stream_putw_at (s
, 0, stream_get_endp (s
));
514 zclient_send_message (zclient
);
519 eigrp_is_type_redistributed (int type
)
521 return (DEFAULT_ROUTE_TYPE (type
)) ?
522 zclient
->default_information
: zclient
->redist
[AFI_IP
][type
];
526 eigrp_redistribute_set (struct eigrp
*eigrp
, int type
, struct eigrp_metrics metric
)
529 if (eigrp_is_type_redistributed (type
))
531 if (eigrp_metrics_is_same(&metric
, &eigrp
->dmetric
[type
]))
533 eigrp
->dmetric
[type
] = metric
;
536 eigrp_external_routes_refresh (eigrp
, type
);
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));
545 eigrp
->dmetric
[type
] = metric
;
547 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
548 AFI_IP
, type
, 0, VRF_DEFAULT
);
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));
555 ++eigrp
->redistribute
;
561 eigrp_redistribute_unset (struct eigrp
*eigrp
, int type
)
564 if (eigrp_is_type_redistributed (type
))
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
;
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));