blob: bdb0c0f5acf77fe69993a3e9051b61c6f5b56303 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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"
35#include "log.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_abr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_dump.h"
45#include "ospfd/ospf_route.h"
46#include "ospfd/ospf_zebra.h"
47#ifdef HAVE_SNMP
48#include "ospfd/ospf_snmp.h"
49#endif /* HAVE_SNMP */
50
51/* Zebra structure to hold current status. */
52struct zclient *zclient = NULL;
53
54/* For registering threads. */
55extern struct thread_master *master;
56
57/* Inteface addition message from zebra. */
58int
59ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
60{
61 struct interface *ifp;
paul020709f2003-04-04 02:44:16 +000062 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +000063
64 ifp = zebra_interface_add_read (zclient->ibuf);
65
66 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
67 zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
68 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
69
paulf2c80652002-12-13 21:44:27 +000070 assert(ifp->info);
71
paul718e3742002-12-13 20:15:29 +000072 if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
73 {
74 SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
75 IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
76
77 if (if_is_broadcast (ifp))
78 IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
79 else if (if_is_pointopoint (ifp))
80 IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT;
81 else if (if_is_loopback (ifp))
82 IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_LOOPBACK;
83 }
84
paul020709f2003-04-04 02:44:16 +000085 ospf = ospf_lookup ();
86 if (ospf != NULL)
87 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +000088
89#ifdef HAVE_SNMP
90 ospf_snmp_if_update (ifp);
91#endif /* HAVE_SNMP */
92
93 return 0;
94}
95
96int
97ospf_interface_delete (int command, struct zclient *zclient,
98 zebra_size_t length)
99{
100 struct interface *ifp;
101 struct stream *s;
102 struct route_node *rn;
103
104 s = zclient->ibuf;
105 /* zebra_interface_state_read() updates interface structure in iflist */
106 ifp = zebra_interface_state_read (s);
107
108 if (ifp == NULL)
109 return 0;
110
111 if (if_is_up (ifp))
112 zlog_warn ("Zebra: got delete of %s, but interface is still up",
113 ifp->name);
114
115 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
116 zlog_info ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
117 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
118
119#ifdef HAVE_SNMP
120 ospf_snmp_if_delete (ifp);
121#endif /* HAVE_SNMP */
122
123 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
124 if (rn->info)
125 ospf_if_free ((struct ospf_interface *) rn->info);
126
127 for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
128 if (rn->info)
129 ospf_del_if_params (rn->info);
130
131 if_delete (ifp);
132
133 return 0;
134}
135
136struct interface *
137zebra_interface_if_lookup (struct stream *s)
138{
139 struct interface *ifp;
140 u_char ifname_tmp[INTERFACE_NAMSIZ];
141
142 /* Read interface name. */
143 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
144
145 /* Lookup this by interface index. */
146 ifp = if_lookup_by_name (ifname_tmp);
147
148 /* If such interface does not exist, indicate an error */
149 if (!ifp)
150 return NULL;
151
152 return ifp;
153}
154
155void
156zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
157{
158 /* Read interface's index. */
159 ifp->ifindex = stream_getl (s);
160
161 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000162 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000163 ifp->flags = stream_getl (s);
164 ifp->metric = stream_getl (s);
165 ifp->mtu = stream_getl (s);
166 ifp->bandwidth = stream_getl (s);
167}
168
169int
170ospf_interface_state_up (int command, struct zclient *zclient,
171 zebra_size_t length)
172{
173 struct interface *ifp;
174 struct interface if_tmp;
175 struct ospf_interface *oi;
176 struct route_node *rn;
177
178 ifp = zebra_interface_if_lookup (zclient->ibuf);
179
180 if (ifp == NULL)
181 return 0;
182
183 /* Interface is already up. */
paul2e3b2e42002-12-13 21:03:13 +0000184 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000185 {
186 /* Temporarily keep ifp values. */
187 memcpy (&if_tmp, ifp, sizeof (struct interface));
188
189 zebra_interface_if_set_value (zclient->ibuf, ifp);
190
191 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
192 zlog_info ("Zebra: Interface[%s] state update.", ifp->name);
193
194 if (if_tmp.bandwidth != ifp->bandwidth)
195 {
196 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
197 zlog_info ("Zebra: Interface[%s] bandwidth change %d -> %d.",
198 ifp->name, if_tmp.bandwidth, ifp->bandwidth);
199
200 ospf_if_recalculate_output_cost (ifp);
201 }
202 return 0;
203 }
204
205 zebra_interface_if_set_value (zclient->ibuf, ifp);
206
207 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
208 zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);
209
210 for (rn = route_top (IF_OIFS (ifp));rn; rn = route_next (rn))
211 {
212 if ( (oi = rn->info) == NULL)
213 continue;
214
215 ospf_if_up (oi);
216 }
217
218 return 0;
219}
220
221int
222ospf_interface_state_down (int command, struct zclient *zclient,
223 zebra_size_t length)
224{
225 struct interface *ifp;
226 struct ospf_interface *oi;
227 struct route_node *node;
228
229 ifp = zebra_interface_state_read (zclient->ibuf);
230
231 if (ifp == NULL)
232 return 0;
233
234 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
235 zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);
236
237 for (node = route_top (IF_OIFS (ifp));node; node = route_next (node))
238 {
239 if ( (oi = node->info) == NULL)
240 continue;
241 ospf_if_down (oi);
242 }
243
244 return 0;
245}
246
247int
248ospf_interface_address_add (int command, struct zclient *zclient,
249 zebra_size_t length)
250{
paul020709f2003-04-04 02:44:16 +0000251 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000252 struct connected *c;
253
254 c = zebra_interface_address_add_read (zclient->ibuf);
255
256 if (c == NULL)
257 return 0;
258
paul020709f2003-04-04 02:44:16 +0000259 ospf = ospf_lookup ();
260 if (ospf != NULL)
261 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000262
263#ifdef HAVE_SNMP
264 ospf_snmp_if_update (c->ifp);
265#endif /* HAVE_SNMP */
266
267 return 0;
268}
269
270int
271ospf_interface_address_delete (int command, struct zclient *zclient,
272 zebra_size_t length)
273{
paul020709f2003-04-04 02:44:16 +0000274 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000275 struct connected *c;
276 struct interface *ifp;
277 struct ospf_interface *oi;
278 struct route_node *rn;
279 struct prefix p;
280
281 c = zebra_interface_address_delete_read (zclient->ibuf);
282
283 if (c == NULL)
284 return 0;
285
286 ifp = c->ifp;
287 p = *c->address;
288 p.prefixlen = IPV4_MAX_PREFIXLEN;
289
290 rn = route_node_lookup (IF_OIFS (ifp), &p);
291 if (! rn)
292 return 0;
293
294 assert (rn->info);
295 oi = rn->info;
296
297 /* Call interface hook functions to clean up */
298 ospf_if_free (oi);
299
300#ifdef HAVE_SNMP
301 ospf_snmp_if_update (c->ifp);
302#endif /* HAVE_SNMP */
303
304 connected_free (c);
305
paul020709f2003-04-04 02:44:16 +0000306 ospf = ospf_lookup ();
307 if (ospf != NULL)
308 ospf_if_update (ospf);
paul718e3742002-12-13 20:15:29 +0000309
310 return 0;
311}
312
313void
314ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
315{
316 u_char message;
317 u_char distance;
318 u_char flags;
319 int psize;
320 struct stream *s;
321 struct ospf_path *path;
322 listnode node;
323
324 if (zclient->redist[ZEBRA_ROUTE_OSPF])
325 {
326 message = 0;
327 flags = 0;
328
329 /* OSPF pass nexthop and metric */
330 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
331 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
332
333 /* Distance value. */
334 distance = ospf_distance_apply (p, or);
335 if (distance)
336 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
337
338 /* Make packet. */
339 s = zclient->obuf;
340 stream_reset (s);
341
342 /* Length place holder. */
343 stream_putw (s, 0);
344
345 /* Put command, type, flags, message. */
346 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
347 stream_putc (s, ZEBRA_ROUTE_OSPF);
348 stream_putc (s, flags);
349 stream_putc (s, message);
350
351 /* Put prefix information. */
352 psize = PSIZE (p->prefixlen);
353 stream_putc (s, p->prefixlen);
354 stream_write (s, (u_char *)&p->prefix, psize);
355
356 /* Nexthop count. */
357 stream_putc (s, or->path->count);
358
359 /* Nexthop, ifindex, distance and metric information. */
360 for (node = listhead (or->path); node; nextnode (node))
361 {
362 path = getdata (node);
363
364 if (path->nexthop.s_addr != INADDR_ANY)
365 {
366 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
367 stream_put_in_addr (s, &path->nexthop);
368 }
369 else
370 {
371 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
372 if (path->oi)
373 stream_putl (s, path->oi->ifp->ifindex);
374 else
375 stream_putl (s, 0);
376 }
377 }
378
379 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
380 stream_putc (s, distance);
381 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
382 {
383 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
384 stream_putl (s, or->cost + or->u.ext.type2_cost);
385 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
386 stream_putl (s, or->u.ext.type2_cost);
387 else
388 stream_putl (s, or->cost);
389 }
390
391 stream_putw_at (s, 0, stream_get_endp (s));
392
393 writen (zclient->sock, s->data, stream_get_endp (s));
394
395#if 0
396 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
397 {
398 char *nexthop_str;
399
400 nexthop_str = strdup (inet_ntoa (*nexthop));
401 zlog_info ("Zebra: Route add %s/%d nexthop %s metric %d",
402 inet_ntoa (p->prefix), p->prefixlen, nexthop_str,
403 metric);
404 free (nexthop_str);
405 }
406#endif /* 0 */
407 }
408}
409
410void
411ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
412{
413 struct zapi_ipv4 api;
414
415 if (zclient->redist[ZEBRA_ROUTE_OSPF])
416 {
417 api.type = ZEBRA_ROUTE_OSPF;
418 api.flags = 0;
419 api.message = 0;
420 zapi_ipv4_delete (zclient, p, &api);
421
422#if 0
423 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
424 {
425 char *nexthop_str;
426
427 nexthop_str = strdup (inet_ntoa (*nexthop));
428 zlog_info ("Zebra: Route delete %s/%d nexthop %s",
429 inet_ntoa (p->prefix), p->prefixlen, nexthop_str);
430 free (nexthop_str);
431 }
432#endif /* 0 */
433 }
434}
435
436void
437ospf_zebra_add_discard (struct prefix_ipv4 *p)
438{
439 struct zapi_ipv4 api;
440
441 if (zclient->redist[ZEBRA_ROUTE_OSPF])
442 {
443 api.type = ZEBRA_ROUTE_OSPF;
444 api.flags = ZEBRA_FLAG_BLACKHOLE;
445 api.message = 0;
446 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
447 api.nexthop_num = 0;
448 api.ifindex_num = 0;
449
450 zapi_ipv4_add (zclient, p, &api);
451 }
452}
453
454void
455ospf_zebra_delete_discard (struct prefix_ipv4 *p)
456{
457 struct zapi_ipv4 api;
458
459 if (zclient->redist[ZEBRA_ROUTE_OSPF])
460 {
461 api.type = ZEBRA_ROUTE_OSPF;
462 api.flags = ZEBRA_FLAG_BLACKHOLE;
463 api.message = 0;
464 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
465 api.nexthop_num = 0;
466 api.ifindex_num = 0;
467
468 zapi_ipv4_delete (zclient, p, &api);
469 }
470}
471
472int
473ospf_is_type_redistributed (int type)
474{
475 return (DEFAULT_ROUTE_TYPE (type)) ?
476 zclient->default_information : zclient->redist[type];
477}
478
479int
paul020709f2003-04-04 02:44:16 +0000480ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
paul718e3742002-12-13 20:15:29 +0000481{
482 int force = 0;
483
484 if (ospf_is_type_redistributed (type))
485 {
paul68980082003-03-25 05:07:42 +0000486 if (mtype != ospf->dmetric[type].type)
paul718e3742002-12-13 20:15:29 +0000487 {
paul68980082003-03-25 05:07:42 +0000488 ospf->dmetric[type].type = mtype;
paul718e3742002-12-13 20:15:29 +0000489 force = LSA_REFRESH_FORCE;
490 }
paul68980082003-03-25 05:07:42 +0000491 if (mvalue != ospf->dmetric[type].value)
paul718e3742002-12-13 20:15:29 +0000492 {
paul68980082003-03-25 05:07:42 +0000493 ospf->dmetric[type].value = mvalue;
paul718e3742002-12-13 20:15:29 +0000494 force = LSA_REFRESH_FORCE;
495 }
496
paul68980082003-03-25 05:07:42 +0000497 ospf_external_lsa_refresh_type (ospf, type, force);
paul718e3742002-12-13 20:15:29 +0000498
499 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
500 zlog_info ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
501 LOOKUP (ospf_redistributed_proto, type),
paul68980082003-03-25 05:07:42 +0000502 metric_type (ospf, type), metric_value (ospf, type));
paul718e3742002-12-13 20:15:29 +0000503
504 return CMD_SUCCESS;
505 }
506
paul68980082003-03-25 05:07:42 +0000507 ospf->dmetric[type].type = mtype;
508 ospf->dmetric[type].value = mvalue;
paul718e3742002-12-13 20:15:29 +0000509
510 zclient_redistribute_set (zclient, type);
511
512 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
513 zlog_info ("Redistribute[%s]: Start Type[%d], Metric[%d]",
514 LOOKUP (ospf_redistributed_proto, type),
paul68980082003-03-25 05:07:42 +0000515 metric_type (ospf, type), metric_value (ospf, type));
paul718e3742002-12-13 20:15:29 +0000516
paul68980082003-03-25 05:07:42 +0000517 ospf_asbr_status_update (ospf, ++ospf->redistribute);
paul718e3742002-12-13 20:15:29 +0000518
519 return CMD_SUCCESS;
520}
521
522int
paul020709f2003-04-04 02:44:16 +0000523ospf_redistribute_unset (struct ospf *ospf, int type)
paul718e3742002-12-13 20:15:29 +0000524{
525 if (type == zclient->redist_default)
526 return CMD_SUCCESS;
527
528 if (! ospf_is_type_redistributed (type))
529 return CMD_SUCCESS;
530
531 zclient_redistribute_unset (zclient, type);
532
533 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
534 zlog_info ("Redistribute[%s]: Stop",
535 LOOKUP (ospf_redistributed_proto, type));
536
paul68980082003-03-25 05:07:42 +0000537 ospf->dmetric[type].type = -1;
538 ospf->dmetric[type].value = -1;
paul718e3742002-12-13 20:15:29 +0000539
540 /* Remove the routes from OSPF table. */
541 ospf_redistribute_withdraw (type);
542
paul68980082003-03-25 05:07:42 +0000543 ospf_asbr_status_update (ospf, --ospf->redistribute);
paul718e3742002-12-13 20:15:29 +0000544
545 return CMD_SUCCESS;
546}
547
548int
paul020709f2003-04-04 02:44:16 +0000549ospf_redistribute_default_set (struct ospf *ospf, int originate,
550 int mtype, int mvalue)
paul718e3742002-12-13 20:15:29 +0000551{
552 int force = 0;
paul020709f2003-04-04 02:44:16 +0000553
paul718e3742002-12-13 20:15:29 +0000554 if (ospf_is_type_redistributed (DEFAULT_ROUTE))
555 {
paul68980082003-03-25 05:07:42 +0000556 if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)
paul718e3742002-12-13 20:15:29 +0000557 {
paul68980082003-03-25 05:07:42 +0000558 ospf->dmetric[DEFAULT_ROUTE].type = mtype;
paul718e3742002-12-13 20:15:29 +0000559 force = 1;
560 }
paul68980082003-03-25 05:07:42 +0000561 if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)
paul718e3742002-12-13 20:15:29 +0000562 {
563 force = 1;
paul68980082003-03-25 05:07:42 +0000564 ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
paul718e3742002-12-13 20:15:29 +0000565 }
566
paul68980082003-03-25 05:07:42 +0000567 ospf_external_lsa_refresh_default (ospf);
paul718e3742002-12-13 20:15:29 +0000568
569 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
570 zlog_info ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
571 LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),
paul68980082003-03-25 05:07:42 +0000572 metric_type (ospf, DEFAULT_ROUTE),
573 metric_value (ospf, DEFAULT_ROUTE));
paul718e3742002-12-13 20:15:29 +0000574 return CMD_SUCCESS;
575 }
576
paul68980082003-03-25 05:07:42 +0000577 ospf->default_originate = originate;
578 ospf->dmetric[DEFAULT_ROUTE].type = mtype;
579 ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
paul718e3742002-12-13 20:15:29 +0000580
581 zclient_redistribute_default_set (zclient);
582
583 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
584 zlog_info ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
paul68980082003-03-25 05:07:42 +0000585 metric_type (ospf, DEFAULT_ROUTE),
586 metric_value (ospf, DEFAULT_ROUTE));
paul718e3742002-12-13 20:15:29 +0000587
paul68980082003-03-25 05:07:42 +0000588 if (ospf->router_id.s_addr == 0)
589 ospf->external_origin |= (1 << DEFAULT_ROUTE);
paul718e3742002-12-13 20:15:29 +0000590 else
591 thread_add_timer (master, ospf_default_originate_timer,
paul68980082003-03-25 05:07:42 +0000592 &ospf->default_originate, 1);
paul718e3742002-12-13 20:15:29 +0000593
paul68980082003-03-25 05:07:42 +0000594 ospf_asbr_status_update (ospf, ++ospf->redistribute);
paul718e3742002-12-13 20:15:29 +0000595
596 return CMD_SUCCESS;
597}
598
599int
paul020709f2003-04-04 02:44:16 +0000600ospf_redistribute_default_unset (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000601{
602 if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
603 return CMD_SUCCESS;
604
paul68980082003-03-25 05:07:42 +0000605 ospf->default_originate = DEFAULT_ORIGINATE_NONE;
606 ospf->dmetric[DEFAULT_ROUTE].type = -1;
607 ospf->dmetric[DEFAULT_ROUTE].value = -1;
paul718e3742002-12-13 20:15:29 +0000608
609 zclient_redistribute_default_unset (zclient);
610
611 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
612 zlog_info ("Redistribute[DEFAULT]: Stop");
613
paul68980082003-03-25 05:07:42 +0000614 ospf_asbr_status_update (ospf, --ospf->redistribute);
paul718e3742002-12-13 20:15:29 +0000615
616 return CMD_SUCCESS;
617}
618
619int
paul020709f2003-04-04 02:44:16 +0000620ospf_external_lsa_originate_check (struct ospf *ospf,
621 struct external_info *ei)
paul718e3742002-12-13 20:15:29 +0000622{
623 /* If prefix is multicast, then do not originate LSA. */
624 if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
625 {
626 zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
627 "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
628 return 0;
629 }
630
631 /* Take care of default-originate. */
632 if (is_prefix_default (&ei->p))
paul68980082003-03-25 05:07:42 +0000633 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
paul718e3742002-12-13 20:15:29 +0000634 {
635 zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
636 "for default");
637 return 0;
638 }
639
640 return 1;
641}
642
643/* If connected prefix is OSPF enable interface, then do not announce. */
644int
paul68980082003-03-25 05:07:42 +0000645ospf_distribute_check_connected (struct ospf *ospf,
646 struct external_info *ei)
paul718e3742002-12-13 20:15:29 +0000647{
648 struct route_node *rn;
649
paul68980082003-03-25 05:07:42 +0000650 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000651 if (rn->info != NULL)
652 if (prefix_match (&rn->p, (struct prefix *)&ei->p))
paul68980082003-03-25 05:07:42 +0000653 {
654 route_unlock_node (rn);
655 return 0;
656 }
paul718e3742002-12-13 20:15:29 +0000657
658 return 1;
659}
660
661/* return 1 if external LSA must be originated, 0 otherwise */
662int
paul68980082003-03-25 05:07:42 +0000663ospf_redistribute_check (struct ospf *ospf,
664 struct external_info *ei, int *changed)
paul718e3742002-12-13 20:15:29 +0000665{
666 struct route_map_set_values save_values;
667 struct prefix_ipv4 *p = &ei->p;
668 u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
669
670 if (changed)
671 *changed = 0;
672
paul020709f2003-04-04 02:44:16 +0000673 if (!ospf_external_lsa_originate_check (ospf, ei))
paul718e3742002-12-13 20:15:29 +0000674 return 0;
675
676 /* Take care connected route. */
paul68980082003-03-25 05:07:42 +0000677 if (type == ZEBRA_ROUTE_CONNECT &&
678 !ospf_distribute_check_connected (ospf, ei))
paul718e3742002-12-13 20:15:29 +0000679 return 0;
680
paul020709f2003-04-04 02:44:16 +0000681 if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
paul718e3742002-12-13 20:15:29 +0000682 /* distirbute-list exists, but access-list may not? */
paul020709f2003-04-04 02:44:16 +0000683 if (DISTRIBUTE_LIST (ospf, type))
684 if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
paul718e3742002-12-13 20:15:29 +0000685 {
686 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
687 zlog_info ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
688 LOOKUP (ospf_redistributed_proto, type),
689 inet_ntoa (p->prefix), p->prefixlen);
690 return 0;
691 }
692
693 save_values = ei->route_map_set;
694 ospf_reset_route_map_set_values (&ei->route_map_set);
695
696 /* apply route-map if needed */
paul020709f2003-04-04 02:44:16 +0000697 if (ROUTEMAP_NAME (ospf, type))
paul718e3742002-12-13 20:15:29 +0000698 {
699 int ret;
700
paul020709f2003-04-04 02:44:16 +0000701 ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *)p,
paul718e3742002-12-13 20:15:29 +0000702 RMAP_OSPF, ei);
703
704 if (ret == RMAP_DENYMATCH)
705 {
706 ei->route_map_set = save_values;
707 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
708 zlog_info ("Redistribute[%s]: %s/%d filtered by route-map.",
709 LOOKUP (ospf_redistributed_proto, type),
710 inet_ntoa (p->prefix), p->prefixlen);
711 return 0;
712 }
713
714 /* check if 'route-map set' changed something */
715 if (changed)
716 *changed = !ospf_route_map_set_compare (&ei->route_map_set,
717 &save_values);
718 }
719
720 return 1;
721}
722
723/* OSPF route-map set for redistribution */
724void
paul020709f2003-04-04 02:44:16 +0000725ospf_routemap_set (struct ospf *ospf, int type, char *name)
paul718e3742002-12-13 20:15:29 +0000726{
paul020709f2003-04-04 02:44:16 +0000727 if (ROUTEMAP_NAME (ospf, type))
728 free (ROUTEMAP_NAME (ospf, type));
paul718e3742002-12-13 20:15:29 +0000729
paul020709f2003-04-04 02:44:16 +0000730 ROUTEMAP_NAME (ospf, type) = strdup (name);
731 ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
paul718e3742002-12-13 20:15:29 +0000732}
733
734void
paul020709f2003-04-04 02:44:16 +0000735ospf_routemap_unset (struct ospf *ospf, int type)
paul718e3742002-12-13 20:15:29 +0000736{
paul020709f2003-04-04 02:44:16 +0000737 if (ROUTEMAP_NAME (ospf, type))
738 free (ROUTEMAP_NAME (ospf, type));
paul718e3742002-12-13 20:15:29 +0000739
paul020709f2003-04-04 02:44:16 +0000740 ROUTEMAP_NAME (ospf, type) = NULL;
741 ROUTEMAP (ospf, type) = NULL;
paul718e3742002-12-13 20:15:29 +0000742}
743
744/* Zebra route add and delete treatment. */
745int
746ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
747 zebra_size_t length)
748{
749 struct stream *s;
750 struct zapi_ipv4 api;
751 unsigned long ifindex;
752 struct in_addr nexthop;
753 struct prefix_ipv4 p;
754 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +0000755 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000756
757 s = zclient->ibuf;
758 ifindex = 0;
759 nexthop.s_addr = 0;
760
761 /* Type, flags, message. */
762 api.type = stream_getc (s);
763 api.flags = stream_getc (s);
764 api.message = stream_getc (s);
765
766 /* IPv4 prefix. */
767 memset (&p, 0, sizeof (struct prefix_ipv4));
768 p.family = AF_INET;
769 p.prefixlen = stream_getc (s);
770 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
771
772 /* Nexthop, ifindex, distance, metric. */
773 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
774 {
775 api.nexthop_num = stream_getc (s);
776 nexthop.s_addr = stream_get_ipv4 (s);
777 }
778 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
779 {
780 api.ifindex_num = stream_getc (s);
781 ifindex = stream_getl (s);
782 }
783 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
784 api.distance = stream_getc (s);
785 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
786 api.metric = stream_getl (s);
787
paul020709f2003-04-04 02:44:16 +0000788 ospf = ospf_lookup ();
789 if (ospf == NULL)
790 return 0;
791
paul718e3742002-12-13 20:15:29 +0000792 if (command == ZEBRA_IPV4_ROUTE_ADD)
793 {
794 ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
795
paul68980082003-03-25 05:07:42 +0000796 if (ospf->router_id.s_addr == 0)
paul718e3742002-12-13 20:15:29 +0000797 /* Set flags to generate AS-external-LSA originate event
798 for each redistributed protocols later. */
paul68980082003-03-25 05:07:42 +0000799 ospf->external_origin |= (1 << api.type);
paul718e3742002-12-13 20:15:29 +0000800 else
801 {
802 if (ei)
803 {
804 if (is_prefix_default (&p))
paul68980082003-03-25 05:07:42 +0000805 ospf_external_lsa_refresh_default (ospf);
paul718e3742002-12-13 20:15:29 +0000806 else
807 {
808 struct ospf_lsa *current;
809
paul68980082003-03-25 05:07:42 +0000810 current = ospf_external_info_find_lsa (ospf, &ei->p);
paul718e3742002-12-13 20:15:29 +0000811 if (!current)
paul68980082003-03-25 05:07:42 +0000812 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000813 else if (IS_LSA_MAXAGE (current))
paul68980082003-03-25 05:07:42 +0000814 ospf_external_lsa_refresh (ospf, current,
815 ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +0000816 else
817 zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
818 inet_ntoa (p.prefix));
819 }
820 }
821 }
822 }
823 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
824 {
825 ospf_external_info_delete (api.type, p);
826 if ( !is_prefix_default (&p))
paul68980082003-03-25 05:07:42 +0000827 ospf_external_lsa_flush (ospf, api.type, &p, ifindex, nexthop);
paul718e3742002-12-13 20:15:29 +0000828 else
paul68980082003-03-25 05:07:42 +0000829 ospf_external_lsa_refresh_default (ospf);
paul718e3742002-12-13 20:15:29 +0000830 }
831
832 return 0;
833}
834
835
836int
paul68980082003-03-25 05:07:42 +0000837ospf_distribute_list_out_set (struct ospf *ospf, int type, char *name)
paul718e3742002-12-13 20:15:29 +0000838{
839 /* Lookup access-list for distribute-list. */
paul020709f2003-04-04 02:44:16 +0000840 DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
paul718e3742002-12-13 20:15:29 +0000841
842 /* Clear previous distribute-name. */
paul020709f2003-04-04 02:44:16 +0000843 if (DISTRIBUTE_NAME (ospf, type))
844 free (DISTRIBUTE_NAME (ospf, type));
paul718e3742002-12-13 20:15:29 +0000845
846 /* Set distribute-name. */
paul020709f2003-04-04 02:44:16 +0000847 DISTRIBUTE_NAME (ospf, type) = strdup (name);
paul718e3742002-12-13 20:15:29 +0000848
849 /* If access-list have been set, schedule update timer. */
paul020709f2003-04-04 02:44:16 +0000850 if (DISTRIBUTE_LIST (ospf, type))
paul68980082003-03-25 05:07:42 +0000851 ospf_distribute_list_update (ospf, type);
paul718e3742002-12-13 20:15:29 +0000852
853 return CMD_SUCCESS;
854}
855
856int
paul68980082003-03-25 05:07:42 +0000857ospf_distribute_list_out_unset (struct ospf *ospf, int type, char *name)
paul718e3742002-12-13 20:15:29 +0000858{
859 /* Schedule update timer. */
paul020709f2003-04-04 02:44:16 +0000860 if (DISTRIBUTE_LIST (ospf, type))
paul68980082003-03-25 05:07:42 +0000861 ospf_distribute_list_update (ospf, type);
paul718e3742002-12-13 20:15:29 +0000862
863 /* Unset distribute-list. */
paul020709f2003-04-04 02:44:16 +0000864 DISTRIBUTE_LIST (ospf, type) = NULL;
paul718e3742002-12-13 20:15:29 +0000865
866 /* Clear distribute-name. */
paul020709f2003-04-04 02:44:16 +0000867 if (DISTRIBUTE_NAME (ospf, type))
868 free (DISTRIBUTE_NAME (ospf, type));
paul718e3742002-12-13 20:15:29 +0000869
paul020709f2003-04-04 02:44:16 +0000870 DISTRIBUTE_NAME (ospf, type) = NULL;
paul718e3742002-12-13 20:15:29 +0000871
872 return CMD_SUCCESS;
873}
874
875/* distribute-list update timer. */
876int
877ospf_distribute_list_update_timer (struct thread *thread)
878{
879 struct route_node *rn;
880 struct external_info *ei;
881 struct route_table *rt;
882 struct ospf_lsa *lsa;
883 u_char type;
paul020709f2003-04-04 02:44:16 +0000884 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000885
886 type = (int) THREAD_ARG (thread);
887 rt = EXTERNAL_INFO (type);
888
paul020709f2003-04-04 02:44:16 +0000889 ospf = ospf_lookup ();
890 if (ospf == NULL)
891 return 0;
892
paul68980082003-03-25 05:07:42 +0000893 ospf->t_distribute_update = NULL;
paul718e3742002-12-13 20:15:29 +0000894
895 zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
896
897 /* foreach all external info. */
898 if (rt)
899 for (rn = route_top (rt); rn; rn = route_next (rn))
900 if ((ei = rn->info) != NULL)
901 {
902 if (is_prefix_default (&ei->p))
paul68980082003-03-25 05:07:42 +0000903 ospf_external_lsa_refresh_default (ospf);
904 else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
905 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
paul718e3742002-12-13 20:15:29 +0000906 else
paul68980082003-03-25 05:07:42 +0000907 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +0000908 }
909 return 0;
910}
911
912#define OSPF_DISTRIBUTE_UPDATE_DELAY 5
913
914/* Update distribute-list and set timer to apply access-list. */
915void
paul68980082003-03-25 05:07:42 +0000916ospf_distribute_list_update (struct ospf *ospf, int type)
paul718e3742002-12-13 20:15:29 +0000917{
918 struct route_table *rt;
919
paul718e3742002-12-13 20:15:29 +0000920 /* External info does not exist. */
921 if (!(rt = EXTERNAL_INFO (type)))
922 return;
923
924 /* If exists previously invoked thread, then cancel it. */
paul68980082003-03-25 05:07:42 +0000925 if (ospf->t_distribute_update)
926 OSPF_TIMER_OFF (ospf->t_distribute_update);
paul718e3742002-12-13 20:15:29 +0000927
928 /* Set timer. */
paul68980082003-03-25 05:07:42 +0000929 ospf->t_distribute_update =
paul718e3742002-12-13 20:15:29 +0000930 thread_add_timer (master, ospf_distribute_list_update_timer,
931 (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
paul718e3742002-12-13 20:15:29 +0000932}
933
934/* If access-list is updated, apply some check. */
935void
936ospf_filter_update (struct access_list *access)
937{
paul020709f2003-04-04 02:44:16 +0000938 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000939 int type;
940 int abr_inv = 0;
941 struct ospf_area *area;
942 listnode node;
943
944 /* If OSPF instatnce does not exist, return right now. */
paul020709f2003-04-04 02:44:16 +0000945 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000946 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000947 return;
948
paul718e3742002-12-13 20:15:29 +0000949 /* Update distribute-list, and apply filter. */
950 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
951 {
paul020709f2003-04-04 02:44:16 +0000952 if (ROUTEMAP (ospf, type) != NULL)
paul718e3742002-12-13 20:15:29 +0000953 {
954 /* if route-map is not NULL it may be using this access list */
paul68980082003-03-25 05:07:42 +0000955 ospf_distribute_list_update (ospf, type);
paul718e3742002-12-13 20:15:29 +0000956 continue;
957 }
958
959
paul020709f2003-04-04 02:44:16 +0000960 if (DISTRIBUTE_NAME (ospf, type))
paul718e3742002-12-13 20:15:29 +0000961 {
962 /* Keep old access-list for distribute-list. */
paul020709f2003-04-04 02:44:16 +0000963 struct access_list *old = DISTRIBUTE_LIST (ospf, type);
paul718e3742002-12-13 20:15:29 +0000964
965 /* Update access-list for distribute-list. */
paul020709f2003-04-04 02:44:16 +0000966 DISTRIBUTE_LIST (ospf, type) =
967 access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
paul718e3742002-12-13 20:15:29 +0000968
969 /* No update for this distribute type. */
paul020709f2003-04-04 02:44:16 +0000970 if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
paul718e3742002-12-13 20:15:29 +0000971 continue;
972
973 /* Schedule distribute-list update timer. */
paul020709f2003-04-04 02:44:16 +0000974 if (DISTRIBUTE_LIST (ospf, type) == NULL ||
975 strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
paul68980082003-03-25 05:07:42 +0000976 ospf_distribute_list_update (ospf, type);
paul718e3742002-12-13 20:15:29 +0000977 }
978 }
979
980 /* Update Area access-list. */
paul68980082003-03-25 05:07:42 +0000981 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000982 if ((area = getdata (node)) != NULL)
983 {
984 if (EXPORT_NAME (area))
985 {
986 EXPORT_LIST (area) = NULL;
987 abr_inv++;
988 }
989
990 if (IMPORT_NAME (area))
991 {
992 IMPORT_LIST (area) = NULL;
993 abr_inv++;
994 }
995 }
996
997 /* Schedule ABR tasks -- this will be changed -- takada. */
paul020709f2003-04-04 02:44:16 +0000998 if (IS_OSPF_ABR (ospf) && abr_inv)
paul68980082003-03-25 05:07:42 +0000999 ospf_schedule_abr_task (ospf);
paul718e3742002-12-13 20:15:29 +00001000}
1001
1002
1003struct ospf_distance *
1004ospf_distance_new ()
1005{
1006 struct ospf_distance *new;
1007 new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1008 memset (new, 0, sizeof (struct ospf_distance));
1009 return new;
1010}
1011
1012void
1013ospf_distance_free (struct ospf_distance *odistance)
1014{
1015 XFREE (MTYPE_OSPF_DISTANCE, odistance);
1016}
1017
1018int
paul020709f2003-04-04 02:44:16 +00001019ospf_distance_set (struct vty *vty, struct ospf *ospf, char *distance_str,
1020 char *ip_str, char *access_list_str)
paul718e3742002-12-13 20:15:29 +00001021{
1022 int ret;
1023 struct prefix_ipv4 p;
1024 u_char distance;
1025 struct route_node *rn;
1026 struct ospf_distance *odistance;
1027
1028 ret = str2prefix_ipv4 (ip_str, &p);
1029 if (ret == 0)
1030 {
1031 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1032 return CMD_WARNING;
1033 }
1034
1035 distance = atoi (distance_str);
1036
1037 /* Get OSPF distance node. */
paul68980082003-03-25 05:07:42 +00001038 rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
paul718e3742002-12-13 20:15:29 +00001039 if (rn->info)
1040 {
1041 odistance = rn->info;
1042 route_unlock_node (rn);
1043 }
1044 else
1045 {
1046 odistance = ospf_distance_new ();
1047 rn->info = odistance;
1048 }
1049
1050 /* Set distance value. */
1051 odistance->distance = distance;
1052
1053 /* Reset access-list configuration. */
1054 if (odistance->access_list)
1055 {
1056 free (odistance->access_list);
1057 odistance->access_list = NULL;
1058 }
1059 if (access_list_str)
1060 odistance->access_list = strdup (access_list_str);
1061
1062 return CMD_SUCCESS;
1063}
1064
1065int
paul020709f2003-04-04 02:44:16 +00001066ospf_distance_unset (struct vty *vty, struct ospf *ospf, char *distance_str,
1067 char *ip_str, char *access_list_str)
paul718e3742002-12-13 20:15:29 +00001068{
1069 int ret;
1070 struct prefix_ipv4 p;
1071 u_char distance;
1072 struct route_node *rn;
1073 struct ospf_distance *odistance;
1074
1075 ret = str2prefix_ipv4 (ip_str, &p);
1076 if (ret == 0)
1077 {
1078 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1079 return CMD_WARNING;
1080 }
1081
1082 distance = atoi (distance_str);
1083
paul68980082003-03-25 05:07:42 +00001084 rn = route_node_lookup (ospf->distance_table, (struct prefix *)&p);
paul718e3742002-12-13 20:15:29 +00001085 if (! rn)
1086 {
1087 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1088 return CMD_WARNING;
1089 }
1090
1091 odistance = rn->info;
1092
1093 if (odistance->access_list)
1094 free (odistance->access_list);
1095 ospf_distance_free (odistance);
1096
1097 rn->info = NULL;
1098 route_unlock_node (rn);
1099 route_unlock_node (rn);
1100
1101 return CMD_SUCCESS;
1102}
1103
1104void
paul68980082003-03-25 05:07:42 +00001105ospf_distance_reset (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001106{
1107 struct route_node *rn;
1108 struct ospf_distance *odistance;
1109
paul68980082003-03-25 05:07:42 +00001110 for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +00001111 if ((odistance = rn->info) != NULL)
1112 {
1113 if (odistance->access_list)
1114 free (odistance->access_list);
1115 ospf_distance_free (odistance);
1116 rn->info = NULL;
1117 route_unlock_node (rn);
1118 }
1119}
1120
1121u_char
1122ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1123{
paul020709f2003-04-04 02:44:16 +00001124 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001125
paul020709f2003-04-04 02:44:16 +00001126 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001127 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001128 return 0;
1129
paul68980082003-03-25 05:07:42 +00001130 if (ospf->distance_intra)
paul718e3742002-12-13 20:15:29 +00001131 if (or->path_type == OSPF_PATH_INTRA_AREA)
paul68980082003-03-25 05:07:42 +00001132 return ospf->distance_intra;
paul718e3742002-12-13 20:15:29 +00001133
paul68980082003-03-25 05:07:42 +00001134 if (ospf->distance_inter)
paul718e3742002-12-13 20:15:29 +00001135 if (or->path_type == OSPF_PATH_INTER_AREA)
paul68980082003-03-25 05:07:42 +00001136 return ospf->distance_inter;
paul718e3742002-12-13 20:15:29 +00001137
paul68980082003-03-25 05:07:42 +00001138 if (ospf->distance_external)
paul718e3742002-12-13 20:15:29 +00001139 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1140 || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
paul68980082003-03-25 05:07:42 +00001141 return ospf->distance_external;
paul718e3742002-12-13 20:15:29 +00001142
paul68980082003-03-25 05:07:42 +00001143 if (ospf->distance_all)
1144 return ospf->distance_all;
paul718e3742002-12-13 20:15:29 +00001145
1146 return 0;
1147}
1148
1149void
1150ospf_zebra_init ()
1151{
1152 /* Allocate zebra structure. */
1153 zclient = zclient_new ();
1154 zclient_init (zclient, ZEBRA_ROUTE_OSPF);
1155 zclient->interface_add = ospf_interface_add;
1156 zclient->interface_delete = ospf_interface_delete;
1157 zclient->interface_up = ospf_interface_state_up;
1158 zclient->interface_down = ospf_interface_state_down;
1159 zclient->interface_address_add = ospf_interface_address_add;
1160 zclient->interface_address_delete = ospf_interface_address_delete;
1161 zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1162 zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1163
1164 access_list_add_hook (ospf_filter_update);
1165 access_list_delete_hook (ospf_filter_update);
1166}