]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_zebra.c
ospfd: Fix memory leak
[mirror_frr.git] / ospfd / ospf_zebra.c
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 *
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
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"
34 #include "plist.h"
35 #include "log.h"
36 #include "lib/bfd.h"
37 #include "nexthop.h"
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"
48 #include "ospfd/ospf_lsdb.h"
49 #include "ospfd/ospf_neighbor.h"
50 #include "ospfd/ospf_nsm.h"
51 #include "ospfd/ospf_zebra.h"
52 #include "ospfd/ospf_te.h"
53
54 DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
55 DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
56 DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
57
58 DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
59 DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
60
61 /* Zebra structure to hold current status. */
62 struct zclient *zclient = NULL;
63
64 /* For registering threads. */
65 extern struct thread_master *master;
66 struct in_addr router_id_zebra;
67
68 /* Router-id update message from zebra. */
69 static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
70 zebra_size_t length, vrf_id_t vrf_id)
71 {
72 struct ospf *ospf = NULL;
73 struct prefix router_id;
74 zebra_router_id_update_read(zclient->ibuf, &router_id);
75
76 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
77 char buf[PREFIX2STR_BUFFER];
78 prefix2str(&router_id, buf, sizeof(buf));
79 zlog_debug("Zebra rcvd: router id update %s vrf %s id %u",
80 buf, ospf_vrf_id_to_name(vrf_id), vrf_id);
81 }
82
83 router_id_zebra = router_id.u.prefix4;
84
85 ospf = ospf_lookup_by_vrf_id(vrf_id);
86
87 if (ospf != NULL)
88 ospf_router_id_update(ospf);
89 else {
90 if (IS_DEBUG_OSPF_EVENT) {
91 char buf[PREFIX2STR_BUFFER];
92
93 prefix2str(&router_id, buf, sizeof(buf));
94 zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s",
95 __PRETTY_FUNCTION__,
96 ospf_vrf_id_to_name(vrf_id), vrf_id, buf);
97 }
98 }
99 return 0;
100 }
101
102 /* Inteface addition message from zebra. */
103 static int ospf_interface_add(int command, struct zclient *zclient,
104 zebra_size_t length, vrf_id_t vrf_id)
105 {
106 struct interface *ifp = NULL;
107 struct ospf *ospf = NULL;
108
109 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
110 if (ifp == NULL)
111 return 0;
112
113 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
114 zlog_debug(
115 "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
116 ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
117 ifp->vrf_id, ifp->ifindex,
118 (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
119
120 assert(ifp->info);
121
122 if (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
123 SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
124 IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
125 }
126
127 ospf = ospf_lookup_by_vrf_id(vrf_id);
128 if (!ospf)
129 return 0;
130
131 ospf_if_update(ospf, ifp);
132
133 hook_call(ospf_if_update, ifp);
134
135 return 0;
136 }
137
138 static int ospf_interface_delete(int command, struct zclient *zclient,
139 zebra_size_t length, vrf_id_t vrf_id)
140 {
141 struct interface *ifp;
142 struct stream *s;
143 struct route_node *rn;
144
145 s = zclient->ibuf;
146 /* zebra_interface_state_read() updates interface structure in iflist */
147 ifp = zebra_interface_state_read(s, vrf_id);
148
149 if (ifp == NULL)
150 return 0;
151
152 if (if_is_up(ifp))
153 zlog_warn("Zebra: got delete of %s, but interface is still up",
154 ifp->name);
155
156 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
157 zlog_debug(
158 "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
159 ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
160 ifp->vrf_id, ifp->ifindex,
161 (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
162
163 hook_call(ospf_if_delete, ifp);
164
165 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
166 if (rn->info)
167 ospf_if_free((struct ospf_interface *)rn->info);
168
169 ifp->ifindex = IFINDEX_DELETED;
170 return 0;
171 }
172
173 static struct interface *zebra_interface_if_lookup(struct stream *s,
174 vrf_id_t vrf_id)
175 {
176 char ifname_tmp[INTERFACE_NAMSIZ];
177
178 /* Read interface name. */
179 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
180
181 /* And look it up. */
182 return if_lookup_by_name_len(
183 ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
184 }
185
186 static int ospf_interface_state_up(int command, struct zclient *zclient,
187 zebra_size_t length, vrf_id_t vrf_id)
188 {
189 struct interface *ifp;
190 struct ospf_interface *oi;
191 struct route_node *rn;
192
193 ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id);
194
195 if (ifp == NULL)
196 return 0;
197
198 /* Interface is already up. */
199 if (if_is_operative(ifp)) {
200 /* Temporarily keep ifp values. */
201 struct interface if_tmp;
202 memcpy(&if_tmp, ifp, sizeof(struct interface));
203
204 zebra_interface_if_set_value(zclient->ibuf, ifp);
205
206 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
207 zlog_debug(
208 "Zebra: Interface[%s] state update speed %u -> %u, bw %d -> %d",
209 ifp->name, if_tmp.speed, ifp->speed,
210 if_tmp.bandwidth, ifp->bandwidth);
211
212 ospf_if_recalculate_output_cost(ifp);
213
214 if (if_tmp.mtu != ifp->mtu) {
215 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
216 zlog_debug(
217 "Zebra: Interface[%s] MTU change %u -> %u.",
218 ifp->name, if_tmp.mtu, ifp->mtu);
219
220 /* Must reset the interface (simulate down/up) when MTU
221 * changes. */
222 ospf_if_reset(ifp);
223 }
224 return 0;
225 }
226
227 zebra_interface_if_set_value(zclient->ibuf, ifp);
228
229 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
230 zlog_debug("Zebra: Interface[%s] state change to up.",
231 ifp->name);
232
233 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
234 if ((oi = rn->info) == NULL)
235 continue;
236
237 ospf_if_up(oi);
238 }
239
240 return 0;
241 }
242
243 static int ospf_interface_state_down(int command, struct zclient *zclient,
244 zebra_size_t length, vrf_id_t vrf_id)
245 {
246 struct interface *ifp;
247 struct ospf_interface *oi;
248 struct route_node *node;
249
250 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
251
252 if (ifp == NULL)
253 return 0;
254
255 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
256 zlog_debug("Zebra: Interface[%s] state change to down.",
257 ifp->name);
258
259 for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
260 if ((oi = node->info) == NULL)
261 continue;
262 ospf_if_down(oi);
263 }
264
265 return 0;
266 }
267
268 static int ospf_interface_address_add(int command, struct zclient *zclient,
269 zebra_size_t length, vrf_id_t vrf_id)
270 {
271 struct connected *c;
272 struct ospf *ospf = NULL;
273
274
275 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
276
277 if (c == NULL)
278 return 0;
279
280 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
281 char buf[PREFIX2STR_BUFFER];
282 prefix2str(c->address, buf, sizeof(buf));
283 zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
284 c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
285 vrf_id);
286 }
287
288 ospf = ospf_lookup_by_vrf_id(vrf_id);
289 if (!ospf)
290 return 0;
291
292 ospf_if_update(ospf, c->ifp);
293
294 hook_call(ospf_if_update, c->ifp);
295
296 return 0;
297 }
298
299 static int ospf_interface_address_delete(int command, struct zclient *zclient,
300 zebra_size_t length, vrf_id_t vrf_id)
301 {
302 struct connected *c;
303 struct interface *ifp;
304 struct ospf_interface *oi;
305 struct route_node *rn;
306 struct prefix p;
307
308 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
309
310 if (c == NULL)
311 return 0;
312
313 if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
314 char buf[PREFIX2STR_BUFFER];
315 prefix2str(c->address, buf, sizeof(buf));
316 zlog_debug("Zebra: interface %s address delete %s",
317 c->ifp->name, buf);
318 }
319
320 ifp = c->ifp;
321 p = *c->address;
322 p.prefixlen = IPV4_MAX_PREFIXLEN;
323
324 rn = route_node_lookup(IF_OIFS(ifp), &p);
325 if (!rn) {
326 connected_free(c);
327 return 0;
328 }
329
330 assert(rn->info);
331 oi = rn->info;
332 route_unlock_node(rn);
333
334 /* Call interface hook functions to clean up */
335 ospf_if_free(oi);
336
337 hook_call(ospf_if_update, c->ifp);
338
339 connected_free(c);
340
341 return 0;
342 }
343
344 static int ospf_interface_link_params(int command, struct zclient *zclient,
345 zebra_size_t length)
346 {
347 struct interface *ifp;
348
349 ifp = zebra_interface_link_params_read(zclient->ibuf);
350
351 if (ifp == NULL)
352 return 0;
353
354 /* Update TE TLV */
355 ospf_mpls_te_update_if(ifp);
356
357 return 0;
358 }
359
360 /* VRF update for an interface. */
361 static int ospf_interface_vrf_update(int command, struct zclient *zclient,
362 zebra_size_t length, vrf_id_t vrf_id)
363 {
364 struct interface *ifp = NULL;
365 vrf_id_t new_vrf_id;
366
367 ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
368 &new_vrf_id);
369 if (!ifp)
370 return 0;
371
372 if (IS_DEBUG_OSPF_EVENT)
373 zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
374 __PRETTY_FUNCTION__, ifp->name, vrf_id,
375 ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
376
377 /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
378 if_update_to_new_vrf(ifp, new_vrf_id);
379
380 return 0;
381 }
382
383 void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
384 struct ospf_route *or)
385 {
386 struct zapi_route api;
387 struct zapi_nexthop *api_nh;
388 u_char distance;
389 struct ospf_path *path;
390 struct listnode *node;
391 int count = 0;
392
393 memset(&api, 0, sizeof(api));
394 api.vrf_id = ospf->vrf_id;
395 api.type = ZEBRA_ROUTE_OSPF;
396 api.instance = ospf->instance;
397 api.safi = SAFI_UNICAST;
398
399 memcpy(&api.prefix, p, sizeof(*p));
400 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
401
402 /* Metric value. */
403 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
404 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
405 api.metric = or->cost + or->u.ext.type2_cost;
406 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
407 api.metric = or->u.ext.type2_cost;
408 else
409 api.metric = or->cost;
410
411 /* Check if path type is ASE */
412 if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
413 || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL))
414 && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) {
415 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
416 api.tag = or->u.ext.tag;
417 }
418
419 /* Distance value. */
420 distance = ospf_distance_apply(ospf, p, or);
421 if (distance) {
422 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
423 api.distance = distance;
424 }
425
426 /* Nexthop, ifindex, distance and metric information. */
427 for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) {
428 if (count >= MULTIPATH_NUM)
429 break;
430 api_nh = &api.nexthops[count];
431 #ifdef HAVE_NETLINK
432 if (path->unnumbered || (path->nexthop.s_addr != INADDR_ANY
433 && path->ifindex != 0)) {
434 #else /* HAVE_NETLINK */
435 if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) {
436 #endif /* HAVE_NETLINK */
437 api_nh->gate.ipv4 = path->nexthop;
438 api_nh->ifindex = path->ifindex;
439 api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
440 } else if (path->nexthop.s_addr != INADDR_ANY) {
441 api_nh->gate.ipv4 = path->nexthop;
442 api_nh->type = NEXTHOP_TYPE_IPV4;
443 } else {
444 api_nh->ifindex = path->ifindex;
445 api_nh->type = NEXTHOP_TYPE_IFINDEX;
446 }
447 count++;
448
449 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
450 char buf[2][INET_ADDRSTRLEN];
451 zlog_debug(
452 "Zebra: Route add %s/%d nexthop %s, ifindex=%d",
453 inet_ntop(AF_INET, &p->prefix, buf[0],
454 sizeof(buf[0])),
455 p->prefixlen, inet_ntop(AF_INET, &path->nexthop,
456 buf[1], sizeof(buf[1])),
457 path->ifindex);
458 }
459 }
460 api.nexthop_num = count;
461
462 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
463 }
464
465 void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
466 struct ospf_route *or)
467 {
468 struct zapi_route api;
469
470 memset(&api, 0, sizeof(api));
471 api.vrf_id = ospf->vrf_id;
472 api.type = ZEBRA_ROUTE_OSPF;
473 api.instance = ospf->instance;
474 api.safi = SAFI_UNICAST;
475 memcpy(&api.prefix, p, sizeof(*p));
476
477 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
478 char buf[INET_ADDRSTRLEN];
479 zlog_debug("Zebra: Route delete %s/%d",
480 inet_ntop(AF_INET, &p->prefix, buf, sizeof(buf[0])),
481 p->prefixlen);
482 }
483
484 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
485 }
486
487 void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
488 {
489 struct zapi_route api;
490
491 memset(&api, 0, sizeof(api));
492 api.vrf_id = ospf->vrf_id;
493 api.type = ZEBRA_ROUTE_OSPF;
494 api.instance = ospf->instance;
495 api.safi = SAFI_UNICAST;
496 memcpy(&api.prefix, p, sizeof(*p));
497 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
498
499 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
500
501 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
502 zlog_debug("Zebra: Route add discard %s/%d",
503 inet_ntoa(p->prefix), p->prefixlen);
504 }
505
506 void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
507 {
508 struct zapi_route api;
509
510 memset(&api, 0, sizeof(api));
511 api.vrf_id = ospf->vrf_id;
512 api.type = ZEBRA_ROUTE_OSPF;
513 api.instance = ospf->instance;
514 api.safi = SAFI_UNICAST;
515 memcpy(&api.prefix, p, sizeof(*p));
516 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
517
518 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
519
520 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
521 zlog_debug("Zebra: Route delete discard %s/%d",
522 inet_ntoa(p->prefix), p->prefixlen);
523 }
524
525 struct ospf_external *ospf_external_lookup(u_char type, u_short instance)
526 {
527 struct list *ext_list;
528 struct listnode *node;
529 struct ospf_external *ext;
530
531 ext_list = om->external[type];
532 if (!ext_list)
533 return (NULL);
534
535 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
536 if (ext->instance == instance)
537 return ext;
538
539 return NULL;
540 }
541
542 struct ospf_external *ospf_external_add(u_char type, u_short instance)
543 {
544 struct list *ext_list;
545 struct ospf_external *ext;
546
547 ext = ospf_external_lookup(type, instance);
548 if (ext)
549 return ext;
550
551 if (!om->external[type])
552 om->external[type] = list_new();
553
554 ext_list = om->external[type];
555 ext = (struct ospf_external *)XCALLOC(MTYPE_OSPF_EXTERNAL,
556 sizeof(struct ospf_external));
557 ext->instance = instance;
558 EXTERNAL_INFO(ext) = route_table_init();
559
560 listnode_add(ext_list, ext);
561
562 return ext;
563 }
564
565 void ospf_external_del(u_char type, u_short instance)
566 {
567 struct ospf_external *ext;
568
569 ext = ospf_external_lookup(type, instance);
570
571 if (ext) {
572 if (EXTERNAL_INFO(ext))
573 route_table_finish(EXTERNAL_INFO(ext));
574
575 listnode_delete(om->external[type], ext);
576 if (!om->external[type]->count) {
577 list_delete_and_null(&om->external[type]);
578 }
579 XFREE(MTYPE_OSPF_EXTERNAL, ext);
580 }
581 }
582
583 struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, u_char type,
584 u_short instance)
585 {
586 struct list *red_list;
587 struct listnode *node;
588 struct ospf_redist *red;
589
590 red_list = ospf->redist[type];
591 if (!red_list)
592 return (NULL);
593
594 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
595 if (red->instance == instance)
596 return red;
597
598 return NULL;
599 }
600
601 struct ospf_redist *ospf_redist_add(struct ospf *ospf, u_char type,
602 u_short instance)
603 {
604 struct list *red_list;
605 struct ospf_redist *red;
606
607 red = ospf_redist_lookup(ospf, type, instance);
608 if (red)
609 return red;
610
611 if (!ospf->redist[type])
612 ospf->redist[type] = list_new();
613
614 red_list = ospf->redist[type];
615 red = (struct ospf_redist *)XCALLOC(MTYPE_OSPF_REDISTRIBUTE,
616 sizeof(struct ospf_redist));
617 red->instance = instance;
618 red->dmetric.type = -1;
619 red->dmetric.value = -1;
620
621 listnode_add(red_list, red);
622
623 return red;
624 }
625
626 void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
627 {
628 struct ospf_redist *red;
629
630 red = ospf_redist_lookup(ospf, type, instance);
631
632 if (red) {
633 listnode_delete(ospf->redist[type], red);
634 if (!ospf->redist[type]->count) {
635 list_delete_and_null(&ospf->redist[type]);
636 }
637 ospf_routemap_unset(red);
638 XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
639 }
640 }
641
642
643 int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
644 {
645 return (DEFAULT_ROUTE_TYPE(type)
646 ? vrf_bitmap_check(zclient->default_information,
647 ospf->vrf_id)
648 : ((instance
649 && redist_check_instance(
650 &zclient->mi_redist[AFI_IP][type],
651 instance))
652 || (!instance
653 && vrf_bitmap_check(
654 zclient->redist[AFI_IP][type],
655 ospf->vrf_id))));
656 }
657
658 int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
659 int mtype, int mvalue)
660 {
661 int force = 0;
662 struct ospf_redist *red;
663
664 red = ospf_redist_lookup(ospf, type, instance);
665 if (ospf_is_type_redistributed(ospf, type, instance)) {
666 if (mtype != red->dmetric.type) {
667 red->dmetric.type = mtype;
668 force = LSA_REFRESH_FORCE;
669 }
670 if (mvalue != red->dmetric.value) {
671 red->dmetric.value = mvalue;
672 force = LSA_REFRESH_FORCE;
673 }
674
675 ospf_external_lsa_refresh_type(ospf, type, instance, force);
676
677 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
678 zlog_debug(
679 "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
680 ospf_redist_string(type), instance,
681 metric_type(ospf, type, instance),
682 metric_value(ospf, type, instance));
683
684 return CMD_SUCCESS;
685 }
686
687 red->dmetric.type = mtype;
688 red->dmetric.value = mvalue;
689
690 ospf_external_add(type, instance);
691
692 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
693 instance, ospf->vrf_id);
694
695 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
696 zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
697 ospf_redist_string(type), instance, ospf->vrf_id,
698 metric_type(ospf, type, instance),
699 metric_value(ospf, type, instance));
700
701 ospf_asbr_status_update(ospf, ++ospf->redistribute);
702
703 return CMD_SUCCESS;
704 }
705
706 int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
707 {
708 if (type == zclient->redist_default && instance == zclient->instance)
709 return CMD_SUCCESS;
710
711 if (!ospf_is_type_redistributed(ospf, type, instance))
712 return CMD_SUCCESS;
713
714 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
715 instance, ospf->vrf_id);
716
717 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
718 zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
719 ospf_redist_string(type), instance, ospf->vrf_id);
720
721 ospf_redist_del(ospf, type, instance);
722
723 /* Remove the routes from OSPF table. */
724 ospf_redistribute_withdraw(ospf, type, instance);
725
726 ospf_external_del(type, instance);
727
728 ospf_asbr_status_update(ospf, --ospf->redistribute);
729
730 return CMD_SUCCESS;
731 }
732
733 int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
734 int mvalue)
735 {
736 struct ospf_redist *red;
737
738 ospf->default_originate = originate;
739
740 red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
741 red->dmetric.type = mtype;
742 red->dmetric.value = mvalue;
743
744 ospf_external_add(DEFAULT_ROUTE, 0);
745
746 if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
747 /* if ospf->default_originate changes value, is calling
748 ospf_external_lsa_refresh_default sufficient to implement
749 the change? */
750 ospf_external_lsa_refresh_default(ospf);
751
752 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
753 zlog_debug(
754 "Redistribute[%s]: Refresh Type[%d], Metric[%d]",
755 ospf_redist_string(DEFAULT_ROUTE),
756 metric_type(ospf, DEFAULT_ROUTE, 0),
757 metric_value(ospf, DEFAULT_ROUTE, 0));
758 return CMD_SUCCESS;
759 }
760
761 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
762 ospf->vrf_id);
763
764 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
765 zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
766 metric_type(ospf, DEFAULT_ROUTE, 0),
767 metric_value(ospf, DEFAULT_ROUTE, 0));
768
769 if (ospf->router_id.s_addr == 0)
770 ospf->external_origin |= (1 << DEFAULT_ROUTE);
771 else
772 thread_add_timer(master, ospf_default_originate_timer, ospf, 1,
773 NULL);
774
775 ospf_asbr_status_update(ospf, ++ospf->redistribute);
776
777 return CMD_SUCCESS;
778 }
779
780 int ospf_redistribute_default_unset(struct ospf *ospf)
781 {
782 if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
783 return CMD_SUCCESS;
784
785 ospf->default_originate = DEFAULT_ORIGINATE_NONE;
786 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
787
788 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
789 ospf->vrf_id);
790
791 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
792 zlog_debug("Redistribute[DEFAULT]: Stop");
793
794 // Pending: how does the external_info cleanup work in this case?
795
796 ospf_asbr_status_update(ospf, --ospf->redistribute);
797
798 return CMD_SUCCESS;
799 }
800
801 static int ospf_external_lsa_originate_check(struct ospf *ospf,
802 struct external_info *ei)
803 {
804 /* If prefix is multicast, then do not originate LSA. */
805 if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) {
806 zlog_info(
807 "LSA[Type5:%s]: Not originate AS-external-LSA, "
808 "Prefix belongs multicast",
809 inet_ntoa(ei->p.prefix));
810 return 0;
811 }
812
813 /* Take care of default-originate. */
814 if (is_prefix_default(&ei->p))
815 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) {
816 zlog_info(
817 "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
818 "for default");
819 return 0;
820 }
821
822 return 1;
823 }
824
825 /* If connected prefix is OSPF enable interface, then do not announce. */
826 int ospf_distribute_check_connected(struct ospf *ospf, struct external_info *ei)
827 {
828 struct listnode *node;
829 struct ospf_interface *oi;
830
831
832 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
833 if (prefix_match(oi->address, (struct prefix *)&ei->p))
834 return 0;
835 return 1;
836 }
837
838 /* return 1 if external LSA must be originated, 0 otherwise */
839 int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
840 int *changed)
841 {
842 struct route_map_set_values save_values;
843 struct prefix_ipv4 *p = &ei->p;
844 struct ospf_redist *red;
845 u_char type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type;
846 u_short instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
847
848 if (changed)
849 *changed = 0;
850
851 if (!ospf_external_lsa_originate_check(ospf, ei))
852 return 0;
853
854 /* Take care connected route. */
855 if (type == ZEBRA_ROUTE_CONNECT
856 && !ospf_distribute_check_connected(ospf, ei))
857 return 0;
858
859 if (!DEFAULT_ROUTE_TYPE(type) && DISTRIBUTE_NAME(ospf, type))
860 /* distirbute-list exists, but access-list may not? */
861 if (DISTRIBUTE_LIST(ospf, type))
862 if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p)
863 == FILTER_DENY) {
864 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
865 zlog_debug(
866 "Redistribute[%s]: %s/%d filtered by ditribute-list.",
867 ospf_redist_string(type),
868 inet_ntoa(p->prefix),
869 p->prefixlen);
870 return 0;
871 }
872
873 save_values = ei->route_map_set;
874 ospf_reset_route_map_set_values(&ei->route_map_set);
875
876 /* apply route-map if needed */
877 red = ospf_redist_lookup(ospf, type, instance);
878 if (red && ROUTEMAP_NAME(red)) {
879 int ret;
880
881 ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p,
882 RMAP_OSPF, ei);
883
884 if (ret == RMAP_DENYMATCH) {
885 ei->route_map_set = save_values;
886 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
887 zlog_debug(
888 "Redistribute[%s]: %s/%d filtered by route-map.",
889 ospf_redist_string(type),
890 inet_ntoa(p->prefix), p->prefixlen);
891 return 0;
892 }
893
894 /* check if 'route-map set' changed something */
895 if (changed)
896 *changed = !ospf_route_map_set_compare(
897 &ei->route_map_set, &save_values);
898 }
899
900 return 1;
901 }
902
903 /* OSPF route-map set for redistribution */
904 void ospf_routemap_set(struct ospf_redist *red, const char *name)
905 {
906 if (ROUTEMAP_NAME(red))
907 free(ROUTEMAP_NAME(red));
908
909 ROUTEMAP_NAME(red) = strdup(name);
910 ROUTEMAP(red) = route_map_lookup_by_name(name);
911 }
912
913 void ospf_routemap_unset(struct ospf_redist *red)
914 {
915 if (ROUTEMAP_NAME(red))
916 free(ROUTEMAP_NAME(red));
917
918 ROUTEMAP_NAME(red) = NULL;
919 ROUTEMAP(red) = NULL;
920 }
921
922 /* Zebra route add and delete treatment. */
923 static int ospf_zebra_read_route(int command, struct zclient *zclient,
924 zebra_size_t length, vrf_id_t vrf_id)
925 {
926 struct zapi_route api;
927 struct prefix_ipv4 p;
928 unsigned long ifindex;
929 struct in_addr nexthop;
930 struct external_info *ei;
931 struct ospf *ospf;
932 int i;
933
934 ospf = ospf_lookup_by_vrf_id(vrf_id);
935 if (ospf == NULL)
936 return 0;
937
938 if (zapi_route_decode(zclient->ibuf, &api) < 0)
939 return -1;
940
941 ifindex = api.nexthops[0].ifindex;
942 nexthop = api.nexthops[0].gate.ipv4;
943
944 memcpy(&p, &api.prefix, sizeof(p));
945 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
946 return 0;
947
948 if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
949 /* XXX|HACK|TODO|FIXME:
950 * Maybe we should ignore reject/blackhole routes? Testing
951 * shows that there is no problems though and this is only way
952 * to "summarize" routes in ASBR at the moment. Maybe we need
953 * just a better generalised solution for these types?
954 */
955
956 /* Protocol tag overwrites all other tag value sent by zebra */
957 if (ospf->dtag[api.type] > 0)
958 api.tag = ospf->dtag[api.type];
959
960 /*
961 * Given zebra sends update for a prefix via ADD message, it
962 * should
963 * be considered as an implicit DEL for that prefix with other
964 * source
965 * types.
966 */
967 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
968 if (i != api.type)
969 ospf_external_info_delete(i, api.instance, p);
970
971 ei = ospf_external_info_add(api.type, api.instance, p, ifindex,
972 nexthop, api.tag);
973 if (ei == NULL) {
974 /* Nothing has changed, so nothing to do; return */
975 return 0;
976 }
977 if (ospf->router_id.s_addr == 0)
978 /* Set flags to generate AS-external-LSA originate event
979 for each redistributed protocols later. */
980 ospf->external_origin |= (1 << api.type);
981 else {
982 if (ei) {
983 if (is_prefix_default(&p))
984 ospf_external_lsa_refresh_default(ospf);
985 else {
986 struct ospf_lsa *current;
987
988 current = ospf_external_info_find_lsa(
989 ospf, &ei->p);
990 if (!current)
991 ospf_external_lsa_originate(
992 ospf, ei);
993 else {
994 if (IS_DEBUG_OSPF(
995 zebra,
996 ZEBRA_REDISTRIBUTE))
997 zlog_debug(
998 "ospf_zebra_read_route() : %s refreshing LSA",
999 inet_ntoa(
1000 p.prefix));
1001 ospf_external_lsa_refresh(
1002 ospf, current, ei,
1003 LSA_REFRESH_FORCE);
1004 }
1005 }
1006 }
1007 }
1008 } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
1009 {
1010 ospf_external_info_delete(api.type, api.instance, p);
1011 if (is_prefix_default(&p))
1012 ospf_external_lsa_refresh_default(ospf);
1013 else
1014 ospf_external_lsa_flush(ospf, api.type, &p,
1015 ifindex /*, nexthop */);
1016 }
1017
1018 return 0;
1019 }
1020
1021
1022 int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
1023 {
1024 /* Lookup access-list for distribute-list. */
1025 DISTRIBUTE_LIST(ospf, type) = access_list_lookup(AFI_IP, name);
1026
1027 /* Clear previous distribute-name. */
1028 if (DISTRIBUTE_NAME(ospf, type))
1029 free(DISTRIBUTE_NAME(ospf, type));
1030
1031 /* Set distribute-name. */
1032 DISTRIBUTE_NAME(ospf, type) = strdup(name);
1033
1034 /* If access-list have been set, schedule update timer. */
1035 if (DISTRIBUTE_LIST(ospf, type))
1036 ospf_distribute_list_update(ospf, type, 0);
1037
1038 return CMD_SUCCESS;
1039 }
1040
1041 int ospf_distribute_list_out_unset(struct ospf *ospf, int type,
1042 const char *name)
1043 {
1044 /* Schedule update timer. */
1045 if (DISTRIBUTE_LIST(ospf, type))
1046 ospf_distribute_list_update(ospf, type, 0);
1047
1048 /* Unset distribute-list. */
1049 DISTRIBUTE_LIST(ospf, type) = NULL;
1050
1051 /* Clear distribute-name. */
1052 if (DISTRIBUTE_NAME(ospf, type))
1053 free(DISTRIBUTE_NAME(ospf, type));
1054
1055 DISTRIBUTE_NAME(ospf, type) = NULL;
1056
1057 return CMD_SUCCESS;
1058 }
1059
1060 /* distribute-list update timer. */
1061 static int ospf_distribute_list_update_timer(struct thread *thread)
1062 {
1063 struct route_node *rn;
1064 struct external_info *ei;
1065 struct route_table *rt;
1066 struct ospf_lsa *lsa;
1067 int type, default_refresh = 0, arg_type;
1068 struct ospf *ospf = NULL;
1069 void **arg = THREAD_ARG (thread);
1070
1071 ospf = (struct ospf *)arg[0];
1072 arg_type = (int)(intptr_t)arg[1];
1073
1074 if (ospf == NULL)
1075 return 0;
1076
1077 ospf->t_distribute_update = NULL;
1078
1079 zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
1080
1081 if (IS_DEBUG_OSPF_EVENT) {
1082 zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
1083 __PRETTY_FUNCTION__, arg_type,
1084 ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
1085 }
1086
1087 /* foreach all external info. */
1088 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1089 struct list *ext_list;
1090 struct listnode *node;
1091 struct ospf_external *ext;
1092
1093 ext_list = om->external[type];
1094 if (!ext_list)
1095 continue;
1096
1097 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
1098 rt = ext->external_info;
1099 if (!rt)
1100 continue;
1101 for (rn = route_top(rt); rn; rn = route_next(rn))
1102 if ((ei = rn->info) != NULL) {
1103 if (is_prefix_default(&ei->p))
1104 default_refresh = 1;
1105 else if (
1106 (lsa = ospf_external_info_find_lsa(
1107 ospf, &ei->p)))
1108 ospf_external_lsa_refresh(
1109 ospf, lsa, ei,
1110 LSA_REFRESH_IF_CHANGED);
1111 else
1112 ospf_external_lsa_originate(
1113 ospf, ei);
1114 }
1115 }
1116 }
1117 if (default_refresh)
1118 ospf_external_lsa_refresh_default(ospf);
1119
1120 XFREE(MTYPE_OSPF_DIST_ARGS, arg);
1121 return 0;
1122 }
1123
1124 /* Update distribute-list and set timer to apply access-list. */
1125 void ospf_distribute_list_update(struct ospf *ospf, int type,
1126 u_short instance)
1127 {
1128 struct route_table *rt;
1129 struct ospf_external *ext;
1130 void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
1131
1132 args[0] = ospf;
1133 args[1] = (void *)((ptrdiff_t) type);
1134
1135 /* External info does not exist. */
1136 ext = ospf_external_lookup(type, instance);
1137 if (!ext || !(rt = EXTERNAL_INFO(ext))) {
1138 XFREE(MTYPE_OSPF_DIST_ARGS, args);
1139 return;
1140 }
1141
1142 /* If exists previously invoked thread, then let it continue. */
1143 if (ospf->t_distribute_update) {
1144 XFREE(MTYPE_OSPF_DIST_ARGS, args);
1145 return;
1146 }
1147
1148 /* Set timer. */
1149 ospf->t_distribute_update = NULL;
1150 thread_add_timer_msec(master, ospf_distribute_list_update_timer,
1151 (void **)args, ospf->min_ls_interval,
1152 &ospf->t_distribute_update);
1153 }
1154
1155 /* If access-list is updated, apply some check. */
1156 static void ospf_filter_update(struct access_list *access)
1157 {
1158 struct ospf *ospf;
1159 int type;
1160 int abr_inv = 0;
1161 struct ospf_area *area;
1162 struct listnode *node, *n1;
1163
1164 /* If OSPF instance does not exist, return right now. */
1165 if (listcount(om->ospf) == 0)
1166 return;
1167
1168 /* Iterate all ospf [VRF] instances */
1169 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
1170 /* Update distribute-list, and apply filter. */
1171 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1172 struct list *red_list;
1173 struct listnode *node;
1174 struct ospf_redist *red;
1175
1176 red_list = ospf->redist[type];
1177 if (red_list)
1178 for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
1179 if (ROUTEMAP(red)) {
1180 /* if route-map is not NULL it may be
1181 * using this access list */
1182 ospf_distribute_list_update(
1183 ospf,
1184 type, red->instance);
1185 }
1186 }
1187
1188 /* There is place for route-map for default-information
1189 * (ZEBRA_ROUTE_MAX),
1190 * but no distribute list. */
1191 if (type == ZEBRA_ROUTE_MAX)
1192 break;
1193
1194 if (DISTRIBUTE_NAME(ospf, type)) {
1195 /* Keep old access-list for distribute-list. */
1196 struct access_list *old = DISTRIBUTE_LIST(ospf,
1197 type);
1198
1199 /* Update access-list for distribute-list. */
1200 DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
1201 AFI_IP, DISTRIBUTE_NAME(ospf, type));
1202
1203 /* No update for this distribute type. */
1204 if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
1205 continue;
1206
1207 /* Schedule distribute-list update timer. */
1208 if (DISTRIBUTE_LIST(ospf, type) == NULL
1209 || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
1210 == 0)
1211 ospf_distribute_list_update(ospf, type, 0);
1212 }
1213 }
1214
1215 /* Update Area access-list. */
1216 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1217 if (EXPORT_NAME(area)) {
1218 EXPORT_LIST(area) = NULL;
1219 abr_inv++;
1220 }
1221
1222 if (IMPORT_NAME(area)) {
1223 IMPORT_LIST(area) = NULL;
1224 abr_inv++;
1225 }
1226 }
1227
1228 /* Schedule ABR tasks -- this will be changed -- takada. */
1229 if (IS_OSPF_ABR(ospf) && abr_inv)
1230 ospf_schedule_abr_task(ospf);
1231 }
1232 }
1233
1234 /* If prefix-list is updated, do some updates. */
1235 void ospf_prefix_list_update(struct prefix_list *plist)
1236 {
1237 struct ospf *ospf = NULL;
1238 int type;
1239 int abr_inv = 0;
1240 struct ospf_area *area;
1241 struct listnode *node, *n1;
1242
1243 /* If OSPF instatnce does not exist, return right now. */
1244 if (listcount(om->ospf) == 0)
1245 return;
1246
1247 /* Iterate all ospf [VRF] instances */
1248 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
1249
1250 /* Update all route-maps which are used
1251 * as redistribution filters.
1252 * They might use prefix-list.
1253 */
1254 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1255 struct list *red_list;
1256 struct listnode *node;
1257 struct ospf_redist *red;
1258
1259 red_list = ospf->redist[type];
1260 if (red_list) {
1261 for (ALL_LIST_ELEMENTS_RO(red_list,
1262 node, red)) {
1263 if (ROUTEMAP(red)) {
1264 /* if route-map is not NULL
1265 * it may be using
1266 * this prefix list */
1267 ospf_distribute_list_update(
1268 ospf, type,
1269 red->instance);
1270 }
1271 }
1272 }
1273 }
1274
1275 /* Update area filter-lists. */
1276 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1277 /* Update filter-list in. */
1278 if (PREFIX_NAME_IN(area))
1279 if (strcmp(PREFIX_NAME_IN(area),
1280 prefix_list_name(plist)) == 0) {
1281 PREFIX_LIST_IN(area) =
1282 prefix_list_lookup(
1283 AFI_IP,
1284 PREFIX_NAME_IN(area));
1285 abr_inv++;
1286 }
1287
1288 /* Update filter-list out. */
1289 if (PREFIX_NAME_OUT(area))
1290 if (strcmp(PREFIX_NAME_OUT(area),
1291 prefix_list_name(plist)) == 0) {
1292 PREFIX_LIST_IN(area) =
1293 prefix_list_lookup(
1294 AFI_IP,
1295 PREFIX_NAME_OUT(area));
1296 abr_inv++;
1297 }
1298 }
1299
1300 /* Schedule ABR task. */
1301 if (IS_OSPF_ABR(ospf) && abr_inv)
1302 ospf_schedule_abr_task(ospf);
1303 }
1304 }
1305
1306 static struct ospf_distance *ospf_distance_new(void)
1307 {
1308 return XCALLOC(MTYPE_OSPF_DISTANCE, sizeof(struct ospf_distance));
1309 }
1310
1311 static void ospf_distance_free(struct ospf_distance *odistance)
1312 {
1313 XFREE(MTYPE_OSPF_DISTANCE, odistance);
1314 }
1315
1316 int ospf_distance_set(struct vty *vty, struct ospf *ospf,
1317 const char *distance_str, const char *ip_str,
1318 const char *access_list_str)
1319 {
1320 int ret;
1321 struct prefix_ipv4 p;
1322 u_char distance;
1323 struct route_node *rn;
1324 struct ospf_distance *odistance;
1325
1326 ret = str2prefix_ipv4(ip_str, &p);
1327 if (ret == 0) {
1328 vty_out(vty, "Malformed prefix\n");
1329 return CMD_WARNING_CONFIG_FAILED;
1330 }
1331
1332 distance = atoi(distance_str);
1333
1334 /* Get OSPF distance node. */
1335 rn = route_node_get(ospf->distance_table, (struct prefix *)&p);
1336 if (rn->info) {
1337 odistance = rn->info;
1338 route_unlock_node(rn);
1339 } else {
1340 odistance = ospf_distance_new();
1341 rn->info = odistance;
1342 }
1343
1344 /* Set distance value. */
1345 odistance->distance = distance;
1346
1347 /* Reset access-list configuration. */
1348 if (odistance->access_list) {
1349 free(odistance->access_list);
1350 odistance->access_list = NULL;
1351 }
1352 if (access_list_str)
1353 odistance->access_list = strdup(access_list_str);
1354
1355 return CMD_SUCCESS;
1356 }
1357
1358 int ospf_distance_unset(struct vty *vty, struct ospf *ospf,
1359 const char *distance_str, const char *ip_str,
1360 char const *access_list_str)
1361 {
1362 int ret;
1363 struct prefix_ipv4 p;
1364 struct route_node *rn;
1365 struct ospf_distance *odistance;
1366
1367 ret = str2prefix_ipv4(ip_str, &p);
1368 if (ret == 0) {
1369 vty_out(vty, "Malformed prefix\n");
1370 return CMD_WARNING_CONFIG_FAILED;
1371 }
1372
1373 rn = route_node_lookup(ospf->distance_table, (struct prefix *)&p);
1374 if (!rn) {
1375 vty_out(vty, "Can't find specified prefix\n");
1376 return CMD_WARNING_CONFIG_FAILED;
1377 }
1378
1379 odistance = rn->info;
1380
1381 if (odistance->access_list)
1382 free(odistance->access_list);
1383 ospf_distance_free(odistance);
1384
1385 rn->info = NULL;
1386 route_unlock_node(rn);
1387 route_unlock_node(rn);
1388
1389 return CMD_SUCCESS;
1390 }
1391
1392 void ospf_distance_reset(struct ospf *ospf)
1393 {
1394 struct route_node *rn;
1395 struct ospf_distance *odistance;
1396
1397 for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
1398 if ((odistance = rn->info) != NULL) {
1399 if (odistance->access_list)
1400 free(odistance->access_list);
1401 ospf_distance_free(odistance);
1402 rn->info = NULL;
1403 route_unlock_node(rn);
1404 }
1405 }
1406
1407 u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
1408 struct ospf_route *or)
1409 {
1410
1411 if (ospf == NULL)
1412 return 0;
1413
1414 if (ospf->distance_intra)
1415 if (or->path_type == OSPF_PATH_INTRA_AREA)
1416 return ospf->distance_intra;
1417
1418 if (ospf->distance_inter)
1419 if (or->path_type == OSPF_PATH_INTER_AREA)
1420 return ospf->distance_inter;
1421
1422 if (ospf->distance_external)
1423 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL ||
1424 or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1425 return ospf->distance_external;
1426
1427 if (ospf->distance_all)
1428 return ospf->distance_all;
1429
1430 return 0;
1431 }
1432
1433 void ospf_zebra_vrf_register(struct ospf *ospf)
1434 {
1435 if (!zclient || zclient->sock < 0 || !ospf)
1436 return;
1437
1438 if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
1439 if (IS_DEBUG_OSPF_EVENT)
1440 zlog_debug("%s: Register VRF %s id %u",
1441 __PRETTY_FUNCTION__,
1442 ospf_vrf_id_to_name(ospf->vrf_id),
1443 ospf->vrf_id);
1444 zclient_send_reg_requests(zclient, ospf->vrf_id);
1445 }
1446 }
1447
1448 void ospf_zebra_vrf_deregister(struct ospf *ospf)
1449 {
1450 if (!zclient || zclient->sock < 0 || !ospf)
1451 return;
1452
1453 if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
1454 if (IS_DEBUG_OSPF_EVENT)
1455 zlog_debug("%s: De-Register VRF %s id %u",
1456 __PRETTY_FUNCTION__,
1457 ospf_vrf_id_to_name(ospf->vrf_id),
1458 ospf->vrf_id);
1459 /* Deregister for router-id, interfaces,
1460 * redistributed routes. */
1461 zclient_send_dereg_requests(zclient, ospf->vrf_id);
1462 }
1463 }
1464 static void ospf_zebra_connected(struct zclient *zclient)
1465 {
1466 /* Send the client registration */
1467 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
1468
1469 zclient_send_reg_requests(zclient, VRF_DEFAULT);
1470 }
1471
1472 void ospf_zebra_init(struct thread_master *master, u_short instance)
1473 {
1474 /* Allocate zebra structure. */
1475 zclient = zclient_new(master);
1476 zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance);
1477 zclient->zebra_connected = ospf_zebra_connected;
1478 zclient->router_id_update = ospf_router_id_update_zebra;
1479 zclient->interface_add = ospf_interface_add;
1480 zclient->interface_delete = ospf_interface_delete;
1481 zclient->interface_up = ospf_interface_state_up;
1482 zclient->interface_down = ospf_interface_state_down;
1483 zclient->interface_address_add = ospf_interface_address_add;
1484 zclient->interface_address_delete = ospf_interface_address_delete;
1485 zclient->interface_link_params = ospf_interface_link_params;
1486 zclient->interface_vrf_update = ospf_interface_vrf_update;
1487
1488 zclient->redistribute_route_add = ospf_zebra_read_route;
1489 zclient->redistribute_route_del = ospf_zebra_read_route;
1490
1491 access_list_add_hook(ospf_filter_update);
1492 access_list_delete_hook(ospf_filter_update);
1493 prefix_list_add_hook(ospf_prefix_list_update);
1494 prefix_list_delete_hook(ospf_prefix_list_update);
1495 }