Annotation of embedaddon/quagga/ripd/rip_zebra.c, revision 1.1.1.1
1.1 misho 1: /* RIPd and zebra interface.
2: * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the Free
18: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: * 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #include "command.h"
25: #include "prefix.h"
26: #include "stream.h"
27: #include "routemap.h"
28: #include "zclient.h"
29: #include "log.h"
30: #include "ripd/ripd.h"
31: #include "ripd/rip_debug.h"
32: #include "ripd/rip_interface.h"
33:
34: /* All information about zebra. */
35: struct zclient *zclient = NULL;
36:
37: /* RIPd to zebra command interface. */
38: void
39: rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop,
40: u_int32_t metric, u_char distance)
41: {
42: struct zapi_ipv4 api;
43:
44: if (zclient->redist[ZEBRA_ROUTE_RIP])
45: {
46: api.type = ZEBRA_ROUTE_RIP;
47: api.flags = 0;
48: api.message = 0;
49: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
50: api.nexthop_num = 1;
51: api.nexthop = &nexthop;
52: api.ifindex_num = 0;
53: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
54: api.metric = metric;
55:
56: if (distance && distance != ZEBRA_RIP_DISTANCE_DEFAULT)
57: {
58: SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
59: api.distance = distance;
60: }
61:
62: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
63:
64: rip_global_route_changes++;
65: }
66: }
67:
68: void
69: rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop,
70: u_int32_t metric)
71: {
72: struct zapi_ipv4 api;
73:
74: if (zclient->redist[ZEBRA_ROUTE_RIP])
75: {
76: api.type = ZEBRA_ROUTE_RIP;
77: api.flags = 0;
78: api.message = 0;
79: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
80: api.nexthop_num = 1;
81: api.nexthop = &nexthop;
82: api.ifindex_num = 0;
83: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
84: api.metric = metric;
85:
86: zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
87:
88: rip_global_route_changes++;
89: }
90: }
91:
92: /* Zebra route add and delete treatment. */
93: static int
94: rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
95: {
96: struct stream *s;
97: struct zapi_ipv4 api;
98: unsigned long ifindex;
99: struct in_addr nexthop;
100: struct prefix_ipv4 p;
101:
102: s = zclient->ibuf;
103: ifindex = 0;
104: nexthop.s_addr = 0;
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: /* IPv4 prefix. */
112: memset (&p, 0, sizeof (struct prefix_ipv4));
113: p.family = AF_INET;
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: nexthop.s_addr = stream_get_ipv4 (s);
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 = 255;
132: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
133: api.metric = stream_getl (s);
134: else
135: api.metric = 0;
136:
137: /* Then fetch IPv4 prefixes. */
138: if (command == ZEBRA_IPV4_ROUTE_ADD)
139: rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
140: &nexthop, api.metric, api.distance);
141: else
142: rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
143:
144: return 0;
145: }
146:
147: void
148: rip_zclient_reset (void)
149: {
150: zclient_reset (zclient);
151: }
152:
153: /* RIP route-map set for redistribution */
154: static void
155: rip_routemap_set (int type, const char *name)
156: {
157: if (rip->route_map[type].name)
158: free(rip->route_map[type].name);
159:
160: rip->route_map[type].name = strdup (name);
161: rip->route_map[type].map = route_map_lookup_by_name (name);
162: }
163:
164: static void
165: rip_redistribute_metric_set (int type, unsigned int metric)
166: {
167: rip->route_map[type].metric_config = 1;
168: rip->route_map[type].metric = metric;
169: }
170:
171: static int
172: rip_metric_unset (int type, unsigned int metric)
173: {
174: #define DONT_CARE_METRIC_RIP 17
175: if (metric != DONT_CARE_METRIC_RIP &&
176: rip->route_map[type].metric != metric)
177: return 1;
178: rip->route_map[type].metric_config = 0;
179: rip->route_map[type].metric = 0;
180: return 0;
181: }
182:
183: /* RIP route-map unset for redistribution */
184: static int
185: rip_routemap_unset (int type, const char *name)
186: {
187: if (! rip->route_map[type].name ||
188: (name != NULL && strcmp(rip->route_map[type].name,name)))
189: return 1;
190:
191: free (rip->route_map[type].name);
192: rip->route_map[type].name = NULL;
193: rip->route_map[type].map = NULL;
194:
195: return 0;
196: }
197:
198: /* Redistribution types */
199: static struct {
200: int type;
201: int str_min_len;
202: const char *str;
203: } redist_type[] = {
204: {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
205: {ZEBRA_ROUTE_CONNECT, 1, "connected"},
206: {ZEBRA_ROUTE_STATIC, 1, "static"},
207: {ZEBRA_ROUTE_OSPF, 1, "ospf"},
208: {ZEBRA_ROUTE_BGP, 1, "bgp"},
209: {0, 0, NULL}
210: };
211:
212: DEFUN (router_zebra,
213: router_zebra_cmd,
214: "router zebra",
215: "Enable a routing process\n"
216: "Make connection to zebra daemon\n")
217: {
218: vty->node = ZEBRA_NODE;
219: zclient->enable = 1;
220: zclient_start (zclient);
221: return CMD_SUCCESS;
222: }
223:
224: DEFUN (no_router_zebra,
225: no_router_zebra_cmd,
226: "no router zebra",
227: NO_STR
228: "Enable a routing process\n"
229: "Make connection to zebra daemon\n")
230: {
231: zclient->enable = 0;
232: zclient_stop (zclient);
233: return CMD_SUCCESS;
234: }
235:
236: #if 0
237: static int
238: rip_redistribute_set (int type)
239: {
240: if (zclient->redist[type])
241: return CMD_SUCCESS;
242:
243: zclient->redist[type] = 1;
244:
245: if (zclient->sock > 0)
246: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
247:
248: return CMD_SUCCESS;
249: }
250: #endif
251:
252: static int
253: rip_redistribute_unset (int type)
254: {
255: if (! zclient->redist[type])
256: return CMD_SUCCESS;
257:
258: zclient->redist[type] = 0;
259:
260: if (zclient->sock > 0)
261: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
262:
263: /* Remove the routes from RIP table. */
264: rip_redistribute_withdraw (type);
265:
266: return CMD_SUCCESS;
267: }
268:
269: int
270: rip_redistribute_check (int type)
271: {
272: return (zclient->redist[type]);
273: }
274:
275: void
276: rip_redistribute_clean (void)
277: {
278: int i;
279:
280: for (i = 0; redist_type[i].str; i++)
281: {
282: if (zclient->redist[redist_type[i].type])
283: {
284: if (zclient->sock > 0)
285: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
286: zclient, redist_type[i].type);
287:
288: zclient->redist[redist_type[i].type] = 0;
289:
290: /* Remove the routes from RIP table. */
291: rip_redistribute_withdraw (redist_type[i].type);
292: }
293: }
294: }
295:
296: DEFUN (rip_redistribute_rip,
297: rip_redistribute_rip_cmd,
298: "redistribute rip",
299: "Redistribute information from another routing protocol\n"
300: "Routing Information Protocol (RIP)\n")
301: {
302: zclient->redist[ZEBRA_ROUTE_RIP] = 1;
303: return CMD_SUCCESS;
304: }
305:
306: DEFUN (no_rip_redistribute_rip,
307: no_rip_redistribute_rip_cmd,
308: "no redistribute rip",
309: NO_STR
310: "Redistribute information from another routing protocol\n"
311: "Routing Information Protocol (RIP)\n")
312: {
313: zclient->redist[ZEBRA_ROUTE_RIP] = 0;
314: return CMD_SUCCESS;
315: }
316:
317: DEFUN (rip_redistribute_type,
318: rip_redistribute_type_cmd,
319: "redistribute " QUAGGA_REDIST_STR_RIPD,
320: REDIST_STR
321: QUAGGA_REDIST_HELP_STR_RIPD)
322: {
323: int i;
324:
325: for(i = 0; redist_type[i].str; i++)
326: {
327: if (strncmp (redist_type[i].str, argv[0],
328: redist_type[i].str_min_len) == 0)
329: {
330: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
331: redist_type[i].type);
332: return CMD_SUCCESS;
333: }
334: }
335:
336: vty_out(vty, "Invalid type %s%s", argv[0],
337: VTY_NEWLINE);
338:
339: return CMD_WARNING;
340: }
341:
342: DEFUN (no_rip_redistribute_type,
343: no_rip_redistribute_type_cmd,
344: "no redistribute " QUAGGA_REDIST_STR_RIPD,
345: NO_STR
346: REDIST_STR
347: QUAGGA_REDIST_HELP_STR_RIPD)
348: {
349: int i;
350:
351: for (i = 0; redist_type[i].str; i++)
352: {
353: if (strncmp(redist_type[i].str, argv[0],
354: redist_type[i].str_min_len) == 0)
355: {
356: rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
357: rip_routemap_unset (redist_type[i].type,NULL);
358: rip_redistribute_unset (redist_type[i].type);
359: return CMD_SUCCESS;
360: }
361: }
362:
363: vty_out(vty, "Invalid type %s%s", argv[0],
364: VTY_NEWLINE);
365:
366: return CMD_WARNING;
367: }
368:
369: DEFUN (rip_redistribute_type_routemap,
370: rip_redistribute_type_routemap_cmd,
371: "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
372: REDIST_STR
373: QUAGGA_REDIST_HELP_STR_RIPD
374: "Route map reference\n"
375: "Pointer to route-map entries\n")
376: {
377: int i;
378:
379: for (i = 0; redist_type[i].str; i++) {
380: if (strncmp(redist_type[i].str, argv[0],
381: redist_type[i].str_min_len) == 0)
382: {
383: rip_routemap_set (redist_type[i].type, argv[1]);
384: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
385: return CMD_SUCCESS;
386: }
387: }
388:
389: vty_out(vty, "Invalid type %s%s", argv[0],
390: VTY_NEWLINE);
391:
392: return CMD_WARNING;
393: }
394:
395: DEFUN (no_rip_redistribute_type_routemap,
396: no_rip_redistribute_type_routemap_cmd,
397: "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
398: NO_STR
399: REDIST_STR
400: QUAGGA_REDIST_HELP_STR_RIPD
401: "Route map reference\n"
402: "Pointer to route-map entries\n")
403: {
404: int i;
405:
406: for (i = 0; redist_type[i].str; i++)
407: {
408: if (strncmp(redist_type[i].str, argv[0],
409: redist_type[i].str_min_len) == 0)
410: {
411: if (rip_routemap_unset (redist_type[i].type,argv[1]))
412: return CMD_WARNING;
413: rip_redistribute_unset (redist_type[i].type);
414: return CMD_SUCCESS;
415: }
416: }
417:
418: vty_out(vty, "Invalid type %s%s", argv[0],
419: VTY_NEWLINE);
420:
421: return CMD_WARNING;
422: }
423:
424: DEFUN (rip_redistribute_type_metric,
425: rip_redistribute_type_metric_cmd,
426: "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
427: REDIST_STR
428: QUAGGA_REDIST_HELP_STR_RIPD
429: "Metric\n"
430: "Metric value\n")
431: {
432: int i;
433: int metric;
434:
435: metric = atoi (argv[1]);
436:
437: for (i = 0; redist_type[i].str; i++) {
438: if (strncmp(redist_type[i].str, argv[0],
439: redist_type[i].str_min_len) == 0)
440: {
441: rip_redistribute_metric_set (redist_type[i].type, metric);
442: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
443: return CMD_SUCCESS;
444: }
445: }
446:
447: vty_out(vty, "Invalid type %s%s", argv[0],
448: VTY_NEWLINE);
449:
450: return CMD_WARNING;
451: }
452:
453: DEFUN (no_rip_redistribute_type_metric,
454: no_rip_redistribute_type_metric_cmd,
455: "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
456: NO_STR
457: REDIST_STR
458: QUAGGA_REDIST_HELP_STR_RIPD
459: "Metric\n"
460: "Metric value\n")
461: {
462: int i;
463:
464: for (i = 0; redist_type[i].str; i++)
465: {
466: if (strncmp(redist_type[i].str, argv[0],
467: redist_type[i].str_min_len) == 0)
468: {
469: if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
470: return CMD_WARNING;
471: rip_redistribute_unset (redist_type[i].type);
472: return CMD_SUCCESS;
473: }
474: }
475:
476: vty_out(vty, "Invalid type %s%s", argv[0],
477: VTY_NEWLINE);
478:
479: return CMD_WARNING;
480: }
481:
482: DEFUN (rip_redistribute_type_metric_routemap,
483: rip_redistribute_type_metric_routemap_cmd,
484: "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
485: REDIST_STR
486: QUAGGA_REDIST_HELP_STR_RIPD
487: "Metric\n"
488: "Metric value\n"
489: "Route map reference\n"
490: "Pointer to route-map entries\n")
491: {
492: int i;
493: int metric;
494:
495: metric = atoi (argv[1]);
496:
497: for (i = 0; redist_type[i].str; i++) {
498: if (strncmp(redist_type[i].str, argv[0],
499: redist_type[i].str_min_len) == 0)
500: {
501: rip_redistribute_metric_set (redist_type[i].type, metric);
502: rip_routemap_set (redist_type[i].type, argv[2]);
503: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
504: return CMD_SUCCESS;
505: }
506: }
507:
508: vty_out(vty, "Invalid type %s%s", argv[0],
509: VTY_NEWLINE);
510:
511: return CMD_WARNING;
512: }
513:
514:
515: DEFUN (no_rip_redistribute_type_metric_routemap,
516: no_rip_redistribute_type_metric_routemap_cmd,
517: "no redistribute " QUAGGA_REDIST_STR_RIPD
518: " metric <0-16> route-map WORD",
519: NO_STR
520: REDIST_STR
521: QUAGGA_REDIST_HELP_STR_RIPD
522: "Metric\n"
523: "Metric value\n"
524: "Route map reference\n"
525: "Pointer to route-map entries\n")
526: {
527: int i;
528:
529: for (i = 0; redist_type[i].str; i++)
530: {
531: if (strncmp(redist_type[i].str, argv[0],
532: redist_type[i].str_min_len) == 0)
533: {
534: if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
535: return CMD_WARNING;
536: if (rip_routemap_unset (redist_type[i].type, argv[2]))
537: {
538: rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
539: return CMD_WARNING;
540: }
541: rip_redistribute_unset (redist_type[i].type);
542: return CMD_SUCCESS;
543: }
544: }
545:
546: vty_out(vty, "Invalid type %s%s", argv[0],
547: VTY_NEWLINE);
548:
549: return CMD_WARNING;
550: }
551:
552: /* Default information originate. */
553:
554: DEFUN (rip_default_information_originate,
555: rip_default_information_originate_cmd,
556: "default-information originate",
557: "Control distribution of default route\n"
558: "Distribute a default route\n")
559: {
560: struct prefix_ipv4 p;
561:
562: if (! rip->default_information)
563: {
564: memset (&p, 0, sizeof (struct prefix_ipv4));
565: p.family = AF_INET;
566:
567: rip->default_information = 1;
568:
569: rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
570: NULL, 0, 0);
571: }
572:
573: return CMD_SUCCESS;
574: }
575:
576: DEFUN (no_rip_default_information_originate,
577: no_rip_default_information_originate_cmd,
578: "no default-information originate",
579: NO_STR
580: "Control distribution of default route\n"
581: "Distribute a default route\n")
582: {
583: struct prefix_ipv4 p;
584:
585: if (rip->default_information)
586: {
587: memset (&p, 0, sizeof (struct prefix_ipv4));
588: p.family = AF_INET;
589:
590: rip->default_information = 0;
591:
592: rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
593: }
594:
595: return CMD_SUCCESS;
596: }
597:
598: /* RIP configuration write function. */
599: static int
600: config_write_zebra (struct vty *vty)
601: {
602: if (! zclient->enable)
603: {
604: vty_out (vty, "no router zebra%s", VTY_NEWLINE);
605: return 1;
606: }
607: else if (! zclient->redist[ZEBRA_ROUTE_RIP])
608: {
609: vty_out (vty, "router zebra%s", VTY_NEWLINE);
610: vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
611: return 1;
612: }
613: return 0;
614: }
615:
616: int
617: config_write_rip_redistribute (struct vty *vty, int config_mode)
618: {
619: int i;
620:
621: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
622: if (i != zclient->redist_default && zclient->redist[i])
623: {
624: if (config_mode)
625: {
626: if (rip->route_map[i].metric_config)
627: {
628: if (rip->route_map[i].name)
629: vty_out (vty, " redistribute %s metric %d route-map %s%s",
630: zebra_route_string(i), rip->route_map[i].metric,
631: rip->route_map[i].name,
632: VTY_NEWLINE);
633: else
634: vty_out (vty, " redistribute %s metric %d%s",
635: zebra_route_string(i), rip->route_map[i].metric,
636: VTY_NEWLINE);
637: }
638: else
639: {
640: if (rip->route_map[i].name)
641: vty_out (vty, " redistribute %s route-map %s%s",
642: zebra_route_string(i), rip->route_map[i].name,
643: VTY_NEWLINE);
644: else
645: vty_out (vty, " redistribute %s%s", zebra_route_string(i),
646: VTY_NEWLINE);
647: }
648: }
649: else
650: vty_out (vty, " %s", zebra_route_string(i));
651: }
652: return 0;
653: }
654:
655: /* Zebra node structure. */
656: static struct cmd_node zebra_node =
657: {
658: ZEBRA_NODE,
659: "%s(config-router)# ",
660: };
661:
662: void
663: rip_zclient_init ()
664: {
665: /* Set default value to the zebra client structure. */
666: zclient = zclient_new ();
667: zclient_init (zclient, ZEBRA_ROUTE_RIP);
668: zclient->interface_add = rip_interface_add;
669: zclient->interface_delete = rip_interface_delete;
670: zclient->interface_address_add = rip_interface_address_add;
671: zclient->interface_address_delete = rip_interface_address_delete;
672: zclient->ipv4_route_add = rip_zebra_read_ipv4;
673: zclient->ipv4_route_delete = rip_zebra_read_ipv4;
674: zclient->interface_up = rip_interface_up;
675: zclient->interface_down = rip_interface_down;
676:
677: /* Install zebra node. */
678: install_node (&zebra_node, config_write_zebra);
679:
680: /* Install command elements to zebra node. */
681: install_element (CONFIG_NODE, &router_zebra_cmd);
682: install_element (CONFIG_NODE, &no_router_zebra_cmd);
683: install_default (ZEBRA_NODE);
684: install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
685: install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
686:
687: /* Install command elements to rip node. */
688: install_element (RIP_NODE, &rip_redistribute_type_cmd);
689: install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
690: install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
691: install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
692: install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
693: install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
694: install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
695: install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
696: install_element (RIP_NODE, &rip_default_information_originate_cmd);
697: install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
698: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>