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