1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * RIPngd and zebra interface.
4 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
11 #include "agg_table.h"
18 #include "ripngd/ripngd.h"
19 #include "ripngd/ripng_debug.h"
21 /* All information about zebra. */
22 struct zclient
*zclient
= NULL
;
24 /* Send ECMP routes to zebra. */
25 static void ripng_zebra_ipv6_send(struct ripng
*ripng
, struct agg_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 ripng_info
*rinfo
= NULL
;
34 const struct prefix
*p
= agg_node_get_prefix(rp
);
36 memset(&api
, 0, sizeof(api
));
37 api
.vrf_id
= ripng
->vrf
->vrf_id
;
38 api
.type
= ZEBRA_ROUTE_RIPNG
;
39 api
.safi
= SAFI_UNICAST
;
42 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
43 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
44 if (count
>= MULTIPATH_NUM
)
46 api_nh
= &api
.nexthops
[count
];
47 api_nh
->vrf_id
= ripng
->vrf
->vrf_id
;
48 api_nh
->gate
.ipv6
= rinfo
->nexthop
;
49 api_nh
->ifindex
= rinfo
->ifindex
;
50 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
52 if (cmd
== ZEBRA_ROUTE_ADD
)
53 SET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
55 UNSET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
58 api
.nexthop_num
= count
;
60 rinfo
= listgetdata(listhead(list
));
62 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
63 api
.metric
= rinfo
->metric
;
66 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
70 zclient_route_send(cmd
, zclient
, &api
);
72 if (IS_RIPNG_DEBUG_ZEBRA
) {
74 zlog_debug("%s: %pRN nexthops %d",
75 (cmd
== ZEBRA_ROUTE_ADD
)
76 ? "Install into zebra"
77 : "Delete from zebra",
80 zlog_debug("%s: %pRN",
81 (cmd
== ZEBRA_ROUTE_ADD
)
82 ? "Install into zebra"
83 : "Delete from zebra",
88 /* Add/update ECMP routes to zebra. */
89 void ripng_zebra_ipv6_add(struct ripng
*ripng
, struct agg_node
*rp
)
91 ripng_zebra_ipv6_send(ripng
, rp
, ZEBRA_ROUTE_ADD
);
94 /* Delete ECMP routes from zebra. */
95 void ripng_zebra_ipv6_delete(struct ripng
*ripng
, struct agg_node
*rp
)
97 ripng_zebra_ipv6_send(ripng
, rp
, ZEBRA_ROUTE_DELETE
);
100 /* Zebra route add and delete treatment. */
101 static int ripng_zebra_read_route(ZAPI_CALLBACK_ARGS
)
104 struct zapi_route api
;
105 struct in6_addr nexthop
;
106 unsigned long ifindex
;
108 ripng
= ripng_lookup_by_vrf_id(vrf_id
);
112 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
115 /* we completely ignore srcdest routes for now. */
116 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
119 if (IN6_IS_ADDR_LINKLOCAL(&api
.prefix
.u
.prefix6
))
122 nexthop
= api
.nexthops
[0].gate
.ipv6
;
123 ifindex
= api
.nexthops
[0].ifindex
;
125 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
126 ripng_redistribute_add(ripng
, api
.type
,
127 RIPNG_ROUTE_REDISTRIBUTE
,
128 (struct prefix_ipv6
*)&api
.prefix
,
129 ifindex
, &nexthop
, api
.tag
);
131 ripng_redistribute_delete(
132 ripng
, api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
133 (struct prefix_ipv6
*)&api
.prefix
, ifindex
);
138 void ripng_redistribute_conf_update(struct ripng
*ripng
, int type
)
140 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
,
141 type
, 0, ripng
->vrf
->vrf_id
);
144 void ripng_redistribute_conf_delete(struct ripng
*ripng
, int type
)
146 if (zclient
->sock
> 0)
147 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
148 AFI_IP6
, type
, 0, ripng
->vrf
->vrf_id
);
150 ripng_redistribute_withdraw(ripng
, type
);
153 int ripng_redistribute_check(struct ripng
*ripng
, int type
)
155 return ripng
->redist
[type
].enabled
;
158 void ripng_redistribute_enable(struct ripng
*ripng
)
160 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
161 if (!ripng_redistribute_check(ripng
, i
))
164 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
,
165 AFI_IP6
, i
, 0, ripng
->vrf
->vrf_id
);
169 void ripng_redistribute_disable(struct ripng
*ripng
)
171 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
172 if (!ripng_redistribute_check(ripng
, i
))
175 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
176 AFI_IP6
, i
, 0, ripng
->vrf
->vrf_id
);
180 void ripng_redistribute_write(struct vty
*vty
, struct ripng
*ripng
)
184 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
185 if (i
== zclient
->redist_default
186 || !ripng_redistribute_check(ripng
, i
))
189 vty_out(vty
, " %s", zebra_route_string(i
));
193 void ripng_zebra_vrf_register(struct vrf
*vrf
)
195 if (vrf
->vrf_id
== VRF_DEFAULT
)
198 if (IS_RIPNG_DEBUG_EVENT
)
199 zlog_debug("%s: register VRF %s(%u) to zebra", __func__
,
200 vrf
->name
, vrf
->vrf_id
);
202 zclient_send_reg_requests(zclient
, vrf
->vrf_id
);
205 void ripng_zebra_vrf_deregister(struct vrf
*vrf
)
207 if (vrf
->vrf_id
== VRF_DEFAULT
)
210 if (IS_RIPNG_DEBUG_EVENT
)
211 zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__
,
212 vrf
->name
, vrf
->vrf_id
);
214 zclient_send_dereg_requests(zclient
, vrf
->vrf_id
);
217 static void ripng_zebra_connected(struct zclient
*zclient
)
219 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
222 static zclient_handler
*const ripng_handlers
[] = {
223 [ZEBRA_INTERFACE_ADDRESS_ADD
] = ripng_interface_address_add
,
224 [ZEBRA_INTERFACE_ADDRESS_DELETE
] = ripng_interface_address_delete
,
225 [ZEBRA_INTERFACE_VRF_UPDATE
] = ripng_interface_vrf_update
,
226 [ZEBRA_REDISTRIBUTE_ROUTE_ADD
] = ripng_zebra_read_route
,
227 [ZEBRA_REDISTRIBUTE_ROUTE_DEL
] = ripng_zebra_read_route
,
230 /* Initialize zebra structure and it's commands. */
231 void zebra_init(struct thread_master
*master
)
233 /* Allocate zebra structure. */
234 zclient
= zclient_new(master
, &zclient_options_default
, ripng_handlers
,
235 array_size(ripng_handlers
));
236 zclient_init(zclient
, ZEBRA_ROUTE_RIPNG
, 0, &ripngd_privs
);
238 zclient
->zebra_connected
= ripng_zebra_connected
;
241 void ripng_zebra_stop(void)
243 zclient_stop(zclient
);
244 zclient_free(zclient
);