1 /* RIPd and zebra interface.
2 * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
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
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.
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
30 #include "ripd/ripd.h"
31 #include "ripd/rip_debug.h"
32 #include "ripd/rip_interface.h"
34 /* All information about zebra. */
35 struct zclient
*zclient
= NULL
;
37 /* RIPd to zebra command interface. */
39 rip_zebra_ipv4_add (struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
40 u_int32_t metric
, u_char distance
)
44 if (zclient
->redist
[ZEBRA_ROUTE_RIP
])
46 api
.type
= ZEBRA_ROUTE_RIP
;
49 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
51 api
.nexthop
= &nexthop
;
53 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
56 if (distance
&& distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
)
58 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
59 api
.distance
= distance
;
62 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
, p
, &api
);
64 rip_global_route_changes
++;
69 rip_zebra_ipv4_delete (struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
74 if (zclient
->redist
[ZEBRA_ROUTE_RIP
])
76 api
.type
= ZEBRA_ROUTE_RIP
;
79 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
81 api
.nexthop
= &nexthop
;
83 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
86 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
, p
, &api
);
88 rip_global_route_changes
++;
92 /* Zebra route add and delete treatment. */
94 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
98 unsigned long ifindex
;
99 struct in_addr nexthop
;
100 struct prefix_ipv4 p
;
106 /* Type, flags, message. */
107 api
.type
= stream_getc (s
);
108 api
.flags
= stream_getc (s
);
109 api
.message
= stream_getc (s
);
112 memset (&p
, 0, sizeof (struct prefix_ipv4
));
114 p
.prefixlen
= stream_getc (s
);
115 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
117 /* Nexthop, ifindex, distance, metric. */
118 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
120 api
.nexthop_num
= stream_getc (s
);
121 nexthop
.s_addr
= stream_get_ipv4 (s
);
123 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
125 api
.ifindex_num
= stream_getc (s
);
126 ifindex
= stream_getl (s
);
128 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
129 api
.distance
= stream_getc (s
);
132 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
133 api
.metric
= stream_getl (s
);
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
);
142 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
148 rip_zclient_reset (void)
150 zclient_reset (zclient
);
153 /* RIP route-map set for redistribution */
155 rip_routemap_set (int type
, const char *name
)
157 if (rip
->route_map
[type
].name
)
158 free(rip
->route_map
[type
].name
);
160 rip
->route_map
[type
].name
= strdup (name
);
161 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
165 rip_redistribute_metric_set (int type
, unsigned int metric
)
167 rip
->route_map
[type
].metric_config
= 1;
168 rip
->route_map
[type
].metric
= metric
;
172 rip_metric_unset (int type
, unsigned int metric
)
174 #define DONT_CARE_METRIC_RIP 17
175 if (metric
!= DONT_CARE_METRIC_RIP
&&
176 rip
->route_map
[type
].metric
!= metric
)
178 rip
->route_map
[type
].metric_config
= 0;
179 rip
->route_map
[type
].metric
= 0;
183 /* RIP route-map unset for redistribution */
185 rip_routemap_unset (int type
, const char *name
)
187 if (! rip
->route_map
[type
].name
||
188 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
191 free (rip
->route_map
[type
].name
);
192 rip
->route_map
[type
].name
= NULL
;
193 rip
->route_map
[type
].map
= NULL
;
198 /* Redistribution types */
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"},
215 "Enable a routing process\n"
216 "Make connection to zebra daemon\n")
218 vty
->node
= ZEBRA_NODE
;
220 zclient_start (zclient
);
224 DEFUN (no_router_zebra
,
228 "Enable a routing process\n"
229 "Make connection to zebra daemon\n")
232 zclient_stop (zclient
);
237 rip_redistribute_set (int type
)
239 if (zclient
->redist
[type
])
242 zclient
->redist
[type
] = 1;
244 if (zclient
->sock
> 0)
245 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
251 rip_redistribute_unset (int type
)
253 if (! zclient
->redist
[type
])
256 zclient
->redist
[type
] = 0;
258 if (zclient
->sock
> 0)
259 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
261 /* Remove the routes from RIP table. */
262 rip_redistribute_withdraw (type
);
268 rip_redistribute_check (int type
)
270 return (zclient
->redist
[type
]);
274 rip_redistribute_clean (void)
278 for (i
= 0; redist_type
[i
].str
; i
++)
280 if (zclient
->redist
[redist_type
[i
].type
])
282 if (zclient
->sock
> 0)
283 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
284 zclient
, redist_type
[i
].type
);
286 zclient
->redist
[redist_type
[i
].type
] = 0;
288 /* Remove the routes from RIP table. */
289 rip_redistribute_withdraw (redist_type
[i
].type
);
294 DEFUN (rip_redistribute_rip
,
295 rip_redistribute_rip_cmd
,
297 "Redistribute information from another routing protocol\n"
298 "Routing Information Protocol (RIP)\n")
300 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 1;
304 DEFUN (no_rip_redistribute_rip
,
305 no_rip_redistribute_rip_cmd
,
306 "no redistribute rip",
308 "Redistribute information from another routing protocol\n"
309 "Routing Information Protocol (RIP)\n")
311 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 0;
315 DEFUN (rip_redistribute_type
,
316 rip_redistribute_type_cmd
,
317 "redistribute " QUAGGA_REDIST_STR_RIPD
,
319 QUAGGA_REDIST_HELP_STR_RIPD
)
323 for(i
= 0; redist_type
[i
].str
; i
++)
325 if (strncmp (redist_type
[i
].str
, argv
[0],
326 redist_type
[i
].str_min_len
) == 0)
328 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
329 redist_type
[i
].type
);
334 vty_out(vty
, "Invalid type %s%s", argv
[0],
340 DEFUN (no_rip_redistribute_type
,
341 no_rip_redistribute_type_cmd
,
342 "no redistribute " QUAGGA_REDIST_STR_RIPD
,
345 QUAGGA_REDIST_HELP_STR_RIPD
)
349 for (i
= 0; redist_type
[i
].str
; i
++)
351 if (strncmp(redist_type
[i
].str
, argv
[0],
352 redist_type
[i
].str_min_len
) == 0)
354 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
355 rip_routemap_unset (redist_type
[i
].type
,NULL
);
356 rip_redistribute_unset (redist_type
[i
].type
);
361 vty_out(vty
, "Invalid type %s%s", argv
[0],
367 DEFUN (rip_redistribute_type_routemap
,
368 rip_redistribute_type_routemap_cmd
,
369 "redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
371 QUAGGA_REDIST_HELP_STR_RIPD
372 "Route map reference\n"
373 "Pointer to route-map entries\n")
377 for (i
= 0; redist_type
[i
].str
; i
++) {
378 if (strncmp(redist_type
[i
].str
, argv
[0],
379 redist_type
[i
].str_min_len
) == 0)
381 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
382 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
387 vty_out(vty
, "Invalid type %s%s", argv
[0],
393 DEFUN (no_rip_redistribute_type_routemap
,
394 no_rip_redistribute_type_routemap_cmd
,
395 "no redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
398 QUAGGA_REDIST_HELP_STR_RIPD
399 "Route map reference\n"
400 "Pointer to route-map entries\n")
404 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)
409 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
411 rip_redistribute_unset (redist_type
[i
].type
);
416 vty_out(vty
, "Invalid type %s%s", argv
[0],
422 DEFUN (rip_redistribute_type_metric
,
423 rip_redistribute_type_metric_cmd
,
424 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
426 QUAGGA_REDIST_HELP_STR_RIPD
433 metric
= atoi (argv
[1]);
435 for (i
= 0; redist_type
[i
].str
; i
++) {
436 if (strncmp(redist_type
[i
].str
, argv
[0],
437 redist_type
[i
].str_min_len
) == 0)
439 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
440 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
445 vty_out(vty
, "Invalid type %s%s", argv
[0],
451 DEFUN (no_rip_redistribute_type_metric
,
452 no_rip_redistribute_type_metric_cmd
,
453 "no redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
456 QUAGGA_REDIST_HELP_STR_RIPD
462 for (i
= 0; redist_type
[i
].str
; i
++)
464 if (strncmp(redist_type
[i
].str
, argv
[0],
465 redist_type
[i
].str_min_len
) == 0)
467 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
469 rip_redistribute_unset (redist_type
[i
].type
);
474 vty_out(vty
, "Invalid type %s%s", argv
[0],
480 DEFUN (rip_redistribute_type_metric_routemap
,
481 rip_redistribute_type_metric_routemap_cmd
,
482 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16> route-map WORD",
484 QUAGGA_REDIST_HELP_STR_RIPD
487 "Route map reference\n"
488 "Pointer to route-map entries\n")
493 metric
= atoi (argv
[1]);
495 for (i
= 0; redist_type
[i
].str
; i
++) {
496 if (strncmp(redist_type
[i
].str
, argv
[0],
497 redist_type
[i
].str_min_len
) == 0)
499 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
500 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
501 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
506 vty_out(vty
, "Invalid type %s%s", argv
[0],
513 DEFUN (no_rip_redistribute_type_metric_routemap
,
514 no_rip_redistribute_type_metric_routemap_cmd
,
515 "no redistribute " QUAGGA_REDIST_STR_RIPD
516 " metric <0-16> route-map WORD",
519 QUAGGA_REDIST_HELP_STR_RIPD
522 "Route map reference\n"
523 "Pointer to route-map entries\n")
527 for (i
= 0; redist_type
[i
].str
; i
++)
529 if (strncmp(redist_type
[i
].str
, argv
[0],
530 redist_type
[i
].str_min_len
) == 0)
532 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
534 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
536 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
539 rip_redistribute_unset (redist_type
[i
].type
);
544 vty_out(vty
, "Invalid type %s%s", argv
[0],
550 /* Default information originate. */
552 DEFUN (rip_default_information_originate
,
553 rip_default_information_originate_cmd
,
554 "default-information originate",
555 "Control distribution of default route\n"
556 "Distribute a default route\n")
558 struct prefix_ipv4 p
;
560 if (! rip
->default_information
)
562 memset (&p
, 0, sizeof (struct prefix_ipv4
));
565 rip
->default_information
= 1;
567 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
574 DEFUN (no_rip_default_information_originate
,
575 no_rip_default_information_originate_cmd
,
576 "no default-information originate",
578 "Control distribution of default route\n"
579 "Distribute a default route\n")
581 struct prefix_ipv4 p
;
583 if (rip
->default_information
)
585 memset (&p
, 0, sizeof (struct prefix_ipv4
));
588 rip
->default_information
= 0;
590 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
596 /* RIP configuration write function. */
598 config_write_zebra (struct vty
*vty
)
600 if (! zclient
->enable
)
602 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
605 else if (! zclient
->redist
[ZEBRA_ROUTE_RIP
])
607 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
608 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
615 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
619 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
620 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
624 if (rip
->route_map
[i
].metric_config
)
626 if (rip
->route_map
[i
].name
)
627 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
628 zebra_route_string(i
), rip
->route_map
[i
].metric
,
629 rip
->route_map
[i
].name
,
632 vty_out (vty
, " redistribute %s metric %d%s",
633 zebra_route_string(i
), rip
->route_map
[i
].metric
,
638 if (rip
->route_map
[i
].name
)
639 vty_out (vty
, " redistribute %s route-map %s%s",
640 zebra_route_string(i
), rip
->route_map
[i
].name
,
643 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
648 vty_out (vty
, " %s", zebra_route_string(i
));
653 /* Zebra node structure. */
654 static struct cmd_node zebra_node
=
657 "%s(config-router)# ",
663 /* Set default value to the zebra client structure. */
664 zclient
= zclient_new ();
665 zclient_init (zclient
, ZEBRA_ROUTE_RIP
);
666 zclient
->interface_add
= rip_interface_add
;
667 zclient
->interface_delete
= rip_interface_delete
;
668 zclient
->interface_address_add
= rip_interface_address_add
;
669 zclient
->interface_address_delete
= rip_interface_address_delete
;
670 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
671 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
672 zclient
->interface_up
= rip_interface_up
;
673 zclient
->interface_down
= rip_interface_down
;
675 /* Install zebra node. */
676 install_node (&zebra_node
, config_write_zebra
);
678 /* Install command elements to zebra node. */
679 install_element (CONFIG_NODE
, &router_zebra_cmd
);
680 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
681 install_default (ZEBRA_NODE
);
682 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
683 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
685 /* Install command elements to rip node. */
686 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
687 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
688 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
689 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
690 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
691 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
692 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
693 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
694 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
695 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);