]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_zebra.c
Merge pull request #5625 from qlyoung/fix-zapi-ipset-name-nullterm
[mirror_frr.git] / isisd / isis_zebra.c
CommitLineData
eb5d44eb 1/*
d62a17ae 2 * IS-IS Rout(e)ing protocol - isis_zebra.c
eb5d44eb 3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
d62a17ae 5 * Tampere University of Technology
eb5d44eb 6 * Institute of Communications Engineering
f3ccedaa 7 * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
eb5d44eb 8 *
d62a17ae 9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
eb5d44eb 12 * any later version.
13 *
d62a17ae 14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
eb5d44eb 17 * more details.
896014f4
DL
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
eb5d44eb 22 */
23
24#include <zebra.h>
eb5d44eb 25
26#include "thread.h"
27#include "command.h"
28#include "memory.h"
29#include "log.h"
363be4dd 30#include "lib_errors.h"
eb5d44eb 31#include "if.h"
32#include "network.h"
33#include "prefix.h"
34#include "zclient.h"
35#include "stream.h"
36#include "linklist.h"
f3ccedaa 37#include "nexthop.h"
7076bb2f 38#include "vrf.h"
8879bd22 39#include "libfrr.h"
eb5d44eb 40
41#include "isisd/isis_constants.h"
42#include "isisd/isis_common.h"
3f045a08
JB
43#include "isisd/isis_flags.h"
44#include "isisd/isis_misc.h"
45#include "isisd/isis_circuit.h"
c89c05dd 46#include "isisd/isisd.h"
eb5d44eb 47#include "isisd/isis_circuit.h"
48#include "isisd/isis_csm.h"
3f045a08 49#include "isisd/isis_lsp.h"
eb5d44eb 50#include "isisd/isis_route.h"
51#include "isisd/isis_zebra.h"
f8c06e2c 52#include "isisd/isis_te.h"
eb5d44eb 53
54struct zclient *zclient = NULL;
55
18a6dce6 56/* Router-id update message from zebra. */
121f9dee 57static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
18a6dce6 58{
d62a17ae 59 struct isis_area *area;
60 struct listnode *node;
61 struct prefix router_id;
62
d62a17ae 63 zebra_router_id_update_read(zclient->ibuf, &router_id);
64 if (isis->router_id == router_id.u.prefix4.s_addr)
65 return 0;
66
67 isis->router_id = router_id.u.prefix4.s_addr;
68 for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
69 if (listcount(area->area_addrs) > 0)
70 lsp_regenerate_schedule(area, area->is_type, 0);
71
72 return 0;
18a6dce6 73}
eb5d44eb 74
121f9dee 75static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
eb5d44eb 76{
d62a17ae 77 struct connected *c;
78 struct prefix *p;
79 char buf[PREFIX2STR_BUFFER];
eb5d44eb 80
d62a17ae 81 c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
82 zclient->ibuf, vrf_id);
f390d2c7 83
d62a17ae 84 if (c == NULL)
85 return 0;
f390d2c7 86
d62a17ae 87 p = c->address;
f390d2c7 88
d62a17ae 89 prefix2str(p, buf, sizeof(buf));
eb5d44eb 90#ifdef EXTREME_DEBUG
d62a17ae 91 if (p->family == AF_INET)
92 zlog_debug("connected IP address %s", buf);
93 if (p->family == AF_INET6)
94 zlog_debug("connected IPv6 address %s", buf);
eb5d44eb 95#endif /* EXTREME_DEBUG */
d62a17ae 96 if (if_is_operative(c->ifp))
97 isis_circuit_add_addr(circuit_scan_by_ifp(c->ifp), c);
eb5d44eb 98
d62a17ae 99 return 0;
eb5d44eb 100}
101
121f9dee 102static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
eb5d44eb 103{
d62a17ae 104 struct connected *c;
105 struct interface *ifp;
1cd80845 106#ifdef EXTREME_DEBUG
d62a17ae 107 struct prefix *p;
108 char buf[PREFIX2STR_BUFFER];
1cd80845 109#endif /* EXTREME_DEBUG */
eb5d44eb 110
d62a17ae 111 c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
112 zclient->ibuf, vrf_id);
f390d2c7 113
d62a17ae 114 if (c == NULL)
115 return 0;
f390d2c7 116
d62a17ae 117 ifp = c->ifp;
f390d2c7 118
f891f443 119#ifdef EXTREME_DEBUG
d62a17ae 120 p = c->address;
121 prefix2str(p, buf, sizeof(buf));
f891f443 122
d62a17ae 123 if (p->family == AF_INET)
124 zlog_debug("disconnected IP address %s", buf);
125 if (p->family == AF_INET6)
126 zlog_debug("disconnected IPv6 address %s", buf);
f891f443 127#endif /* EXTREME_DEBUG */
f390d2c7 128
d62a17ae 129 if (if_is_operative(ifp))
130 isis_circuit_del_addr(circuit_scan_by_ifp(ifp), c);
721c0857 131 connected_free(&c);
f390d2c7 132
d62a17ae 133 return 0;
eb5d44eb 134}
135
121f9dee 136static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
f8c06e2c 137{
d62a17ae 138 struct interface *ifp;
f8c06e2c 139
edc12762 140 ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id);
f8c06e2c 141
d62a17ae 142 if (ifp == NULL)
143 return 0;
f8c06e2c 144
d62a17ae 145 /* Update TE TLV */
146 isis_mpls_te_update(ifp);
f8c06e2c 147
d62a17ae 148 return 0;
f8c06e2c
OD
149}
150
0a5f3f4f
RW
151void isis_zebra_route_add_route(struct prefix *prefix,
152 struct prefix_ipv6 *src_p,
153 struct isis_route_info *route_info)
eb5d44eb 154{
c0721de4
RW
155 struct zapi_route api;
156 struct zapi_nexthop *api_nh;
d62a17ae 157 struct isis_nexthop *nexthop;
158 struct listnode *node;
c0721de4 159 int count = 0;
d62a17ae 160
0a5f3f4f 161 if (zclient->sock < 0)
d62a17ae 162 return;
163
c0721de4
RW
164 memset(&api, 0, sizeof(api));
165 api.vrf_id = VRF_DEFAULT;
7c0cbd0e 166 api.type = PROTO_TYPE;
c0721de4
RW
167 api.safi = SAFI_UNICAST;
168 api.prefix = *prefix;
321c1bbb
CF
169 if (src_p && src_p->prefixlen) {
170 api.src_prefix = *src_p;
171 SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
172 }
c0721de4
RW
173 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
174 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
175 api.metric = route_info->cost;
2097cd8a 176#if 0
c0721de4
RW
177 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
178 api.distance = route_info->depth;
2097cd8a 179#endif
f390d2c7 180
f80dd32b 181 /* Nexthops */
363be4dd
RW
182 for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) {
183 if (count >= MULTIPATH_NUM)
184 break;
185 api_nh = &api.nexthops[count];
186 if (fabricd)
68a02e06 187 SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
363be4dd
RW
188 api_nh->vrf_id = VRF_DEFAULT;
189
190 switch (nexthop->family) {
191 case AF_INET:
f80dd32b 192 /* FIXME: can it be ? */
363be4dd 193 if (nexthop->ip.ipv4.s_addr != INADDR_ANY) {
f80dd32b 194 api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
363be4dd 195 api_nh->gate.ipv4 = nexthop->ip.ipv4;
f80dd32b
RW
196 } else {
197 api_nh->type = NEXTHOP_TYPE_IFINDEX;
198 }
363be4dd
RW
199 break;
200 case AF_INET6:
201 if (!IN6_IS_ADDR_LINKLOCAL(&nexthop->ip.ipv6)
202 && !IN6_IS_ADDR_UNSPECIFIED(&nexthop->ip.ipv6)) {
f80dd32b
RW
203 continue;
204 }
363be4dd 205 api_nh->gate.ipv6 = nexthop->ip.ipv6;
f80dd32b 206 api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
363be4dd
RW
207 break;
208 default:
209 flog_err(EC_LIB_DEVELOPMENT,
210 "%s: unknown address family [%d]", __func__,
211 nexthop->family);
212 exit(1);
d62a17ae 213 }
363be4dd
RW
214
215 api_nh->ifindex = nexthop->ifindex;
216 count++;
d62a17ae 217 }
c0721de4
RW
218 if (!count)
219 return;
f390d2c7 220
c0721de4 221 api.nexthop_num = count;
f390d2c7 222
c0721de4 223 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
eb5d44eb 224}
225
0a5f3f4f
RW
226void isis_zebra_route_del_route(struct prefix *prefix,
227 struct prefix_ipv6 *src_p,
228 struct isis_route_info *route_info)
eb5d44eb 229{
c0721de4 230 struct zapi_route api;
d62a17ae 231
0a5f3f4f 232 if (zclient->sock < 0)
d62a17ae 233 return;
234
c0721de4 235 memset(&api, 0, sizeof(api));
d62a17ae 236 api.vrf_id = VRF_DEFAULT;
7c0cbd0e 237 api.type = PROTO_TYPE;
d62a17ae 238 api.safi = SAFI_UNICAST;
c0721de4 239 api.prefix = *prefix;
321c1bbb
CF
240 if (src_p && src_p->prefixlen) {
241 api.src_prefix = *src_p;
242 SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
243 }
f390d2c7 244
c0721de4 245 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
eb5d44eb 246}
247
121f9dee 248static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
eb5d44eb 249{
74489921 250 struct zapi_route api;
d62a17ae 251
74489921
RW
252 if (zapi_route_decode(zclient->ibuf, &api) < 0)
253 return -1;
d62a17ae 254
9fb2b879
DS
255 if (api.prefix.family == AF_INET6
256 && IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
257 return 0;
258
d62a17ae 259 /*
260 * Avoid advertising a false default reachability. (A default
261 * route installed by IS-IS gets redistributed from zebra back
262 * into IS-IS causing us to start advertising default reachabity
263 * without this check)
264 */
d43d2df5
CF
265 if (api.prefix.prefixlen == 0
266 && api.src_prefix.prefixlen == 0
7c0cbd0e 267 && api.type == PROTO_TYPE) {
121f9dee 268 cmd = ZEBRA_REDISTRIBUTE_ROUTE_DEL;
d43d2df5 269 }
d62a17ae 270
121f9dee 271 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
d43d2df5
CF
272 isis_redist_add(api.type, &api.prefix, &api.src_prefix,
273 api.distance, api.metric);
d62a17ae 274 else
d43d2df5 275 isis_redist_delete(api.type, &api.prefix, &api.src_prefix);
d62a17ae 276
277 return 0;
eb5d44eb 278}
eb5d44eb 279
d62a17ae 280int isis_distribute_list_update(int routetype)
eb5d44eb 281{
d62a17ae 282 return 0;
eb5d44eb 283}
284
d62a17ae 285void isis_zebra_redistribute_set(afi_t afi, int type)
eb5d44eb 286{
d62a17ae 287 if (type == DEFAULT_ROUTE)
288 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
49db7a7b 289 zclient, afi, VRF_DEFAULT);
d62a17ae 290 else
291 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
292 0, VRF_DEFAULT);
f3ccedaa
CF
293}
294
d62a17ae 295void isis_zebra_redistribute_unset(afi_t afi, int type)
f3ccedaa 296{
d62a17ae 297 if (type == DEFAULT_ROUTE)
298 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
49db7a7b 299 zclient, afi, VRF_DEFAULT);
d62a17ae 300 else
301 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
302 type, 0, VRF_DEFAULT);
eb5d44eb 303}
304
d62a17ae 305static void isis_zebra_connected(struct zclient *zclient)
7076bb2f 306{
d62a17ae 307 zclient_send_reg_requests(zclient, VRF_DEFAULT);
7076bb2f
FL
308}
309
d62a17ae 310void isis_zebra_init(struct thread_master *master)
eb5d44eb 311{
26f63a1e 312 zclient = zclient_new(master, &zclient_options_default);
7c0cbd0e 313 zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
d62a17ae 314 zclient->zebra_connected = isis_zebra_connected;
315 zclient->router_id_update = isis_router_id_update_zebra;
d62a17ae 316 zclient->interface_address_add = isis_zebra_if_address_add;
317 zclient->interface_address_delete = isis_zebra_if_address_del;
318 zclient->interface_link_params = isis_zebra_link_params;
74489921
RW
319 zclient->redistribute_route_add = isis_zebra_read;
320 zclient->redistribute_route_del = isis_zebra_read;
d62a17ae 321
322 return;
eb5d44eb 323}
8d429559 324
d62a17ae 325void isis_zebra_stop(void)
8d429559 326{
d62a17ae 327 zclient_stop(zclient);
328 zclient_free(zclient);
8879bd22 329 frr_fini();
8d429559 330}