]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_zebra.c
build: test program needs to be warning-free
[mirror_frr.git] / ospfd / ospf_zebra.c
CommitLineData
718e3744 1/*
2 * Zebra connect library for OSPFd
3 * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
896014f4
DL
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
718e3744 20 */
21
22#include <zebra.h>
23
24#include "thread.h"
25#include "command.h"
26#include "network.h"
27#include "prefix.h"
28#include "routemap.h"
29#include "table.h"
30#include "stream.h"
31#include "memory.h"
32#include "zclient.h"
33#include "filter.h"
dd669bb0 34#include "plist.h"
718e3744 35#include "log.h"
2376c3f2 36#include "lib/bfd.h"
5b30316e 37#include "nexthop.h"
718e3744 38
39#include "ospfd/ospfd.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_asbr.h"
44#include "ospfd/ospf_abr.h"
45#include "ospfd/ospf_lsa.h"
46#include "ospfd/ospf_dump.h"
47#include "ospfd/ospf_route.h"
d5a5c8f0
DS
48#include "ospfd/ospf_lsdb.h"
49#include "ospfd/ospf_neighbor.h"
50#include "ospfd/ospf_nsm.h"
718e3744 51#include "ospfd/ospf_zebra.h"
16f1b9ee 52#include "ospfd/ospf_te.h"
43e7abb5 53#include "ospfd/ospf_sr.h"
132a782e 54#include "ospfd/ospf_ldp_sync.h"
718e3744 55
bf8d3d6a
DL
56DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table");
57DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute");
58DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments");
dfac5d39 59
1febb13d 60
718e3744 61/* Zebra structure to hold current status. */
62struct zclient *zclient = NULL;
d81b8e0e
OD
63/* and for the Synchronous connection to the Label Manager */
64static struct zclient *zclient_sync;
718e3744 65
66/* For registering threads. */
67extern struct thread_master *master;
18a6dce6 68
69/* Router-id update message from zebra. */
121f9dee 70static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
18a6dce6 71{
b5a8894d 72 struct ospf *ospf = NULL;
d62a17ae 73 struct prefix router_id;
74 zebra_router_id_update_read(zclient->ibuf, &router_id);
75
2dbe669b
DA
76 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
77 zlog_debug("Zebra rcvd: router id update %pFX vrf %s id %u",
78 &router_id, ospf_vrf_id_to_name(vrf_id), vrf_id);
d62a17ae 79
b5a8894d 80 ospf = ospf_lookup_by_vrf_id(vrf_id);
d62a17ae 81
6021c6c0
CS
82 if (ospf != NULL) {
83 ospf->router_id_zebra = router_id.u.prefix4;
d62a17ae 84 ospf_router_id_update(ospf);
6021c6c0 85 } else {
2dbe669b 86 if (IS_DEBUG_OSPF_EVENT)
996c9314 87 zlog_debug(
2dbe669b 88 "%s: ospf instance not found for vrf %s id %u router_id %pFX",
15569c58 89 __func__, ospf_vrf_id_to_name(vrf_id), vrf_id,
2dbe669b 90 &router_id);
b5a8894d 91 }
d62a17ae 92 return 0;
18a6dce6 93}
718e3744 94
121f9dee 95static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS)
718e3744 96{
d62a17ae 97 struct connected *c;
b5a8894d
CS
98 struct ospf *ospf = NULL;
99
718e3744 100
121f9dee 101 c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
718e3744 102
d62a17ae 103 if (c == NULL)
104 return 0;
718e3744 105
2dbe669b
DA
106 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
107 zlog_debug("Zebra: interface %s address add %pFX vrf %s id %u",
108 c->ifp->name, c->address,
109 ospf_vrf_id_to_name(vrf_id), vrf_id);
7f643ebf 110
b5a8894d 111 ospf = ospf_lookup_by_vrf_id(vrf_id);
43b8d1d8
CS
112 if (!ospf)
113 return 0;
b5a8894d
CS
114
115 ospf_if_update(ospf, c->ifp);
718e3744 116
ef7bd2a3 117 ospf_if_interface(c->ifp);
718e3744 118
d62a17ae 119 return 0;
718e3744 120}
121
121f9dee 122static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
718e3744 123{
d62a17ae 124 struct connected *c;
125 struct interface *ifp;
126 struct ospf_interface *oi;
127 struct route_node *rn;
128 struct prefix p;
129
121f9dee 130 c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
d62a17ae 131
132 if (c == NULL)
133 return 0;
134
2dbe669b
DA
135 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
136 zlog_debug("Zebra: interface %s address delete %pFX",
137 c->ifp->name, c->address);
7f643ebf 138
d62a17ae 139 ifp = c->ifp;
140 p = *c->address;
141 p.prefixlen = IPV4_MAX_PREFIXLEN;
718e3744 142
d62a17ae 143 rn = route_node_lookup(IF_OIFS(ifp), &p);
144 if (!rn) {
721c0857 145 connected_free(&c);
d62a17ae 146 return 0;
147 }
718e3744 148
d62a17ae 149 assert(rn->info);
150 oi = rn->info;
151 route_unlock_node(rn);
cf795c5d 152
d62a17ae 153 /* Call interface hook functions to clean up */
154 ospf_if_free(oi);
cf795c5d 155
ef7bd2a3 156 ospf_if_interface(c->ifp);
718e3744 157
721c0857 158 connected_free(&c);
718e3744 159
d62a17ae 160 return 0;
718e3744 161}
72357f2b 162
121f9dee 163static int ospf_interface_link_params(ZAPI_CALLBACK_ARGS)
16f1b9ee 164{
d62a17ae 165 struct interface *ifp;
16f1b9ee 166
edc12762 167 ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id);
16f1b9ee 168
d62a17ae 169 if (ifp == NULL)
170 return 0;
16f1b9ee 171
d62a17ae 172 /* Update TE TLV */
173 ospf_mpls_te_update_if(ifp);
16f1b9ee 174
d62a17ae 175 return 0;
16f1b9ee
OD
176}
177
b5a8894d 178/* VRF update for an interface. */
121f9dee 179static int ospf_interface_vrf_update(ZAPI_CALLBACK_ARGS)
b5a8894d
CS
180{
181 struct interface *ifp = NULL;
182 vrf_id_t new_vrf_id;
16f1b9ee 183
b5a8894d 184 ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
996c9314 185 &new_vrf_id);
b5a8894d
CS
186 if (!ifp)
187 return 0;
188
189 if (IS_DEBUG_OSPF_EVENT)
996c9314
LB
190 zlog_debug(
191 "%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
15569c58 192 __func__, ifp->name, vrf_id,
996c9314 193 ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
b5a8894d
CS
194
195 /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
a36898e7 196 if_update_to_new_vrf(ifp, new_vrf_id);
b5a8894d 197
996c9314 198 return 0;
b5a8894d
CS
199}
200
7fd0729f
G
201/* Nexthop, ifindex, distance and metric information. */
202static void ospf_zebra_add_nexthop(struct ospf *ospf, struct ospf_path *path,
203 struct zapi_route *api)
204{
205 struct zapi_nexthop *api_nh;
206 struct zapi_nexthop *api_nh_backup;
207
208 /* TI-LFA backup path label stack comes first, if present */
209 if (path->srni.backup_label_stack) {
210 api_nh_backup = &api->backup_nexthops[api->backup_nexthop_num];
211 api_nh_backup->vrf_id = ospf->vrf_id;
212
f026b24e 213 api_nh_backup->type = NEXTHOP_TYPE_IPV4;
7fd0729f
G
214 api_nh_backup->gate.ipv4 = path->srni.backup_nexthop;
215
216 api_nh_backup->label_num =
217 path->srni.backup_label_stack->num_labels;
218 memcpy(api_nh_backup->labels,
219 path->srni.backup_label_stack->label,
220 sizeof(mpls_label_t) * api_nh_backup->label_num);
221
222 api->backup_nexthop_num++;
223 }
224
225 /* And here comes the primary nexthop */
226 api_nh = &api->nexthops[api->nexthop_num];
227#ifdef HAVE_NETLINK
228 if (path->unnumbered
229 || (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0)) {
230#else /* HAVE_NETLINK */
231 if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) {
232#endif /* HAVE_NETLINK */
233 api_nh->gate.ipv4 = path->nexthop;
234 api_nh->ifindex = path->ifindex;
235 api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
236 } else if (path->nexthop.s_addr != INADDR_ANY) {
237 api_nh->gate.ipv4 = path->nexthop;
238 api_nh->type = NEXTHOP_TYPE_IPV4;
239 } else {
240 api_nh->ifindex = path->ifindex;
241 api_nh->type = NEXTHOP_TYPE_IFINDEX;
242 }
243 api_nh->vrf_id = ospf->vrf_id;
244
245 /* Set TI-LFA backup nexthop info if present */
246 if (path->srni.backup_label_stack) {
247 SET_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
248 SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
249
250 /* Just care about a single TI-LFA backup path for now */
251 api_nh->backup_num = 1;
252 api_nh->backup_idx[0] = api->backup_nexthop_num - 1;
253 }
254
255 api->nexthop_num++;
256}
257
b5a8894d 258void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
996c9314 259 struct ospf_route * or)
718e3744 260{
5fef910e 261 struct zapi_route api;
d7c0a89a 262 uint8_t distance;
d62a17ae 263 struct ospf_path *path;
264 struct listnode *node;
d62a17ae 265
5fef910e 266 memset(&api, 0, sizeof(api));
b5a8894d 267 api.vrf_id = ospf->vrf_id;
5fef910e
RW
268 api.type = ZEBRA_ROUTE_OSPF;
269 api.instance = ospf->instance;
270 api.safi = SAFI_UNICAST;
d00061ea 271
5fef910e
RW
272 memcpy(&api.prefix, p, sizeof(*p));
273 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
d00061ea 274
5fef910e
RW
275 /* Metric value. */
276 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
277 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
278 api.metric = or->cost + or->u.ext.type2_cost;
279 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
280 api.metric = or->u.ext.type2_cost;
281 else
282 api.metric = or->cost;
d00061ea
RW
283
284 /* Check if path type is ASE */
285 if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
286 || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL))
5fef910e
RW
287 && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) {
288 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
289 api.tag = or->u.ext.tag;
290 }
d00061ea 291
5fef910e 292 /* Distance value. */
b5a8894d 293 distance = ospf_distance_apply(ospf, p, or);
5fef910e
RW
294 if (distance) {
295 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
296 api.distance = distance;
297 }
d00061ea 298
d00061ea 299 for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) {
7fd0729f 300 if (api.nexthop_num >= MULTIPATH_NUM)
a74e593b 301 break;
7fd0729f
G
302
303 ospf_zebra_add_nexthop(ospf, path, &api);
72357f2b 304
d00061ea 305 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
96065dc3
CS
306 struct interface *ifp;
307
308 ifp = if_lookup_by_index(path->ifindex, ospf->vrf_id);
4259ea81 309
d00061ea 310 zlog_debug(
2dbe669b
DA
311 "Zebra: Route add %pFX nexthop %pI4, ifindex=%d %s",
312 p, &path->nexthop, path->ifindex,
313 ifp ? ifp->name : " ");
d62a17ae 314 }
d00061ea 315 }
d62a17ae 316
5fef910e 317 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
718e3744 318}
319
b5a8894d 320void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
996c9314 321 struct ospf_route * or)
718e3744 322{
5fef910e 323 struct zapi_route api;
d62a17ae 324
5fef910e 325 memset(&api, 0, sizeof(api));
b5a8894d 326 api.vrf_id = ospf->vrf_id;
5fef910e
RW
327 api.type = ZEBRA_ROUTE_OSPF;
328 api.instance = ospf->instance;
329 api.safi = SAFI_UNICAST;
330 memcpy(&api.prefix, p, sizeof(*p));
d62a17ae 331
2dbe669b
DA
332 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
333 zlog_debug("Zebra: Route delete %pFX", p);
d00061ea 334
5fef910e 335 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
718e3744 336}
337
b5a8894d 338void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
718e3744 339{
5fef910e 340 struct zapi_route api;
d62a17ae 341
5fef910e 342 memset(&api, 0, sizeof(api));
b5a8894d 343 api.vrf_id = ospf->vrf_id;
d00061ea
RW
344 api.type = ZEBRA_ROUTE_OSPF;
345 api.instance = ospf->instance;
d00061ea 346 api.safi = SAFI_UNICAST;
5fef910e 347 memcpy(&api.prefix, p, sizeof(*p));
09a484dd 348 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
d00061ea 349
5fef910e 350 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
d00061ea 351
2dbe669b
DA
352 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
353 zlog_debug("Zebra: Route add discard %pFX", p);
718e3744 354}
355
b5a8894d 356void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
718e3744 357{
5fef910e 358 struct zapi_route api;
d62a17ae 359
5fef910e 360 memset(&api, 0, sizeof(api));
b5a8894d 361 api.vrf_id = ospf->vrf_id;
d00061ea
RW
362 api.type = ZEBRA_ROUTE_OSPF;
363 api.instance = ospf->instance;
d00061ea 364 api.safi = SAFI_UNICAST;
5fef910e 365 memcpy(&api.prefix, p, sizeof(*p));
09a484dd 366 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
d00061ea 367
5fef910e 368 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
d00061ea 369
2dbe669b
DA
370 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
371 zlog_debug("Zebra: Route delete discard %pFX", p);
718e3744 372}
373
d7c0a89a
QY
374struct ospf_external *ospf_external_lookup(struct ospf *ospf, uint8_t type,
375 unsigned short instance)
7c8ff89e 376{
d62a17ae 377 struct list *ext_list;
378 struct listnode *node;
379 struct ospf_external *ext;
7c8ff89e 380
de1ac5fd 381 ext_list = ospf->external[type];
d62a17ae 382 if (!ext_list)
383 return (NULL);
7c8ff89e 384
d62a17ae 385 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
386 if (ext->instance == instance)
387 return ext;
7c8ff89e 388
d62a17ae 389 return NULL;
7c8ff89e
DS
390}
391
d7c0a89a
QY
392struct ospf_external *ospf_external_add(struct ospf *ospf, uint8_t type,
393 unsigned short instance)
7c8ff89e 394{
d62a17ae 395 struct list *ext_list;
396 struct ospf_external *ext;
7c8ff89e 397
de1ac5fd 398 ext = ospf_external_lookup(ospf, type, instance);
d62a17ae 399 if (ext)
400 return ext;
7c8ff89e 401
de1ac5fd
CS
402 if (!ospf->external[type])
403 ospf->external[type] = list_new();
7c8ff89e 404
de1ac5fd 405 ext_list = ospf->external[type];
9f5dc319 406 ext = XCALLOC(MTYPE_OSPF_EXTERNAL, sizeof(struct ospf_external));
d62a17ae 407 ext->instance = instance;
408 EXTERNAL_INFO(ext) = route_table_init();
7c8ff89e 409
d62a17ae 410 listnode_add(ext_list, ext);
7c8ff89e 411
d62a17ae 412 return ext;
7c8ff89e
DS
413}
414
1febb13d
S
415/*
416 * Walk all the ei received from zebra for a route type and apply
417 * default route-map.
418 */
419bool ospf_external_default_routemap_apply_walk(struct ospf *ospf,
420 struct list *ext_list,
421 struct external_info *default_ei)
422{
423 struct listnode *node;
424 struct ospf_external *ext;
425 struct route_node *rn;
426 struct external_info *ei = NULL;
427 int ret = 0;
428
429 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
430 if (!ext->external_info)
431 continue;
432
433 for (rn = route_top(ext->external_info); rn;
434 rn = route_next(rn)) {
435 ei = rn->info;
436 if (!ei)
437 continue;
438 ret = ospf_external_info_apply_default_routemap(
439 ospf, ei, default_ei);
440 if (ret)
441 break;
442 }
443 }
444
445 if (ret && ei) {
446 if (IS_DEBUG_OSPF_DEFAULT_INFO)
96b663a3
MS
447 zlog_debug("Default originate routemap permit ei: %pI4",
448 &ei->p.prefix);
1febb13d
S
449 return true;
450 }
451
452 return false;
453}
454
455/*
456 * Function to originate or flush default after applying
457 * route-map on all ei.
458 */
459static int ospf_external_lsa_default_routemap_timer(struct thread *thread)
460{
461 struct list *ext_list;
462 struct ospf *ospf = THREAD_ARG(thread);
463 struct prefix_ipv4 p;
464 int type;
465 int ret = 0;
466 struct ospf_lsa *lsa;
467 struct external_info *default_ei;
468
469 p.family = AF_INET;
470 p.prefixlen = 0;
471 p.prefix.s_addr = INADDR_ANY;
472
473 /* Get the default extenal info. */
474 default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE,
475 ospf->instance, &p);
476 if (!default_ei) {
477 /* Nothing to be done here. */
478 if (IS_DEBUG_OSPF_DEFAULT_INFO)
479 zlog_debug("Default originate info not present");
480 return 0;
481 }
482
483 /* For all the ei apply route-map */
484 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
485 ext_list = ospf->external[type];
486 if (!ext_list || type == ZEBRA_ROUTE_OSPF)
487 continue;
488
489 ret = ospf_external_default_routemap_apply_walk(ospf, ext_list,
490 default_ei);
491 if (ret)
492 break;
493 }
494
495 /* Get the default LSA. */
496 lsa = ospf_external_info_find_lsa(ospf, &p);
497
498 /* If permit then originate default. */
499 if (ret && !lsa)
500 ospf_external_lsa_originate(ospf, default_ei);
501 else if (ret && lsa && IS_LSA_MAXAGE(lsa))
63f0e941 502 ospf_external_lsa_refresh(ospf, lsa, default_ei, true, false);
1febb13d
S
503 else if (!ret && lsa)
504 ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &default_ei->p, 0);
505
506 return 1;
507}
508
509
d7c0a89a 510void ospf_external_del(struct ospf *ospf, uint8_t type, unsigned short instance)
7c8ff89e 511{
d62a17ae 512 struct ospf_external *ext;
513
de1ac5fd 514 ext = ospf_external_lookup(ospf, type, instance);
d62a17ae 515
516 if (ext) {
517 if (EXTERNAL_INFO(ext))
518 route_table_finish(EXTERNAL_INFO(ext));
519
de1ac5fd
CS
520 listnode_delete(ospf->external[type], ext);
521
522 if (!ospf->external[type]->count)
6a154c88 523 list_delete(&ospf->external[type]);
de1ac5fd 524
7f586094 525 XFREE(MTYPE_OSPF_EXTERNAL, ext);
d62a17ae 526 }
1febb13d
S
527
528 /*
529 * Check if default needs to be flushed too.
530 */
531 thread_add_event(master, ospf_external_lsa_default_routemap_timer, ospf,
532 0, &ospf->t_default_routemap_timer);
7c8ff89e
DS
533}
534
43e7abb5
OD
535/* Update NHLFE for Prefix SID */
536void ospf_zebra_update_prefix_sid(const struct sr_prefix *srp)
537{
538 struct zapi_labels zl;
539 struct zapi_nexthop *znh;
4ea5353b 540 struct zapi_nexthop *znh_backup;
43e7abb5
OD
541 struct listnode *node;
542 struct ospf_path *path;
543
43e7abb5
OD
544 /* Prepare message. */
545 memset(&zl, 0, sizeof(zl));
546 zl.type = ZEBRA_LSP_OSPF_SR;
547 zl.local_label = srp->label_in;
548
549 switch (srp->type) {
550 case LOCAL_SID:
551 /* Set Label for local Prefix */
552 znh = &zl.nexthops[zl.nexthop_num++];
553 znh->type = NEXTHOP_TYPE_IFINDEX;
554 znh->ifindex = srp->nhlfe.ifindex;
555 znh->label_num = 1;
556 znh->labels[0] = srp->nhlfe.label_out;
56981b40
OD
557
558 osr_debug("SR (%s): Configure Prefix %pFX with labels %u/%u",
559 __func__, (struct prefix *)&srp->prefv4,
560 srp->label_in, srp->nhlfe.label_out);
561
43e7abb5
OD
562 break;
563
564 case PREF_SID:
565 /* Update route in the RIB too. */
566 SET_FLAG(zl.message, ZAPI_LABELS_FTN);
567 zl.route.prefix.u.prefix4 = srp->prefv4.prefix;
568 zl.route.prefix.prefixlen = srp->prefv4.prefixlen;
569 zl.route.prefix.family = srp->prefv4.family;
570 zl.route.type = ZEBRA_ROUTE_OSPF;
571 zl.route.instance = 0;
572
573 /* Check that SRP contains at least one valid path */
574 if (srp->route == NULL) {
575 return;
576 }
56981b40
OD
577
578 osr_debug("SR (%s): Configure Prefix %pFX with",
579 __func__, (struct prefix *)&srp->prefv4);
580
43e7abb5
OD
581 for (ALL_LIST_ELEMENTS_RO(srp->route->paths, node, path)) {
582 if (path->srni.label_out == MPLS_INVALID_LABEL)
583 continue;
584
585 if (zl.nexthop_num >= MULTIPATH_NUM)
586 break;
587
f026b24e
G
588 /*
589 * TI-LFA backup path label stack comes first, if
590 * present.
591 */
4ea5353b
G
592 if (path->srni.backup_label_stack) {
593 znh_backup = &zl.backup_nexthops
594 [zl.backup_nexthop_num++];
f026b24e 595 znh_backup->type = NEXTHOP_TYPE_IPV4;
4ea5353b
G
596 znh_backup->gate.ipv4 =
597 path->srni.backup_nexthop;
598
4ea5353b
G
599 memcpy(znh_backup->labels,
600 path->srni.backup_label_stack->label,
601 sizeof(mpls_label_t)
f026b24e
G
602 * path->srni.backup_label_stack
603 ->num_labels);
604
605 znh_backup->label_num =
606 path->srni.backup_label_stack
607 ->num_labels;
608 if (path->srni.label_out
609 != MPLS_LABEL_IPV4_EXPLICIT_NULL
610 && path->srni.label_out
611 != MPLS_LABEL_IMPLICIT_NULL)
612 znh_backup->labels
613 [znh_backup->label_num++] =
614 path->srni.label_out;
4ea5353b
G
615 }
616
43e7abb5
OD
617 znh = &zl.nexthops[zl.nexthop_num++];
618 znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
619 znh->gate.ipv4 = path->nexthop;
620 znh->ifindex = path->ifindex;
621 znh->label_num = 1;
622 znh->labels[0] = path->srni.label_out;
4ea5353b 623
56981b40 624 osr_debug(" |- labels %u/%u", srp->label_in,
270e66a2 625 path->srni.label_out);
56981b40 626
4ea5353b
G
627 /* Set TI-LFA backup nexthop info if present */
628 if (path->srni.backup_label_stack) {
629 SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
630 SET_FLAG(znh->flags,
631 ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
632
633 /* Just care about a single TI-LFA backup path
634 * for now */
635 znh->backup_num = 1;
636 znh->backup_idx[0] = zl.backup_nexthop_num - 1;
637 }
43e7abb5
OD
638 }
639 break;
640 default:
641 return;
642 }
643
644 /* Finally, send message to zebra. */
645 (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
646}
647
648/* Remove NHLFE for Prefix-SID */
649void ospf_zebra_delete_prefix_sid(const struct sr_prefix *srp)
650{
651 struct zapi_labels zl;
652
653 osr_debug("SR (%s): Delete Labels %u for Prefix %pFX", __func__,
654 srp->label_in, (struct prefix *)&srp->prefv4);
655
656 /* Prepare message. */
657 memset(&zl, 0, sizeof(zl));
658 zl.type = ZEBRA_LSP_OSPF_SR;
659 zl.local_label = srp->label_in;
660
661 if (srp->type == PREF_SID) {
662 /* Update route in the RIB too */
663 SET_FLAG(zl.message, ZAPI_LABELS_FTN);
664 zl.route.prefix.u.prefix4 = srp->prefv4.prefix;
665 zl.route.prefix.prefixlen = srp->prefv4.prefixlen;
666 zl.route.prefix.family = srp->prefv4.family;
667 zl.route.type = ZEBRA_ROUTE_OSPF;
668 zl.route.instance = 0;
669 }
670
671 /* Send message to zebra. */
672 (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
673}
674
675/* Send MPLS Label entry to Zebra for installation or deletion */
676void ospf_zebra_send_adjacency_sid(int cmd, struct sr_nhlfe nhlfe)
677{
678 struct zapi_labels zl;
679 struct zapi_nexthop *znh;
680
681 osr_debug("SR (%s): %s Labels %u/%u for Adjacency via %u", __func__,
682 cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete",
683 nhlfe.label_in, nhlfe.label_out, nhlfe.ifindex);
684
685 memset(&zl, 0, sizeof(zl));
686 zl.type = ZEBRA_LSP_OSPF_SR;
687 zl.local_label = nhlfe.label_in;
688 zl.nexthop_num = 1;
689 znh = &zl.nexthops[0];
690 znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
691 znh->gate.ipv4 = nhlfe.nexthop;
692 znh->ifindex = nhlfe.ifindex;
693 znh->label_num = 1;
694 znh->labels[0] = nhlfe.label_out;
695
696 (void)zebra_send_mpls_labels(zclient, cmd, &zl);
697}
698
d7c0a89a
QY
699struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, uint8_t type,
700 unsigned short instance)
7c8ff89e 701{
d62a17ae 702 struct list *red_list;
703 struct listnode *node;
704 struct ospf_redist *red;
7c8ff89e 705
d62a17ae 706 red_list = ospf->redist[type];
707 if (!red_list)
708 return (NULL);
7c8ff89e 709
d62a17ae 710 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
711 if (red->instance == instance)
712 return red;
7c8ff89e 713
d62a17ae 714 return NULL;
7c8ff89e
DS
715}
716
d7c0a89a
QY
717struct ospf_redist *ospf_redist_add(struct ospf *ospf, uint8_t type,
718 unsigned short instance)
7c8ff89e 719{
d62a17ae 720 struct list *red_list;
721 struct ospf_redist *red;
7c8ff89e 722
d62a17ae 723 red = ospf_redist_lookup(ospf, type, instance);
724 if (red)
725 return red;
7c8ff89e 726
d62a17ae 727 if (!ospf->redist[type])
728 ospf->redist[type] = list_new();
7c8ff89e 729
d62a17ae 730 red_list = ospf->redist[type];
9f5dc319 731 red = XCALLOC(MTYPE_OSPF_REDISTRIBUTE, sizeof(struct ospf_redist));
d62a17ae 732 red->instance = instance;
733 red->dmetric.type = -1;
734 red->dmetric.value = -1;
1fb93326 735 ROUTEMAP_NAME(red) = NULL;
736 ROUTEMAP(red) = NULL;
7c8ff89e 737
d62a17ae 738 listnode_add(red_list, red);
7c8ff89e 739
d62a17ae 740 return red;
7c8ff89e
DS
741}
742
d7c0a89a 743void ospf_redist_del(struct ospf *ospf, uint8_t type, unsigned short instance)
7c8ff89e 744{
d62a17ae 745 struct ospf_redist *red;
746
747 red = ospf_redist_lookup(ospf, type, instance);
748
749 if (red) {
750 listnode_delete(ospf->redist[type], red);
751 if (!ospf->redist[type]->count) {
6a154c88 752 list_delete(&ospf->redist[type]);
d62a17ae 753 }
97a69b31 754 ospf_routemap_unset(red);
7f586094 755 XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
d62a17ae 756 }
7c8ff89e
DS
757}
758
759
d7c0a89a
QY
760int ospf_is_type_redistributed(struct ospf *ospf, int type,
761 unsigned short instance)
718e3744 762{
d62a17ae 763 return (DEFAULT_ROUTE_TYPE(type)
49db7a7b 764 ? vrf_bitmap_check(zclient->default_information[AFI_IP],
b5a8894d 765 ospf->vrf_id)
d62a17ae 766 : ((instance
767 && redist_check_instance(
768 &zclient->mi_redist[AFI_IP][type],
769 instance))
770 || (!instance
771 && vrf_bitmap_check(
772 zclient->redist[AFI_IP][type],
b5a8894d 773 ospf->vrf_id))));
718e3744 774}
775
d7c0a89a 776int ospf_redistribute_set(struct ospf *ospf, int type, unsigned short instance,
d62a17ae 777 int mtype, int mvalue)
718e3744 778{
d62a17ae 779 int force = 0;
780 struct ospf_redist *red;
781
782 red = ospf_redist_lookup(ospf, type, instance);
162dbe41 783
784 if (red == NULL) {
785 zlog_err(
786 "Redistribute[%s][%d]: Lookup failed Type[%d] , Metric[%d]",
787 ospf_redist_string(type), instance,
788 metric_type(ospf, type, instance),
789 metric_value(ospf, type, instance));
790 return CMD_WARNING_CONFIG_FAILED;
791 }
792
b5a8894d 793 if (ospf_is_type_redistributed(ospf, type, instance)) {
d62a17ae 794 if (mtype != red->dmetric.type) {
795 red->dmetric.type = mtype;
796 force = LSA_REFRESH_FORCE;
797 }
798 if (mvalue != red->dmetric.value) {
799 red->dmetric.value = mvalue;
800 force = LSA_REFRESH_FORCE;
801 }
802
803 ospf_external_lsa_refresh_type(ospf, type, instance, force);
804
805 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
806 zlog_debug(
807 "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
808 ospf_redist_string(type), instance,
809 metric_type(ospf, type, instance),
810 metric_value(ospf, type, instance));
811
812 return CMD_SUCCESS;
813 }
814
815 red->dmetric.type = mtype;
816 red->dmetric.value = mvalue;
817
de1ac5fd 818 ospf_external_add(ospf, type, instance);
d62a17ae 819
820 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
b5a8894d 821 instance, ospf->vrf_id);
d62a17ae 822
823 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
996c9314
LB
824 zlog_debug(
825 "Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
826 ospf_redist_string(type), instance, ospf->vrf_id,
827 metric_type(ospf, type, instance),
828 metric_value(ospf, type, instance));
d62a17ae 829
830 ospf_asbr_status_update(ospf, ++ospf->redistribute);
831
832 return CMD_SUCCESS;
718e3744 833}
834
d7c0a89a
QY
835int ospf_redistribute_unset(struct ospf *ospf, int type,
836 unsigned short instance)
718e3744 837{
d62a17ae 838 if (type == zclient->redist_default && instance == zclient->instance)
839 return CMD_SUCCESS;
718e3744 840
b5a8894d 841 if (!ospf_is_type_redistributed(ospf, type, instance))
d62a17ae 842 return CMD_SUCCESS;
718e3744 843
d62a17ae 844 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
b5a8894d 845 instance, ospf->vrf_id);
cf795c5d 846
d62a17ae 847 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
b5a8894d
CS
848 zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
849 ospf_redist_string(type), instance, ospf->vrf_id);
718e3744 850
d62a17ae 851 /* Remove the routes from OSPF table. */
852 ospf_redistribute_withdraw(ospf, type, instance);
7c8ff89e 853
de1ac5fd 854 ospf_external_del(ospf, type, instance);
718e3744 855
d62a17ae 856 ospf_asbr_status_update(ospf, --ospf->redistribute);
718e3744 857
d62a17ae 858 return CMD_SUCCESS;
718e3744 859}
860
d62a17ae 861int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
862 int mvalue)
718e3744 863{
1fb93326 864 struct prefix_ipv4 p;
865 struct in_addr nexthop;
866 int cur_originate = ospf->default_originate;
d5eac1e0 867 const char *type_str = NULL;
1fb93326 868
975a328e 869 nexthop.s_addr = INADDR_ANY;
1fb93326 870 p.family = AF_INET;
975a328e 871 p.prefix.s_addr = INADDR_ANY;
1fb93326 872 p.prefixlen = 0;
873
d62a17ae 874 ospf->default_originate = originate;
020709f9 875
d5eac1e0 876 if (cur_originate == originate) {
1fb93326 877 /* Refresh the lsa since metric might different */
d62a17ae 878 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
879 zlog_debug(
880 "Redistribute[%s]: Refresh Type[%d], Metric[%d]",
881 ospf_redist_string(DEFAULT_ROUTE),
882 metric_type(ospf, DEFAULT_ROUTE, 0),
883 metric_value(ospf, DEFAULT_ROUTE, 0));
718e3744 884
1fb93326 885 ospf_external_lsa_refresh_default(ospf);
d5eac1e0 886 return CMD_SUCCESS;
1fb93326 887 }
718e3744 888
d5eac1e0
DL
889 switch (cur_originate) {
890 case DEFAULT_ORIGINATE_NONE:
891 break;
892 case DEFAULT_ORIGINATE_ZEBRA:
1fb93326 893 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
49db7a7b 894 zclient, AFI_IP, ospf->vrf_id);
d5eac1e0
DL
895 ospf->redistribute--;
896 break;
897 case DEFAULT_ORIGINATE_ALWAYS:
898 ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, p);
899 ospf_external_del(ospf, DEFAULT_ROUTE, 0);
900 ospf->redistribute--;
901 break;
1fb93326 902 }
718e3744 903
d5eac1e0
DL
904 switch (originate) {
905 case DEFAULT_ORIGINATE_NONE:
906 type_str = "none";
907 break;
908 case DEFAULT_ORIGINATE_ZEBRA:
909 type_str = "normal";
910 ospf->redistribute++;
911 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
912 zclient, AFI_IP, ospf->vrf_id);
913 break;
914 case DEFAULT_ORIGINATE_ALWAYS:
915 type_str = "always";
916 ospf->redistribute++;
917 ospf_external_add(ospf, DEFAULT_ROUTE, 0);
918 ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, p, 0, nexthop,
919 0);
920 break;
921 }
718e3744 922
d62a17ae 923 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
d5eac1e0
DL
924 zlog_debug("Redistribute[DEFAULT]: %s Type[%d], Metric[%d]",
925 type_str,
926 metric_type(ospf, DEFAULT_ROUTE, 0),
927 metric_value(ospf, DEFAULT_ROUTE, 0));
718e3744 928
d5eac1e0
DL
929 ospf_external_lsa_refresh_default(ospf);
930 ospf_asbr_status_update(ospf, ospf->redistribute);
d62a17ae 931 return CMD_SUCCESS;
718e3744 932}
933
d62a17ae 934static int ospf_external_lsa_originate_check(struct ospf *ospf,
935 struct external_info *ei)
718e3744 936{
d62a17ae 937 /* If prefix is multicast, then do not originate LSA. */
938 if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) {
939 zlog_info(
96b663a3
MS
940 "LSA[Type5:%pI4]: Not originate AS-external-LSA, Prefix belongs multicast",
941 &ei->p.prefix);
d62a17ae 942 return 0;
943 }
944
945 /* Take care of default-originate. */
946 if (is_prefix_default(&ei->p))
947 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) {
948 zlog_info(
3efd0893 949 "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA for default");
d62a17ae 950 return 0;
951 }
952
953 return 1;
718e3744 954}
955
956/* If connected prefix is OSPF enable interface, then do not announce. */
d62a17ae 957int ospf_distribute_check_connected(struct ospf *ospf, struct external_info *ei)
718e3744 958{
d62a17ae 959 struct listnode *node;
960 struct ospf_interface *oi;
718e3744 961
718e3744 962
d62a17ae 963 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
964 if (prefix_match(oi->address, (struct prefix *)&ei->p))
965 return 0;
966 return 1;
718e3744 967}
968
1febb13d
S
969
970/* Apply default route-map on ei received. */
971int ospf_external_info_apply_default_routemap(struct ospf *ospf,
972 struct external_info *ei,
973 struct external_info *default_ei)
974{
975 struct ospf_redist *red;
976 int type = default_ei->type;
977 struct prefix_ipv4 *p = &ei->p;
978 struct route_map_set_values save_values;
979
980
981 if (!ospf_external_lsa_originate_check(ospf, default_ei))
982 return 0;
983
984 save_values = default_ei->route_map_set;
985 ospf_reset_route_map_set_values(&default_ei->route_map_set);
986
987 /* apply route-map if needed */
988 red = ospf_redist_lookup(ospf, type, ospf->instance);
989 if (red && ROUTEMAP_NAME(red)) {
990 route_map_result_t ret;
991
1782514f 992 ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, ei);
1febb13d
S
993
994 if (ret == RMAP_DENYMATCH) {
995 ei->route_map_set = save_values;
996 return 0;
997 }
998 }
999
1000 return 1;
1001}
1002
1003
1004/*
1005 * Default originated is based on route-map condition then
1006 * apply route-map on received external info. Originate or
1007 * flush based on route-map condition.
1008 */
1009static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
1010 struct external_info *ei,
1011 int cmd)
1012{
1013 struct external_info *default_ei;
1014 struct prefix_ipv4 p;
1015 struct ospf_lsa *lsa;
1016 int ret;
1017
1018 p.family = AF_INET;
1019 p.prefixlen = 0;
1020 p.prefix.s_addr = INADDR_ANY;
1021
1022
1023 /* Get the default extenal info. */
1024 default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE,
1025 ospf->instance, &p);
1026 if (!default_ei) {
1027 /* Nothing to be done here. */
1028 return false;
1029 }
1030
1031 if (IS_DEBUG_OSPF_DEFAULT_INFO)
96b663a3
MS
1032 zlog_debug("Apply default originate routemap on ei: %pI4 cmd: %d",
1033 &ei->p.prefix, cmd);
1febb13d
S
1034
1035 ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei);
1036
1037 /* If deny then nothing to be done both in add and del case. */
1038 if (!ret) {
1039 if (IS_DEBUG_OSPF_DEFAULT_INFO)
96b663a3
MS
1040 zlog_debug("Default originte routemap deny for ei: %pI4",
1041 &ei->p.prefix);
1febb13d
S
1042 return false;
1043 }
1044
1045 /* Get the default LSA. */
1046 lsa = ospf_external_info_find_lsa(ospf, &p);
1047
1048 /* If this is add route and permit then ooriginate default. */
1049 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
1050 /* If permit and default already advertise then return. */
1051 if (lsa && !IS_LSA_MAXAGE(lsa)) {
1052 if (IS_DEBUG_OSPF_DEFAULT_INFO)
02c671af 1053 zlog_debug("Default lsa already originated");
1febb13d
S
1054 return true;
1055 }
1056
1057 if (IS_DEBUG_OSPF_DEFAULT_INFO)
1058 zlog_debug("Originating/Refreshing default lsa");
1059
1060 if (lsa && IS_LSA_MAXAGE(lsa))
1061 /* Refresh lsa.*/
63f0e941 1062 ospf_external_lsa_refresh(ospf, lsa, default_ei, true,
1063 false);
1febb13d
S
1064 else
1065 /* If permit and default not advertised then advertise.
1066 */
1067 ospf_external_lsa_originate(ospf, default_ei);
1068
1069 } else if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) {
1070 /* If deny and lsa is not originated then nothing to be done.*/
1071 if (!lsa) {
1072 if (IS_DEBUG_OSPF_DEFAULT_INFO)
1073 zlog_debug(
1074 "Default lsa not originated, not flushing");
1075 return true;
1076 }
1077
1078 if (IS_DEBUG_OSPF_DEFAULT_INFO)
1079 zlog_debug(
96b663a3
MS
1080 "Running default route-map again as ei: %pI4 deleted",
1081 &ei->p.prefix);
1febb13d
S
1082 /*
1083 * if this route delete was permitted then we need to check
1084 * there are any other external info which can still trigger
1085 * default route origination else flush it.
1086 */
1087 thread_add_event(master,
1088 ospf_external_lsa_default_routemap_timer, ospf,
1089 0, &ospf->t_default_routemap_timer);
1090 }
1091
1092 return true;
1093}
1094
718e3744 1095/* return 1 if external LSA must be originated, 0 otherwise */
d62a17ae 1096int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
1097 int *changed)
718e3744 1098{
d62a17ae 1099 struct route_map_set_values save_values;
1100 struct prefix_ipv4 *p = &ei->p;
1101 struct ospf_redist *red;
d7c0a89a
QY
1102 uint8_t type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type;
1103 unsigned short instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
87e6e11e 1104 route_tag_t saved_tag = 0;
d62a17ae 1105
1febb13d
S
1106 /* Default is handled differently. */
1107 if (type == DEFAULT_ROUTE)
1108 return 1;
1109
d62a17ae 1110 if (changed)
1111 *changed = 0;
1112
1113 if (!ospf_external_lsa_originate_check(ospf, ei))
1114 return 0;
1115
1116 /* Take care connected route. */
1117 if (type == ZEBRA_ROUTE_CONNECT
1118 && !ospf_distribute_check_connected(ospf, ei))
1119 return 0;
1120
1121 if (!DEFAULT_ROUTE_TYPE(type) && DISTRIBUTE_NAME(ospf, type))
1122 /* distirbute-list exists, but access-list may not? */
1123 if (DISTRIBUTE_LIST(ospf, type))
1124 if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p)
1125 == FILTER_DENY) {
2dbe669b 1126 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
d62a17ae 1127 zlog_debug(
2dbe669b
DA
1128 "Redistribute[%s]: %pFX filtered by distribute-list.",
1129 ospf_redist_string(type), p);
d62a17ae 1130 return 0;
1131 }
1132
1133 save_values = ei->route_map_set;
1134 ospf_reset_route_map_set_values(&ei->route_map_set);
04e94d39 1135
87e6e11e 1136 saved_tag = ei->tag;
04e94d39 1137 /* Resetting with original route tag */
1138 ei->tag = ei->orig_tag;
d62a17ae 1139
1140 /* apply route-map if needed */
1141 red = ospf_redist_lookup(ospf, type, instance);
1142 if (red && ROUTEMAP_NAME(red)) {
b68885f9 1143 route_map_result_t ret;
d62a17ae 1144
1782514f 1145 ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, ei);
d62a17ae 1146
1147 if (ret == RMAP_DENYMATCH) {
1148 ei->route_map_set = save_values;
2dbe669b 1149 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
d62a17ae 1150 zlog_debug(
2dbe669b
DA
1151 "Redistribute[%s]: %pFX filtered by route-map.",
1152 ospf_redist_string(type), p);
d62a17ae 1153 return 0;
1154 }
1155
1156 /* check if 'route-map set' changed something */
87e6e11e 1157 if (changed) {
d62a17ae 1158 *changed = !ospf_route_map_set_compare(
1159 &ei->route_map_set, &save_values);
87e6e11e 1160
1161 /* check if tag is modified */
1162 *changed |= (saved_tag != ei->tag);
1163 }
d62a17ae 1164 }
1165
1166 return 1;
718e3744 1167}
1168
1169/* OSPF route-map set for redistribution */
d62a17ae 1170void ospf_routemap_set(struct ospf_redist *red, const char *name)
718e3744 1171{
93d836e6 1172 if (ROUTEMAP_NAME(red)) {
1173 route_map_counter_decrement(ROUTEMAP(red));
d62a17ae 1174 free(ROUTEMAP_NAME(red));
93d836e6 1175 }
718e3744 1176
d62a17ae 1177 ROUTEMAP_NAME(red) = strdup(name);
1178 ROUTEMAP(red) = route_map_lookup_by_name(name);
93d836e6 1179 route_map_counter_increment(ROUTEMAP(red));
718e3744 1180}
1181
d62a17ae 1182void ospf_routemap_unset(struct ospf_redist *red)
718e3744 1183{
93d836e6 1184 if (ROUTEMAP_NAME(red)) {
1185 route_map_counter_decrement(ROUTEMAP(red));
d62a17ae 1186 free(ROUTEMAP_NAME(red));
93d836e6 1187 }
718e3744 1188
d62a17ae 1189 ROUTEMAP_NAME(red) = NULL;
1190 ROUTEMAP(red) = NULL;
718e3744 1191}
1192
1193/* Zebra route add and delete treatment. */
121f9dee 1194static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
718e3744 1195{
74489921
RW
1196 struct zapi_route api;
1197 struct prefix_ipv4 p;
d62a17ae 1198 unsigned long ifindex;
1199 struct in_addr nexthop;
d62a17ae 1200 struct external_info *ei;
1201 struct ospf *ospf;
1202 int i;
1fb93326 1203 uint8_t rt_type;
d62a17ae 1204
b5a8894d 1205 ospf = ospf_lookup_by_vrf_id(vrf_id);
74489921
RW
1206 if (ospf == NULL)
1207 return 0;
d62a17ae 1208
74489921
RW
1209 if (zapi_route_decode(zclient->ibuf, &api) < 0)
1210 return -1;
d62a17ae 1211
74489921
RW
1212 ifindex = api.nexthops[0].ifindex;
1213 nexthop = api.nexthops[0].gate.ipv4;
1fb93326 1214 rt_type = api.type;
d62a17ae 1215
74489921 1216 memcpy(&p, &api.prefix, sizeof(p));
d62a17ae 1217 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
1218 return 0;
1219
1fb93326 1220 /* Re-destributed route is default route.
1221 * Here, route type is used as 'ZEBRA_ROUTE_KERNEL' for
1222 * updating ex-info. But in resetting (no default-info
1223 * originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
1224 * Resolved this inconsistency by maintaining same route type.
1225 */
1226 if (is_prefix_default(&p))
1227 rt_type = DEFAULT_ROUTE;
1228
2dbe669b
DA
1229 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
1230 zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %pFX",
ae4080c5 1231 __func__, zserv_command_string(cmd),
2dbe669b 1232 zebra_route_string(api.type), vrf_id, &api.prefix);
5c780bc9 1233
121f9dee 1234 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
d62a17ae 1235 /* XXX|HACK|TODO|FIXME:
09a484dd
DL
1236 * Maybe we should ignore reject/blackhole routes? Testing
1237 * shows that there is no problems though and this is only way
1238 * to "summarize" routes in ASBR at the moment. Maybe we need
1239 * just a better generalised solution for these types?
d62a17ae 1240 */
1241
74489921 1242 /* Protocol tag overwrites all other tag value sent by zebra */
1fb93326 1243 if (ospf->dtag[rt_type] > 0)
1244 api.tag = ospf->dtag[rt_type];
d62a17ae 1245
1246 /*
1247 * Given zebra sends update for a prefix via ADD message, it
1248 * should
1249 * be considered as an implicit DEL for that prefix with other
1250 * source
1251 * types.
1252 */
1fb93326 1253 for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
1254 if (i != rt_type)
996c9314
LB
1255 ospf_external_info_delete(ospf, i, api.instance,
1256 p);
d62a17ae 1257
1fb93326 1258 ei = ospf_external_info_add(ospf, rt_type, api.instance, p,
de1ac5fd 1259 ifindex, nexthop, api.tag);
d62a17ae 1260 if (ei == NULL) {
1261 /* Nothing has changed, so nothing to do; return */
1262 return 0;
1263 }
975a328e 1264 if (ospf->router_id.s_addr != INADDR_ANY) {
d62a17ae 1265 if (ei) {
1266 if (is_prefix_default(&p))
1267 ospf_external_lsa_refresh_default(ospf);
1268 else {
960417cf 1269 struct ospf_external_aggr_rt *aggr;
1270 struct as_external_lsa *al;
1271 struct ospf_lsa *lsa = NULL;
1272 struct in_addr mask;
1273
1274 aggr = ospf_external_aggr_match(ospf,
1275 &ei->p);
1276
1277 if (aggr) {
1278 /* Check the AS-external-LSA
1279 * should be originated.
1280 */
1281 if (!ospf_redistribute_check(
1282 ospf, ei, NULL))
1283 return 0;
d62a17ae 1284
d62a17ae 1285 if (IS_DEBUG_OSPF(
960417cf 1286 lsa,
1287 EXTNL_LSA_AGGR))
d62a17ae 1288 zlog_debug(
960417cf 1289 "%s: Send Aggreate LSA (%pI4/%d)",
1290 __func__,
1291 &aggr->p.prefix,
1292 aggr->p.prefixlen);
1293
1294 ospf_originate_summary_lsa(
1295 ospf, aggr, ei);
1296
1297 /* Handling the case where the
1298 * external route prefix
1299 * and aggegate prefix is same
1300 * If same dont flush the
1301 * originated
1302 * external LSA.
1303 */
1304 if (prefix_same(
1305 (struct prefix
1306 *)&aggr->p,
1307 (struct prefix *)&ei
1308 ->p))
1309 return 0;
1310
1311 lsa = ospf_external_info_find_lsa(
1312 ospf, &ei->p);
1313
1314 if (lsa) {
1315 al = (struct
1316 as_external_lsa *)
1317 lsa->data;
1318 masklen2ip(
1319 ei->p.prefixlen,
1320 &mask);
1321
1322 if (mask.s_addr
1323 != al->mask.s_addr)
1324 return 0;
1325
1326 ospf_external_lsa_flush(
1327 ospf, ei->type,
1328 &ei->p, 0);
1329 }
1330 } else {
1331 struct ospf_lsa *current;
1332
1333 current =
1334 ospf_external_info_find_lsa(
1335 ospf, &ei->p);
1336 if (!current) {
1337 /* Check the
1338 * AS-external-LSA
1339 * should be
1340 * originated.
1341 */
1342 if (!ospf_redistribute_check(
1343 ospf, ei,
1344 NULL))
1345 return 0;
1346
1347 ospf_external_lsa_originate(
1348 ospf, ei);
1349 } else {
1350 if (IS_DEBUG_OSPF(
1351 zebra,
1352 ZEBRA_REDISTRIBUTE))
1353 zlog_debug(
1354 "%s: %pI4 refreshing LSA",
1355 __func__,
1356 &p.prefix);
1357 ospf_external_lsa_refresh(
1358 ospf, current,
1359 ei,
1360 LSA_REFRESH_FORCE,
1361 false);
1362 }
d62a17ae 1363 }
1364 }
1365 }
1366 }
1febb13d
S
1367
1368 /*
1369 * Check if default-information originate is
1370 * with some routemap prefix/access list match.
1371 */
1372 ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
1373
121f9dee 1374 } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
5048fe14 1375 {
960417cf 1376 struct ospf_external_aggr_rt *aggr;
1377
1febb13d 1378 ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p);
960417cf 1379 if (ei == NULL)
1380 return 0;
1381 else
1382 /*
1383 * Check if default-information originate i
1384 * with some routemap prefix/access list match.
1385 * Apply before ei is deleted.
1386 */
1febb13d
S
1387 ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
1388
960417cf 1389 aggr = ospf_external_aggr_match(ospf, &ei->p);
1390
1391 if (aggr && (ei->aggr_route == aggr)) {
1392 ospf_unlink_ei_from_aggr(ospf, aggr, ei);
1393
1394 ospf_external_info_delete(ospf, rt_type, api.instance,
1395 p);
1396 } else {
1397 ospf_external_info_delete(ospf, rt_type, api.instance,
1398 p);
1399
1400 if (is_prefix_default(&p))
1401 ospf_external_lsa_refresh_default(ospf);
1402 else
1403 ospf_external_lsa_flush(ospf, rt_type, &p,
1404 ifindex /*, nexthop */);
1405 }
5048fe14 1406 }
d62a17ae 1407
1febb13d 1408
d62a17ae 1409 return 0;
718e3744 1410}
6b0655a2 1411
cf795c5d 1412
d62a17ae 1413int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
718e3744 1414{
d62a17ae 1415 /* Lookup access-list for distribute-list. */
1416 DISTRIBUTE_LIST(ospf, type) = access_list_lookup(AFI_IP, name);
718e3744 1417
d62a17ae 1418 /* Clear previous distribute-name. */
1419 if (DISTRIBUTE_NAME(ospf, type))
1420 free(DISTRIBUTE_NAME(ospf, type));
718e3744 1421
d62a17ae 1422 /* Set distribute-name. */
1423 DISTRIBUTE_NAME(ospf, type) = strdup(name);
718e3744 1424
d62a17ae 1425 /* If access-list have been set, schedule update timer. */
1426 if (DISTRIBUTE_LIST(ospf, type))
1427 ospf_distribute_list_update(ospf, type, 0);
718e3744 1428
d62a17ae 1429 return CMD_SUCCESS;
718e3744 1430}
1431
d62a17ae 1432int ospf_distribute_list_out_unset(struct ospf *ospf, int type,
1433 const char *name)
718e3744 1434{
d62a17ae 1435 /* Schedule update timer. */
1436 if (DISTRIBUTE_LIST(ospf, type))
1437 ospf_distribute_list_update(ospf, type, 0);
718e3744 1438
d62a17ae 1439 /* Unset distribute-list. */
1440 DISTRIBUTE_LIST(ospf, type) = NULL;
718e3744 1441
d62a17ae 1442 /* Clear distribute-name. */
1443 if (DISTRIBUTE_NAME(ospf, type))
1444 free(DISTRIBUTE_NAME(ospf, type));
cf795c5d 1445
d62a17ae 1446 DISTRIBUTE_NAME(ospf, type) = NULL;
718e3744 1447
d62a17ae 1448 return CMD_SUCCESS;
718e3744 1449}
1450
1451/* distribute-list update timer. */
d62a17ae 1452static int ospf_distribute_list_update_timer(struct thread *thread)
718e3744 1453{
d62a17ae 1454 struct route_node *rn;
1455 struct external_info *ei;
1456 struct route_table *rt;
1457 struct ospf_lsa *lsa;
b5a8894d
CS
1458 int type, default_refresh = 0, arg_type;
1459 struct ospf *ospf = NULL;
996c9314 1460 void **arg = THREAD_ARG(thread);
b5a8894d
CS
1461
1462 ospf = (struct ospf *)arg[0];
1463 arg_type = (int)(intptr_t)arg[1];
d62a17ae 1464
d62a17ae 1465 if (ospf == NULL)
1466 return 0;
1467
1468 ospf->t_distribute_update = NULL;
1469
1470 zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
1471
b5a8894d 1472 if (IS_DEBUG_OSPF_EVENT) {
996c9314
LB
1473 zlog_debug(
1474 "%s: ospf distribute-list update arg_type %d vrf %s id %d",
5e81f5dd
DS
1475 __func__, arg_type, ospf_vrf_id_to_name(ospf->vrf_id),
1476 ospf->vrf_id);
b5a8894d
CS
1477 }
1478
d62a17ae 1479 /* foreach all external info. */
1480 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1481 struct list *ext_list;
1482 struct listnode *node;
1483 struct ospf_external *ext;
1484
de1ac5fd 1485 ext_list = ospf->external[type];
d62a17ae 1486 if (!ext_list)
1487 continue;
1488
1489 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
1490 rt = ext->external_info;
1491 if (!rt)
1492 continue;
1493 for (rn = route_top(rt); rn; rn = route_next(rn))
1494 if ((ei = rn->info) != NULL) {
1495 if (is_prefix_default(&ei->p))
1496 default_refresh = 1;
960417cf 1497 else {
1498 struct ospf_external_aggr_rt
1499 *aggr;
1500 aggr = ospf_external_aggr_match(
1501 ospf, &ei->p);
1502 if (aggr) {
1503 /* Check the
1504 * AS-external-LSA
1505 * should be originated.
1506 */
1507 if (!ospf_redistribute_check(
1508 ospf, ei,
1509 NULL)) {
1510
1511 ospf_unlink_ei_from_aggr(
1512 ospf,
1513 aggr,
1514 ei);
1515 continue;
1516 }
1517
1518 if (IS_DEBUG_OSPF(
1519 lsa,
1520 EXTNL_LSA_AGGR))
1521 zlog_debug(
1522 "%s: Send Aggregate LSA (%pI4/%d)",
1523 __func__,
1524 &aggr->p.prefix,
1525 aggr->p.prefixlen);
1526
1527 /* Originate Aggregate
1528 * LSA
1529 */
1530 ospf_originate_summary_lsa(
1531 ospf, aggr, ei);
1532 } else if (
1533 (lsa = ospf_external_info_find_lsa(
1534 ospf,
1535 &ei->p))) {
1536 int force =
1537 LSA_REFRESH_IF_CHANGED;
1538 /* If this is a MaxAge
1539 * LSA, we need to
1540 * force refresh it
1541 * because distribute
1542 * settings might have
1543 * changed and now,
1544 * this LSA needs to be
1545 * originated, not be
1546 * removed.
1547 * If we don't force
1548 * refresh it, it will
1549 * remain a MaxAge LSA
1550 * because it will look
1551 * like it hasn't
1552 * changed. Neighbors
1553 * will not receive
1554 * updates for this LSA.
1555 */
1556 if (IS_LSA_MAXAGE(lsa))
1557 force = LSA_REFRESH_FORCE;
1558
1559 ospf_external_lsa_refresh(
1560 ospf, lsa, ei,
1561 force, false);
1562 } else {
1563 if (!ospf_redistribute_check(
1564 ospf, ei,
1565 NULL))
1566 continue;
1567 ospf_external_lsa_originate(
1568 ospf, ei);
1569 }
1570 }
d62a17ae 1571 }
1572 }
1573 }
1574 if (default_refresh)
1575 ospf_external_lsa_refresh_default(ospf);
b5a8894d
CS
1576
1577 XFREE(MTYPE_OSPF_DIST_ARGS, arg);
d62a17ae 1578 return 0;
718e3744 1579}
1580
718e3744 1581/* Update distribute-list and set timer to apply access-list. */
d7c0a89a
QY
1582void ospf_distribute_list_update(struct ospf *ospf, int type,
1583 unsigned short instance)
718e3744 1584{
d62a17ae 1585 struct ospf_external *ext;
996c9314 1586 void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *) * 2);
d62a17ae 1587
b5a8894d 1588 args[0] = ospf;
996c9314 1589 args[1] = (void *)((ptrdiff_t)type);
b5a8894d 1590
d62a17ae 1591 /* External info does not exist. */
de1ac5fd 1592 ext = ospf_external_lookup(ospf, type, instance);
6e3e2c6d 1593 if (!ext || !EXTERNAL_INFO(ext)) {
a68730c6 1594 XFREE(MTYPE_OSPF_DIST_ARGS, args);
d62a17ae 1595 return;
a68730c6 1596 }
d62a17ae 1597
1598 /* If exists previously invoked thread, then let it continue. */
a68730c6
DS
1599 if (ospf->t_distribute_update) {
1600 XFREE(MTYPE_OSPF_DIST_ARGS, args);
d62a17ae 1601 return;
a68730c6 1602 }
d62a17ae 1603
1604 /* Set timer. */
1605 ospf->t_distribute_update = NULL;
c4efd0f4
DA
1606 thread_add_timer_msec(master, ospf_distribute_list_update_timer, args,
1607 ospf->min_ls_interval,
d62a17ae 1608 &ospf->t_distribute_update);
718e3744 1609}
1610
1611/* If access-list is updated, apply some check. */
d62a17ae 1612static void ospf_filter_update(struct access_list *access)
718e3744 1613{
d62a17ae 1614 struct ospf *ospf;
1615 int type;
1616 int abr_inv = 0;
1617 struct ospf_area *area;
b5a8894d 1618 struct listnode *node, *n1;
d62a17ae 1619
1620 /* If OSPF instance does not exist, return right now. */
b5a8894d 1621 if (listcount(om->ospf) == 0)
d62a17ae 1622 return;
1623
b5a8894d 1624 /* Iterate all ospf [VRF] instances */
43b8d1d8 1625 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
b5a8894d
CS
1626 /* Update distribute-list, and apply filter. */
1627 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1628 struct list *red_list;
b5a8894d
CS
1629 struct ospf_redist *red;
1630
1631 red_list = ospf->redist[type];
1632 if (red_list)
996c9314
LB
1633 for (ALL_LIST_ELEMENTS_RO(red_list, node,
1634 red)) {
b5a8894d 1635 if (ROUTEMAP(red)) {
996c9314
LB
1636 /* if route-map is not NULL it
1637 * may be
b5a8894d
CS
1638 * using this access list */
1639 ospf_distribute_list_update(
996c9314
LB
1640 ospf, type,
1641 red->instance);
b5a8894d 1642 }
d62a17ae 1643 }
d62a17ae 1644
b5a8894d
CS
1645 /* There is place for route-map for default-information
1646 * (ZEBRA_ROUTE_MAX),
1647 * but no distribute list. */
1648 if (type == ZEBRA_ROUTE_MAX)
1649 break;
1650
1651 if (DISTRIBUTE_NAME(ospf, type)) {
1652 /* Keep old access-list for distribute-list. */
996c9314
LB
1653 struct access_list *old =
1654 DISTRIBUTE_LIST(ospf, type);
b5a8894d
CS
1655
1656 /* Update access-list for distribute-list. */
996c9314
LB
1657 DISTRIBUTE_LIST(ospf, type) =
1658 access_list_lookup(
1659 AFI_IP,
1660 DISTRIBUTE_NAME(ospf, type));
b5a8894d
CS
1661
1662 /* No update for this distribute type. */
996c9314
LB
1663 if (old == NULL
1664 && DISTRIBUTE_LIST(ospf, type) == NULL)
b5a8894d
CS
1665 continue;
1666
1667 /* Schedule distribute-list update timer. */
1668 if (DISTRIBUTE_LIST(ospf, type) == NULL
996c9314
LB
1669 || strcmp(DISTRIBUTE_NAME(ospf, type),
1670 access->name)
1671 == 0)
1672 ospf_distribute_list_update(ospf, type,
1673 0);
b5a8894d 1674 }
d62a17ae 1675 }
d62a17ae 1676
b5a8894d
CS
1677 /* Update Area access-list. */
1678 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1679 if (EXPORT_NAME(area)) {
1680 EXPORT_LIST(area) = NULL;
1681 abr_inv++;
1682 }
d62a17ae 1683
b5a8894d
CS
1684 if (IMPORT_NAME(area)) {
1685 IMPORT_LIST(area) = NULL;
1686 abr_inv++;
1687 }
d62a17ae 1688 }
d62a17ae 1689
b5a8894d
CS
1690 /* Schedule ABR tasks -- this will be changed -- takada. */
1691 if (IS_OSPF_ABR(ospf) && abr_inv)
1692 ospf_schedule_abr_task(ospf);
1693 }
718e3744 1694}
dd669bb0 1695
1696/* If prefix-list is updated, do some updates. */
d62a17ae 1697void ospf_prefix_list_update(struct prefix_list *plist)
dd669bb0 1698{
b5a8894d 1699 struct ospf *ospf = NULL;
d62a17ae 1700 int type;
1701 int abr_inv = 0;
1702 struct ospf_area *area;
b5a8894d 1703 struct listnode *node, *n1;
d62a17ae 1704
1705 /* If OSPF instatnce does not exist, return right now. */
b5a8894d 1706 if (listcount(om->ospf) == 0)
d62a17ae 1707 return;
1708
b5a8894d
CS
1709 /* Iterate all ospf [VRF] instances */
1710 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
1711
1712 /* Update all route-maps which are used
1713 * as redistribution filters.
1714 * They might use prefix-list.
1715 */
1716 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1717 struct list *red_list;
b5a8894d
CS
1718 struct ospf_redist *red;
1719
1720 red_list = ospf->redist[type];
1721 if (red_list) {
996c9314
LB
1722 for (ALL_LIST_ELEMENTS_RO(red_list, node,
1723 red)) {
b5a8894d
CS
1724 if (ROUTEMAP(red)) {
1725 /* if route-map is not NULL
1726 * it may be using
1727 * this prefix list */
1728 ospf_distribute_list_update(
1729 ospf, type,
1730 red->instance);
1731 }
d62a17ae 1732 }
1733 }
b5a8894d 1734 }
d62a17ae 1735
b5a8894d
CS
1736 /* Update area filter-lists. */
1737 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1738 /* Update filter-list in. */
1739 if (PREFIX_NAME_IN(area))
1740 if (strcmp(PREFIX_NAME_IN(area),
996c9314
LB
1741 prefix_list_name(plist))
1742 == 0) {
b5a8894d
CS
1743 PREFIX_LIST_IN(area) =
1744 prefix_list_lookup(
996c9314
LB
1745 AFI_IP,
1746 PREFIX_NAME_IN(area));
b5a8894d
CS
1747 abr_inv++;
1748 }
d62a17ae 1749
b5a8894d
CS
1750 /* Update filter-list out. */
1751 if (PREFIX_NAME_OUT(area))
1752 if (strcmp(PREFIX_NAME_OUT(area),
996c9314
LB
1753 prefix_list_name(plist))
1754 == 0) {
b5a8894d
CS
1755 PREFIX_LIST_IN(area) =
1756 prefix_list_lookup(
996c9314
LB
1757 AFI_IP,
1758 PREFIX_NAME_OUT(area));
b5a8894d
CS
1759 abr_inv++;
1760 }
1761 }
d62a17ae 1762
b5a8894d
CS
1763 /* Schedule ABR task. */
1764 if (IS_OSPF_ABR(ospf) && abr_inv)
1765 ospf_schedule_abr_task(ospf);
1766 }
dd669bb0 1767}
cf795c5d 1768
d62a17ae 1769static struct ospf_distance *ospf_distance_new(void)
718e3744 1770{
d62a17ae 1771 return XCALLOC(MTYPE_OSPF_DISTANCE, sizeof(struct ospf_distance));
718e3744 1772}
1773
d62a17ae 1774static void ospf_distance_free(struct ospf_distance *odistance)
718e3744 1775{
d62a17ae 1776 XFREE(MTYPE_OSPF_DISTANCE, odistance);
718e3744 1777}
1778
d62a17ae 1779int ospf_distance_set(struct vty *vty, struct ospf *ospf,
1780 const char *distance_str, const char *ip_str,
1781 const char *access_list_str)
718e3744 1782{
d62a17ae 1783 int ret;
1784 struct prefix_ipv4 p;
d7c0a89a 1785 uint8_t distance;
d62a17ae 1786 struct route_node *rn;
1787 struct ospf_distance *odistance;
1788
1789 ret = str2prefix_ipv4(ip_str, &p);
1790 if (ret == 0) {
1791 vty_out(vty, "Malformed prefix\n");
1792 return CMD_WARNING_CONFIG_FAILED;
1793 }
1794
1795 distance = atoi(distance_str);
1796
1797 /* Get OSPF distance node. */
1798 rn = route_node_get(ospf->distance_table, (struct prefix *)&p);
1799 if (rn->info) {
1800 odistance = rn->info;
1801 route_unlock_node(rn);
1802 } else {
1803 odistance = ospf_distance_new();
1804 rn->info = odistance;
1805 }
1806
1807 /* Set distance value. */
1808 odistance->distance = distance;
1809
1810 /* Reset access-list configuration. */
1811 if (odistance->access_list) {
1812 free(odistance->access_list);
1813 odistance->access_list = NULL;
1814 }
1815 if (access_list_str)
1816 odistance->access_list = strdup(access_list_str);
1817
1818 return CMD_SUCCESS;
718e3744 1819}
1820
d62a17ae 1821int ospf_distance_unset(struct vty *vty, struct ospf *ospf,
1822 const char *distance_str, const char *ip_str,
1823 char const *access_list_str)
718e3744 1824{
d62a17ae 1825 int ret;
1826 struct prefix_ipv4 p;
1827 struct route_node *rn;
1828 struct ospf_distance *odistance;
1829
1830 ret = str2prefix_ipv4(ip_str, &p);
1831 if (ret == 0) {
1832 vty_out(vty, "Malformed prefix\n");
1833 return CMD_WARNING_CONFIG_FAILED;
1834 }
1835
1836 rn = route_node_lookup(ospf->distance_table, (struct prefix *)&p);
1837 if (!rn) {
1838 vty_out(vty, "Can't find specified prefix\n");
1839 return CMD_WARNING_CONFIG_FAILED;
1840 }
1841
1842 odistance = rn->info;
1843
1844 if (odistance->access_list)
1845 free(odistance->access_list);
1846 ospf_distance_free(odistance);
1847
1848 rn->info = NULL;
1849 route_unlock_node(rn);
1850 route_unlock_node(rn);
1851
1852 return CMD_SUCCESS;
718e3744 1853}
1854
d62a17ae 1855void ospf_distance_reset(struct ospf *ospf)
718e3744 1856{
d62a17ae 1857 struct route_node *rn;
1858 struct ospf_distance *odistance;
1859
1860 for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
1861 if ((odistance = rn->info) != NULL) {
1862 if (odistance->access_list)
1863 free(odistance->access_list);
1864 ospf_distance_free(odistance);
1865 rn->info = NULL;
1866 route_unlock_node(rn);
1867 }
718e3744 1868}
1869
d7c0a89a
QY
1870uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
1871 struct ospf_route * or)
718e3744 1872{
718e3744 1873
d62a17ae 1874 if (ospf == NULL)
1875 return 0;
718e3744 1876
d62a17ae 1877 if (ospf->distance_intra)
1878 if (or->path_type == OSPF_PATH_INTRA_AREA)
1879 return ospf->distance_intra;
718e3744 1880
d62a17ae 1881 if (ospf->distance_inter)
1882 if (or->path_type == OSPF_PATH_INTER_AREA)
1883 return ospf->distance_inter;
718e3744 1884
d62a17ae 1885 if (ospf->distance_external)
1886 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL ||
1887 or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1888 return ospf->distance_external;
cf795c5d 1889
d62a17ae 1890 if (ospf->distance_all)
1891 return ospf->distance_all;
718e3744 1892
d62a17ae 1893 return 0;
718e3744 1894}
1895
b5a8894d
CS
1896void ospf_zebra_vrf_register(struct ospf *ospf)
1897{
1898 if (!zclient || zclient->sock < 0 || !ospf)
1899 return;
1900
6021c6c0 1901 if (ospf->vrf_id != VRF_UNKNOWN) {
b5a8894d 1902 if (IS_DEBUG_OSPF_EVENT)
15569c58 1903 zlog_debug("%s: Register VRF %s id %u", __func__,
b5a8894d
CS
1904 ospf_vrf_id_to_name(ospf->vrf_id),
1905 ospf->vrf_id);
1906 zclient_send_reg_requests(zclient, ospf->vrf_id);
1907 }
1908}
1909
1910void ospf_zebra_vrf_deregister(struct ospf *ospf)
1911{
1912 if (!zclient || zclient->sock < 0 || !ospf)
1913 return;
1914
1915 if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
1916 if (IS_DEBUG_OSPF_EVENT)
6021c6c0 1917 zlog_debug("%s: De-Register VRF %s id %u to Zebra.",
15569c58 1918 __func__, ospf_vrf_id_to_name(ospf->vrf_id),
b5a8894d
CS
1919 ospf->vrf_id);
1920 /* Deregister for router-id, interfaces,
1921 * redistributed routes. */
1922 zclient_send_dereg_requests(zclient, ospf->vrf_id);
1923 }
1924}
b61264a8 1925
d81b8e0e
OD
1926/* Label Manager Functions */
1927
1928/**
1929 * Check if Label Manager is Ready or not.
1930 *
1931 * @return True if Label Manager is ready, False otherwise
1932 */
1933bool ospf_zebra_label_manager_ready(void)
1934{
1935 return (zclient_sync->sock > 0);
1936}
1937
1938/**
1939 * Request Label Range to the Label Manager.
1940 *
1941 * @param base base label of the label range to request
1942 * @param chunk_size size of the label range to request
1943 *
1944 * @return 0 on success, -1 on failure
1945 */
1946int ospf_zebra_request_label_range(uint32_t base, uint32_t chunk_size)
1947{
1948 int ret;
1949 uint32_t start, end;
1950
1951 if (zclient_sync->sock < 0)
1952 return -1;
1953
1954 ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start,
1955 &end);
1956 if (ret < 0) {
1957 zlog_warn("%s: error getting label range!", __func__);
1958 return -1;
1959 }
1960
1961 return 0;
1962}
1963
1964/**
1965 * Release Label Range to the Label Manager.
1966 *
1967 * @param start start of label range to release
1968 * @param end end of label range to release
1969 *
1970 * @return 0 on success, -1 otherwise
1971 */
1972int ospf_zebra_release_label_range(uint32_t start, uint32_t end)
1973{
1974 int ret;
1975
1976 if (zclient_sync->sock < 0)
1977 return -1;
1978
1979 ret = lm_release_label_chunk(zclient_sync, start, end);
1980 if (ret < 0) {
1981 zlog_warn("%s: error releasing label range!", __func__);
1982 return -1;
1983 }
1984
1985 return 0;
1986}
1987
1988/**
1989 * Connect to the Label Manager.
1990 *
1991 * @return 0 on success, -1 otherwise
1992 */
1993int ospf_zebra_label_manager_connect(void)
1994{
1995 /* Connect to label manager. */
1996 if (zclient_socket_connect(zclient_sync) < 0) {
1997 zlog_warn("%s: failed connecting synchronous zclient!",
1998 __func__);
1999 return -1;
2000 }
2001 /* make socket non-blocking */
2002 set_nonblocking(zclient_sync->sock);
2003
2004 /* Send hello to notify zebra this is a synchronous client */
7cfdb485 2005 if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
d81b8e0e
OD
2006 zlog_warn("%s: failed sending hello for synchronous zclient!",
2007 __func__);
2008 close(zclient_sync->sock);
2009 zclient_sync->sock = -1;
2010 return -1;
2011 }
2012
2013 /* Connect to label manager */
2014 if (lm_label_manager_connect(zclient_sync, 0) != 0) {
2015 zlog_warn("%s: failed connecting to label manager!", __func__);
2016 if (zclient_sync->sock > 0) {
2017 close(zclient_sync->sock);
2018 zclient_sync->sock = -1;
2019 }
2020 return -1;
2021 }
2022
2023 osr_debug("SR (%s): Successfully connected to the Label Manager",
2024 __func__);
2025
2026 return 0;
2027}
2028
d62a17ae 2029static void ospf_zebra_connected(struct zclient *zclient)
7076bb2f 2030{
d62a17ae 2031 /* Send the client registration */
0945d5ed 2032 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT);
2376c3f2 2033
d62a17ae 2034 zclient_send_reg_requests(zclient, VRF_DEFAULT);
7076bb2f
FL
2035}
2036
132a782e 2037/*
2038 * opaque messages between processes
2039 */
2040static int ospf_opaque_msg_handler(ZAPI_CALLBACK_ARGS)
2041{
2042 struct stream *s;
2043 struct zapi_opaque_msg info;
2044 struct ldp_igp_sync_if_state state;
2045 struct ldp_igp_sync_announce announce;
132a782e 2046 int ret = 0;
2047
2048 s = zclient->ibuf;
2049
2050 if (zclient_opaque_decode(s, &info) != 0)
2051 return -1;
2052
2053 switch (info.type) {
2054 case LDP_IGP_SYNC_IF_STATE_UPDATE:
2055 STREAM_GET(&state, s, sizeof(state));
2056 ret = ospf_ldp_sync_state_update(state);
2057 break;
2058 case LDP_IGP_SYNC_ANNOUNCE_UPDATE:
2059 STREAM_GET(&announce, s, sizeof(announce));
2060 ret = ospf_ldp_sync_announce_update(announce);
2061 break;
132a782e 2062 default:
2063 break;
2064 }
2065
2066stream_failure:
2067
2068 return ret;
2069}
2070
cb135cc9
KS
2071static int ospf_zebra_client_close_notify(ZAPI_CALLBACK_ARGS)
2072{
2073 int ret = 0;
2074
2075 struct zapi_client_close_info info;
2076
2077 if (zapi_client_close_notify_decode(zclient->ibuf, &info) < 0)
2078 return -1;
2079
2080 ospf_ldp_sync_handle_client_close(&info);
2081
2082 return ret;
2083}
2084
d7c0a89a 2085void ospf_zebra_init(struct thread_master *master, unsigned short instance)
718e3744 2086{
d62a17ae 2087 /* Allocate zebra structure. */
26f63a1e 2088 zclient = zclient_new(master, &zclient_options_default);
342213ea 2089 zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
d62a17ae 2090 zclient->zebra_connected = ospf_zebra_connected;
2091 zclient->router_id_update = ospf_router_id_update_zebra;
d62a17ae 2092 zclient->interface_address_add = ospf_interface_address_add;
2093 zclient->interface_address_delete = ospf_interface_address_delete;
2094 zclient->interface_link_params = ospf_interface_link_params;
b5a8894d 2095 zclient->interface_vrf_update = ospf_interface_vrf_update;
d62a17ae 2096
74489921
RW
2097 zclient->redistribute_route_add = ospf_zebra_read_route;
2098 zclient->redistribute_route_del = ospf_zebra_read_route;
d62a17ae 2099
d81b8e0e
OD
2100 /* Initialize special zclient for synchronous message exchanges. */
2101 struct zclient_options options = zclient_options_default;
2102 options.synchronous = true;
2103 zclient_sync = zclient_new(master, &options);
2104 zclient_sync->sock = -1;
2105 zclient_sync->redist_default = ZEBRA_ROUTE_OSPF;
2106 zclient_sync->instance = instance;
2107 /*
2108 * session_id must be different from default value (0) to distinguish
2109 * the asynchronous socket from the synchronous one
2110 */
2111 zclient_sync->session_id = 1;
2112 zclient_sync->privs = &ospfd_privs;
2113
d62a17ae 2114 access_list_add_hook(ospf_filter_update);
2115 access_list_delete_hook(ospf_filter_update);
2116 prefix_list_add_hook(ospf_prefix_list_update);
2117 prefix_list_delete_hook(ospf_prefix_list_update);
132a782e 2118
2119 zclient->opaque_msg_handler = ospf_opaque_msg_handler;
cb135cc9
KS
2120
2121 zclient->zebra_client_close_notify = ospf_zebra_client_close_notify;
718e3744 2122}
aa530b62
JU
2123
2124void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
2125{
2126 zclient_send_neigh_discovery_req(zclient, ifp, p);
2127}