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 (kernel|connected|static|ospf|bgp)",
318 "Redistribute information from another routing protocol\n"
322 "Open Shortest Path First (OSPF)\n"
323 "Border Gateway Protocol (BGP)\n")
327 for(i
= 0; redist_type
[i
].str
; i
++)
329 if (strncmp (redist_type
[i
].str
, argv
[0],
330 redist_type
[i
].str_min_len
) == 0)
332 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
333 redist_type
[i
].type
);
338 vty_out(vty
, "Invalid type %s%s", argv
[0],
344 DEFUN (no_rip_redistribute_type
,
345 no_rip_redistribute_type_cmd
,
346 "no redistribute (kernel|connected|static|ospf|bgp)",
348 "Redistribute information from another routing protocol\n"
352 "Open Shortest Path First (OSPF)\n"
353 "Border Gateway Protocol (BGP)\n")
357 for (i
= 0; redist_type
[i
].str
; i
++)
359 if (strncmp(redist_type
[i
].str
, argv
[0],
360 redist_type
[i
].str_min_len
) == 0)
362 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
363 rip_routemap_unset (redist_type
[i
].type
,NULL
);
364 rip_redistribute_unset (redist_type
[i
].type
);
369 vty_out(vty
, "Invalid type %s%s", argv
[0],
375 DEFUN (rip_redistribute_type_routemap
,
376 rip_redistribute_type_routemap_cmd
,
377 "redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
378 "Redistribute information from another routing protocol\n"
382 "Open Shortest Path First (OSPF)\n"
383 "Border Gateway Protocol (BGP)\n"
384 "Route map reference\n"
385 "Pointer to route-map entries\n")
389 for (i
= 0; redist_type
[i
].str
; i
++) {
390 if (strncmp(redist_type
[i
].str
, argv
[0],
391 redist_type
[i
].str_min_len
) == 0)
393 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
394 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
399 vty_out(vty
, "Invalid type %s%s", argv
[0],
405 DEFUN (no_rip_redistribute_type_routemap
,
406 no_rip_redistribute_type_routemap_cmd
,
407 "no redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
409 "Redistribute information from another routing protocol\n"
413 "Open Shortest Path First (OSPF)\n"
414 "Border Gateway Protocol (BGP)\n"
415 "Route map reference\n"
416 "Pointer to route-map entries\n")
420 for (i
= 0; redist_type
[i
].str
; i
++)
422 if (strncmp(redist_type
[i
].str
, argv
[0],
423 redist_type
[i
].str_min_len
) == 0)
425 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
427 rip_redistribute_unset (redist_type
[i
].type
);
432 vty_out(vty
, "Invalid type %s%s", argv
[0],
438 DEFUN (rip_redistribute_type_metric
,
439 rip_redistribute_type_metric_cmd
,
440 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
441 "Redistribute information from another routing protocol\n"
445 "Open Shortest Path First (OSPF)\n"
446 "Border Gateway Protocol (BGP)\n"
453 metric
= atoi (argv
[1]);
455 for (i
= 0; redist_type
[i
].str
; i
++) {
456 if (strncmp(redist_type
[i
].str
, argv
[0],
457 redist_type
[i
].str_min_len
) == 0)
459 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
460 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
465 vty_out(vty
, "Invalid type %s%s", argv
[0],
471 DEFUN (no_rip_redistribute_type_metric
,
472 no_rip_redistribute_type_metric_cmd
,
473 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
475 "Redistribute information from another routing protocol\n"
479 "Open Shortest Path First (OSPF)\n"
480 "Border Gateway Protocol (BGP)\n"
486 for (i
= 0; redist_type
[i
].str
; i
++)
488 if (strncmp(redist_type
[i
].str
, argv
[0],
489 redist_type
[i
].str_min_len
) == 0)
491 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
493 rip_redistribute_unset (redist_type
[i
].type
);
498 vty_out(vty
, "Invalid type %s%s", argv
[0],
504 DEFUN (rip_redistribute_type_metric_routemap
,
505 rip_redistribute_type_metric_routemap_cmd
,
506 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
507 "Redistribute information from another routing protocol\n"
511 "Open Shortest Path First (OSPF)\n"
512 "Border Gateway Protocol (BGP)\n"
515 "Route map reference\n"
516 "Pointer to route-map entries\n")
521 metric
= atoi (argv
[1]);
523 for (i
= 0; redist_type
[i
].str
; i
++) {
524 if (strncmp(redist_type
[i
].str
, argv
[0],
525 redist_type
[i
].str_min_len
) == 0)
527 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
528 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
529 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
534 vty_out(vty
, "Invalid type %s%s", argv
[0],
541 DEFUN (no_rip_redistribute_type_metric_routemap
,
542 no_rip_redistribute_type_metric_routemap_cmd
,
543 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
545 "Redistribute information from another routing protocol\n"
549 "Open Shortest Path First (OSPF)\n"
550 "Border Gateway Protocol (BGP)\n"
553 "Route map reference\n"
554 "Pointer to route-map entries\n")
558 for (i
= 0; redist_type
[i
].str
; i
++)
560 if (strncmp(redist_type
[i
].str
, argv
[0],
561 redist_type
[i
].str_min_len
) == 0)
563 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
565 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
567 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
570 rip_redistribute_unset (redist_type
[i
].type
);
575 vty_out(vty
, "Invalid type %s%s", argv
[0],
581 /* Default information originate. */
583 DEFUN (rip_default_information_originate
,
584 rip_default_information_originate_cmd
,
585 "default-information originate",
586 "Control distribution of default route\n"
587 "Distribute a default route\n")
589 struct prefix_ipv4 p
;
591 if (! rip
->default_information
)
593 memset (&p
, 0, sizeof (struct prefix_ipv4
));
596 rip
->default_information
= 1;
598 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
605 DEFUN (no_rip_default_information_originate
,
606 no_rip_default_information_originate_cmd
,
607 "no default-information originate",
609 "Control distribution of default route\n"
610 "Distribute a default route\n")
612 struct prefix_ipv4 p
;
614 if (rip
->default_information
)
616 memset (&p
, 0, sizeof (struct prefix_ipv4
));
619 rip
->default_information
= 0;
621 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
627 /* RIP configuration write function. */
629 config_write_zebra (struct vty
*vty
)
631 if (! zclient
->enable
)
633 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
636 else if (! zclient
->redist
[ZEBRA_ROUTE_RIP
])
638 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
639 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
646 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
650 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
651 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
655 if (rip
->route_map
[i
].metric_config
)
657 if (rip
->route_map
[i
].name
)
658 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
659 zebra_route_string(i
), rip
->route_map
[i
].metric
,
660 rip
->route_map
[i
].name
,
663 vty_out (vty
, " redistribute %s metric %d%s",
664 zebra_route_string(i
), rip
->route_map
[i
].metric
,
669 if (rip
->route_map
[i
].name
)
670 vty_out (vty
, " redistribute %s route-map %s%s",
671 zebra_route_string(i
), rip
->route_map
[i
].name
,
674 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
679 vty_out (vty
, " %s", zebra_route_string(i
));
684 /* Zebra node structure. */
685 struct cmd_node zebra_node
=
688 "%s(config-router)# ",
694 /* Set default value to the zebra client structure. */
695 zclient
= zclient_new ();
696 zclient_init (zclient
, ZEBRA_ROUTE_RIP
);
697 zclient
->interface_add
= rip_interface_add
;
698 zclient
->interface_delete
= rip_interface_delete
;
699 zclient
->interface_address_add
= rip_interface_address_add
;
700 zclient
->interface_address_delete
= rip_interface_address_delete
;
701 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
702 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
703 zclient
->interface_up
= rip_interface_up
;
704 zclient
->interface_down
= rip_interface_down
;
706 /* Install zebra node. */
707 install_node (&zebra_node
, config_write_zebra
);
709 /* Install command elements to zebra node. */
710 install_element (CONFIG_NODE
, &router_zebra_cmd
);
711 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
712 install_default (ZEBRA_NODE
);
713 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
714 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
716 /* Install command elements to rip node. */
717 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
718 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
719 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
720 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
721 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
722 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
723 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
724 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
725 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
726 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);