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 api
.safi
= SAFI_UNICAST
;
50 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
52 api
.nexthop
= &nexthop
;
54 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
57 if (distance
&& distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
)
59 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
60 api
.distance
= distance
;
63 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
, p
, &api
);
65 rip_global_route_changes
++;
70 rip_zebra_ipv4_delete (struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
75 if (zclient
->redist
[ZEBRA_ROUTE_RIP
])
77 api
.type
= ZEBRA_ROUTE_RIP
;
80 api
.safi
= SAFI_UNICAST
;
81 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
83 api
.nexthop
= &nexthop
;
85 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
88 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
, p
, &api
);
90 rip_global_route_changes
++;
94 /* Zebra route add and delete treatment. */
96 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
100 unsigned long ifindex
;
101 struct in_addr nexthop
;
102 struct prefix_ipv4 p
;
108 /* Type, flags, message. */
109 api
.type
= stream_getc (s
);
110 api
.flags
= stream_getc (s
);
111 api
.message
= stream_getc (s
);
114 memset (&p
, 0, sizeof (struct prefix_ipv4
));
116 p
.prefixlen
= stream_getc (s
);
117 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
119 /* Nexthop, ifindex, distance, metric. */
120 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
122 api
.nexthop_num
= stream_getc (s
);
123 nexthop
.s_addr
= stream_get_ipv4 (s
);
125 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
127 api
.ifindex_num
= stream_getc (s
);
128 ifindex
= stream_getl (s
);
130 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
131 api
.distance
= stream_getc (s
);
134 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
135 api
.metric
= stream_getl (s
);
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
);
144 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
150 rip_zclient_reset (void)
152 zclient_reset (zclient
);
155 /* RIP route-map set for redistribution */
157 rip_routemap_set (int type
, const char *name
)
159 if (rip
->route_map
[type
].name
)
160 free(rip
->route_map
[type
].name
);
162 rip
->route_map
[type
].name
= strdup (name
);
163 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
167 rip_redistribute_metric_set (int type
, unsigned int metric
)
169 rip
->route_map
[type
].metric_config
= 1;
170 rip
->route_map
[type
].metric
= metric
;
174 rip_metric_unset (int type
, unsigned int metric
)
176 #define DONT_CARE_METRIC_RIP 17
177 if (metric
!= DONT_CARE_METRIC_RIP
&&
178 rip
->route_map
[type
].metric
!= metric
)
180 rip
->route_map
[type
].metric_config
= 0;
181 rip
->route_map
[type
].metric
= 0;
185 /* RIP route-map unset for redistribution */
187 rip_routemap_unset (int type
, const char *name
)
189 if (! rip
->route_map
[type
].name
||
190 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
193 free (rip
->route_map
[type
].name
);
194 rip
->route_map
[type
].name
= NULL
;
195 rip
->route_map
[type
].map
= NULL
;
200 /* Redistribution types */
206 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
207 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
208 {ZEBRA_ROUTE_STATIC
, 1, "static"},
209 {ZEBRA_ROUTE_OSPF
, 1, "ospf"},
210 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
211 {ZEBRA_ROUTE_BABEL
, 2, "babel"},
218 "Enable a routing process\n"
219 "Make connection to zebra daemon\n")
221 vty
->node
= ZEBRA_NODE
;
223 zclient_start (zclient
);
227 DEFUN (no_router_zebra
,
231 "Enable a routing process\n"
232 "Make connection to zebra daemon\n")
235 zclient_stop (zclient
);
241 rip_redistribute_set (int type
)
243 if (zclient
->redist
[type
])
246 zclient
->redist
[type
] = 1;
248 if (zclient
->sock
> 0)
249 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
256 rip_redistribute_unset (int type
)
258 if (! zclient
->redist
[type
])
261 zclient
->redist
[type
] = 0;
263 if (zclient
->sock
> 0)
264 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
266 /* Remove the routes from RIP table. */
267 rip_redistribute_withdraw (type
);
273 rip_redistribute_check (int type
)
275 return (zclient
->redist
[type
]);
279 rip_redistribute_clean (void)
283 for (i
= 0; redist_type
[i
].str
; i
++)
285 if (zclient
->redist
[redist_type
[i
].type
])
287 if (zclient
->sock
> 0)
288 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
289 zclient
, redist_type
[i
].type
);
291 zclient
->redist
[redist_type
[i
].type
] = 0;
293 /* Remove the routes from RIP table. */
294 rip_redistribute_withdraw (redist_type
[i
].type
);
299 DEFUN (rip_redistribute_rip
,
300 rip_redistribute_rip_cmd
,
302 "Redistribute information from another routing protocol\n"
303 "Routing Information Protocol (RIP)\n")
305 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 1;
309 DEFUN (no_rip_redistribute_rip
,
310 no_rip_redistribute_rip_cmd
,
311 "no redistribute rip",
313 "Redistribute information from another routing protocol\n"
314 "Routing Information Protocol (RIP)\n")
316 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 0;
320 DEFUN (rip_redistribute_type
,
321 rip_redistribute_type_cmd
,
322 "redistribute " QUAGGA_REDIST_STR_RIPD
,
324 QUAGGA_REDIST_HELP_STR_RIPD
)
328 for(i
= 0; redist_type
[i
].str
; i
++)
330 if (strncmp (redist_type
[i
].str
, argv
[0],
331 redist_type
[i
].str_min_len
) == 0)
333 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
334 redist_type
[i
].type
);
339 vty_out(vty
, "Invalid type %s%s", argv
[0],
345 DEFUN (no_rip_redistribute_type
,
346 no_rip_redistribute_type_cmd
,
347 "no redistribute " QUAGGA_REDIST_STR_RIPD
,
350 QUAGGA_REDIST_HELP_STR_RIPD
)
354 for (i
= 0; redist_type
[i
].str
; i
++)
356 if (strncmp(redist_type
[i
].str
, argv
[0],
357 redist_type
[i
].str_min_len
) == 0)
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
);
366 vty_out(vty
, "Invalid type %s%s", argv
[0],
372 DEFUN (rip_redistribute_type_routemap
,
373 rip_redistribute_type_routemap_cmd
,
374 "redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
376 QUAGGA_REDIST_HELP_STR_RIPD
377 "Route map reference\n"
378 "Pointer to route-map entries\n")
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)
386 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
387 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
392 vty_out(vty
, "Invalid type %s%s", argv
[0],
398 DEFUN (no_rip_redistribute_type_routemap
,
399 no_rip_redistribute_type_routemap_cmd
,
400 "no redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
403 QUAGGA_REDIST_HELP_STR_RIPD
404 "Route map reference\n"
405 "Pointer to route-map entries\n")
409 for (i
= 0; redist_type
[i
].str
; i
++)
411 if (strncmp(redist_type
[i
].str
, argv
[0],
412 redist_type
[i
].str_min_len
) == 0)
414 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
416 rip_redistribute_unset (redist_type
[i
].type
);
421 vty_out(vty
, "Invalid type %s%s", argv
[0],
427 DEFUN (rip_redistribute_type_metric
,
428 rip_redistribute_type_metric_cmd
,
429 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
431 QUAGGA_REDIST_HELP_STR_RIPD
438 metric
= atoi (argv
[1]);
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)
444 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
445 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
450 vty_out(vty
, "Invalid type %s%s", argv
[0],
456 DEFUN (no_rip_redistribute_type_metric
,
457 no_rip_redistribute_type_metric_cmd
,
458 "no redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
461 QUAGGA_REDIST_HELP_STR_RIPD
467 for (i
= 0; redist_type
[i
].str
; i
++)
469 if (strncmp(redist_type
[i
].str
, argv
[0],
470 redist_type
[i
].str_min_len
) == 0)
472 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
474 rip_redistribute_unset (redist_type
[i
].type
);
479 vty_out(vty
, "Invalid type %s%s", argv
[0],
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",
489 QUAGGA_REDIST_HELP_STR_RIPD
492 "Route map reference\n"
493 "Pointer to route-map entries\n")
498 metric
= atoi (argv
[1]);
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)
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
);
511 vty_out(vty
, "Invalid type %s%s", argv
[0],
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",
524 QUAGGA_REDIST_HELP_STR_RIPD
527 "Route map reference\n"
528 "Pointer to route-map entries\n")
532 for (i
= 0; redist_type
[i
].str
; i
++)
534 if (strncmp(redist_type
[i
].str
, argv
[0],
535 redist_type
[i
].str_min_len
) == 0)
537 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
539 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
541 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
544 rip_redistribute_unset (redist_type
[i
].type
);
549 vty_out(vty
, "Invalid type %s%s", argv
[0],
555 /* Default information originate. */
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")
563 struct prefix_ipv4 p
;
565 if (! rip
->default_information
)
567 memset (&p
, 0, sizeof (struct prefix_ipv4
));
570 rip
->default_information
= 1;
572 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
579 DEFUN (no_rip_default_information_originate
,
580 no_rip_default_information_originate_cmd
,
581 "no default-information originate",
583 "Control distribution of default route\n"
584 "Distribute a default route\n")
586 struct prefix_ipv4 p
;
588 if (rip
->default_information
)
590 memset (&p
, 0, sizeof (struct prefix_ipv4
));
593 rip
->default_information
= 0;
595 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
601 /* RIP configuration write function. */
603 config_write_zebra (struct vty
*vty
)
605 if (! zclient
->enable
)
607 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
610 else if (! zclient
->redist
[ZEBRA_ROUTE_RIP
])
612 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
613 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
620 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
624 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
625 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
629 if (rip
->route_map
[i
].metric_config
)
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
,
637 vty_out (vty
, " redistribute %s metric %d%s",
638 zebra_route_string(i
), rip
->route_map
[i
].metric
,
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
,
648 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
653 vty_out (vty
, " %s", zebra_route_string(i
));
658 /* Zebra node structure. */
659 static struct cmd_node zebra_node
=
662 "%s(config-router)# ",
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
;
680 /* Install zebra node. */
681 install_node (&zebra_node
, config_write_zebra
);
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
);
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
);