2 * RIPngd and zebra interface.
3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "agg_table.h"
33 #include "ripngd/ripngd.h"
34 #include "ripngd/ripng_debug.h"
36 /* All information about zebra. */
37 struct zclient
*zclient
= NULL
;
39 /* Send ECMP routes to zebra. */
40 static void ripng_zebra_ipv6_send(struct ripng
*ripng
, struct agg_node
*rp
,
43 struct list
*list
= (struct list
*)rp
->info
;
44 struct zapi_route api
;
45 struct zapi_nexthop
*api_nh
;
46 struct listnode
*listnode
= NULL
;
47 struct ripng_info
*rinfo
= NULL
;
50 memset(&api
, 0, sizeof(api
));
51 api
.vrf_id
= ripng
->vrf
->vrf_id
;
52 api
.type
= ZEBRA_ROUTE_RIPNG
;
53 api
.safi
= SAFI_UNICAST
;
56 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
57 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
58 if (count
>= MULTIPATH_NUM
)
60 api_nh
= &api
.nexthops
[count
];
61 api_nh
->vrf_id
= ripng
->vrf
->vrf_id
;
62 api_nh
->gate
.ipv6
= rinfo
->nexthop
;
63 api_nh
->ifindex
= rinfo
->ifindex
;
64 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
66 if (cmd
== ZEBRA_ROUTE_ADD
)
67 SET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
69 UNSET_FLAG(rinfo
->flags
, RIPNG_RTF_FIB
);
72 api
.nexthop_num
= count
;
74 rinfo
= listgetdata(listhead(list
));
76 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
77 api
.metric
= rinfo
->metric
;
80 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
84 zclient_route_send(cmd
, zclient
, &api
);
86 if (IS_RIPNG_DEBUG_ZEBRA
) {
88 zlog_debug("%s: %s/%d nexthops %d",
89 (cmd
== ZEBRA_ROUTE_ADD
)
90 ? "Install into zebra"
91 : "Delete from zebra",
92 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
,
97 (cmd
== ZEBRA_ROUTE_ADD
) ? "Install into zebra"
98 : "Delete from zebra",
99 inet6_ntoa(rp
->p
.u
.prefix6
), rp
->p
.prefixlen
);
103 /* Add/update ECMP routes to zebra. */
104 void ripng_zebra_ipv6_add(struct ripng
*ripng
, struct agg_node
*rp
)
106 ripng_zebra_ipv6_send(ripng
, rp
, ZEBRA_ROUTE_ADD
);
109 /* Delete ECMP routes from zebra. */
110 void ripng_zebra_ipv6_delete(struct ripng
*ripng
, struct agg_node
*rp
)
112 ripng_zebra_ipv6_send(ripng
, rp
, ZEBRA_ROUTE_DELETE
);
115 /* Zebra route add and delete treatment. */
116 static int ripng_zebra_read_route(int command
, struct zclient
*zclient
,
117 zebra_size_t length
, vrf_id_t vrf_id
)
120 struct zapi_route api
;
121 struct in6_addr nexthop
;
122 unsigned long ifindex
;
124 ripng
= ripng_lookup_by_vrf_id(vrf_id
);
128 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
131 /* we completely ignore srcdest routes for now. */
132 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
135 if (IN6_IS_ADDR_LINKLOCAL(&api
.prefix
.u
.prefix6
))
138 nexthop
= api
.nexthops
[0].gate
.ipv6
;
139 ifindex
= api
.nexthops
[0].ifindex
;
141 if (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
142 ripng_redistribute_add(ripng
, api
.type
,
143 RIPNG_ROUTE_REDISTRIBUTE
,
144 (struct prefix_ipv6
*)&api
.prefix
,
145 ifindex
, &nexthop
, api
.tag
);
147 ripng_redistribute_delete(
148 ripng
, api
.type
, RIPNG_ROUTE_REDISTRIBUTE
,
149 (struct prefix_ipv6
*)&api
.prefix
, ifindex
);
154 void ripng_redistribute_conf_update(struct ripng
*ripng
, int type
)
156 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP6
, type
, 0,
160 void ripng_redistribute_conf_delete(struct ripng
*ripng
, int type
)
162 if (zclient
->sock
> 0)
163 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
164 AFI_IP6
, type
, 0, ripng
->vrf
->vrf_id
);
166 ripng_redistribute_withdraw(ripng
, type
);
169 int ripng_redistribute_check(struct ripng
*ripng
, int type
)
171 return ripng
->redist
[type
].enabled
;
174 void ripng_redistribute_enable(struct ripng
*ripng
)
176 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
177 if (!ripng_redistribute_check(ripng
, i
))
180 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
,
181 AFI_IP6
, i
, 0, ripng
->vrf
->vrf_id
);
185 void ripng_redistribute_disable(struct ripng
*ripng
)
187 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
188 if (!ripng_redistribute_check(ripng
, i
))
191 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
192 AFI_IP6
, i
, 0, ripng
->vrf
->vrf_id
);
196 void ripng_redistribute_write(struct vty
*vty
, struct ripng
*ripng
)
200 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
201 if (i
== zclient
->redist_default
202 || !ripng_redistribute_check(ripng
, i
))
205 vty_out(vty
, " %s", zebra_route_string(i
));
209 void ripng_zebra_vrf_register(struct vrf
*vrf
)
211 if (vrf
->vrf_id
== VRF_DEFAULT
)
214 if (IS_RIPNG_DEBUG_EVENT
)
215 zlog_debug("%s: register VRF %s(%u) to zebra", __func__
,
216 vrf
->name
, vrf
->vrf_id
);
218 zclient_send_reg_requests(zclient
, vrf
->vrf_id
);
221 void ripng_zebra_vrf_deregister(struct vrf
*vrf
)
223 if (vrf
->vrf_id
== VRF_DEFAULT
)
226 if (IS_RIPNG_DEBUG_EVENT
)
227 zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__
,
228 vrf
->name
, vrf
->vrf_id
);
230 zclient_send_dereg_requests(zclient
, vrf
->vrf_id
);
233 static void ripng_zebra_connected(struct zclient
*zclient
)
235 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
238 /* Initialize zebra structure and it's commands. */
239 void zebra_init(struct thread_master
*master
)
241 /* Allocate zebra structure. */
242 zclient
= zclient_new(master
, &zclient_options_default
);
243 zclient_init(zclient
, ZEBRA_ROUTE_RIPNG
, 0, &ripngd_privs
);
245 zclient
->zebra_connected
= ripng_zebra_connected
;
246 zclient
->interface_up
= ripng_interface_up
;
247 zclient
->interface_down
= ripng_interface_down
;
248 zclient
->interface_add
= ripng_interface_add
;
249 zclient
->interface_delete
= ripng_interface_delete
;
250 zclient
->interface_address_add
= ripng_interface_address_add
;
251 zclient
->interface_address_delete
= ripng_interface_address_delete
;
252 zclient
->interface_vrf_update
= ripng_interface_vrf_update
;
253 zclient
->redistribute_route_add
= ripng_zebra_read_route
;
254 zclient
->redistribute_route_del
= ripng_zebra_read_route
;
257 void ripng_zebra_stop(void)
259 zclient_stop(zclient
);
260 zclient_free(zclient
);