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