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
31 #include "ripd/ripd.h"
32 #include "ripd/rip_debug.h"
33 #include "ripd/rip_interface.h"
35 /* All information about zebra. */
36 struct zclient
*zclient
= NULL
;
38 /* Send ECMP routes to zebra. */
39 static void rip_zebra_ipv4_send(struct rip
*rip
, struct route_node
*rp
,
42 struct list
*list
= (struct list
*)rp
->info
;
43 struct zapi_route api
;
44 struct zapi_nexthop
*api_nh
;
45 struct listnode
*listnode
= NULL
;
46 struct rip_info
*rinfo
= NULL
;
49 memset(&api
, 0, sizeof(api
));
50 api
.vrf_id
= rip
->vrf
->vrf_id
;
51 api
.type
= ZEBRA_ROUTE_RIP
;
52 api
.safi
= SAFI_UNICAST
;
54 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
55 for (ALL_LIST_ELEMENTS_RO(list
, listnode
, rinfo
)) {
56 if (count
>= MULTIPATH_NUM
)
58 api_nh
= &api
.nexthops
[count
];
59 api_nh
->vrf_id
= rip
->vrf
->vrf_id
;
60 api_nh
->gate
= rinfo
->nh
.gate
;
61 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
62 if (cmd
== ZEBRA_ROUTE_ADD
)
63 SET_FLAG(rinfo
->flags
, RIP_RTF_FIB
);
65 UNSET_FLAG(rinfo
->flags
, RIP_RTF_FIB
);
70 api
.nexthop_num
= count
;
72 rinfo
= listgetdata(listhead(list
));
74 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
75 api
.metric
= rinfo
->metric
;
77 if (rinfo
->distance
&& rinfo
->distance
!= ZEBRA_RIP_DISTANCE_DEFAULT
) {
78 SET_FLAG(api
.message
, ZAPI_MESSAGE_DISTANCE
);
79 api
.distance
= rinfo
->distance
;
83 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
87 zclient_route_send(cmd
, zclient
, &api
);
89 if (IS_RIP_DEBUG_ZEBRA
) {
91 zlog_debug("%s: %s/%d nexthops %d",
92 (cmd
== ZEBRA_ROUTE_ADD
)
93 ? "Install into zebra"
94 : "Delete from zebra",
95 inet_ntoa(rp
->p
.u
.prefix4
), rp
->p
.prefixlen
,
98 zlog_debug("%s: %s/%d",
99 (cmd
== ZEBRA_ROUTE_ADD
)
100 ? "Install into zebra"
101 : "Delete from zebra",
102 inet_ntoa(rp
->p
.u
.prefix4
), rp
->p
.prefixlen
);
105 rip
->counters
.route_changes
++;
108 /* Add/update ECMP routes to zebra. */
109 void rip_zebra_ipv4_add(struct rip
*rip
, struct route_node
*rp
)
111 rip_zebra_ipv4_send(rip
, rp
, ZEBRA_ROUTE_ADD
);
114 /* Delete ECMP routes from zebra. */
115 void rip_zebra_ipv4_delete(struct rip
*rip
, struct route_node
*rp
)
117 rip_zebra_ipv4_send(rip
, rp
, ZEBRA_ROUTE_DELETE
);
120 /* Zebra route add and delete treatment. */
121 static int rip_zebra_read_route(ZAPI_CALLBACK_ARGS
)
124 struct zapi_route api
;
127 rip
= rip_lookup_by_vrf_id(vrf_id
);
131 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
134 memset(&nh
, 0, sizeof(nh
));
135 nh
.type
= api
.nexthops
[0].type
;
136 nh
.gate
.ipv4
= api
.nexthops
[0].gate
.ipv4
;
137 nh
.ifindex
= api
.nexthops
[0].ifindex
;
139 /* Then fetch IPv4 prefixes. */
140 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
141 rip_redistribute_add(rip
, api
.type
, RIP_ROUTE_REDISTRIBUTE
,
142 (struct prefix_ipv4
*)&api
.prefix
, &nh
,
143 api
.metric
, api
.distance
, api
.tag
);
144 else if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_DEL
)
145 rip_redistribute_delete(rip
, api
.type
, RIP_ROUTE_REDISTRIBUTE
,
146 (struct prefix_ipv4
*)&api
.prefix
,
152 void rip_redistribute_conf_update(struct rip
*rip
, int type
)
154 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
, type
,
155 0, rip
->vrf
->vrf_id
);
158 void rip_redistribute_conf_delete(struct rip
*rip
, int type
)
160 if (zclient
->sock
> 0)
161 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
162 AFI_IP
, type
, 0, rip
->vrf
->vrf_id
);
164 /* Remove the routes from RIP table. */
165 rip_redistribute_withdraw(rip
, type
);
168 int rip_redistribute_check(struct rip
*rip
, int type
)
170 return rip
->redist
[type
].enabled
;
173 void rip_redistribute_enable(struct rip
*rip
)
175 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
176 if (!rip_redistribute_check(rip
, i
))
179 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
,
180 i
, 0, rip
->vrf
->vrf_id
);
184 void rip_redistribute_disable(struct rip
*rip
)
186 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
187 if (!rip_redistribute_check(rip
, i
))
190 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
191 AFI_IP
, i
, 0, rip
->vrf
->vrf_id
);
195 void rip_show_redistribute_config(struct vty
*vty
, struct rip
*rip
)
197 for (int i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
198 if (i
== zclient
->redist_default
199 || !rip_redistribute_check(rip
, i
))
202 vty_out(vty
, " %s", zebra_route_string(i
));
206 void rip_zebra_vrf_register(struct vrf
*vrf
)
208 if (vrf
->vrf_id
== VRF_DEFAULT
)
211 if (IS_RIP_DEBUG_EVENT
)
212 zlog_debug("%s: register VRF %s(%u) to zebra", __func__
,
213 vrf
->name
, vrf
->vrf_id
);
215 zclient_send_reg_requests(zclient
, vrf
->vrf_id
);
218 void rip_zebra_vrf_deregister(struct vrf
*vrf
)
220 if (vrf
->vrf_id
== VRF_DEFAULT
)
223 if (IS_RIP_DEBUG_EVENT
)
224 zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__
,
225 vrf
->name
, vrf
->vrf_id
);
227 zclient_send_dereg_requests(zclient
, vrf
->vrf_id
);
230 static void rip_zebra_connected(struct zclient
*zclient
)
232 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
235 void rip_zclient_init(struct thread_master
*master
)
237 /* Set default value to the zebra client structure. */
238 zclient
= zclient_new(master
, &zclient_options_default
);
239 zclient_init(zclient
, ZEBRA_ROUTE_RIP
, 0, &ripd_privs
);
240 zclient
->zebra_connected
= rip_zebra_connected
;
241 zclient
->interface_add
= rip_interface_add
;
242 zclient
->interface_delete
= rip_interface_delete
;
243 zclient
->interface_address_add
= rip_interface_address_add
;
244 zclient
->interface_address_delete
= rip_interface_address_delete
;
245 zclient
->interface_up
= rip_interface_up
;
246 zclient
->interface_down
= rip_interface_down
;
247 zclient
->interface_vrf_update
= rip_interface_vrf_update
;
248 zclient
->redistribute_route_add
= rip_zebra_read_route
;
249 zclient
->redistribute_route_del
= rip_zebra_read_route
;
252 void rip_zclient_stop(void)
254 zclient_stop(zclient
);
255 zclient_free(zclient
);