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"
33 /* All information about zebra. */
34 struct zclient
*zclient
= NULL
;
36 /* Callback prototypes for zebra client service. */
37 int rip_interface_add (int, struct zclient
*, zebra_size_t
);
38 int rip_interface_delete (int, struct zclient
*, zebra_size_t
);
39 int rip_interface_address_add (int, struct zclient
*, zebra_size_t
);
40 int rip_interface_address_delete (int, struct zclient
*, zebra_size_t
);
41 int rip_interface_up (int, struct zclient
*, zebra_size_t
);
42 int rip_interface_down (int, struct zclient
*, zebra_size_t
);
44 /* RIPd to zebra command interface. */
46 rip_zebra_ipv4_add (struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
47 u_int32_t metric
, u_char distance
)
51 if (zclient
->redist
[ZEBRA_ROUTE_RIP
])
53 api
.type
= ZEBRA_ROUTE_RIP
;
56 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
58 api
.nexthop
= &nexthop
;
60 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
63 if (distance
&& distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
)
65 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
66 api
.distance
= distance
;
69 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
, p
, &api
);
71 rip_global_route_changes
++;
76 rip_zebra_ipv4_delete (struct prefix_ipv4
*p
, struct in_addr
*nexthop
,
81 if (zclient
->redist
[ZEBRA_ROUTE_RIP
])
83 api
.type
= ZEBRA_ROUTE_RIP
;
86 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
88 api
.nexthop
= &nexthop
;
90 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
93 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
, p
, &api
);
95 rip_global_route_changes
++;
99 /* Zebra route add and delete treatment. */
101 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
104 struct zapi_ipv4 api
;
105 unsigned long ifindex
;
106 struct in_addr nexthop
;
107 struct prefix_ipv4 p
;
113 /* Type, flags, message. */
114 api
.type
= stream_getc (s
);
115 api
.flags
= stream_getc (s
);
116 api
.message
= stream_getc (s
);
119 memset (&p
, 0, sizeof (struct prefix_ipv4
));
121 p
.prefixlen
= stream_getc (s
);
122 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
124 /* Nexthop, ifindex, distance, metric. */
125 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
127 api
.nexthop_num
= stream_getc (s
);
128 nexthop
.s_addr
= stream_get_ipv4 (s
);
130 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
132 api
.ifindex_num
= stream_getc (s
);
133 ifindex
= stream_getl (s
);
135 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
136 api
.distance
= stream_getc (s
);
139 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
140 api
.metric
= stream_getl (s
);
144 /* Then fetch IPv4 prefixes. */
145 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
146 rip_redistribute_add (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
,
147 &nexthop
, api
.metric
, api
.distance
);
149 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
157 zclient_reset (zclient
);
160 /* RIP route-map set for redistribution */
162 rip_routemap_set (int type
, const char *name
)
164 if (rip
->route_map
[type
].name
)
165 free(rip
->route_map
[type
].name
);
167 rip
->route_map
[type
].name
= strdup (name
);
168 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
172 rip_redistribute_metric_set (int type
, unsigned int metric
)
174 rip
->route_map
[type
].metric_config
= 1;
175 rip
->route_map
[type
].metric
= metric
;
179 rip_metric_unset (int type
, unsigned int metric
)
181 #define DONT_CARE_METRIC_RIP 17
182 if (metric
!= DONT_CARE_METRIC_RIP
&&
183 rip
->route_map
[type
].metric
!= metric
)
185 rip
->route_map
[type
].metric_config
= 0;
186 rip
->route_map
[type
].metric
= 0;
190 /* RIP route-map unset for redistribution */
192 rip_routemap_unset (int type
, const char *name
)
194 if (! rip
->route_map
[type
].name
||
195 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
198 free (rip
->route_map
[type
].name
);
199 rip
->route_map
[type
].name
= NULL
;
200 rip
->route_map
[type
].map
= NULL
;
205 /* Redistribution types */
211 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
212 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
213 {ZEBRA_ROUTE_STATIC
, 1, "static"},
214 {ZEBRA_ROUTE_OSPF
, 1, "ospf"},
215 {ZEBRA_ROUTE_BGP
, 1, "bgp"},
222 "Enable a routing process\n"
223 "Make connection to zebra daemon\n")
225 vty
->node
= ZEBRA_NODE
;
227 zclient_start (zclient
);
231 DEFUN (no_router_zebra
,
235 "Enable a routing process\n"
236 "Make connection to zebra daemon\n")
239 zclient_stop (zclient
);
244 rip_redistribute_set (int type
)
246 if (zclient
->redist
[type
])
249 zclient
->redist
[type
] = 1;
251 if (zclient
->sock
> 0)
252 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
258 rip_redistribute_unset (int type
)
260 if (! zclient
->redist
[type
])
263 zclient
->redist
[type
] = 0;
265 if (zclient
->sock
> 0)
266 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
268 /* Remove the routes from RIP table. */
269 rip_redistribute_withdraw (type
);
275 rip_redistribute_check (int type
)
277 return (zclient
->redist
[type
]);
281 rip_redistribute_clean ()
285 for (i
= 0; redist_type
[i
].str
; i
++)
287 if (zclient
->redist
[redist_type
[i
].type
])
289 if (zclient
->sock
> 0)
290 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
291 zclient
, redist_type
[i
].type
);
293 zclient
->redist
[redist_type
[i
].type
] = 0;
295 /* Remove the routes from RIP table. */
296 rip_redistribute_withdraw (redist_type
[i
].type
);
301 DEFUN (rip_redistribute_rip
,
302 rip_redistribute_rip_cmd
,
304 "Redistribute information from another routing protocol\n"
305 "Routing Information Protocol (RIP)\n")
307 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 1;
311 DEFUN (no_rip_redistribute_rip
,
312 no_rip_redistribute_rip_cmd
,
313 "no redistribute rip",
315 "Redistribute information from another routing protocol\n"
316 "Routing Information Protocol (RIP)\n")
318 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 0;
322 DEFUN (rip_redistribute_type
,
323 rip_redistribute_type_cmd
,
324 "redistribute (kernel|connected|static|ospf|bgp)",
325 "Redistribute information from another routing protocol\n"
329 "Open Shortest Path First (OSPF)\n"
330 "Border Gateway Protocol (BGP)\n")
334 for(i
= 0; redist_type
[i
].str
; i
++)
336 if (strncmp (redist_type
[i
].str
, argv
[0],
337 redist_type
[i
].str_min_len
) == 0)
339 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
340 redist_type
[i
].type
);
345 vty_out(vty
, "Invalid type %s%s", argv
[0],
351 DEFUN (no_rip_redistribute_type
,
352 no_rip_redistribute_type_cmd
,
353 "no redistribute (kernel|connected|static|ospf|bgp)",
355 "Redistribute information from another routing protocol\n"
359 "Open Shortest Path First (OSPF)\n"
360 "Border Gateway Protocol (BGP)\n")
364 for (i
= 0; redist_type
[i
].str
; i
++)
366 if (strncmp(redist_type
[i
].str
, argv
[0],
367 redist_type
[i
].str_min_len
) == 0)
369 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
370 rip_routemap_unset (redist_type
[i
].type
,NULL
);
371 rip_redistribute_unset (redist_type
[i
].type
);
376 vty_out(vty
, "Invalid type %s%s", argv
[0],
382 DEFUN (rip_redistribute_type_routemap
,
383 rip_redistribute_type_routemap_cmd
,
384 "redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
385 "Redistribute information from another routing protocol\n"
389 "Open Shortest Path First (OSPF)\n"
390 "Border Gateway Protocol (BGP)\n"
391 "Route map reference\n"
392 "Pointer to route-map entries\n")
396 for (i
= 0; redist_type
[i
].str
; i
++) {
397 if (strncmp(redist_type
[i
].str
, argv
[0],
398 redist_type
[i
].str_min_len
) == 0)
400 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
401 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
406 vty_out(vty
, "Invalid type %s%s", argv
[0],
412 DEFUN (no_rip_redistribute_type_routemap
,
413 no_rip_redistribute_type_routemap_cmd
,
414 "no redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
416 "Redistribute information from another routing protocol\n"
420 "Open Shortest Path First (OSPF)\n"
421 "Border Gateway Protocol (BGP)\n"
422 "Route map reference\n"
423 "Pointer to route-map entries\n")
427 for (i
= 0; redist_type
[i
].str
; i
++)
429 if (strncmp(redist_type
[i
].str
, argv
[0],
430 redist_type
[i
].str_min_len
) == 0)
432 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
434 rip_redistribute_unset (redist_type
[i
].type
);
439 vty_out(vty
, "Invalid type %s%s", argv
[0],
445 DEFUN (rip_redistribute_type_metric
,
446 rip_redistribute_type_metric_cmd
,
447 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
448 "Redistribute information from another routing protocol\n"
452 "Open Shortest Path First (OSPF)\n"
453 "Border Gateway Protocol (BGP)\n"
460 metric
= atoi (argv
[1]);
462 for (i
= 0; redist_type
[i
].str
; i
++) {
463 if (strncmp(redist_type
[i
].str
, argv
[0],
464 redist_type
[i
].str_min_len
) == 0)
466 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
467 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
472 vty_out(vty
, "Invalid type %s%s", argv
[0],
478 DEFUN (no_rip_redistribute_type_metric
,
479 no_rip_redistribute_type_metric_cmd
,
480 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
482 "Redistribute information from another routing protocol\n"
486 "Open Shortest Path First (OSPF)\n"
487 "Border Gateway Protocol (BGP)\n"
493 for (i
= 0; redist_type
[i
].str
; i
++)
495 if (strncmp(redist_type
[i
].str
, argv
[0],
496 redist_type
[i
].str_min_len
) == 0)
498 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
500 rip_redistribute_unset (redist_type
[i
].type
);
505 vty_out(vty
, "Invalid type %s%s", argv
[0],
511 DEFUN (rip_redistribute_type_metric_routemap
,
512 rip_redistribute_type_metric_routemap_cmd
,
513 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
514 "Redistribute information from another routing protocol\n"
518 "Open Shortest Path First (OSPF)\n"
519 "Border Gateway Protocol (BGP)\n"
522 "Route map reference\n"
523 "Pointer to route-map entries\n")
528 metric
= atoi (argv
[1]);
530 for (i
= 0; redist_type
[i
].str
; i
++) {
531 if (strncmp(redist_type
[i
].str
, argv
[0],
532 redist_type
[i
].str_min_len
) == 0)
534 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
535 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
536 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
541 vty_out(vty
, "Invalid type %s%s", argv
[0],
548 DEFUN (no_rip_redistribute_type_metric_routemap
,
549 no_rip_redistribute_type_metric_routemap_cmd
,
550 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
552 "Redistribute information from another routing protocol\n"
556 "Open Shortest Path First (OSPF)\n"
557 "Border Gateway Protocol (BGP)\n"
560 "Route map reference\n"
561 "Pointer to route-map entries\n")
565 for (i
= 0; redist_type
[i
].str
; i
++)
567 if (strncmp(redist_type
[i
].str
, argv
[0],
568 redist_type
[i
].str_min_len
) == 0)
570 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
572 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
574 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
577 rip_redistribute_unset (redist_type
[i
].type
);
582 vty_out(vty
, "Invalid type %s%s", argv
[0],
588 /* Default information originate. */
590 DEFUN (rip_default_information_originate
,
591 rip_default_information_originate_cmd
,
592 "default-information originate",
593 "Control distribution of default route\n"
594 "Distribute a default route\n")
596 struct prefix_ipv4 p
;
598 if (! rip
->default_information
)
600 memset (&p
, 0, sizeof (struct prefix_ipv4
));
603 rip
->default_information
= 1;
605 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
612 DEFUN (no_rip_default_information_originate
,
613 no_rip_default_information_originate_cmd
,
614 "no default-information originate",
616 "Control distribution of default route\n"
617 "Distribute a default route\n")
619 struct prefix_ipv4 p
;
621 if (rip
->default_information
)
623 memset (&p
, 0, sizeof (struct prefix_ipv4
));
626 rip
->default_information
= 0;
628 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
634 /* RIP configuration write function. */
636 config_write_zebra (struct vty
*vty
)
638 if (! zclient
->enable
)
640 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
643 else if (! zclient
->redist
[ZEBRA_ROUTE_RIP
])
645 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
646 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
653 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
656 const char *str
[] = { "system", "kernel", "connected", "static", "rip",
657 "ripng", "ospf", "ospf6", "isis", "bgp"};
659 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
660 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
664 if (rip
->route_map
[i
].metric_config
)
666 if (rip
->route_map
[i
].name
)
667 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
668 str
[i
], rip
->route_map
[i
].metric
,
669 rip
->route_map
[i
].name
,
672 vty_out (vty
, " redistribute %s metric %d%s",
673 str
[i
], rip
->route_map
[i
].metric
,
678 if (rip
->route_map
[i
].name
)
679 vty_out (vty
, " redistribute %s route-map %s%s",
680 str
[i
], rip
->route_map
[i
].name
,
683 vty_out (vty
, " redistribute %s%s", str
[i
],
688 vty_out (vty
, " %s", str
[i
]);
693 /* Zebra node structure. */
694 struct cmd_node zebra_node
=
697 "%s(config-router)# ",
703 /* Set default value to the zebra client structure. */
704 zclient
= zclient_new ();
705 zclient_init (zclient
, ZEBRA_ROUTE_RIP
);
706 zclient
->interface_add
= rip_interface_add
;
707 zclient
->interface_delete
= rip_interface_delete
;
708 zclient
->interface_address_add
= rip_interface_address_add
;
709 zclient
->interface_address_delete
= rip_interface_address_delete
;
710 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
711 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
712 zclient
->interface_up
= rip_interface_up
;
713 zclient
->interface_down
= rip_interface_down
;
715 /* Install zebra node. */
716 install_node (&zebra_node
, config_write_zebra
);
718 /* Install command elements to zebra node. */
719 install_element (CONFIG_NODE
, &router_zebra_cmd
);
720 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
721 install_default (ZEBRA_NODE
);
722 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
723 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
725 /* Install command elements to rip node. */
726 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
727 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
728 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
729 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
730 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
731 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
732 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
733 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
734 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
735 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);