]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_zebra.c
Only warning left is the known lvalue problem in ripng_nexthop.c.
[mirror_frr.git] / ripngd / ripng_zebra.c
1 /*
2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "command.h"
26 #include "prefix.h"
27 #include "stream.h"
28 #include "routemap.h"
29 #include "zclient.h"
30 #include "log.h"
31
32 #include "ripngd/ripngd.h"
33
34 /* All information about zebra. */
35 struct zclient *zclient = NULL;
36
37 /* Callback prototypes for zebra client service. */
38 int ripng_interface_up (int, struct zclient *, zebra_size_t);
39 int ripng_interface_down (int, struct zclient *, zebra_size_t);
40 int ripng_interface_add (int, struct zclient *, zebra_size_t);
41 int ripng_interface_delete (int, struct zclient *, zebra_size_t);
42 int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
43 int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
44 \f
45 void
46 ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
47 unsigned int ifindex)
48 {
49 struct zapi_ipv6 api;
50
51 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
52 {
53 api.type = ZEBRA_ROUTE_RIPNG;
54 api.flags = 0;
55 api.message = 0;
56 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
57 api.nexthop_num = 1;
58 api.nexthop = &nexthop;
59 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
60 api.ifindex_num = 1;
61 api.ifindex = &ifindex;
62
63 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
64 }
65 }
66
67 void
68 ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
69 unsigned int ifindex)
70 {
71 struct zapi_ipv6 api;
72
73 if (zclient->redist[ZEBRA_ROUTE_RIPNG])
74 {
75 api.type = ZEBRA_ROUTE_RIPNG;
76 api.flags = 0;
77 api.message = 0;
78 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
79 api.nexthop_num = 1;
80 api.nexthop = &nexthop;
81 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
82 api.ifindex_num = 1;
83 api.ifindex = &ifindex;
84
85 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
86 }
87 }
88
89 /* Zebra route add and delete treatment. */
90 int
91 ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
92 zebra_size_t length)
93 {
94 struct stream *s;
95 struct zapi_ipv6 api;
96 unsigned long ifindex;
97 struct in6_addr nexthop;
98 struct prefix_ipv6 p;
99
100 s = zclient->ibuf;
101 ifindex = 0;
102 memset (&nexthop, 0, sizeof (struct in6_addr));
103
104 /* Type, flags, message. */
105 api.type = stream_getc (s);
106 api.flags = stream_getc (s);
107 api.message = stream_getc (s);
108
109 /* IPv6 prefix. */
110 memset (&p, 0, sizeof (struct prefix_ipv6));
111 p.family = AF_INET6;
112 p.prefixlen = stream_getc (s);
113 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
114
115 /* Nexthop, ifindex, distance, metric. */
116 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
117 {
118 api.nexthop_num = stream_getc (s);
119 stream_get (&nexthop, s, 16);
120 }
121 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
122 {
123 api.ifindex_num = stream_getc (s);
124 ifindex = stream_getl (s);
125 }
126 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
127 api.distance = stream_getc (s);
128 else
129 api.distance = 0;
130 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
131 api.metric = stream_getl (s);
132 else
133 api.metric = 0;
134
135 if (command == ZEBRA_IPV6_ROUTE_ADD)
136 ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
137 else
138 ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
139
140 return 0;
141 }
142
143 void
144 ripng_zclient_reset ()
145 {
146 zclient_reset (zclient);
147 }
148
149 int
150 ripng_redistribute_unset (int type)
151 {
152 if (! zclient->redist[type])
153 return CMD_SUCCESS;
154
155 zclient->redist[type] = 0;
156
157 if (zclient->sock > 0)
158 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
159
160 ripng_redistribute_withdraw (type);
161
162 return CMD_SUCCESS;
163 }
164
165 int
166 ripng_redistribute_check (int type)
167 {
168 return (zclient->redist[type]);
169 }
170
171 void
172 ripng_redistribute_metric_set (int type, int metric)
173 {
174 ripng->route_map[type].metric_config = 1;
175 ripng->route_map[type].metric = metric;
176 }
177
178 int
179 ripng_redistribute_metric_unset (int type)
180 {
181 ripng->route_map[type].metric_config = 0;
182 ripng->route_map[type].metric = 0;
183 return 0;
184 }
185
186 void
187 ripng_redistribute_routemap_set (int type, char *name)
188 {
189 if (ripng->route_map[type].name)
190 free (ripng->route_map[type].name);
191
192 ripng->route_map[type].name = strdup (name);
193 ripng->route_map[type].map = route_map_lookup_by_name (name);
194 }
195
196 void
197 ripng_redistribute_routemap_unset (int type)
198 {
199 if (ripng->route_map[type].name)
200 free (ripng->route_map[type].name);
201
202 ripng->route_map[type].name = NULL;
203 ripng->route_map[type].map = NULL;
204 }
205 \f
206 /* Redistribution types */
207 static struct {
208 int type;
209 int str_min_len;
210 const char *str;
211 } redist_type[] = {
212 {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
213 {ZEBRA_ROUTE_CONNECT, 1, "connected"},
214 {ZEBRA_ROUTE_STATIC, 1, "static"},
215 {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
216 {ZEBRA_ROUTE_BGP, 1, "bgp"},
217 {0, 0, NULL}
218 };
219
220 void
221 ripng_redistribute_clean ()
222 {
223 int i;
224
225 for (i = 0; redist_type[i].str; i++)
226 {
227 if (zclient->redist[redist_type[i].type])
228 {
229 if (zclient->sock > 0)
230 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
231 zclient->sock, redist_type[i].type);
232
233 zclient->redist[redist_type[i].type] = 0;
234
235 /* Remove the routes from RIPng table. */
236 ripng_redistribute_withdraw (redist_type[i].type);
237 }
238 }
239 }
240
241 DEFUN (router_zebra,
242 router_zebra_cmd,
243 "router zebra",
244 "Enable a routing process\n"
245 "Make connection to zebra daemon\n")
246 {
247 vty->node = ZEBRA_NODE;
248 zclient->enable = 1;
249 zclient_start (zclient);
250 return CMD_SUCCESS;
251 }
252
253 DEFUN (no_router_zebra,
254 no_router_zebra_cmd,
255 "no router zebra",
256 NO_STR
257 "Disable a routing process\n"
258 "Stop connection to zebra daemon\n")
259 {
260 zclient->enable = 0;
261 zclient_stop (zclient);
262 return CMD_SUCCESS;
263 }
264
265 DEFUN (ripng_redistribute_ripng,
266 ripng_redistribute_ripng_cmd,
267 "redistribute ripng",
268 "Redistribute information from another routing protocol\n"
269 "RIPng route\n")
270 {
271 zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
272 return CMD_SUCCESS;
273 }
274
275 DEFUN (no_ripng_redistribute_ripng,
276 no_ripng_redistribute_ripng_cmd,
277 "no redistribute ripng",
278 NO_STR
279 "Redistribute information from another routing protocol\n"
280 "RIPng route\n")
281 {
282 zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
283 return CMD_SUCCESS;
284 }
285
286 DEFUN (ripng_redistribute_type,
287 ripng_redistribute_type_cmd,
288 "redistribute (kernel|connected|static|ospf6|bgp)",
289 "Redistribute information from another routing protocol\n"
290 "Kernel routes\n"
291 "Connected\n"
292 "Static routes\n"
293 "Open Shortest Path First (OSPFv3)\n"
294 "Border Gateway Protocol (BGP)\n")
295 {
296 int i;
297
298 for(i = 0; redist_type[i].str; i++)
299 {
300 if (strncmp (redist_type[i].str, argv[0],
301 redist_type[i].str_min_len) == 0)
302 {
303 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
304 return CMD_SUCCESS;
305 }
306 }
307
308 vty_out(vty, "Invalid type %s%s", argv[0],
309 VTY_NEWLINE);
310
311 return CMD_WARNING;
312 }
313
314 DEFUN (no_ripng_redistribute_type,
315 no_ripng_redistribute_type_cmd,
316 "no redistribute (kernel|connected|static|ospf6|bgp)",
317 NO_STR
318 "Redistribute information from another routing protocol\n"
319 "Kernel routes\n"
320 "Connected\n"
321 "Static routes\n"
322 "Open Shortest Path First (OSPFv3)\n"
323 "Border Gateway Protocol (BGP)\n")
324 {
325 int i;
326
327 for (i = 0; redist_type[i].str; i++)
328 {
329 if (strncmp(redist_type[i].str, argv[0],
330 redist_type[i].str_min_len) == 0)
331 {
332 ripng_redistribute_metric_unset (redist_type[i].type);
333 ripng_redistribute_routemap_unset (redist_type[i].type);
334 return ripng_redistribute_unset (redist_type[i].type);
335 }
336 }
337
338 vty_out(vty, "Invalid type %s%s", argv[0],
339 VTY_NEWLINE);
340
341 return CMD_WARNING;
342 }
343
344
345 DEFUN (ripng_redistribute_type_metric,
346 ripng_redistribute_type_metric_cmd,
347 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
348 "Redistribute information from another routing protocol\n"
349 "Kernel routes\n"
350 "Connected\n"
351 "Static routes\n"
352 "Open Shortest Path First (OSPFv3)\n"
353 "Border Gateway Protocol (BGP)\n"
354 "Metric\n"
355 "Metric value\n")
356 {
357 int i;
358 int metric;
359
360 metric = atoi (argv[1]);
361
362 for (i = 0; redist_type[i].str; i++) {
363 if (strncmp(redist_type[i].str, argv[0],
364 redist_type[i].str_min_len) == 0)
365 {
366 ripng_redistribute_metric_set (redist_type[i].type, metric);
367 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
368 return CMD_SUCCESS;
369 }
370 }
371
372 vty_out(vty, "Invalid type %s%s", argv[0],
373 VTY_NEWLINE);
374
375 return CMD_WARNING;
376 }
377
378 ALIAS (no_ripng_redistribute_type,
379 no_ripng_redistribute_type_metric_cmd,
380 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
381 NO_STR
382 "Redistribute information from another routing protocol\n"
383 "Kernel routes\n"
384 "Connected\n"
385 "Static routes\n"
386 "Open Shortest Path First (OSPFv3)\n"
387 "Border Gateway Protocol (BGP)\n"
388 "Metric\n"
389 "Metric value\n")
390
391 DEFUN (ripng_redistribute_type_routemap,
392 ripng_redistribute_type_routemap_cmd,
393 "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
394 "Redistribute information from another routing protocol\n"
395 "Kernel routes\n"
396 "Connected\n"
397 "Static routes\n"
398 "Open Shortest Path First (OSPFv3)\n"
399 "Border Gateway Protocol (BGP)\n"
400 "Route map reference\n"
401 "Pointer to route-map entries\n")
402 {
403 int i;
404
405 for (i = 0; redist_type[i].str; i++) {
406 if (strncmp(redist_type[i].str, argv[0],
407 redist_type[i].str_min_len) == 0)
408 {
409 ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
410 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
411 return CMD_SUCCESS;
412 }
413 }
414
415 vty_out(vty, "Invalid type %s%s", argv[0],
416 VTY_NEWLINE);
417
418 return CMD_WARNING;
419 }
420
421 ALIAS (no_ripng_redistribute_type,
422 no_ripng_redistribute_type_routemap_cmd,
423 "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
424 NO_STR
425 "Redistribute information from another routing protocol\n"
426 "Kernel routes\n"
427 "Connected\n"
428 "Static routes\n"
429 "Open Shortest Path First (OSPFv3)\n"
430 "Border Gateway Protocol (BGP)\n"
431 "Route map reference\n"
432 "Pointer to route-map entries\n")
433
434 DEFUN (ripng_redistribute_type_metric_routemap,
435 ripng_redistribute_type_metric_routemap_cmd,
436 "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
437 "Redistribute information from another routing protocol\n"
438 "Kernel routes\n"
439 "Connected\n"
440 "Static routes\n"
441 "Open Shortest Path First (OSPFv3)\n"
442 "Border Gateway Protocol (BGP)\n"
443 "Metric\n"
444 "Metric value\n"
445 "Route map reference\n"
446 "Pointer to route-map entries\n")
447 {
448 int i;
449 int metric;
450
451 metric = atoi (argv[1]);
452
453 for (i = 0; redist_type[i].str; i++) {
454 if (strncmp(redist_type[i].str, argv[0],
455 redist_type[i].str_min_len) == 0)
456 {
457 ripng_redistribute_metric_set (redist_type[i].type, metric);
458 ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
459 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
460 return CMD_SUCCESS;
461 }
462 }
463
464 vty_out(vty, "Invalid type %s%s", argv[0],
465 VTY_NEWLINE);
466
467 return CMD_WARNING;
468 }
469
470 ALIAS (no_ripng_redistribute_type,
471 no_ripng_redistribute_type_metric_routemap_cmd,
472 "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
473 NO_STR
474 "Redistribute information from another routing protocol\n"
475 "Kernel routes\n"
476 "Connected\n"
477 "Static routes\n"
478 "Open Shortest Path First (OSPFv3)\n"
479 "Border Gateway Protocol (BGP)\n"
480 "Route map reference\n"
481 "Pointer to route-map entries\n")
482
483 void
484 ripng_redistribute_write (struct vty *vty, int config_mode)
485 {
486 int i;
487 const char *str[] = { "system", "kernel", "connected", "static", "rip",
488 "ripng", "ospf", "ospf6", "isis", "bgp"};
489
490 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
491 if (i != zclient->redist_default && zclient->redist[i])
492 {
493 if (config_mode)
494 {
495 if (ripng->route_map[i].metric_config)
496 {
497 if (ripng->route_map[i].name)
498 vty_out (vty, " redistribute %s metric %d route-map %s%s",
499 str[i], ripng->route_map[i].metric,
500 ripng->route_map[i].name, VTY_NEWLINE);
501 else
502 vty_out (vty, " redistribute %s metric %d%s",
503 str[i], ripng->route_map[i].metric, VTY_NEWLINE);
504 }
505 else
506 {
507 if (ripng->route_map[i].name)
508 vty_out (vty, " redistribute %s route-map %s%s",
509 str[i], ripng->route_map[i].name, VTY_NEWLINE);
510 else
511 vty_out (vty, " redistribute %s%s", str[i], VTY_NEWLINE);
512 }
513 }
514 else
515 vty_out (vty, " %s", str[i]);
516 }
517 }
518
519 /* RIPng configuration write function. */
520 int
521 zebra_config_write (struct vty *vty)
522 {
523 if (! zclient->enable)
524 {
525 vty_out (vty, "no router zebra%s", VTY_NEWLINE);
526 return 1;
527 }
528 else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
529 {
530 vty_out (vty, "router zebra%s", VTY_NEWLINE);
531 vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
532 return 1;
533 }
534 return 0;
535 }
536
537 /* Zebra node structure. */
538 struct cmd_node zebra_node =
539 {
540 ZEBRA_NODE,
541 "%s(config-router)# ",
542 };
543
544 /* Initialize zebra structure and it's commands. */
545 void
546 zebra_init ()
547 {
548 /* Allocate zebra structure. */
549 zclient = zclient_new ();
550 zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
551
552 zclient->interface_up = ripng_interface_up;
553 zclient->interface_down = ripng_interface_down;
554 zclient->interface_add = ripng_interface_add;
555 zclient->interface_delete = ripng_interface_delete;
556 zclient->interface_address_add = ripng_interface_address_add;
557 zclient->interface_address_delete = ripng_interface_address_delete;
558 zclient->ipv6_route_add = ripng_zebra_read_ipv6;
559 zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
560
561 /* Install zebra node. */
562 install_node (&zebra_node, zebra_config_write);
563
564 /* Install command element for zebra node. */
565 install_element (CONFIG_NODE, &router_zebra_cmd);
566 install_element (CONFIG_NODE, &no_router_zebra_cmd);
567 install_default (ZEBRA_NODE);
568 install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
569 install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
570
571 /* Install command elements to ripng node */
572 install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
573 install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
574 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
575 install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
576 install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
577 install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
578 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
579 install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
580 }