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