1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* RIPd and zebra interface.
3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
17 #include "ripd/ripd.h"
18 #include "ripd/rip_debug.h"
19 #include "ripd/rip_interface.h"
21 /* All information about zebra. */
22 struct zclient
*zclient
= NULL
;
24 /* Send ECMP routes to zebra. */
25 static void rip_zebra_ipv4_send(struct rip
*rip
, struct route_node
*rp
,
28 struct list
*list
= (struct list
*)rp
->info
;
29 struct zapi_route api
;
30 struct zapi_nexthop
*api_nh
;
31 struct listnode
*listnode
= NULL
;
32 struct rip_info
*rinfo
= NULL
;
35 memset(&api
, 0, sizeof(api
));
36 api
.vrf_id
= rip
->vrf
->vrf_id
;
37 api
.type
= ZEBRA_ROUTE_RIP
;
38 api
.safi
= SAFI_UNICAST
;
40 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
41 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
42 if (count
>= MULTIPATH_NUM
)
44 api_nh
= &api
.nexthops
[count
];
45 api_nh
->vrf_id
= rip
->vrf
->vrf_id
;
46 api_nh
->gate
= rinfo
->nh
.gate
;
47 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
48 if (cmd
== ZEBRA_ROUTE_ADD
)
49 SET_FLAG(rinfo
->flags
, RIP_RTF_FIB
);
51 UNSET_FLAG(rinfo
->flags
, RIP_RTF_FIB
);
56 api
.nexthop_num
= count
;
58 rinfo
= listgetdata(listhead(list
));
60 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
61 api
.metric
= rinfo
->metric
;
63 if (rinfo
->distance
&& rinfo
->distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
) {
64 SET_FLAG(api
.message
, ZAPI_MESSAGE_DISTANCE
);
65 api
.distance
= rinfo
->distance
;
69 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
73 zclient_route_send(cmd
, zclient
, &api
);
75 if (IS_RIP_DEBUG_ZEBRA
) {
77 zlog_debug("%s: %pFX nexthops %d",
78 (cmd
== ZEBRA_ROUTE_ADD
)
79 ? "Install into zebra"
80 : "Delete from zebra",
83 zlog_debug("%s: %pFX",
84 (cmd
== ZEBRA_ROUTE_ADD
)
85 ? "Install into zebra"
86 : "Delete from zebra", &rp
->p
);
89 rip
->counters
.route_changes
++;
92 /* Add/update ECMP routes to zebra. */
93 void rip_zebra_ipv4_add(struct rip
*rip
, struct route_node
*rp
)
95 rip_zebra_ipv4_send(rip
, rp
, ZEBRA_ROUTE_ADD
);
98 /* Delete ECMP routes from zebra. */
99 void rip_zebra_ipv4_delete(struct rip
*rip
, struct route_node
*rp
)
101 rip_zebra_ipv4_send(rip
, rp
, ZEBRA_ROUTE_DELETE
);
104 /* Zebra route add and delete treatment. */
105 static int rip_zebra_read_route(ZAPI_CALLBACK_ARGS
)
108 struct zapi_route api
;
111 rip
= rip_lookup_by_vrf_id(vrf_id
);
115 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
118 memset(&nh
, 0, sizeof(nh
));
119 nh
.type
= api
.nexthops
[0].type
;
120 nh
.gate
.ipv4
= api
.nexthops
[0].gate
.ipv4
;
121 nh
.ifindex
= api
.nexthops
[0].ifindex
;
123 /* Then fetch IPv4 prefixes. */
124 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
125 rip_redistribute_add(rip
, api
.type
, RIP_ROUTE_REDISTRIBUTE
,
126 (struct prefix_ipv4
*)&api
.prefix
, &nh
,
127 api
.metric
, api
.distance
, api
.tag
);
128 else if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_DEL
)
129 rip_redistribute_delete(rip
, api
.type
, RIP_ROUTE_REDISTRIBUTE
,
130 (struct prefix_ipv4
*)&api
.prefix
,
136 void rip_redistribute_conf_update(struct rip
*rip
, int type
)
138 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
139 type
, 0, rip
->vrf
->vrf_id
);
142 void rip_redistribute_conf_delete(struct rip
*rip
, int type
)
144 if (zclient
->sock
> 0)
145 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
146 AFI_IP
, type
, 0, rip
->vrf
->vrf_id
);
148 /* Remove the routes from RIP table. */
149 rip_redistribute_withdraw(rip
, type
);
152 int rip_redistribute_check(struct rip
*rip
, int type
)
154 return rip
->redist
[type
].enabled
;
157 void rip_redistribute_enable(struct rip
*rip
)
159 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
160 if (!rip_redistribute_check(rip
, i
))
163 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
164 i
, 0, rip
->vrf
->vrf_id
);
168 void rip_redistribute_disable(struct rip
*rip
)
170 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
171 if (!rip_redistribute_check(rip
, i
))
174 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
175 AFI_IP
, i
, 0, rip
->vrf
->vrf_id
);
179 void rip_show_redistribute_config(struct vty
*vty
, struct rip
*rip
)
181 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
182 if (i
== zclient
->redist_default
183 || !rip_redistribute_check(rip
, i
))
186 vty_out(vty
, " %s", zebra_route_string(i
));
190 void rip_zebra_vrf_register(struct vrf
*vrf
)
192 if (vrf
->vrf_id
== VRF_DEFAULT
)
195 if (IS_RIP_DEBUG_EVENT
)
196 zlog_debug("%s: register VRF %s(%u) to zebra", __func__
,
197 vrf
->name
, vrf
->vrf_id
);
199 zclient_send_reg_requests(zclient
, vrf
->vrf_id
);
200 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, vrf
->vrf_id
);
203 void rip_zebra_vrf_deregister(struct vrf
*vrf
)
205 if (vrf
->vrf_id
== VRF_DEFAULT
)
208 if (IS_RIP_DEBUG_EVENT
)
209 zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__
,
210 vrf
->name
, vrf
->vrf_id
);
212 zclient_send_dereg_requests(zclient
, vrf
->vrf_id
);
213 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_DEREGISTER
, vrf
->vrf_id
);
216 static void rip_zebra_connected(struct zclient
*zclient
)
218 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
219 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, VRF_DEFAULT
);
222 zclient_handler
*const rip_handlers
[] = {
223 [ZEBRA_INTERFACE_ADDRESS_ADD
] = rip_interface_address_add
,
224 [ZEBRA_INTERFACE_ADDRESS_DELETE
] = rip_interface_address_delete
,
225 [ZEBRA_INTERFACE_VRF_UPDATE
] = rip_interface_vrf_update
,
226 [ZEBRA_REDISTRIBUTE_ROUTE_ADD
] = rip_zebra_read_route
,
227 [ZEBRA_REDISTRIBUTE_ROUTE_DEL
] = rip_zebra_read_route
,
230 void rip_zclient_init(struct event_loop
*master
)
232 /* Set default value to the zebra client structure. */
233 zclient
= zclient_new(master
, &zclient_options_default
, rip_handlers
,
234 array_size(rip_handlers
));
235 zclient_init(zclient
, ZEBRA_ROUTE_RIP
, 0, &ripd_privs
);
236 zclient
->zebra_connected
= rip_zebra_connected
;
239 void rip_zclient_stop(void)
241 zclient_stop(zclient
);
242 zclient_free(zclient
);