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
);
137 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
138 api
.metric
= stream_getl (s
);
140 /* Then fetch IPv4 prefixes. */
141 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
142 rip_redistribute_add (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
, &nexthop
);
144 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
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
, 1, "bgp"},
217 "Enable a routing process\n"
218 "Make connection to zebra daemon\n")
220 vty
->node
= ZEBRA_NODE
;
222 zclient_start (zclient
);
226 DEFUN (no_router_zebra
,
230 "Enable a routing process\n"
231 "Make connection to zebra daemon\n")
234 zclient_stop (zclient
);
239 rip_redistribute_set (int type
)
241 if (zclient
->redist
[type
])
244 zclient
->redist
[type
] = 1;
246 if (zclient
->sock
> 0)
247 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
->sock
, type
);
253 rip_redistribute_unset (int type
)
255 if (! zclient
->redist
[type
])
258 zclient
->redist
[type
] = 0;
260 if (zclient
->sock
> 0)
261 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
->sock
, type
);
263 /* Remove the routes from RIP table. */
264 rip_redistribute_withdraw (type
);
270 rip_redistribute_check (int type
)
272 return (zclient
->redist
[type
]);
276 rip_redistribute_clean ()
280 for (i
= 0; redist_type
[i
].str
; i
++)
282 if (zclient
->redist
[redist_type
[i
].type
])
284 if (zclient
->sock
> 0)
285 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
286 zclient
->sock
, redist_type
[i
].type
);
288 zclient
->redist
[redist_type
[i
].type
] = 0;
290 /* Remove the routes from RIP table. */
291 rip_redistribute_withdraw (redist_type
[i
].type
);
296 DEFUN (rip_redistribute_rip
,
297 rip_redistribute_rip_cmd
,
299 "Redistribute information from another routing protocol\n"
300 "Routing Information Protocol (RIP)\n")
302 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 1;
306 DEFUN (no_rip_redistribute_rip
,
307 no_rip_redistribute_rip_cmd
,
308 "no redistribute rip",
310 "Redistribute information from another routing protocol\n"
311 "Routing Information Protocol (RIP)\n")
313 zclient
->redist
[ZEBRA_ROUTE_RIP
] = 0;
317 DEFUN (rip_redistribute_type
,
318 rip_redistribute_type_cmd
,
319 "redistribute (kernel|connected|static|ospf|bgp)",
320 "Redistribute information from another routing protocol\n"
324 "Open Shortest Path First (OSPF)\n"
325 "Border Gateway Protocol (BGP)\n")
329 for(i
= 0; redist_type
[i
].str
; i
++)
331 if (strncmp (redist_type
[i
].str
, argv
[0],
332 redist_type
[i
].str_min_len
) == 0)
334 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
335 redist_type
[i
].type
);
340 vty_out(vty
, "Invalid type %s%s", argv
[0],
346 DEFUN (no_rip_redistribute_type
,
347 no_rip_redistribute_type_cmd
,
348 "no redistribute (kernel|connected|static|ospf|bgp)",
350 "Redistribute information from another routing protocol\n"
354 "Open Shortest Path First (OSPF)\n"
355 "Border Gateway Protocol (BGP)\n")
359 for (i
= 0; redist_type
[i
].str
; i
++)
361 if (strncmp(redist_type
[i
].str
, argv
[0],
362 redist_type
[i
].str_min_len
) == 0)
364 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
365 rip_routemap_unset (redist_type
[i
].type
,NULL
);
366 rip_redistribute_unset (redist_type
[i
].type
);
371 vty_out(vty
, "Invalid type %s%s", argv
[0],
377 DEFUN (rip_redistribute_type_routemap
,
378 rip_redistribute_type_routemap_cmd
,
379 "redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
380 "Redistribute information from another routing protocol\n"
384 "Open Shortest Path First (OSPF)\n"
385 "Border Gateway Protocol (BGP)\n"
386 "Route map reference\n"
387 "Pointer to route-map entries\n")
391 for (i
= 0; redist_type
[i
].str
; i
++) {
392 if (strncmp(redist_type
[i
].str
, argv
[0],
393 redist_type
[i
].str_min_len
) == 0)
395 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
396 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
401 vty_out(vty
, "Invalid type %s%s", argv
[0],
407 DEFUN (no_rip_redistribute_type_routemap
,
408 no_rip_redistribute_type_routemap_cmd
,
409 "no redistribute (kernel|connected|static|ospf|bgp) route-map WORD",
411 "Redistribute information from another routing protocol\n"
415 "Open Shortest Path First (OSPF)\n"
416 "Border Gateway Protocol (BGP)\n"
417 "Route map reference\n"
418 "Pointer to route-map entries\n")
422 for (i
= 0; redist_type
[i
].str
; i
++)
424 if (strncmp(redist_type
[i
].str
, argv
[0],
425 redist_type
[i
].str_min_len
) == 0)
427 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
429 rip_redistribute_unset (redist_type
[i
].type
);
434 vty_out(vty
, "Invalid type %s%s", argv
[0],
440 DEFUN (rip_redistribute_type_metric
,
441 rip_redistribute_type_metric_cmd
,
442 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
443 "Redistribute information from another routing protocol\n"
447 "Open Shortest Path First (OSPF)\n"
448 "Border Gateway Protocol (BGP)\n"
455 metric
= atoi (argv
[1]);
457 for (i
= 0; redist_type
[i
].str
; i
++) {
458 if (strncmp(redist_type
[i
].str
, argv
[0],
459 redist_type
[i
].str_min_len
) == 0)
461 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
462 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
467 vty_out(vty
, "Invalid type %s%s", argv
[0],
473 DEFUN (no_rip_redistribute_type_metric
,
474 no_rip_redistribute_type_metric_cmd
,
475 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16>",
477 "Redistribute information from another routing protocol\n"
481 "Open Shortest Path First (OSPF)\n"
482 "Border Gateway Protocol (BGP)\n"
488 for (i
= 0; redist_type
[i
].str
; i
++)
490 if (strncmp(redist_type
[i
].str
, argv
[0],
491 redist_type
[i
].str_min_len
) == 0)
493 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
495 rip_redistribute_unset (redist_type
[i
].type
);
500 vty_out(vty
, "Invalid type %s%s", argv
[0],
506 DEFUN (rip_redistribute_type_metric_routemap
,
507 rip_redistribute_type_metric_routemap_cmd
,
508 "redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
509 "Redistribute information from another routing protocol\n"
513 "Open Shortest Path First (OSPF)\n"
514 "Border Gateway Protocol (BGP)\n"
517 "Route map reference\n"
518 "Pointer to route-map entries\n")
523 metric
= atoi (argv
[1]);
525 for (i
= 0; redist_type
[i
].str
; i
++) {
526 if (strncmp(redist_type
[i
].str
, argv
[0],
527 redist_type
[i
].str_min_len
) == 0)
529 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
530 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
531 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, redist_type
[i
].type
);
536 vty_out(vty
, "Invalid type %s%s", argv
[0],
543 DEFUN (no_rip_redistribute_type_metric_routemap
,
544 no_rip_redistribute_type_metric_routemap_cmd
,
545 "no redistribute (kernel|connected|static|ospf|bgp) metric <0-16> route-map WORD",
547 "Redistribute information from another routing protocol\n"
551 "Open Shortest Path First (OSPF)\n"
552 "Border Gateway Protocol (BGP)\n"
555 "Route map reference\n"
556 "Pointer to route-map entries\n")
560 for (i
= 0; redist_type
[i
].str
; i
++)
562 if (strncmp(redist_type
[i
].str
, argv
[0],
563 redist_type
[i
].str_min_len
) == 0)
565 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
567 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
569 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
572 rip_redistribute_unset (redist_type
[i
].type
);
577 vty_out(vty
, "Invalid type %s%s", argv
[0],
583 /* Default information originate. */
585 DEFUN (rip_default_information_originate
,
586 rip_default_information_originate_cmd
,
587 "default-information originate",
588 "Control distribution of default route\n"
589 "Distribute a default route\n")
591 struct prefix_ipv4 p
;
593 if (! rip
->default_information
)
595 memset (&p
, 0, sizeof (struct prefix_ipv4
));
598 rip
->default_information
= 1;
600 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0, NULL
);
606 DEFUN (no_rip_default_information_originate
,
607 no_rip_default_information_originate_cmd
,
608 "no default-information originate",
610 "Control distribution of default route\n"
611 "Distribute a default route\n")
613 struct prefix_ipv4 p
;
615 if (rip
->default_information
)
617 memset (&p
, 0, sizeof (struct prefix_ipv4
));
620 rip
->default_information
= 0;
622 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
628 /* RIP configuration write function. */
630 config_write_zebra (struct vty
*vty
)
632 if (! zclient
->enable
)
634 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
637 else if (! zclient
->redist
[ZEBRA_ROUTE_RIP
])
639 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
640 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
647 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
650 const char *str
[] = { "system", "kernel", "connected", "static", "rip",
651 "ripng", "ospf", "ospf6", "isis", "bgp"};
653 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
654 if (i
!= zclient
->redist_default
&& zclient
->redist
[i
])
658 if (rip
->route_map
[i
].metric_config
)
660 if (rip
->route_map
[i
].name
)
661 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
662 str
[i
], rip
->route_map
[i
].metric
,
663 rip
->route_map
[i
].name
,
666 vty_out (vty
, " redistribute %s metric %d%s",
667 str
[i
], rip
->route_map
[i
].metric
,
672 if (rip
->route_map
[i
].name
)
673 vty_out (vty
, " redistribute %s route-map %s%s",
674 str
[i
], rip
->route_map
[i
].name
,
677 vty_out (vty
, " redistribute %s%s", str
[i
],
682 vty_out (vty
, " %s", str
[i
]);
687 /* Zebra node structure. */
688 struct cmd_node zebra_node
=
691 "%s(config-router)# ",
697 /* Set default value to the zebra client structure. */
698 zclient
= zclient_new ();
699 zclient_init (zclient
, ZEBRA_ROUTE_RIP
);
700 zclient
->interface_add
= rip_interface_add
;
701 zclient
->interface_delete
= rip_interface_delete
;
702 zclient
->interface_address_add
= rip_interface_address_add
;
703 zclient
->interface_address_delete
= rip_interface_address_delete
;
704 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
705 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
706 zclient
->interface_up
= rip_interface_up
;
707 zclient
->interface_down
= rip_interface_down
;
709 /* Install zebra node. */
710 install_node (&zebra_node
, config_write_zebra
);
712 /* Install command elements to zebra node. */
713 install_element (CONFIG_NODE
, &router_zebra_cmd
);
714 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
715 install_default (ZEBRA_NODE
);
716 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
717 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
719 /* Install command elements to rip node. */
720 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
721 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
722 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
723 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
724 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
725 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
726 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
727 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
728 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
729 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);