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
;
96 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
100 zapi_ipv4_route (cmd
, zclient
,
101 (struct prefix_ipv4
*)&rp
->p
, &api
);
103 if (IS_RIP_DEBUG_ZEBRA
)
106 zlog_debug ("%s: %s/%d nexthops %d",
107 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
108 "Install into zebra" : "Delete from zebra",
109 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
, count
);
111 zlog_debug ("%s: %s/%d",
112 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
113 "Install into zebra" : "Delete from zebra",
114 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
117 rip_global_route_changes
++;
121 /* Add/update ECMP routes to zebra. */
123 rip_zebra_ipv4_add (struct route_node
*rp
)
125 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_ADD
);
128 /* Delete ECMP routes from zebra. */
130 rip_zebra_ipv4_delete (struct route_node
*rp
)
132 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_DELETE
);
135 /* Zebra route add and delete treatment. */
137 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
,
141 struct zapi_ipv4 api
;
142 unsigned long ifindex
;
143 struct in_addr nexthop
;
144 struct prefix_ipv4 p
;
153 /* Type, flags, message. */
154 api
.type
= stream_getc (s
);
155 api
.instance
= stream_getw (s
);
156 api
.flags
= stream_getl (s
);
157 api
.message
= stream_getc (s
);
160 memset (&p
, 0, sizeof (struct prefix_ipv4
));
162 p
.prefixlen
= MIN(IPV4_MAX_PREFIXLEN
, stream_getc (s
));
163 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
165 /* Nexthop, ifindex, distance, metric. */
166 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
168 api
.nexthop_num
= stream_getc (s
);
169 nexthop
.s_addr
= stream_get_ipv4 (s
);
171 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
173 api
.ifindex_num
= stream_getc (s
);
174 ifindex
= stream_getl (s
);
176 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
177 api
.distance
= stream_getc (s
);
180 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
181 api
.metric
= stream_getl (s
);
185 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
186 api
.tag
= stream_getl (s
);
190 /* Then fetch IPv4 prefixes. */
191 if (command
== ZEBRA_REDISTRIBUTE_IPV4_ADD
)
192 rip_redistribute_add (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
,
193 &nexthop
, api
.metric
, api
.distance
, api
.tag
);
194 else if (command
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
195 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
201 rip_zclient_reset (void)
203 zclient_reset (zclient
);
206 /* RIP route-map set for redistribution */
208 rip_routemap_set (int type
, const char *name
)
210 if (rip
->route_map
[type
].name
)
211 free(rip
->route_map
[type
].name
);
213 rip
->route_map
[type
].name
= strdup (name
);
214 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
218 rip_redistribute_metric_set (int type
, unsigned int metric
)
220 rip
->route_map
[type
].metric_config
= 1;
221 rip
->route_map
[type
].metric
= metric
;
225 rip_metric_unset (int type
, unsigned int metric
)
227 #define DONT_CARE_METRIC_RIP 17
228 if (metric
!= DONT_CARE_METRIC_RIP
&&
229 rip
->route_map
[type
].metric
!= metric
)
231 rip
->route_map
[type
].metric_config
= 0;
232 rip
->route_map
[type
].metric
= 0;
236 /* RIP route-map unset for redistribution */
238 rip_routemap_unset (int type
, const char *name
)
240 if (! rip
->route_map
[type
].name
||
241 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
244 free (rip
->route_map
[type
].name
);
245 rip
->route_map
[type
].name
= NULL
;
246 rip
->route_map
[type
].map
= NULL
;
251 /* Redistribution types */
257 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
258 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
259 {ZEBRA_ROUTE_STATIC
, 1, "static"},
260 {ZEBRA_ROUTE_OSPF
, 1, "ospf"},
261 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
262 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
269 "Enable a routing process\n"
270 "Make connection to zebra daemon\n")
272 vty
->node
= ZEBRA_NODE
;
274 zclient_start (zclient
);
278 DEFUN (no_router_zebra
,
282 "Enable a routing process\n"
283 "Make connection to zebra daemon\n")
286 zclient_stop (zclient
);
292 rip_redistribute_set (int type
)
294 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
))
297 vrf_bitmap_set (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
299 if (zclient
->sock
> 0)
300 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, API_IP
, type
);
307 rip_redistribute_unset (int type
)
309 if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
))
312 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
314 if (zclient
->sock
> 0)
315 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
317 /* Remove the routes from RIP table. */
318 rip_redistribute_withdraw (type
);
324 rip_redistribute_check (int type
)
326 return vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
330 rip_redistribute_clean (void)
334 for (i
= 0; redist_type
[i
].str
; i
++)
336 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
))
338 if (zclient
->sock
> 0)
339 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
340 zclient
, AFI_IP
, redist_type
[i
].type
, 0,
343 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
);
345 /* Remove the routes from RIP table. */
346 rip_redistribute_withdraw (redist_type
[i
].type
);
351 DEFUN (rip_redistribute_rip
,
352 rip_redistribute_rip_cmd
,
354 "Redistribute information from another routing protocol\n"
355 "Routing Information Protocol (RIP)\n")
357 vrf_bitmap_set (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
361 DEFUN (no_rip_redistribute_rip
,
362 no_rip_redistribute_rip_cmd
,
363 "no redistribute rip",
365 "Redistribute information from another routing protocol\n"
366 "Routing Information Protocol (RIP)\n")
368 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
372 DEFUN (rip_redistribute_type
,
373 rip_redistribute_type_cmd
,
374 "redistribute " FRR_REDIST_STR_RIPD
,
376 FRR_REDIST_HELP_STR_RIPD
)
380 for(i
= 0; redist_type
[i
].str
; i
++)
382 if (strncmp (redist_type
[i
].str
, argv
[0],
383 redist_type
[i
].str_min_len
) == 0)
385 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
386 AFI_IP
, redist_type
[i
].type
, 0, VRF_DEFAULT
);
391 vty_out(vty
, "Invalid type %s%s", argv
[0],
397 DEFUN (no_rip_redistribute_type
,
398 no_rip_redistribute_type_cmd
,
399 "no redistribute " FRR_REDIST_STR_RIPD
,
402 FRR_REDIST_HELP_STR_RIPD
)
406 for (i
= 0; redist_type
[i
].str
; i
++)
408 if (strncmp(redist_type
[i
].str
, argv
[0],
409 redist_type
[i
].str_min_len
) == 0)
411 rip_metric_unset (redist_type
[i
].type
, DONT_CARE_METRIC_RIP
);
412 rip_routemap_unset (redist_type
[i
].type
,NULL
);
413 rip_redistribute_unset (redist_type
[i
].type
);
418 vty_out(vty
, "Invalid type %s%s", argv
[0],
424 DEFUN (rip_redistribute_type_routemap
,
425 rip_redistribute_type_routemap_cmd
,
426 "redistribute " FRR_REDIST_STR_RIPD
" route-map WORD",
428 FRR_REDIST_HELP_STR_RIPD
429 "Route map reference\n"
430 "Pointer to route-map entries\n")
434 for (i
= 0; redist_type
[i
].str
; i
++) {
435 if (strncmp(redist_type
[i
].str
, argv
[0],
436 redist_type
[i
].str_min_len
) == 0)
438 rip_routemap_set (redist_type
[i
].type
, argv
[1]);
439 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
440 redist_type
[i
].type
, 0, VRF_DEFAULT
);
445 vty_out(vty
, "Invalid type %s%s", argv
[0],
451 DEFUN (no_rip_redistribute_type_routemap
,
452 no_rip_redistribute_type_routemap_cmd
,
453 "no redistribute " FRR_REDIST_STR_RIPD
" route-map WORD",
456 FRR_REDIST_HELP_STR_RIPD
457 "Route map reference\n"
458 "Pointer to route-map entries\n")
462 for (i
= 0; redist_type
[i
].str
; i
++)
464 if (strncmp(redist_type
[i
].str
, argv
[0],
465 redist_type
[i
].str_min_len
) == 0)
467 if (rip_routemap_unset (redist_type
[i
].type
,argv
[1]))
469 rip_redistribute_unset (redist_type
[i
].type
);
474 vty_out(vty
, "Invalid type %s%s", argv
[0],
480 DEFUN (rip_redistribute_type_metric
,
481 rip_redistribute_type_metric_cmd
,
482 "redistribute " FRR_REDIST_STR_RIPD
" metric <0-16>",
484 FRR_REDIST_HELP_STR_RIPD
491 metric
= atoi (argv
[1]);
493 for (i
= 0; redist_type
[i
].str
; i
++) {
494 if (strncmp(redist_type
[i
].str
, argv
[0],
495 redist_type
[i
].str_min_len
) == 0)
497 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
498 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
499 redist_type
[i
].type
, 0, VRF_DEFAULT
);
504 vty_out(vty
, "Invalid type %s%s", argv
[0],
510 DEFUN (no_rip_redistribute_type_metric
,
511 no_rip_redistribute_type_metric_cmd
,
512 "no redistribute " FRR_REDIST_STR_RIPD
" metric <0-16>",
515 FRR_REDIST_HELP_STR_RIPD
521 for (i
= 0; redist_type
[i
].str
; i
++)
523 if (strncmp(redist_type
[i
].str
, argv
[0],
524 redist_type
[i
].str_min_len
) == 0)
526 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
528 rip_redistribute_unset (redist_type
[i
].type
);
533 vty_out(vty
, "Invalid type %s%s", argv
[0],
539 DEFUN (rip_redistribute_type_metric_routemap
,
540 rip_redistribute_type_metric_routemap_cmd
,
541 "redistribute " FRR_REDIST_STR_RIPD
" metric <0-16> route-map WORD",
543 FRR_REDIST_HELP_STR_RIPD
546 "Route map reference\n"
547 "Pointer to route-map entries\n")
552 metric
= atoi (argv
[1]);
554 for (i
= 0; redist_type
[i
].str
; i
++) {
555 if (strncmp(redist_type
[i
].str
, argv
[0],
556 redist_type
[i
].str_min_len
) == 0)
558 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
559 rip_routemap_set (redist_type
[i
].type
, argv
[2]);
560 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
561 redist_type
[i
].type
, 0, VRF_DEFAULT
);
566 vty_out(vty
, "Invalid type %s%s", argv
[0],
573 DEFUN (no_rip_redistribute_type_metric_routemap
,
574 no_rip_redistribute_type_metric_routemap_cmd
,
575 "no redistribute " FRR_REDIST_STR_RIPD
576 " metric <0-16> route-map WORD",
579 FRR_REDIST_HELP_STR_RIPD
582 "Route map reference\n"
583 "Pointer to route-map entries\n")
587 for (i
= 0; redist_type
[i
].str
; i
++)
589 if (strncmp(redist_type
[i
].str
, argv
[0],
590 redist_type
[i
].str_min_len
) == 0)
592 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[1])))
594 if (rip_routemap_unset (redist_type
[i
].type
, argv
[2]))
596 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[1]));
599 rip_redistribute_unset (redist_type
[i
].type
);
604 vty_out(vty
, "Invalid type %s%s", argv
[0],
610 /* Default information originate. */
612 DEFUN (rip_default_information_originate
,
613 rip_default_information_originate_cmd
,
614 "default-information originate",
615 "Control distribution of default route\n"
616 "Distribute a default route\n")
618 struct prefix_ipv4 p
;
620 if (! rip
->default_information
)
622 memset (&p
, 0, sizeof (struct prefix_ipv4
));
625 rip
->default_information
= 1;
627 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
634 DEFUN (no_rip_default_information_originate
,
635 no_rip_default_information_originate_cmd
,
636 "no default-information originate",
638 "Control distribution of default route\n"
639 "Distribute a default route\n")
641 struct prefix_ipv4 p
;
643 if (rip
->default_information
)
645 memset (&p
, 0, sizeof (struct prefix_ipv4
));
648 rip
->default_information
= 0;
650 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
656 /* RIP configuration write function. */
658 config_write_zebra (struct vty
*vty
)
660 if (! zclient
->enable
)
662 vty_out (vty
, "no router zebra%s", VTY_NEWLINE
);
665 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
667 vty_out (vty
, "router zebra%s", VTY_NEWLINE
);
668 vty_out (vty
, " no redistribute rip%s", VTY_NEWLINE
);
675 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
679 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
680 if (i
!= zclient
->redist_default
&&
681 vrf_bitmap_check (zclient
->redist
[AFI_IP
][i
], VRF_DEFAULT
))
685 if (rip
->route_map
[i
].metric_config
)
687 if (rip
->route_map
[i
].name
)
688 vty_out (vty
, " redistribute %s metric %d route-map %s%s",
689 zebra_route_string(i
), rip
->route_map
[i
].metric
,
690 rip
->route_map
[i
].name
,
693 vty_out (vty
, " redistribute %s metric %d%s",
694 zebra_route_string(i
), rip
->route_map
[i
].metric
,
699 if (rip
->route_map
[i
].name
)
700 vty_out (vty
, " redistribute %s route-map %s%s",
701 zebra_route_string(i
), rip
->route_map
[i
].name
,
704 vty_out (vty
, " redistribute %s%s", zebra_route_string(i
),
709 vty_out (vty
, " %s", zebra_route_string(i
));
714 /* Zebra node structure. */
715 static struct cmd_node zebra_node
=
718 "%s(config-router)# ",
722 rip_zebra_connected (struct zclient
*zclient
)
724 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
728 rip_zclient_init (struct thread_master
*master
)
730 /* Set default value to the zebra client structure. */
731 zclient
= zclient_new(master
);
732 zclient_init (zclient
, ZEBRA_ROUTE_RIP
, 0);
733 zclient
->zebra_connected
= rip_zebra_connected
;
734 zclient
->interface_add
= rip_interface_add
;
735 zclient
->interface_delete
= rip_interface_delete
;
736 zclient
->interface_address_add
= rip_interface_address_add
;
737 zclient
->interface_address_delete
= rip_interface_address_delete
;
738 zclient
->interface_up
= rip_interface_up
;
739 zclient
->interface_down
= rip_interface_down
;
740 zclient
->redistribute_route_ipv4_add
= rip_zebra_read_ipv4
;
741 zclient
->redistribute_route_ipv4_del
= rip_zebra_read_ipv4
;
743 /* Install zebra node. */
744 install_node (&zebra_node
, config_write_zebra
);
746 /* Install command elements to zebra node. */
747 install_element (CONFIG_NODE
, &router_zebra_cmd
);
748 install_element (CONFIG_NODE
, &no_router_zebra_cmd
);
749 install_default (ZEBRA_NODE
);
750 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
751 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
753 /* Install command elements to rip node. */
754 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
755 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
756 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
757 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
758 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
759 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
760 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
761 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
762 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
763 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);