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