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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "ripd/ripd.h"
33 #include "ripd/rip_debug.h"
34 #include "ripd/rip_interface.h"
36 /* All information about zebra. */
37 struct zclient
*zclient
= NULL
;
39 /* Send ECMP routes to zebra. */
41 rip_zebra_ipv4_send (struct route_node
*rp
, u_char cmd
)
43 static struct in_addr
**nexthops
= NULL
;
44 static unsigned int nexthops_len
= 0;
46 struct list
*list
= (struct list
*)rp
->info
;
48 struct listnode
*listnode
= NULL
;
49 struct rip_info
*rinfo
= NULL
;
52 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
54 api
.vrf_id
= VRF_DEFAULT
;
55 api
.type
= ZEBRA_ROUTE_RIP
;
59 api
.safi
= SAFI_UNICAST
;
61 if (nexthops_len
< listcount (list
))
63 nexthops_len
= listcount (list
);
64 nexthops
= XREALLOC (MTYPE_TMP
, nexthops
,
65 nexthops_len
* sizeof (struct in_addr
*));
68 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
69 for (ALL_LIST_ELEMENTS_RO (list
, listnode
, rinfo
))
71 nexthops
[count
++] = &rinfo
->nexthop
;
72 if (cmd
== ZEBRA_IPV4_ROUTE_ADD
)
73 SET_FLAG (rinfo
->flags
, RIP_RTF_FIB
);
75 UNSET_FLAG (rinfo
->flags
, RIP_RTF_FIB
);
78 api
.nexthop
= nexthops
;
79 api
.nexthop_num
= count
;
82 rinfo
= listgetdata (listhead (list
));
84 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
85 api
.metric
= rinfo
->metric
;
87 if (rinfo
->distance
&& rinfo
->distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
)
89 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
90 api
.distance
= rinfo
->distance
;
95 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
99 zapi_ipv4_route (cmd
, zclient
,
100 (struct prefix_ipv4
*)&rp
->p
, &api
);
102 if (IS_RIP_DEBUG_ZEBRA
)
105 zlog_debug ("%s: %s/%d nexthops %d",
106 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
107 "Install into zebra" : "Delete from zebra",
108 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
, count
);
110 zlog_debug ("%s: %s/%d",
111 (cmd
== ZEBRA_IPV4_ROUTE_ADD
) ? \
112 "Install into zebra" : "Delete from zebra",
113 inet_ntoa (rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
116 rip_global_route_changes
++;
120 /* Add/update ECMP routes to zebra. */
122 rip_zebra_ipv4_add (struct route_node
*rp
)
124 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_ADD
);
127 /* Delete ECMP routes from zebra. */
129 rip_zebra_ipv4_delete (struct route_node
*rp
)
131 rip_zebra_ipv4_send (rp
, ZEBRA_IPV4_ROUTE_DELETE
);
134 /* Zebra route add and delete treatment. */
136 rip_zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
,
140 struct zapi_ipv4 api
;
141 unsigned long ifindex
;
142 struct in_addr nexthop
;
143 struct prefix_ipv4 p
;
152 /* Type, flags, message. */
153 api
.type
= stream_getc (s
);
154 api
.instance
= stream_getw (s
);
155 api
.flags
= stream_getl (s
);
156 api
.message
= stream_getc (s
);
159 memset (&p
, 0, sizeof (struct prefix_ipv4
));
161 p
.prefixlen
= MIN(IPV4_MAX_PREFIXLEN
, stream_getc (s
));
162 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
164 /* Nexthop, ifindex, distance, metric. */
165 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
167 api
.nexthop_num
= stream_getc (s
);
168 nexthop
.s_addr
= stream_get_ipv4 (s
);
170 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
172 api
.ifindex_num
= stream_getc (s
);
173 ifindex
= stream_getl (s
);
175 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
176 api
.distance
= stream_getc (s
);
179 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
180 api
.metric
= stream_getl (s
);
184 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
185 api
.tag
= stream_getl (s
);
189 /* Then fetch IPv4 prefixes. */
190 if (command
== ZEBRA_REDISTRIBUTE_IPV4_ADD
)
191 rip_redistribute_add (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
,
192 &nexthop
, api
.metric
, api
.distance
, api
.tag
);
193 else if (command
== ZEBRA_REDISTRIBUTE_IPV4_DEL
)
194 rip_redistribute_delete (api
.type
, RIP_ROUTE_REDISTRIBUTE
, &p
, ifindex
);
200 rip_zclient_reset (void)
202 zclient_reset (zclient
);
205 /* RIP route-map set for redistribution */
207 rip_routemap_set (int type
, const char *name
)
209 if (rip
->route_map
[type
].name
)
210 free(rip
->route_map
[type
].name
);
212 rip
->route_map
[type
].name
= strdup (name
);
213 rip
->route_map
[type
].map
= route_map_lookup_by_name (name
);
217 rip_redistribute_metric_set (int type
, unsigned int metric
)
219 rip
->route_map
[type
].metric_config
= 1;
220 rip
->route_map
[type
].metric
= metric
;
224 rip_metric_unset (int type
, unsigned int metric
)
226 #define DONT_CARE_METRIC_RIP 17
227 if (metric
!= DONT_CARE_METRIC_RIP
&&
228 rip
->route_map
[type
].metric
!= metric
)
230 rip
->route_map
[type
].metric_config
= 0;
231 rip
->route_map
[type
].metric
= 0;
235 /* RIP route-map unset for redistribution */
237 rip_routemap_unset (int type
, const char *name
)
239 if (! rip
->route_map
[type
].name
||
240 (name
!= NULL
&& strcmp(rip
->route_map
[type
].name
,name
)))
243 free (rip
->route_map
[type
].name
);
244 rip
->route_map
[type
].name
= NULL
;
245 rip
->route_map
[type
].map
= NULL
;
250 /* Redistribution types */
256 {ZEBRA_ROUTE_KERNEL
, 1, "kernel"},
257 {ZEBRA_ROUTE_CONNECT
, 1, "connected"},
258 {ZEBRA_ROUTE_STATIC
, 1, "static"},
259 {ZEBRA_ROUTE_OSPF
, 1, "ospf"},
260 {ZEBRA_ROUTE_BGP
, 2, "bgp"},
261 {ZEBRA_ROUTE_VNC
, 1, "vnc"},
266 rip_redistribute_unset (int type
)
268 if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
))
271 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
273 if (zclient
->sock
> 0)
274 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
, 0, VRF_DEFAULT
);
276 /* Remove the routes from RIP table. */
277 rip_redistribute_withdraw (type
);
283 rip_redistribute_check (int type
)
285 return vrf_bitmap_check (zclient
->redist
[AFI_IP
][type
], VRF_DEFAULT
);
289 rip_redistribute_clean (void)
293 for (i
= 0; redist_type
[i
].str
; i
++)
295 if (vrf_bitmap_check (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
))
297 if (zclient
->sock
> 0)
298 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
,
299 zclient
, AFI_IP
, redist_type
[i
].type
, 0,
302 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][redist_type
[i
].type
], VRF_DEFAULT
);
304 /* Remove the routes from RIP table. */
305 rip_redistribute_withdraw (redist_type
[i
].type
);
310 DEFUN (rip_redistribute_rip
,
311 rip_redistribute_rip_cmd
,
313 "Redistribute information from another routing protocol\n"
314 "Routing Information Protocol (RIP)\n")
316 vrf_bitmap_set (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
320 DEFUN (no_rip_redistribute_rip
,
321 no_rip_redistribute_rip_cmd
,
322 "no redistribute rip",
324 "Redistribute information from another routing protocol\n"
325 "Routing Information Protocol (RIP)\n")
327 vrf_bitmap_unset (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
);
331 DEFUN (rip_redistribute_type
,
332 rip_redistribute_type_cmd
,
333 "redistribute " FRR_REDIST_STR_RIPD
,
335 FRR_REDIST_HELP_STR_RIPD
)
339 for(i
= 0; redist_type
[i
].str
; i
++)
341 if (strncmp (redist_type
[i
].str
, argv
[1]->arg
,
342 redist_type
[i
].str_min_len
) == 0)
344 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
,
345 AFI_IP
, redist_type
[i
].type
, 0, VRF_DEFAULT
);
350 vty_outln (vty
, "Invalid type %s",argv
[1]->arg
);
355 DEFUN (no_rip_redistribute_type
,
356 no_rip_redistribute_type_cmd
,
357 "no redistribute " FRR_REDIST_STR_RIPD
,
360 FRR_REDIST_HELP_STR_RIPD
)
364 for (i
= 0; redist_type
[i
].str
; i
++)
366 if (strncmp(redist_type
[i
].str
, argv
[2]->arg
,
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_outln (vty
, "Invalid type %s",argv
[2]->arg
);
381 DEFUN (rip_redistribute_type_routemap
,
382 rip_redistribute_type_routemap_cmd
,
383 "redistribute " FRR_REDIST_STR_RIPD
" route-map WORD",
385 FRR_REDIST_HELP_STR_RIPD
386 "Route map reference\n"
387 "Pointer to route-map entries\n")
389 int idx_protocol
= 1;
393 for (i
= 0; redist_type
[i
].str
; i
++) {
394 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
396 rip_routemap_set (redist_type
[i
].type
, argv
[idx_word
]->arg
);
397 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
398 redist_type
[i
].type
, 0, VRF_DEFAULT
);
403 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
408 DEFUN (no_rip_redistribute_type_routemap
,
409 no_rip_redistribute_type_routemap_cmd
,
410 "no redistribute " FRR_REDIST_STR_RIPD
" route-map WORD",
413 FRR_REDIST_HELP_STR_RIPD
414 "Route map reference\n"
415 "Pointer to route-map entries\n")
417 int idx_protocol
= 2;
421 for (i
= 0; redist_type
[i
].str
; i
++) {
422 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
424 if (rip_routemap_unset (redist_type
[i
].type
,argv
[idx_word
]->arg
))
426 rip_redistribute_unset (redist_type
[i
].type
);
431 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
436 DEFUN (rip_redistribute_type_metric
,
437 rip_redistribute_type_metric_cmd
,
438 "redistribute " FRR_REDIST_STR_RIPD
" metric (0-16)",
440 FRR_REDIST_HELP_STR_RIPD
444 int idx_protocol
= 1;
449 metric
= atoi (argv
[idx_number
]->arg
);
451 for (i
= 0; redist_type
[i
].str
; i
++) {
452 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
454 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
455 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
456 redist_type
[i
].type
, 0, VRF_DEFAULT
);
461 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
466 DEFUN (no_rip_redistribute_type_metric
,
467 no_rip_redistribute_type_metric_cmd
,
468 "no redistribute " FRR_REDIST_STR_RIPD
" metric (0-16)",
471 FRR_REDIST_HELP_STR_RIPD
475 int idx_protocol
= 2;
479 for (i
= 0; redist_type
[i
].str
; i
++) {
480 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
482 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
)))
484 rip_redistribute_unset (redist_type
[i
].type
);
489 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
494 DEFUN (rip_redistribute_type_metric_routemap
,
495 rip_redistribute_type_metric_routemap_cmd
,
496 "redistribute " FRR_REDIST_STR_RIPD
" metric (0-16) route-map WORD",
498 FRR_REDIST_HELP_STR_RIPD
501 "Route map reference\n"
502 "Pointer to route-map entries\n")
504 int idx_protocol
= 1;
510 metric
= atoi (argv
[idx_number
]->arg
);
512 for (i
= 0; redist_type
[i
].str
; i
++) {
513 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
515 rip_redistribute_metric_set (redist_type
[i
].type
, metric
);
516 rip_routemap_set (redist_type
[i
].type
, argv
[idx_word
]->arg
);
517 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
518 redist_type
[i
].type
, 0, VRF_DEFAULT
);
523 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
529 DEFUN (no_rip_redistribute_type_metric_routemap
,
530 no_rip_redistribute_type_metric_routemap_cmd
,
531 "no redistribute " FRR_REDIST_STR_RIPD
" metric (0-16) route-map WORD",
534 FRR_REDIST_HELP_STR_RIPD
537 "Route map reference\n"
538 "Pointer to route-map entries\n")
540 int idx_protocol
= 2;
545 for (i
= 0; redist_type
[i
].str
; i
++) {
546 if (strmatch (redist_type
[i
].str
, argv
[idx_protocol
]->text
))
548 if (rip_metric_unset (redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
)))
550 if (rip_routemap_unset (redist_type
[i
].type
, argv
[idx_word
]->arg
))
552 rip_redistribute_metric_set(redist_type
[i
].type
, atoi(argv
[idx_number
]->arg
));
555 rip_redistribute_unset (redist_type
[i
].type
);
560 vty_outln (vty
, "Invalid type %s", argv
[idx_protocol
]->text
);
565 /* Default information originate. */
567 DEFUN (rip_default_information_originate
,
568 rip_default_information_originate_cmd
,
569 "default-information originate",
570 "Control distribution of default route\n"
571 "Distribute a default route\n")
573 struct prefix_ipv4 p
;
575 if (! rip
->default_information
)
577 memset (&p
, 0, sizeof (struct prefix_ipv4
));
580 rip
->default_information
= 1;
582 rip_redistribute_add (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0,
589 DEFUN (no_rip_default_information_originate
,
590 no_rip_default_information_originate_cmd
,
591 "no 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
= 0;
605 rip_redistribute_delete (ZEBRA_ROUTE_RIP
, RIP_ROUTE_DEFAULT
, &p
, 0);
611 /* RIP configuration write function. */
613 config_write_zebra (struct vty
*vty
)
615 if (! zclient
->enable
)
617 vty_outln (vty
, "no router zebra");
620 else if (! vrf_bitmap_check (zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_RIP
], VRF_DEFAULT
))
622 vty_outln (vty
, "router zebra");
623 vty_outln (vty
, " no redistribute rip");
630 config_write_rip_redistribute (struct vty
*vty
, int config_mode
)
634 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
635 if (i
!= zclient
->redist_default
&&
636 vrf_bitmap_check (zclient
->redist
[AFI_IP
][i
], VRF_DEFAULT
))
640 if (rip
->route_map
[i
].metric_config
)
642 if (rip
->route_map
[i
].name
)
643 vty_outln (vty
, " redistribute %s metric %d route-map %s",
644 zebra_route_string(i
), rip
->route_map
[i
].metric
,
645 rip
->route_map
[i
].name
);
647 vty_outln (vty
, " redistribute %s metric %d",
648 zebra_route_string(i
),rip
->route_map
[i
].metric
);
652 if (rip
->route_map
[i
].name
)
653 vty_outln (vty
, " redistribute %s route-map %s",
654 zebra_route_string(i
),rip
->route_map
[i
].name
);
656 vty_outln (vty
, " redistribute %s",zebra_route_string(i
));
660 vty_out (vty
, " %s", zebra_route_string(i
));
665 /* Zebra node structure. */
666 static struct cmd_node zebra_node
=
669 "%s(config-router)# ",
673 rip_zebra_connected (struct zclient
*zclient
)
675 zclient_send_reg_requests (zclient
, VRF_DEFAULT
);
679 rip_zclient_init (struct thread_master
*master
)
681 /* Set default value to the zebra client structure. */
682 zclient
= zclient_new(master
);
683 zclient_init (zclient
, ZEBRA_ROUTE_RIP
, 0);
684 zclient
->zebra_connected
= rip_zebra_connected
;
685 zclient
->interface_add
= rip_interface_add
;
686 zclient
->interface_delete
= rip_interface_delete
;
687 zclient
->interface_address_add
= rip_interface_address_add
;
688 zclient
->interface_address_delete
= rip_interface_address_delete
;
689 zclient
->interface_up
= rip_interface_up
;
690 zclient
->interface_down
= rip_interface_down
;
691 zclient
->redistribute_route_ipv4_add
= rip_zebra_read_ipv4
;
692 zclient
->redistribute_route_ipv4_del
= rip_zebra_read_ipv4
;
694 /* Install zebra node. */
695 install_node (&zebra_node
, config_write_zebra
);
697 /* Install command elements to zebra node. */
698 install_default (ZEBRA_NODE
);
699 install_element (ZEBRA_NODE
, &rip_redistribute_rip_cmd
);
700 install_element (ZEBRA_NODE
, &no_rip_redistribute_rip_cmd
);
702 /* Install command elements to rip node. */
703 install_element (RIP_NODE
, &rip_redistribute_type_cmd
);
704 install_element (RIP_NODE
, &rip_redistribute_type_routemap_cmd
);
705 install_element (RIP_NODE
, &rip_redistribute_type_metric_cmd
);
706 install_element (RIP_NODE
, &rip_redistribute_type_metric_routemap_cmd
);
707 install_element (RIP_NODE
, &no_rip_redistribute_type_cmd
);
708 install_element (RIP_NODE
, &no_rip_redistribute_type_routemap_cmd
);
709 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_cmd
);
710 install_element (RIP_NODE
, &no_rip_redistribute_type_metric_routemap_cmd
);
711 install_element (RIP_NODE
, &rip_default_information_originate_cmd
);
712 install_element (RIP_NODE
, &no_rip_default_information_originate_cmd
);
716 rip_zclient_stop (void)
718 zclient_stop (zclient
);
719 zclient_free (zclient
);