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
[2]->arg
,
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
[2]->arg
,
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
[3]->arg
,
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
[3]->arg
,
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")
420 int idx_protocol
= 1;
424 for (i
= 0; redist_type
[i
].str
; i
++) {
425 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
426 redist_type
[i
].str_min_len
) == 0)
428 rip_routemap_set (redist_type
[i
].type
, argv
[idx_word
]->arg
);
429 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
430 redist_type
[i
].type
, 0, VRF_DEFAULT
);
435 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
441 DEFUN (no_rip_redistribute_type_routemap
,
442 no_rip_redistribute_type_routemap_cmd
,
443 "no redistribute " QUAGGA_REDIST_STR_RIPD
" route-map WORD",
446 QUAGGA_REDIST_HELP_STR_RIPD
447 "Route map reference\n"
448 "Pointer to route-map entries\n")
450 int idx_protocol
= 2;
454 for (i
= 0; redist_type
[i
].str
; i
++)
456 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
457 redist_type
[i
].str_min_len
) == 0)
459 if (rip_routemap_unset (redist_type
[i
].type
,argv
[idx_word
]->arg
))
461 rip_redistribute_unset (redist_type
[i
].type
);
466 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
472 DEFUN (rip_redistribute_type_metric
,
473 rip_redistribute_type_metric_cmd
,
474 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric (0-16)",
476 QUAGGA_REDIST_HELP_STR_RIPD
480 int idx_protocol
= 1;
485 metric
= atoi (argv
[idx_number
]->arg
);
487 for (i
= 0; redist_type
[i
].str
; i
++) {
488 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
489 redist_type
[i
].str_min_len
) == 0)
491 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
492 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
493 redist_type
[i
].type
, 0, VRF_DEFAULT
);
498 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
504 DEFUN (no_rip_redistribute_type_metric
,
505 no_rip_redistribute_type_metric_cmd
,
506 "no redistribute " QUAGGA_REDIST_STR_RIPD
" metric (0-16)",
509 QUAGGA_REDIST_HELP_STR_RIPD
513 int idx_protocol
= 2;
517 for (i
= 0; redist_type
[i
].str
; i
++)
519 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
520 redist_type
[i
].str_min_len
) == 0)
522 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
)))
524 rip_redistribute_unset (redist_type
[i
].type
);
529 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
535 DEFUN (rip_redistribute_type_metric_routemap
,
536 rip_redistribute_type_metric_routemap_cmd
,
537 "redistribute " QUAGGA_REDIST_STR_RIPD
" metric (0-16) route-map WORD",
539 QUAGGA_REDIST_HELP_STR_RIPD
542 "Route map reference\n"
543 "Pointer to route-map entries\n")
545 int idx_protocol
= 1;
551 metric
= atoi (argv
[idx_number
]->arg
);
553 for (i
= 0; redist_type
[i
].str
; i
++) {
554 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
555 redist_type
[i
].str_min_len
) == 0)
557 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
558 rip_routemap_set (redist_type
[i
].type
, argv
[idx_word
]->arg
);
559 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
560 redist_type
[i
].type
, 0, VRF_DEFAULT
);
565 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
572 DEFUN (no_rip_redistribute_type_metric_routemap
,
573 no_rip_redistribute_type_metric_routemap_cmd
,
574 "no redistribute " QUAGGA_REDIST_STR_RIPD
" metric (0-16) route-map WORD",
577 QUAGGA_REDIST_HELP_STR_RIPD
580 "Route map reference\n"
581 "Pointer to route-map entries\n")
583 int idx_protocol
= 2;
588 for (i
= 0; redist_type
[i
].str
; i
++)
590 if (strncmp(redist_type
[i
].str
, argv
[idx_protocol
]->arg
,
591 redist_type
[i
].str_min_len
) == 0)
593 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
)))
595 if (rip_routemap_unset (redist_type
[i
].type
, argv
[idx_word
]->arg
))
597 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
));
600 rip_redistribute_unset (redist_type
[i
].type
);
605 vty_out(vty
, "Invalid type %s%s", argv
[idx_protocol
]->arg
,
611 /* Default information originate. */
613 DEFUN (rip_default_information_originate
,
614 rip_default_information_originate_cmd
,
615 "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
= 1;
628 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
635 DEFUN (no_rip_default_information_originate
,
636 no_rip_default_information_originate_cmd
,
637 "no default-information originate",
639 "Control distribution of default route\n"
640 "Distribute a default route\n")
642 struct prefix_ipv4 p
;
644 if (rip
->default_information
)
646 memset (&p
, 0, sizeof (struct prefix_ipv4
));
649 rip
->default_information
= 0;
651 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
657 /* RIP configuration write function. */
659 config_write_zebra (struct vty
*vty
)
661 if (! zclient
->enable
)
663 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
666 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
668 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
669 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
676 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
680 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
681 if (i
!= zclient
->redist_default
&&
682 vrf_bitmap_check (zclient
->redist
[AFI_IP
][i
], VRF_DEFAULT
))
686 if (rip
->route_map
[i
].metric_config
)
688 if (rip
->route_map
[i
].name
)
689 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
690 zebra_route_string(i
), rip
->route_map
[i
].metric
,
691 rip
->route_map
[i
].name
,
694 vty_out (vty
, " redistribute %s metric %d%s",
695 zebra_route_string(i
), rip
->route_map
[i
].metric
,
700 if (rip
->route_map
[i
].name
)
701 vty_out (vty
, " redistribute %s route-map %s%s",
702 zebra_route_string(i
), rip
->route_map
[i
].name
,
705 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
710 vty_out (vty
, " %s", zebra_route_string(i
));
715 /* Zebra node structure. */
716 static struct cmd_node zebra_node
=
719 "%s(config-router)# ",
723 rip_zebra_connected (struct zclient
*zclient
)
725 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
729 rip_zclient_init (struct thread_master
*master
)
731 /* Set default value to the zebra client structure. */
732 zclient
= zclient_new(master
);
733 zclient_init (zclient
, ZEBRA_ROUTE_RIP
, 0);
734 zclient
->zebra_connected
= rip_zebra_connected
;
735 zclient
->interface_add
= rip_interface_add
;
736 zclient
->interface_delete
= rip_interface_delete
;
737 zclient
->interface_address_add
= rip_interface_address_add
;
738 zclient
->interface_address_delete
= rip_interface_address_delete
;
739 zclient
->ipv4_route_add
= rip_zebra_read_ipv4
;
740 zclient
->ipv4_route_delete
= rip_zebra_read_ipv4
;
741 zclient
->interface_up
= rip_interface_up
;
742 zclient
->interface_down
= rip_interface_down
;
743 zclient
->redistribute_route_ipv4_add
= rip_zebra_read_ipv4
;
744 zclient
->redistribute_route_ipv4_del
= rip_zebra_read_ipv4
;
746 /* Install zebra node. */
747 install_node (&zebra_node
, config_write_zebra
);
749 /* Install command elements to zebra node. */
750 install_element (CONFIG_NODE
, &router_zebra_cmd
);
751 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
752 install_default (ZEBRA_NODE
);
753 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
754 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
756 /* Install command elements to rip node. */
757 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
758 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
759 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
760 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
761 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
762 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
763 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
764 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
765 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
766 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);