]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_zebra.c
ospfd: OSPFv2 VRF remove iflist from master
[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_free(om->external[type]);
578 om->external[type] = NULL;
579 }
580 XFREE(MTYPE_OSPF_EXTERNAL, ext);
581 }
582 }
583
584 struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, u_char type,
585 u_short instance)
586 {
587 struct list *red_list;
588 struct listnode *node;
589 struct ospf_redist *red;
590
591 red_list = ospf->redist[type];
592 if (!red_list)
593 return (NULL);
594
595 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
596 if (red->instance == instance)
597 return red;
598
599 return NULL;
600 }
601
602 struct ospf_redist *ospf_redist_add(struct ospf *ospf, u_char type,
603 u_short instance)
604 {
605 struct list *red_list;
606 struct ospf_redist *red;
607
608 red = ospf_redist_lookup(ospf, type, instance);
609 if (red)
610 return red;
611
612 if (!ospf->redist[type])
613 ospf->redist[type] = list_new();
614
615 red_list = ospf->redist[type];
616 red = (struct ospf_redist *)XCALLOC(MTYPE_OSPF_REDISTRIBUTE,
617 sizeof(struct ospf_redist));
618 red->instance = instance;
619 red->dmetric.type = -1;
620 red->dmetric.value = -1;
621
622 listnode_add(red_list, red);
623
624 return red;
625 }
626
627 void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
628 {
629 struct ospf_redist *red;
630
631 red = ospf_redist_lookup(ospf, type, instance);
632
633 if (red) {
634 listnode_delete(ospf->redist[type], red);
635 if (!ospf->redist[type]->count) {
636 list_free(ospf->redist[type]);
637 ospf->redist[type] = NULL;
638 }
639 ospf_routemap_unset(red);
640 XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
641 }
642 }
643
644
645 int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
646 {
647 return (DEFAULT_ROUTE_TYPE(type)
648 ? vrf_bitmap_check(zclient->default_information,
649 ospf->vrf_id)
650 : ((instance
651 && redist_check_instance(
652 &zclient->mi_redist[AFI_IP][type],
653 instance))
654 || (!instance
655 && vrf_bitmap_check(
656 zclient->redist[AFI_IP][type],
657 ospf->vrf_id))));
658 }
659
660 int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
661 int mtype, int mvalue)
662 {
663 int force = 0;
664 struct ospf_redist *red;
665
666 red = ospf_redist_lookup(ospf, type, instance);
667 if (ospf_is_type_redistributed(ospf, type, instance)) {
668 if (mtype != red->dmetric.type) {
669 red->dmetric.type = mtype;
670 force = LSA_REFRESH_FORCE;
671 }
672 if (mvalue != red->dmetric.value) {
673 red->dmetric.value = mvalue;
674 force = LSA_REFRESH_FORCE;
675 }
676
677 ospf_external_lsa_refresh_type(ospf, type, instance, force);
678
679 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
680 zlog_debug(
681 "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
682 ospf_redist_string(type), instance,
683 metric_type(ospf, type, instance),
684 metric_value(ospf, type, instance));
685
686 return CMD_SUCCESS;
687 }
688
689 red->dmetric.type = mtype;
690 red->dmetric.value = mvalue;
691
692 ospf_external_add(type, instance);
693
694 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
695 instance, ospf->vrf_id);
696
697 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
698 zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
699 ospf_redist_string(type), instance, ospf->vrf_id,
700 metric_type(ospf, type, instance),
701 metric_value(ospf, type, instance));
702
703 ospf_asbr_status_update(ospf, ++ospf->redistribute);
704
705 return CMD_SUCCESS;
706 }
707
708 int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
709 {
710 if (type == zclient->redist_default && instance == zclient->instance)
711 return CMD_SUCCESS;
712
713 if (!ospf_is_type_redistributed(ospf, type, instance))
714 return CMD_SUCCESS;
715
716 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
717 instance, ospf->vrf_id);
718
719 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
720 zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
721 ospf_redist_string(type), instance, ospf->vrf_id);
722
723 ospf_redist_del(ospf, type, instance);
724
725 /* Remove the routes from OSPF table. */
726 ospf_redistribute_withdraw(ospf, type, instance);
727
728 ospf_external_del(type, instance);
729
730 ospf_asbr_status_update(ospf, --ospf->redistribute);
731
732 return CMD_SUCCESS;
733 }
734
735 int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
736 int mvalue)
737 {
738 struct ospf_redist *red;
739
740 ospf->default_originate = originate;
741
742 red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
743 red->dmetric.type = mtype;
744 red->dmetric.value = mvalue;
745
746 ospf_external_add(DEFAULT_ROUTE, 0);
747
748 if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
749 /* if ospf->default_originate changes value, is calling
750 ospf_external_lsa_refresh_default sufficient to implement
751 the change? */
752 ospf_external_lsa_refresh_default(ospf);
753
754 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
755 zlog_debug(
756 "Redistribute[%s]: Refresh Type[%d], Metric[%d]",
757 ospf_redist_string(DEFAULT_ROUTE),
758 metric_type(ospf, DEFAULT_ROUTE, 0),
759 metric_value(ospf, DEFAULT_ROUTE, 0));
760 return CMD_SUCCESS;
761 }
762
763 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
764 ospf->vrf_id);
765
766 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
767 zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
768 metric_type(ospf, DEFAULT_ROUTE, 0),
769 metric_value(ospf, DEFAULT_ROUTE, 0));
770
771 if (ospf->router_id.s_addr == 0)
772 ospf->external_origin |= (1 << DEFAULT_ROUTE);
773 else
774 thread_add_timer(master, ospf_default_originate_timer, ospf, 1,
775 NULL);
776
777 ospf_asbr_status_update(ospf, ++ospf->redistribute);
778
779 return CMD_SUCCESS;
780 }
781
782 int ospf_redistribute_default_unset(struct ospf *ospf)
783 {
784 if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
785 return CMD_SUCCESS;
786
787 ospf->default_originate = DEFAULT_ORIGINATE_NONE;
788 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
789
790 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
791 ospf->vrf_id);
792
793 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
794 zlog_debug("Redistribute[DEFAULT]: Stop");
795
796 // Pending: how does the external_info cleanup work in this case?
797
798 ospf_asbr_status_update(ospf, --ospf->redistribute);
799
800 return CMD_SUCCESS;
801 }
802
803 static int ospf_external_lsa_originate_check(struct ospf *ospf,
804 struct external_info *ei)
805 {
806 /* If prefix is multicast, then do not originate LSA. */
807 if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) {
808 zlog_info(
809 "LSA[Type5:%s]: Not originate AS-external-LSA, "
810 "Prefix belongs multicast",
811 inet_ntoa(ei->p.prefix));
812 return 0;
813 }
814
815 /* Take care of default-originate. */
816 if (is_prefix_default(&ei->p))
817 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) {
818 zlog_info(
819 "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
820 "for default");
821 return 0;
822 }
823
824 return 1;
825 }
826
827 /* If connected prefix is OSPF enable interface, then do not announce. */
828 int ospf_distribute_check_connected(struct ospf *ospf, struct external_info *ei)
829 {
830 struct listnode *node;
831 struct ospf_interface *oi;
832
833
834 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
835 if (prefix_match(oi->address, (struct prefix *)&ei->p))
836 return 0;
837 return 1;
838 }
839
840 /* return 1 if external LSA must be originated, 0 otherwise */
841 int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
842 int *changed)
843 {
844 struct route_map_set_values save_values;
845 struct prefix_ipv4 *p = &ei->p;
846 struct ospf_redist *red;
847 u_char type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type;
848 u_short instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
849
850 if (changed)
851 *changed = 0;
852
853 if (!ospf_external_lsa_originate_check(ospf, ei))
854 return 0;
855
856 /* Take care connected route. */
857 if (type == ZEBRA_ROUTE_CONNECT
858 && !ospf_distribute_check_connected(ospf, ei))
859 return 0;
860
861 if (!DEFAULT_ROUTE_TYPE(type) && DISTRIBUTE_NAME(ospf, type))
862 /* distirbute-list exists, but access-list may not? */
863 if (DISTRIBUTE_LIST(ospf, type))
864 if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p)
865 == FILTER_DENY) {
866 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
867 zlog_debug(
868 "Redistribute[%s]: %s/%d filtered by ditribute-list.",
869 ospf_redist_string(type),
870 inet_ntoa(p->prefix),
871 p->prefixlen);
872 return 0;
873 }
874
875 save_values = ei->route_map_set;
876 ospf_reset_route_map_set_values(&ei->route_map_set);
877
878 /* apply route-map if needed */
879 red = ospf_redist_lookup(ospf, type, instance);
880 if (red && ROUTEMAP_NAME(red)) {
881 int ret;
882
883 ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p,
884 RMAP_OSPF, ei);
885
886 if (ret == RMAP_DENYMATCH) {
887 ei->route_map_set = save_values;
888 if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
889 zlog_debug(
890 "Redistribute[%s]: %s/%d filtered by route-map.",
891 ospf_redist_string(type),
892 inet_ntoa(p->prefix), p->prefixlen);
893 return 0;
894 }
895
896 /* check if 'route-map set' changed something */
897 if (changed)
898 *changed = !ospf_route_map_set_compare(
899 &ei->route_map_set, &save_values);
900 }
901
902 return 1;
903 }
904
905 /* OSPF route-map set for redistribution */
906 void ospf_routemap_set(struct ospf_redist *red, const char *name)
907 {
908 if (ROUTEMAP_NAME(red))
909 free(ROUTEMAP_NAME(red));
910
911 ROUTEMAP_NAME(red) = strdup(name);
912 ROUTEMAP(red) = route_map_lookup_by_name(name);
913 }
914
915 void ospf_routemap_unset(struct ospf_redist *red)
916 {
917 if (ROUTEMAP_NAME(red))
918 free(ROUTEMAP_NAME(red));
919
920 ROUTEMAP_NAME(red) = NULL;
921 ROUTEMAP(red) = NULL;
922 }
923
924 /* Zebra route add and delete treatment. */
925 static int ospf_zebra_read_route(int command, struct zclient *zclient,
926 zebra_size_t length, vrf_id_t vrf_id)
927 {
928 struct zapi_route api;
929 struct prefix_ipv4 p;
930 unsigned long ifindex;
931 struct in_addr nexthop;
932 struct external_info *ei;
933 struct ospf *ospf;
934 int i;
935
936 ospf = ospf_lookup_by_vrf_id(vrf_id);
937 if (ospf == NULL)
938 return 0;
939
940 if (zapi_route_decode(zclient->ibuf, &api) < 0)
941 return -1;
942
943 ifindex = api.nexthops[0].ifindex;
944 nexthop = api.nexthops[0].gate.ipv4;
945
946 memcpy(&p, &api.prefix, sizeof(p));
947 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
948 return 0;
949
950 if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
951 /* XXX|HACK|TODO|FIXME:
952 * Maybe we should ignore reject/blackhole routes? Testing
953 * shows that there is no problems though and this is only way
954 * to "summarize" routes in ASBR at the moment. Maybe we need
955 * just a better generalised solution for these types?
956 */
957
958 /* Protocol tag overwrites all other tag value sent by zebra */
959 if (ospf->dtag[api.type] > 0)
960 api.tag = ospf->dtag[api.type];
961
962 /*
963 * Given zebra sends update for a prefix via ADD message, it
964 * should
965 * be considered as an implicit DEL for that prefix with other
966 * source
967 * types.
968 */
969 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
970 if (i != api.type)
971 ospf_external_info_delete(i, api.instance, p);
972
973 ei = ospf_external_info_add(api.type, api.instance, p, ifindex,
974 nexthop, api.tag);
975 if (ei == NULL) {
976 /* Nothing has changed, so nothing to do; return */
977 return 0;
978 }
979 if (ospf->router_id.s_addr == 0)
980 /* Set flags to generate AS-external-LSA originate event
981 for each redistributed protocols later. */
982 ospf->external_origin |= (1 << api.type);
983 else {
984 if (ei) {
985 if (is_prefix_default(&p))
986 ospf_external_lsa_refresh_default(ospf);
987 else {
988 struct ospf_lsa *current;
989
990 current = ospf_external_info_find_lsa(
991 ospf, &ei->p);
992 if (!current)
993 ospf_external_lsa_originate(
994 ospf, ei);
995 else {
996 if (IS_DEBUG_OSPF(
997 zebra,
998 ZEBRA_REDISTRIBUTE))
999 zlog_debug(
1000 "ospf_zebra_read_route() : %s refreshing LSA",
1001 inet_ntoa(
1002 p.prefix));
1003 ospf_external_lsa_refresh(
1004 ospf, current, ei,
1005 LSA_REFRESH_FORCE);
1006 }
1007 }
1008 }
1009 }
1010 } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
1011 {
1012 ospf_external_info_delete(api.type, api.instance, p);
1013 if (is_prefix_default(&p))
1014 ospf_external_lsa_refresh_default(ospf);
1015 else
1016 ospf_external_lsa_flush(ospf, api.type, &p,
1017 ifindex /*, nexthop */);
1018 }
1019
1020 return 0;
1021 }
1022
1023
1024 int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
1025 {
1026 /* Lookup access-list for distribute-list. */
1027 DISTRIBUTE_LIST(ospf, type) = access_list_lookup(AFI_IP, name);
1028
1029 /* Clear previous distribute-name. */
1030 if (DISTRIBUTE_NAME(ospf, type))
1031 free(DISTRIBUTE_NAME(ospf, type));
1032
1033 /* Set distribute-name. */
1034 DISTRIBUTE_NAME(ospf, type) = strdup(name);
1035
1036 /* If access-list have been set, schedule update timer. */
1037 if (DISTRIBUTE_LIST(ospf, type))
1038 ospf_distribute_list_update(ospf, type, 0);
1039
1040 return CMD_SUCCESS;
1041 }
1042
1043 int ospf_distribute_list_out_unset(struct ospf *ospf, int type,
1044 const char *name)
1045 {
1046 /* Schedule update timer. */
1047 if (DISTRIBUTE_LIST(ospf, type))
1048 ospf_distribute_list_update(ospf, type, 0);
1049
1050 /* Unset distribute-list. */
1051 DISTRIBUTE_LIST(ospf, type) = NULL;
1052
1053 /* Clear distribute-name. */
1054 if (DISTRIBUTE_NAME(ospf, type))
1055 free(DISTRIBUTE_NAME(ospf, type));
1056
1057 DISTRIBUTE_NAME(ospf, type) = NULL;
1058
1059 return CMD_SUCCESS;
1060 }
1061
1062 /* distribute-list update timer. */
1063 static int ospf_distribute_list_update_timer(struct thread *thread)
1064 {
1065 struct route_node *rn;
1066 struct external_info *ei;
1067 struct route_table *rt;
1068 struct ospf_lsa *lsa;
1069 int type, default_refresh = 0, arg_type;
1070 struct ospf *ospf = NULL;
1071 void **arg = THREAD_ARG (thread);
1072
1073 ospf = (struct ospf *)arg[0];
1074 arg_type = (int)(intptr_t)arg[1];
1075
1076 if (ospf == NULL)
1077 return 0;
1078
1079 ospf->t_distribute_update = NULL;
1080
1081 zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
1082
1083 if (IS_DEBUG_OSPF_EVENT) {
1084 zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
1085 __PRETTY_FUNCTION__, arg_type,
1086 ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
1087 }
1088
1089 /* foreach all external info. */
1090 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1091 struct list *ext_list;
1092 struct listnode *node;
1093 struct ospf_external *ext;
1094
1095 ext_list = om->external[type];
1096 if (!ext_list)
1097 continue;
1098
1099 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
1100 rt = ext->external_info;
1101 if (!rt)
1102 continue;
1103 for (rn = route_top(rt); rn; rn = route_next(rn))
1104 if ((ei = rn->info) != NULL) {
1105 if (is_prefix_default(&ei->p))
1106 default_refresh = 1;
1107 else if (
1108 (lsa = ospf_external_info_find_lsa(
1109 ospf, &ei->p)))
1110 ospf_external_lsa_refresh(
1111 ospf, lsa, ei,
1112 LSA_REFRESH_IF_CHANGED);
1113 else
1114 ospf_external_lsa_originate(
1115 ospf, ei);
1116 }
1117 }
1118 }
1119 if (default_refresh)
1120 ospf_external_lsa_refresh_default(ospf);
1121
1122 XFREE(MTYPE_OSPF_DIST_ARGS, arg);
1123 return 0;
1124 }
1125
1126 /* Update distribute-list and set timer to apply access-list. */
1127 void ospf_distribute_list_update(struct ospf *ospf, int type,
1128 u_short instance)
1129 {
1130 struct route_table *rt;
1131 struct ospf_external *ext;
1132 void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
1133
1134 args[0] = ospf;
1135 args[1] = (void *)((ptrdiff_t) type);
1136
1137 /* External info does not exist. */
1138 ext = ospf_external_lookup(type, instance);
1139 if (!ext || !(rt = EXTERNAL_INFO(ext)))
1140 return;
1141
1142 /* If exists previously invoked thread, then let it continue. */
1143 if (ospf->t_distribute_update)
1144 return;
1145
1146 /* Set timer. */
1147 ospf->t_distribute_update = NULL;
1148 thread_add_timer_msec(master, ospf_distribute_list_update_timer,
1149 (void **)args, ospf->min_ls_interval,
1150 &ospf->t_distribute_update);
1151 }
1152
1153 /* If access-list is updated, apply some check. */
1154 static void ospf_filter_update(struct access_list *access)
1155 {
1156 struct ospf *ospf;
1157 int type;
1158 int abr_inv = 0;
1159 struct ospf_area *area;
1160 struct listnode *node, *n1;
1161
1162 /* If OSPF instance does not exist, return right now. */
1163 if (listcount(om->ospf) == 0)
1164 return;
1165
1166 /* Iterate all ospf [VRF] instances */
1167 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
1168 /* Update distribute-list, and apply filter. */
1169 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1170 struct list *red_list;
1171 struct listnode *node;
1172 struct ospf_redist *red;
1173
1174 red_list = ospf->redist[type];
1175 if (red_list)
1176 for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
1177 if (ROUTEMAP(red)) {
1178 /* if route-map is not NULL it may be
1179 * using this access list */
1180 ospf_distribute_list_update(
1181 ospf,
1182 type, red->instance);
1183 }
1184 }
1185
1186 /* There is place for route-map for default-information
1187 * (ZEBRA_ROUTE_MAX),
1188 * but no distribute list. */
1189 if (type == ZEBRA_ROUTE_MAX)
1190 break;
1191
1192 if (DISTRIBUTE_NAME(ospf, type)) {
1193 /* Keep old access-list for distribute-list. */
1194 struct access_list *old = DISTRIBUTE_LIST(ospf,
1195 type);
1196
1197 /* Update access-list for distribute-list. */
1198 DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
1199 AFI_IP, DISTRIBUTE_NAME(ospf, type));
1200
1201 /* No update for this distribute type. */
1202 if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
1203 continue;
1204
1205 /* Schedule distribute-list update timer. */
1206 if (DISTRIBUTE_LIST(ospf, type) == NULL
1207 || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
1208 == 0)
1209 ospf_distribute_list_update(ospf, type, 0);
1210 }
1211 }
1212
1213 /* Update Area access-list. */
1214 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1215 if (EXPORT_NAME(area)) {
1216 EXPORT_LIST(area) = NULL;
1217 abr_inv++;
1218 }
1219
1220 if (IMPORT_NAME(area)) {
1221 IMPORT_LIST(area) = NULL;
1222 abr_inv++;
1223 }
1224 }
1225
1226 /* Schedule ABR tasks -- this will be changed -- takada. */
1227 if (IS_OSPF_ABR(ospf) && abr_inv)
1228 ospf_schedule_abr_task(ospf);
1229 }
1230 }
1231
1232 /* If prefix-list is updated, do some updates. */
1233 void ospf_prefix_list_update(struct prefix_list *plist)
1234 {
1235 struct ospf *ospf = NULL;
1236 int type;
1237 int abr_inv = 0;
1238 struct ospf_area *area;
1239 struct listnode *node, *n1;
1240
1241 /* If OSPF instatnce does not exist, return right now. */
1242 if (listcount(om->ospf) == 0)
1243 return;
1244
1245 /* Iterate all ospf [VRF] instances */
1246 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
1247
1248 /* Update all route-maps which are used
1249 * as redistribution filters.
1250 * They might use prefix-list.
1251 */
1252 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
1253 struct list *red_list;
1254 struct listnode *node;
1255 struct ospf_redist *red;
1256
1257 red_list = ospf->redist[type];
1258 if (red_list) {
1259 for (ALL_LIST_ELEMENTS_RO(red_list,
1260 node, red)) {
1261 if (ROUTEMAP(red)) {
1262 /* if route-map is not NULL
1263 * it may be using
1264 * this prefix list */
1265 ospf_distribute_list_update(
1266 ospf, type,
1267 red->instance);
1268 }
1269 }
1270 }
1271 }
1272
1273 /* Update area filter-lists. */
1274 for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
1275 /* Update filter-list in. */
1276 if (PREFIX_NAME_IN(area))
1277 if (strcmp(PREFIX_NAME_IN(area),
1278 prefix_list_name(plist)) == 0) {
1279 PREFIX_LIST_IN(area) =
1280 prefix_list_lookup(
1281 AFI_IP,
1282 PREFIX_NAME_IN(area));
1283 abr_inv++;
1284 }
1285
1286 /* Update filter-list out. */
1287 if (PREFIX_NAME_OUT(area))
1288 if (strcmp(PREFIX_NAME_OUT(area),
1289 prefix_list_name(plist)) == 0) {
1290 PREFIX_LIST_IN(area) =
1291 prefix_list_lookup(
1292 AFI_IP,
1293 PREFIX_NAME_OUT(area));
1294 abr_inv++;
1295 }
1296 }
1297
1298 /* Schedule ABR task. */
1299 if (IS_OSPF_ABR(ospf) && abr_inv)
1300 ospf_schedule_abr_task(ospf);
1301 }
1302 }
1303
1304 static struct ospf_distance *ospf_distance_new(void)
1305 {
1306 return XCALLOC(MTYPE_OSPF_DISTANCE, sizeof(struct ospf_distance));
1307 }
1308
1309 static void ospf_distance_free(struct ospf_distance *odistance)
1310 {
1311 XFREE(MTYPE_OSPF_DISTANCE, odistance);
1312 }
1313
1314 int ospf_distance_set(struct vty *vty, struct ospf *ospf,
1315 const char *distance_str, const char *ip_str,
1316 const char *access_list_str)
1317 {
1318 int ret;
1319 struct prefix_ipv4 p;
1320 u_char distance;
1321 struct route_node *rn;
1322 struct ospf_distance *odistance;
1323
1324 ret = str2prefix_ipv4(ip_str, &p);
1325 if (ret == 0) {
1326 vty_out(vty, "Malformed prefix\n");
1327 return CMD_WARNING_CONFIG_FAILED;
1328 }
1329
1330 distance = atoi(distance_str);
1331
1332 /* Get OSPF distance node. */
1333 rn = route_node_get(ospf->distance_table, (struct prefix *)&p);
1334 if (rn->info) {
1335 odistance = rn->info;
1336 route_unlock_node(rn);
1337 } else {
1338 odistance = ospf_distance_new();
1339 rn->info = odistance;
1340 }
1341
1342 /* Set distance value. */
1343 odistance->distance = distance;
1344
1345 /* Reset access-list configuration. */
1346 if (odistance->access_list) {
1347 free(odistance->access_list);
1348 odistance->access_list = NULL;
1349 }
1350 if (access_list_str)
1351 odistance->access_list = strdup(access_list_str);
1352
1353 return CMD_SUCCESS;
1354 }
1355
1356 int ospf_distance_unset(struct vty *vty, struct ospf *ospf,
1357 const char *distance_str, const char *ip_str,
1358 char const *access_list_str)
1359 {
1360 int ret;
1361 struct prefix_ipv4 p;
1362 struct route_node *rn;
1363 struct ospf_distance *odistance;
1364
1365 ret = str2prefix_ipv4(ip_str, &p);
1366 if (ret == 0) {
1367 vty_out(vty, "Malformed prefix\n");
1368 return CMD_WARNING_CONFIG_FAILED;
1369 }
1370
1371 rn = route_node_lookup(ospf->distance_table, (struct prefix *)&p);
1372 if (!rn) {
1373 vty_out(vty, "Can't find specified prefix\n");
1374 return CMD_WARNING_CONFIG_FAILED;
1375 }
1376
1377 odistance = rn->info;
1378
1379 if (odistance->access_list)
1380 free(odistance->access_list);
1381 ospf_distance_free(odistance);
1382
1383 rn->info = NULL;
1384 route_unlock_node(rn);
1385 route_unlock_node(rn);
1386
1387 return CMD_SUCCESS;
1388 }
1389
1390 void ospf_distance_reset(struct ospf *ospf)
1391 {
1392 struct route_node *rn;
1393 struct ospf_distance *odistance;
1394
1395 for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
1396 if ((odistance = rn->info) != NULL) {
1397 if (odistance->access_list)
1398 free(odistance->access_list);
1399 ospf_distance_free(odistance);
1400 rn->info = NULL;
1401 route_unlock_node(rn);
1402 }
1403 }
1404
1405 u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
1406 struct ospf_route *or)
1407 {
1408
1409 if (ospf == NULL)
1410 return 0;
1411
1412 if (ospf->distance_intra)
1413 if (or->path_type == OSPF_PATH_INTRA_AREA)
1414 return ospf->distance_intra;
1415
1416 if (ospf->distance_inter)
1417 if (or->path_type == OSPF_PATH_INTER_AREA)
1418 return ospf->distance_inter;
1419
1420 if (ospf->distance_external)
1421 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL ||
1422 or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1423 return ospf->distance_external;
1424
1425 if (ospf->distance_all)
1426 return ospf->distance_all;
1427
1428 return 0;
1429 }
1430
1431 void ospf_zebra_vrf_register(struct ospf *ospf)
1432 {
1433 if (!zclient || zclient->sock < 0 || !ospf)
1434 return;
1435
1436 if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
1437 if (IS_DEBUG_OSPF_EVENT)
1438 zlog_debug("%s: Register VRF %s id %u",
1439 __PRETTY_FUNCTION__,
1440 ospf_vrf_id_to_name(ospf->vrf_id),
1441 ospf->vrf_id);
1442 zclient_send_reg_requests(zclient, ospf->vrf_id);
1443 }
1444 }
1445
1446 void ospf_zebra_vrf_deregister(struct ospf *ospf)
1447 {
1448 if (!zclient || zclient->sock < 0 || !ospf)
1449 return;
1450
1451 if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
1452 if (IS_DEBUG_OSPF_EVENT)
1453 zlog_debug("%s: De-Register VRF %s id %u",
1454 __PRETTY_FUNCTION__,
1455 ospf_vrf_id_to_name(ospf->vrf_id),
1456 ospf->vrf_id);
1457 /* Deregister for router-id, interfaces,
1458 * redistributed routes. */
1459 zclient_send_dereg_requests(zclient, ospf->vrf_id);
1460 }
1461 }
1462 static void ospf_zebra_connected(struct zclient *zclient)
1463 {
1464 /* Send the client registration */
1465 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
1466
1467 zclient_send_reg_requests(zclient, VRF_DEFAULT);
1468 }
1469
1470 void ospf_zebra_init(struct thread_master *master, u_short instance)
1471 {
1472 /* Allocate zebra structure. */
1473 zclient = zclient_new(master);
1474 zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance);
1475 zclient->zebra_connected = ospf_zebra_connected;
1476 zclient->router_id_update = ospf_router_id_update_zebra;
1477 zclient->interface_add = ospf_interface_add;
1478 zclient->interface_delete = ospf_interface_delete;
1479 zclient->interface_up = ospf_interface_state_up;
1480 zclient->interface_down = ospf_interface_state_down;
1481 zclient->interface_address_add = ospf_interface_address_add;
1482 zclient->interface_address_delete = ospf_interface_address_delete;
1483 zclient->interface_link_params = ospf_interface_link_params;
1484 zclient->interface_vrf_update = ospf_interface_vrf_update;
1485
1486 zclient->redistribute_route_add = ospf_zebra_read_route;
1487 zclient->redistribute_route_del = ospf_zebra_read_route;
1488
1489 access_list_add_hook(ospf_filter_update);
1490 access_list_delete_hook(ospf_filter_update);
1491 prefix_list_add_hook(ospf_prefix_list_update);
1492 prefix_list_delete_hook(ospf_prefix_list_update);
1493 }