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
33 #include "ripd/ripd.h"
34 #include "ripd/rip_debug.h"
35 #include "ripd/rip_interface.h"
37 /* All information about zebra. */
38 struct zclient
*zclient
= NULL
;
40 /* Send ECMP routes to zebra. */
42 rip_zebra_ipv4_send (struct route_node
*rp
, u_char cmd
)
44 static struct in_addr
**nexthops
= NULL
;
45 static unsigned int nexthops_len
= 0;
47 struct list
*list
= (struct list
*)rp
->info
;
49 struct listnode
*listnode
= NULL
;
50 struct rip_info
*rinfo
= NULL
;
53 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
55 api
.vrf_id
= VRF_DEFAULT
;
56 api
.type
= ZEBRA_ROUTE_RIP
;
60 api
.safi
= SAFI_UNICAST
;
62 if (nexthops_len
< listcount (list
))
64 nexthops_len
= listcount (list
);
65 nexthops
= XREALLOC (MTYPE_TMP
, nexthops
,
66 nexthops_len
* sizeof (struct in_addr
*));
69 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
70 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
72 nexthops
[count
++] = &rinfo
->nexthop
;
73 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
)
74 SET_FLAG (rinfo
->flags
, RIP_RTF_FIB
);
76 UNSET_FLAG (rinfo
->flags
, RIP_RTF_FIB
);
79 api
.nexthop
= nexthops
;
80 api
.nexthop_num
= count
;
83 rinfo
= listgetdata (listhead (list
));
85 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
86 api
.metric
= rinfo
->metric
;
88 if (rinfo
->distance
&& rinfo
->distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
)
90 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
91 api
.distance
= rinfo
->distance
;
94 zapi_ipv4_route (cmd
, zclient
,
95 (struct prefix_ipv4
*)&rp
->p
, &api
);
97 if (IS_RIP_DEBUG_ZEBRA
)
100 zlog_debug ("%s: %s/%d nexthops %d",
101 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
102 "Install into zebra" : "Delete from zebra",
103 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
, count
);
105 zlog_debug ("%s: %s/%d",
106 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
107 "Install into zebra" : "Delete from zebra",
108 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
111 rip_global_route_changes
++;
115 /* Add/update ECMP routes to zebra. */
117 rip_zebra_ipv4_add (struct route_node
*rp
)
119 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_ADD
);
122 /* Delete ECMP routes from zebra. */
124 rip_zebra_ipv4_delete (struct route_node
*rp
)
126 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_DELETE
);
129 /* Zebra route add and delete treatment. */
131 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
,
135 struct zapi_ipv4 api
;
136 unsigned long ifindex
;
137 struct in_addr nexthop
;
138 struct prefix_ipv4 p
;
147 /* Type, flags, message. */
148 api
.type
= stream_getc (s
);
149 api
.instance
= stream_getw (s
);
150 api
.flags
= stream_getc (s
);
151 api
.message
= stream_getc (s
);
154 memset (&p
, 0, sizeof (struct prefix_ipv4
));
156 p
.prefixlen
= stream_getc (s
);
157 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
159 /* Nexthop, ifindex, distance, metric. */
160 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
162 api
.nexthop_num
= stream_getc (s
);
163 nexthop
.s_addr
= stream_get_ipv4 (s
);
165 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
167 api
.ifindex_num
= stream_getc (s
);
168 ifindex
= stream_getl (s
);
170 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
171 api
.distance
= stream_getc (s
);
174 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
175 api
.metric
= stream_getl (s
);
179 /* Then fetch IPv4 prefixes. */
180 if (command
== ZEBRA_REDISTRIBUTE_IPV4_ADD
)
181 rip_redistribute_add (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
,
182 &nexthop
, api
.metric
, api
.distance
);
183 else if (command
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
184 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
190 rip_zclient_reset (void)
192 zclient_reset (zclient
);
195 /* RIP route-map set for redistribution */
197 rip_routemap_set (int type
, const char *name
)
199 if (rip
->route_map
[type
].name
)
200 free(rip
->route_map
[type
].name
);
202 rip
->route_map
[type
].name
= strdup (name
);
203 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
207 rip_redistribute_metric_set (int type
, unsigned int metric
)
209 rip
->route_map
[type
].metric_config
= 1;
210 rip
->route_map
[type
].metric
= metric
;
214 rip_metric_unset (int type
, unsigned int metric
)
216 #define DONT_CARE_METRIC_RIP 17
217 if (metric
!= DONT_CARE_METRIC_RIP
&&
218 rip
->route_map
[type
].metric
!= metric
)
220 rip
->route_map
[type
].metric_config
= 0;
221 rip
->route_map
[type
].metric
= 0;
225 /* RIP route-map unset for redistribution */
227 rip_routemap_unset (int type
, const char *name
)
229 if (! rip
->route_map
[type
].name
||
230 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
233 free (rip
->route_map
[type
].name
);
234 rip
->route_map
[type
].name
= NULL
;
235 rip
->route_map
[type
].map
= NULL
;
240 /* Redistribution types */
246 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
247 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
248 {ZEBRA_ROUTE_STATIC
, 1, "static"},
249 {ZEBRA_ROUTE_OSPF
, 1, "ospf"},
250 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
257 "Enable a routing process\n"
258 "Make connection to zebra daemon\n")
260 vty
->node
= ZEBRA_NODE
;
262 zclient_start (zclient
);
266 DEFUN (no_router_zebra
,
270 "Enable a routing process\n"
271 "Make connection to zebra daemon\n")
274 zclient_stop (zclient
);
280 rip_redistribute_set (int type
)
282 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
))
285 vrf_bitmap_set (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
287 if (zclient
->sock
> 0)
288 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, API_IP
, type
);
295 rip_redistribute_unset (int type
)
297 if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
))
300 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
302 if (zclient
->sock
> 0)
303 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
305 /* Remove the routes from RIP table. */
306 rip_redistribute_withdraw (type
);
312 rip_redistribute_check (int type
)
314 return vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
318 rip_redistribute_clean (void)
322 for (i
= 0; redist_type
[i
].str
; i
++)
324 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
))
326 if (zclient
->sock
> 0)
327 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
328 zclient
, AFI_IP
, redist_type
[i
].type
, 0,
331 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
);
333 /* Remove the routes from RIP table. */
334 rip_redistribute_withdraw (redist_type
[i
].type
);
339 DEFUN (rip_redistribute_rip
,
340 rip_redistribute_rip_cmd
,
342 "Redistribute information from another routing protocol\n"
343 "Routing Information Protocol (RIP)\n")
345 vrf_bitmap_set (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
349 DEFUN (no_rip_redistribute_rip
,
350 no_rip_redistribute_rip_cmd
,
351 "no redistribute rip",
353 "Redistribute information from another routing protocol\n"
354 "Routing Information Protocol (RIP)\n")
356 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
360 DEFUN (rip_redistribute_type
,
361 rip_redistribute_type_cmd
,
362 "redistribute " QUAGGA_REDIST_STR_RIPD
,
364 QUAGGA_REDIST_HELP_STR_RIPD
)
368 for(i
= 0; redist_type
[i
].str
; i
++)
370 if (strncmp (redist_type
[i
].str
, argv
[0],
371 redist_type
[i
].str_min_len
) == 0)
373 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
374 AFI_IP
, redist_type
[i
].type
, 0, VRF_DEFAULT
);
379 vty_out(vty
, "Invalid type %s%s", argv
[0],
385 DEFUN (no_rip_redistribute_type
,
386 no_rip_redistribute_type_cmd
,
387 "no redistribute " QUAGGA_REDIST_STR_RIPD
,
390 QUAGGA_REDIST_HELP_STR_RIPD
)
394 for (i
= 0; redist_type
[i
].str
; i
++)
396 if (strncmp(redist_type
[i
].str
, argv
[0],
397 redist_type
[i
].str_min_len
) == 0)
399 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
400 rip_routemap_unset (redist_type
[i
].type
,NULL
);
401 rip_redistribute_unset (redist_type
[i
].type
);
406 vty_out(vty
, "Invalid type %s%s", argv
[0],
412 DEFUN (rip_redistribute_type_routemap
,
413 rip_redistribute_type_routemap_cmd
,
414 "redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
416 QUAGGA_REDIST_HELP_STR_RIPD
417 "Route map reference\n"
418 "Pointer to route-map entries\n")
422 for (i
= 0; redist_type
[i
].str
; i
++) {
423 if (strncmp(redist_type
[i
].str
, argv
[0],
424 redist_type
[i
].str_min_len
) == 0)
426 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
427 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
428 redist_type
[i
].type
, 0, VRF_DEFAULT
);
433 vty_out(vty
, "Invalid type %s%s", argv
[0],
439 DEFUN (no_rip_redistribute_type_routemap
,
440 no_rip_redistribute_type_routemap_cmd
,
441 "no redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
444 QUAGGA_REDIST_HELP_STR_RIPD
445 "Route map reference\n"
446 "Pointer to route-map entries\n")
450 for (i
= 0; redist_type
[i
].str
; i
++)
452 if (strncmp(redist_type
[i
].str
, argv
[0],
453 redist_type
[i
].str_min_len
) == 0)
455 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
457 rip_redistribute_unset (redist_type
[i
].type
);
462 vty_out(vty
, "Invalid type %s%s", argv
[0],
468 DEFUN (rip_redistribute_type_metric
,
469 rip_redistribute_type_metric_cmd
,
470 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
472 QUAGGA_REDIST_HELP_STR_RIPD
479 metric
= atoi (argv
[1]);
481 for (i
= 0; redist_type
[i
].str
; i
++) {
482 if (strncmp(redist_type
[i
].str
, argv
[0],
483 redist_type
[i
].str_min_len
) == 0)
485 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
486 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
487 redist_type
[i
].type
, 0, VRF_DEFAULT
);
492 vty_out(vty
, "Invalid type %s%s", argv
[0],
498 DEFUN (no_rip_redistribute_type_metric
,
499 no_rip_redistribute_type_metric_cmd
,
500 "no redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16>",
503 QUAGGA_REDIST_HELP_STR_RIPD
509 for (i
= 0; redist_type
[i
].str
; i
++)
511 if (strncmp(redist_type
[i
].str
, argv
[0],
512 redist_type
[i
].str_min_len
) == 0)
514 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
516 rip_redistribute_unset (redist_type
[i
].type
);
521 vty_out(vty
, "Invalid type %s%s", argv
[0],
527 DEFUN (rip_redistribute_type_metric_routemap
,
528 rip_redistribute_type_metric_routemap_cmd
,
529 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric <0-16> route-map WORD",
531 QUAGGA_REDIST_HELP_STR_RIPD
534 "Route map reference\n"
535 "Pointer to route-map entries\n")
540 metric
= atoi (argv
[1]);
542 for (i
= 0; redist_type
[i
].str
; i
++) {
543 if (strncmp(redist_type
[i
].str
, argv
[0],
544 redist_type
[i
].str_min_len
) == 0)
546 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
547 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
548 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
549 redist_type
[i
].type
, 0, VRF_DEFAULT
);
554 vty_out(vty
, "Invalid type %s%s", argv
[0],
561 DEFUN (no_rip_redistribute_type_metric_routemap
,
562 no_rip_redistribute_type_metric_routemap_cmd
,
563 "no redistribute " QUAGGA_REDIST_STR_RIPD
564 " metric <0-16> route-map WORD",
567 QUAGGA_REDIST_HELP_STR_RIPD
570 "Route map reference\n"
571 "Pointer to route-map entries\n")
575 for (i
= 0; redist_type
[i
].str
; i
++)
577 if (strncmp(redist_type
[i
].str
, argv
[0],
578 redist_type
[i
].str_min_len
) == 0)
580 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
582 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
584 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
587 rip_redistribute_unset (redist_type
[i
].type
);
592 vty_out(vty
, "Invalid type %s%s", argv
[0],
598 /* Default information originate. */
600 DEFUN (rip_default_information_originate
,
601 rip_default_information_originate_cmd
,
602 "default-information originate",
603 "Control distribution of default route\n"
604 "Distribute a default route\n")
606 struct prefix_ipv4 p
;
608 if (! rip
->default_information
)
610 memset (&p
, 0, sizeof (struct prefix_ipv4
));
613 rip
->default_information
= 1;
615 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
622 DEFUN (no_rip_default_information_originate
,
623 no_rip_default_information_originate_cmd
,
624 "no default-information originate",
626 "Control distribution of default route\n"
627 "Distribute a default route\n")
629 struct prefix_ipv4 p
;
631 if (rip
->default_information
)
633 memset (&p
, 0, sizeof (struct prefix_ipv4
));
636 rip
->default_information
= 0;
638 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
644 /* RIP configuration write function. */
646 config_write_zebra (struct vty
*vty
)
648 if (! zclient
->enable
)
650 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
653 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
655 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
656 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
663 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
667 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
668 if (i
!= zclient
->redist_default
&&
669 vrf_bitmap_check (zclient
->redist
[AFI_IP
][i
], VRF_DEFAULT
))
673 if (rip
->route_map
[i
].metric_config
)
675 if (rip
->route_map
[i
].name
)
676 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
677 zebra_route_string(i
), rip
->route_map
[i
].metric
,
678 rip
->route_map
[i
].name
,
681 vty_out (vty
, " redistribute %s metric %d%s",
682 zebra_route_string(i
), rip
->route_map
[i
].metric
,
687 if (rip
->route_map
[i
].name
)
688 vty_out (vty
, " redistribute %s route-map %s%s",
689 zebra_route_string(i
), rip
->route_map
[i
].name
,
692 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
697 vty_out (vty
, " %s", zebra_route_string(i
));
702 /* Zebra node structure. */
703 static struct cmd_node zebra_node
=
706 "%s(config-router)# ",
710 rip_zebra_connected (struct zclient
*zclient
)
712 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
716 rip_zclient_init (struct thread_master
*master
)
718 /* Set default value to the zebra client structure. */
719 zclient
= zclient_new(master
);
720 zclient_init (zclient
, ZEBRA_ROUTE_RIP
, 0);
721 zclient
->zebra_connected
= rip_zebra_connected
;
722 zclient
->interface_add
= rip_interface_add
;
723 zclient
->interface_delete
= rip_interface_delete
;
724 zclient
->interface_address_add
= rip_interface_address_add
;
725 zclient
->interface_address_delete
= rip_interface_address_delete
;
726 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
727 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
728 zclient
->interface_up
= rip_interface_up
;
729 zclient
->interface_down
= rip_interface_down
;
730 zclient
->redistribute_route_ipv4_add
= rip_zebra_read_ipv4
;
731 zclient
->redistribute_route_ipv4_del
= rip_zebra_read_ipv4
;
733 /* Install zebra node. */
734 install_node (&zebra_node
, config_write_zebra
);
736 /* Install command elements to zebra node. */
737 install_element (CONFIG_NODE
, &router_zebra_cmd
);
738 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
739 install_default (ZEBRA_NODE
);
740 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
741 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
743 /* Install command elements to rip node. */
744 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
745 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
746 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
747 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
748 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
749 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
750 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
751 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
752 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
753 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);