Annotation of embedaddon/quagga/ripngd/ripng_zebra.c, revision 1.1.1.1
1.1 misho 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:
45: void
46: ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
47: unsigned int ifindex, u_char metric)
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: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
63: api.metric = metric;
64:
65: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
66: }
67: }
68:
69: void
70: ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
71: unsigned int ifindex)
72: {
73: struct zapi_ipv6 api;
74:
75: if (zclient->redist[ZEBRA_ROUTE_RIPNG])
76: {
77: api.type = ZEBRA_ROUTE_RIPNG;
78: api.flags = 0;
79: api.message = 0;
80: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
81: api.nexthop_num = 1;
82: api.nexthop = &nexthop;
83: SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
84: api.ifindex_num = 1;
85: api.ifindex = &ifindex;
86:
87: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
88: }
89: }
90:
91: /* Zebra route add and delete treatment. */
92: static int
93: ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
94: zebra_size_t length)
95: {
96: struct stream *s;
97: struct zapi_ipv6 api;
98: unsigned long ifindex;
99: struct in6_addr nexthop;
100: struct prefix_ipv6 p;
101:
102: s = zclient->ibuf;
103: ifindex = 0;
104: memset (&nexthop, 0, sizeof (struct in6_addr));
105:
106: /* Type, flags, message. */
107: api.type = stream_getc (s);
108: api.flags = stream_getc (s);
109: api.message = stream_getc (s);
110:
111: /* IPv6 prefix. */
112: memset (&p, 0, sizeof (struct prefix_ipv6));
113: p.family = AF_INET6;
114: p.prefixlen = stream_getc (s);
115: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
116:
117: /* Nexthop, ifindex, distance, metric. */
118: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
119: {
120: api.nexthop_num = stream_getc (s);
121: stream_get (&nexthop, s, 16);
122: }
123: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
124: {
125: api.ifindex_num = stream_getc (s);
126: ifindex = stream_getl (s);
127: }
128: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
129: api.distance = stream_getc (s);
130: else
131: api.distance = 0;
132: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
133: api.metric = stream_getl (s);
134: else
135: api.metric = 0;
136:
137: if (command == ZEBRA_IPV6_ROUTE_ADD)
138: ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
139: else
140: ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
141:
142: return 0;
143: }
144:
145: void
146: ripng_zclient_reset (void)
147: {
148: zclient_reset (zclient);
149: }
150:
151: static int
152: ripng_redistribute_unset (int type)
153: {
154: if (! zclient->redist[type])
155: return CMD_SUCCESS;
156:
157: zclient->redist[type] = 0;
158:
159: if (zclient->sock > 0)
160: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
161:
162: ripng_redistribute_withdraw (type);
163:
164: return CMD_SUCCESS;
165: }
166:
167: int
168: ripng_redistribute_check (int type)
169: {
170: return (zclient->redist[type]);
171: }
172:
173: static void
174: ripng_redistribute_metric_set (int type, int metric)
175: {
176: ripng->route_map[type].metric_config = 1;
177: ripng->route_map[type].metric = metric;
178: }
179:
180: static int
181: ripng_redistribute_metric_unset (int type)
182: {
183: ripng->route_map[type].metric_config = 0;
184: ripng->route_map[type].metric = 0;
185: return 0;
186: }
187:
188: static void
189: ripng_redistribute_routemap_set (int type, const char *name)
190: {
191: if (ripng->route_map[type].name)
192: free (ripng->route_map[type].name);
193:
194: ripng->route_map[type].name = strdup (name);
195: ripng->route_map[type].map = route_map_lookup_by_name (name);
196: }
197:
198: static void
199: ripng_redistribute_routemap_unset (int type)
200: {
201: if (ripng->route_map[type].name)
202: free (ripng->route_map[type].name);
203:
204: ripng->route_map[type].name = NULL;
205: ripng->route_map[type].map = NULL;
206: }
207:
208: /* Redistribution types */
209: static struct {
210: int type;
211: int str_min_len;
212: const char *str;
213: } redist_type[] = {
214: {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
215: {ZEBRA_ROUTE_CONNECT, 1, "connected"},
216: {ZEBRA_ROUTE_STATIC, 1, "static"},
217: {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
218: {ZEBRA_ROUTE_BGP, 1, "bgp"},
219: {0, 0, NULL}
220: };
221:
222: void
223: ripng_redistribute_clean ()
224: {
225: int i;
226:
227: for (i = 0; redist_type[i].str; i++)
228: {
229: if (zclient->redist[redist_type[i].type])
230: {
231: if (zclient->sock > 0)
232: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
233: zclient, redist_type[i].type);
234:
235: zclient->redist[redist_type[i].type] = 0;
236:
237: /* Remove the routes from RIPng table. */
238: ripng_redistribute_withdraw (redist_type[i].type);
239: }
240: }
241: }
242:
243: DEFUN (router_zebra,
244: router_zebra_cmd,
245: "router zebra",
246: "Enable a routing process\n"
247: "Make connection to zebra daemon\n")
248: {
249: vty->node = ZEBRA_NODE;
250: zclient->enable = 1;
251: zclient_start (zclient);
252: return CMD_SUCCESS;
253: }
254:
255: DEFUN (no_router_zebra,
256: no_router_zebra_cmd,
257: "no router zebra",
258: NO_STR
259: "Disable a routing process\n"
260: "Stop connection to zebra daemon\n")
261: {
262: zclient->enable = 0;
263: zclient_stop (zclient);
264: return CMD_SUCCESS;
265: }
266:
267: DEFUN (ripng_redistribute_ripng,
268: ripng_redistribute_ripng_cmd,
269: "redistribute ripng",
270: "Redistribute information from another routing protocol\n"
271: "RIPng route\n")
272: {
273: zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
274: return CMD_SUCCESS;
275: }
276:
277: DEFUN (no_ripng_redistribute_ripng,
278: no_ripng_redistribute_ripng_cmd,
279: "no redistribute ripng",
280: NO_STR
281: "Redistribute information from another routing protocol\n"
282: "RIPng route\n")
283: {
284: zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
285: return CMD_SUCCESS;
286: }
287:
288: DEFUN (ripng_redistribute_type,
289: ripng_redistribute_type_cmd,
290: "redistribute (kernel|connected|static|ospf6|bgp)",
291: "Redistribute information from another routing protocol\n"
292: "Kernel routes\n"
293: "Connected\n"
294: "Static routes\n"
295: "Open Shortest Path First (OSPFv3)\n"
296: "Border Gateway Protocol (BGP)\n")
297: {
298: int i;
299:
300: for(i = 0; redist_type[i].str; i++)
301: {
302: if (strncmp (redist_type[i].str, argv[0],
303: redist_type[i].str_min_len) == 0)
304: {
305: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
306: return CMD_SUCCESS;
307: }
308: }
309:
310: vty_out(vty, "Invalid type %s%s", argv[0],
311: VTY_NEWLINE);
312:
313: return CMD_WARNING;
314: }
315:
316: DEFUN (no_ripng_redistribute_type,
317: no_ripng_redistribute_type_cmd,
318: "no redistribute (kernel|connected|static|ospf6|bgp)",
319: NO_STR
320: "Redistribute information from another routing protocol\n"
321: "Kernel routes\n"
322: "Connected\n"
323: "Static routes\n"
324: "Open Shortest Path First (OSPFv3)\n"
325: "Border Gateway Protocol (BGP)\n")
326: {
327: int i;
328:
329: for (i = 0; redist_type[i].str; i++)
330: {
331: if (strncmp(redist_type[i].str, argv[0],
332: redist_type[i].str_min_len) == 0)
333: {
334: ripng_redistribute_metric_unset (redist_type[i].type);
335: ripng_redistribute_routemap_unset (redist_type[i].type);
336: return ripng_redistribute_unset (redist_type[i].type);
337: }
338: }
339:
340: vty_out(vty, "Invalid type %s%s", argv[0],
341: VTY_NEWLINE);
342:
343: return CMD_WARNING;
344: }
345:
346:
347: DEFUN (ripng_redistribute_type_metric,
348: ripng_redistribute_type_metric_cmd,
349: "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
350: "Redistribute information from another routing protocol\n"
351: "Kernel routes\n"
352: "Connected\n"
353: "Static routes\n"
354: "Open Shortest Path First (OSPFv3)\n"
355: "Border Gateway Protocol (BGP)\n"
356: "Metric\n"
357: "Metric value\n")
358: {
359: int i;
360: int metric;
361:
362: metric = atoi (argv[1]);
363:
364: for (i = 0; redist_type[i].str; i++) {
365: if (strncmp(redist_type[i].str, argv[0],
366: redist_type[i].str_min_len) == 0)
367: {
368: ripng_redistribute_metric_set (redist_type[i].type, metric);
369: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
370: return CMD_SUCCESS;
371: }
372: }
373:
374: vty_out(vty, "Invalid type %s%s", argv[0],
375: VTY_NEWLINE);
376:
377: return CMD_WARNING;
378: }
379:
380: ALIAS (no_ripng_redistribute_type,
381: no_ripng_redistribute_type_metric_cmd,
382: "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
383: NO_STR
384: "Redistribute information from another routing protocol\n"
385: "Kernel routes\n"
386: "Connected\n"
387: "Static routes\n"
388: "Open Shortest Path First (OSPFv3)\n"
389: "Border Gateway Protocol (BGP)\n"
390: "Metric\n"
391: "Metric value\n")
392:
393: DEFUN (ripng_redistribute_type_routemap,
394: ripng_redistribute_type_routemap_cmd,
395: "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
396: "Redistribute information from another routing protocol\n"
397: "Kernel routes\n"
398: "Connected\n"
399: "Static routes\n"
400: "Open Shortest Path First (OSPFv3)\n"
401: "Border Gateway Protocol (BGP)\n"
402: "Route map reference\n"
403: "Pointer to route-map entries\n")
404: {
405: int i;
406:
407: for (i = 0; redist_type[i].str; i++) {
408: if (strncmp(redist_type[i].str, argv[0],
409: redist_type[i].str_min_len) == 0)
410: {
411: ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
412: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
413: return CMD_SUCCESS;
414: }
415: }
416:
417: vty_out(vty, "Invalid type %s%s", argv[0],
418: VTY_NEWLINE);
419:
420: return CMD_WARNING;
421: }
422:
423: ALIAS (no_ripng_redistribute_type,
424: no_ripng_redistribute_type_routemap_cmd,
425: "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
426: NO_STR
427: "Redistribute information from another routing protocol\n"
428: "Kernel routes\n"
429: "Connected\n"
430: "Static routes\n"
431: "Open Shortest Path First (OSPFv3)\n"
432: "Border Gateway Protocol (BGP)\n"
433: "Route map reference\n"
434: "Pointer to route-map entries\n")
435:
436: DEFUN (ripng_redistribute_type_metric_routemap,
437: ripng_redistribute_type_metric_routemap_cmd,
438: "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
439: "Redistribute information from another routing protocol\n"
440: "Kernel routes\n"
441: "Connected\n"
442: "Static routes\n"
443: "Open Shortest Path First (OSPFv3)\n"
444: "Border Gateway Protocol (BGP)\n"
445: "Metric\n"
446: "Metric value\n"
447: "Route map reference\n"
448: "Pointer to route-map entries\n")
449: {
450: int i;
451: int metric;
452:
453: metric = atoi (argv[1]);
454:
455: for (i = 0; redist_type[i].str; i++) {
456: if (strncmp(redist_type[i].str, argv[0],
457: redist_type[i].str_min_len) == 0)
458: {
459: ripng_redistribute_metric_set (redist_type[i].type, metric);
460: ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
461: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
462: return CMD_SUCCESS;
463: }
464: }
465:
466: vty_out(vty, "Invalid type %s%s", argv[0],
467: VTY_NEWLINE);
468:
469: return CMD_WARNING;
470: }
471:
472: ALIAS (no_ripng_redistribute_type,
473: no_ripng_redistribute_type_metric_routemap_cmd,
474: "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
475: NO_STR
476: "Redistribute information from another routing protocol\n"
477: "Kernel routes\n"
478: "Connected\n"
479: "Static routes\n"
480: "Open Shortest Path First (OSPFv3)\n"
481: "Border Gateway Protocol (BGP)\n"
482: "Route map reference\n"
483: "Pointer to route-map entries\n")
484:
485: void
486: ripng_redistribute_write (struct vty *vty, int config_mode)
487: {
488: int i;
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: zebra_route_string(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: zebra_route_string(i), ripng->route_map[i].metric,
504: VTY_NEWLINE);
505: }
506: else
507: {
508: if (ripng->route_map[i].name)
509: vty_out (vty, " redistribute %s route-map %s%s",
510: zebra_route_string(i), ripng->route_map[i].name,
511: VTY_NEWLINE);
512: else
513: vty_out (vty, " redistribute %s%s", zebra_route_string(i),
514: VTY_NEWLINE);
515: }
516: }
517: else
518: vty_out (vty, " %s", zebra_route_string(i));
519: }
520: }
521:
522: /* RIPng configuration write function. */
523: static int
524: zebra_config_write (struct vty *vty)
525: {
526: if (! zclient->enable)
527: {
528: vty_out (vty, "no router zebra%s", VTY_NEWLINE);
529: return 1;
530: }
531: else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
532: {
533: vty_out (vty, "router zebra%s", VTY_NEWLINE);
534: vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
535: return 1;
536: }
537: return 0;
538: }
539:
540: /* Zebra node structure. */
541: static struct cmd_node zebra_node =
542: {
543: ZEBRA_NODE,
544: "%s(config-router)# ",
545: };
546:
547: /* Initialize zebra structure and it's commands. */
548: void
549: zebra_init ()
550: {
551: /* Allocate zebra structure. */
552: zclient = zclient_new ();
553: zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
554:
555: zclient->interface_up = ripng_interface_up;
556: zclient->interface_down = ripng_interface_down;
557: zclient->interface_add = ripng_interface_add;
558: zclient->interface_delete = ripng_interface_delete;
559: zclient->interface_address_add = ripng_interface_address_add;
560: zclient->interface_address_delete = ripng_interface_address_delete;
561: zclient->ipv6_route_add = ripng_zebra_read_ipv6;
562: zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
563:
564: /* Install zebra node. */
565: install_node (&zebra_node, zebra_config_write);
566:
567: /* Install command element for zebra node. */
568: install_element (CONFIG_NODE, &router_zebra_cmd);
569: install_element (CONFIG_NODE, &no_router_zebra_cmd);
570: install_default (ZEBRA_NODE);
571: install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
572: install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
573:
574: /* Install command elements to ripng node */
575: install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
576: install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
577: install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
578: install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
579: install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
580: install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
581: install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
582: install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
583: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>