]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_zebra.c
Merge pull request #476 from qlyoung/abort-select-fd
[mirror_frr.git] / eigrpd / eigrp_zebra.c
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
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 *);
69
70 static 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. */
74 struct zclient *zclient = NULL;
75
76 /* For registering threads. */
77 extern struct thread_master *master;
78 struct in_addr router_id_zebra;
79
80 /* Router-id update message from zebra. */
81 static int
82 eigrp_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 static void
100 eigrp_zebra_connected (struct zclient *zclient)
101 {
102 zclient_send_reg_requests (zclient, VRF_DEFAULT);
103 }
104
105 void
106 eigrp_zebra_init (void)
107 {
108 zclient = zclient_new (master);
109
110 zclient_init (zclient, ZEBRA_ROUTE_EIGRP, 0);
111 zclient->zebra_connected = eigrp_zebra_connected;
112 zclient->router_id_update = eigrp_router_id_update_zebra;
113 zclient->interface_add = eigrp_interface_add;
114 zclient->interface_delete = eigrp_interface_delete;
115 zclient->interface_up = eigrp_interface_state_up;
116 zclient->interface_down = eigrp_interface_state_down;
117 zclient->interface_address_add = eigrp_interface_address_add;
118 zclient->interface_address_delete = eigrp_interface_address_delete;
119 zclient->redistribute_route_ipv4_add = eigrp_zebra_read_ipv4;
120 zclient->redistribute_route_ipv4_del = eigrp_zebra_read_ipv4;
121 }
122
123
124 /* Zebra route add and delete treatment. */
125 static int
126 eigrp_zebra_read_ipv4 (int command, struct zclient *zclient,
127 zebra_size_t length, vrf_id_t vrf_id)
128 {
129 struct stream *s;
130 struct zapi_ipv4 api;
131 struct prefix_ipv4 p;
132 struct eigrp *eigrp;
133
134 s = zclient->ibuf;
135
136 /* Type, flags, message. */
137 api.type = stream_getc (s);
138 api.instance = stream_getw (s);
139 api.flags = stream_getc (s);
140 api.message = stream_getc (s);
141
142 /* IPv4 prefix. */
143 memset (&p, 0, sizeof (struct prefix_ipv4));
144 p.family = AF_INET;
145 p.prefixlen = stream_getc (s);
146 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
147
148 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
149 return 0;
150
151 /* Nexthop, ifindex, distance, metric. */
152 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
153 {
154 api.nexthop_num = stream_getc (s);
155 stream_get_ipv4 (s);
156 }
157 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
158 {
159 api.ifindex_num = stream_getc (s);
160 /* XXX assert(api.ifindex_num == 1); */
161 stream_getl (s); /* ifindex, unused */
162 }
163 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
164 api.distance = stream_getc (s);
165 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
166 api.metric = stream_getl (s);
167
168 eigrp = eigrp_lookup ();
169 if (eigrp == NULL)
170 return 0;
171
172 if (command == ZEBRA_IPV4_ROUTE_ADD)
173 {
174
175 }
176 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
177 {
178
179 }
180
181 return 0;
182 }
183
184 /* Inteface addition message from zebra. */
185 static int
186 eigrp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
187 vrf_id_t vrf_id)
188 {
189 struct interface *ifp;
190
191 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
192
193 assert (ifp->info);
194
195 if (!EIGRP_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
196 {
197 SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
198 IF_DEF_PARAMS (ifp)->type = eigrp_default_iftype (ifp);
199 }
200
201 eigrp_if_update (ifp);
202
203 return 0;
204 }
205
206 static int
207 eigrp_interface_delete (int command, struct zclient *zclient,
208 zebra_size_t length, vrf_id_t vrf_id)
209 {
210 struct interface *ifp;
211 struct stream *s;
212 struct route_node *rn;
213
214 s = zclient->ibuf;
215 /* zebra_interface_state_read () updates interface structure in iflist */
216 ifp = zebra_interface_state_read (s, vrf_id);
217
218 if (ifp == NULL)
219 return 0;
220
221 if (if_is_up (ifp))
222 zlog_warn ("Zebra: got delete of %s, but interface is still up",
223 ifp->name);
224
225 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
226 zlog_debug("Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
227 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
228
229 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
230 if (rn->info)
231 eigrp_if_free ((struct eigrp_interface *) rn->info, INTERFACE_DOWN_BY_ZEBRA);
232
233 ifp->ifindex = IFINDEX_INTERNAL;
234 return 0;
235 }
236
237 static int
238 eigrp_interface_address_add (int command, struct zclient *zclient,
239 zebra_size_t length, vrf_id_t vrf_id)
240 {
241 struct connected *c;
242
243 c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
244
245 if (c == NULL)
246 return 0;
247
248 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
249 {
250 char buf[128];
251 prefix2str (c->address, buf, sizeof (buf));
252 zlog_debug ("Zebra: interface %s address add %s", c->ifp->name, buf);
253 }
254
255 eigrp_if_update (c->ifp);
256
257 return 0;
258 }
259
260 static int
261 eigrp_interface_address_delete (int command, struct zclient *zclient,
262 zebra_size_t length, vrf_id_t vrf_id)
263 {
264 struct connected *c;
265 struct interface *ifp;
266 struct eigrp_interface *ei;
267 struct route_node *rn;
268 struct prefix p;
269
270 c = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
271
272 if (c == NULL)
273 return 0;
274
275 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
276 {
277 char buf[128];
278 prefix2str (c->address, buf, sizeof (buf));
279 zlog_debug ("Zebra: interface %s address delete %s", c->ifp->name, buf);
280 }
281
282 ifp = c->ifp;
283 p = *c->address;
284 p.prefixlen = IPV4_MAX_PREFIXLEN;
285
286 rn = route_node_lookup (IF_OIFS (ifp), &p);
287 if (!rn)
288 {
289 connected_free (c);
290 return 0;
291 }
292
293 assert (rn->info);
294 ei = rn->info;
295
296 /* Call interface hook functions to clean up */
297 eigrp_if_free (ei, INTERFACE_DOWN_BY_ZEBRA);
298
299 connected_free (c);
300
301 return 0;
302 }
303
304 static int
305 eigrp_interface_state_up (int command, struct zclient *zclient,
306 zebra_size_t length, vrf_id_t vrf_id)
307 {
308 struct interface *ifp;
309 struct eigrp_interface *ei;
310 struct route_node *rn;
311
312 ifp = zebra_interface_if_lookup (zclient->ibuf);
313
314 if (ifp == NULL)
315 return 0;
316
317 /* Interface is already up. */
318 if (if_is_operative (ifp))
319 {
320 /* Temporarily keep ifp values. */
321 struct interface if_tmp;
322 memcpy (&if_tmp, ifp, sizeof (struct interface));
323
324 zebra_interface_if_set_value (zclient->ibuf, ifp);
325
326 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
327 zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
328
329 if (if_tmp.bandwidth != ifp->bandwidth)
330 {
331 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
332 zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
333 ifp->name, if_tmp.bandwidth, ifp->bandwidth);
334
335 // eigrp_if_recalculate_output_cost (ifp);
336 }
337
338 if (if_tmp.mtu != ifp->mtu)
339 {
340 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
341 zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
342 ifp->name, if_tmp.mtu, ifp->mtu);
343
344 /* Must reset the interface (simulate down/up) when MTU changes. */
345 eigrp_if_reset (ifp);
346 }
347 return 0;
348 }
349
350 zebra_interface_if_set_value (zclient->ibuf, ifp);
351
352 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
353 zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
354
355 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
356 {
357 if ((ei = rn->info) == NULL)
358 continue;
359
360 eigrp_if_up (ei);
361 }
362
363 return 0;
364 }
365
366 static int
367 eigrp_interface_state_down (int command, struct zclient *zclient,
368 zebra_size_t length, vrf_id_t vrf_id)
369 {
370 struct interface *ifp;
371 struct eigrp_interface *ei;
372 struct route_node *node;
373
374 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
375
376 if (ifp == NULL)
377 return 0;
378
379 if (IS_DEBUG_EIGRP (zebra, ZEBRA_INTERFACE))
380 zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
381
382 for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
383 {
384 if ((ei = node->info) == NULL)
385 continue;
386 eigrp_if_down (ei);
387 }
388
389 return 0;
390 }
391
392 static struct interface *
393 zebra_interface_if_lookup (struct stream *s)
394 {
395 char ifname_tmp[INTERFACE_NAMSIZ];
396
397 /* Read interface name. */
398 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
399
400 /* And look it up. */
401 return if_lookup_by_name_len (ifname_tmp,
402 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
403 VRF_DEFAULT);
404 }
405
406 void
407 eigrp_zebra_route_add (struct prefix_ipv4 *p, struct list *successors)
408 {
409 struct eigrp_neighbor_entry *te;
410 struct listnode *node;
411 u_char message;
412 u_char flags;
413 int psize;
414 struct stream *s;
415
416 if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
417 {
418 message = 0;
419 flags = 0;
420
421 /* EIGRP pass nexthop and metric */
422 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
423
424 /* Make packet. */
425 s = zclient->obuf;
426 stream_reset (s);
427
428 /* Put command, type, flags, message. */
429 zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
430 stream_putc (s, ZEBRA_ROUTE_EIGRP);
431 stream_putw (s, 0);
432 stream_putl (s, flags);
433 stream_putc (s, message);
434 stream_putw (s, SAFI_UNICAST);
435
436 /* Put prefix information. */
437 psize = PSIZE (p->prefixlen);
438 stream_putc (s, p->prefixlen);
439 stream_write (s, (u_char *) & p->prefix, psize);
440
441 /* Nexthop count. */
442 stream_putc (s, successors->count);
443
444 /* Nexthop, ifindex, distance and metric information. */
445 for (ALL_LIST_ELEMENTS_RO (successors, node, te))
446 {
447 stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX);
448 stream_put_in_addr (s, &te->adv_router->src);
449 stream_putl (s, te->ei->ifp->ifindex);
450 }
451
452 if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
453 {
454 char buf[2][INET_ADDRSTRLEN];
455 zlog_debug ("Zebra: Route add %s/%d nexthop %s",
456 inet_ntop(AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
457 p->prefixlen,
458 inet_ntop(AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
459 }
460
461 stream_putw_at (s, 0, stream_get_endp (s));
462
463 zclient_send_message (zclient);
464 }
465 }
466
467 void
468 eigrp_zebra_route_delete (struct prefix_ipv4 *p)
469 {
470 struct zapi_ipv4 api;
471
472 if (zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
473 {
474 api.vrf_id = VRF_DEFAULT;
475 api.type = ZEBRA_ROUTE_EIGRP;
476 api.instance = 0;
477 api.flags = 0;
478 api.message = 0;
479 api.safi = SAFI_UNICAST;
480 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
481
482 if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
483 {
484 char buf[2][INET_ADDRSTRLEN];
485 zlog_debug ("Zebra: Route del %s/%d nexthop %s",
486 inet_ntop (AF_INET, &p->prefix, buf[0], sizeof (buf[0])),
487 p->prefixlen,
488 inet_ntop (AF_INET, 0 /*&p->nexthop*/, buf[1], sizeof (buf[1])));
489 }
490 }
491
492 return;
493 }
494
495 vrf_bitmap_t
496 eigrp_is_type_redistributed (int type)
497 {
498 return (DEFAULT_ROUTE_TYPE (type)) ?
499 zclient->default_information : zclient->redist[AFI_IP][type];
500 }
501
502 int
503 eigrp_redistribute_set (struct eigrp *eigrp, int type, struct eigrp_metrics metric)
504 {
505
506 if (eigrp_is_type_redistributed (type))
507 {
508 if (eigrp_metrics_is_same(&metric, &eigrp->dmetric[type]))
509 {
510 eigrp->dmetric[type] = metric;
511 }
512
513 eigrp_external_routes_refresh (eigrp, type);
514
515 // if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE))
516 // zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
517 // eigrp_redist_string(type),
518 // metric_type (eigrp, type), metric_value (eigrp, type));
519 return CMD_SUCCESS;
520 }
521
522 eigrp->dmetric[type] = metric;
523
524 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
525 AFI_IP, type, 0, VRF_DEFAULT);
526
527 // if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
528 // zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
529 // ospf_redist_string(type),
530 // metric_type (ospf, type), metric_value (ospf, type));
531
532 ++eigrp->redistribute;
533
534 return CMD_SUCCESS;
535 }
536
537 int
538 eigrp_redistribute_unset (struct eigrp *eigrp, int type)
539 {
540
541 if (eigrp_is_type_redistributed (type))
542 {
543 memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics));
544 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient,
545 AFI_IP, type, 0, VRF_DEFAULT);
546 --eigrp->redistribute;
547 }
548
549 // if (IS_DEBUG_EIGRP (zebra, ZEBRA_REDISTRIBUTE))
550 // zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
551 // ospf_redist_string(type),
552 // metric_type (ospf, type), metric_value (ospf, type));
553
554 return CMD_SUCCESS;
555 }
556