~ubuntu-branches/ubuntu/warty/quagga/warty

« back to all changes in this revision

Viewing changes to ospfd/ospf_zebra.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-06-29 09:50:59 UTC
  • Revision ID: james.westby@ubuntu.com-20040629095059-px1m2m108z4qw1mr
Tags: upstream-0.96.5
ImportĀ upstreamĀ versionĀ 0.96.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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"
 
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. */
 
52
struct zclient *zclient = NULL;
 
53
 
 
54
/* For registering threads. */
 
55
extern struct thread_master *master;
 
56
 
 
57
/* Inteface addition message from zebra. */
 
58
int
 
59
ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
 
60
{
 
61
  struct interface *ifp;
 
62
  struct ospf *ospf;
 
63
 
 
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
 
 
70
  assert (ifp->info);
 
71
 
 
72
  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
 
 
85
  ospf = ospf_lookup ();
 
86
  if (ospf != NULL)
 
87
    ospf_if_update (ospf);
 
88
 
 
89
#ifdef HAVE_SNMP
 
90
  ospf_snmp_if_update (ifp);
 
91
#endif /* HAVE_SNMP */
 
92
 
 
93
  return 0;
 
94
}
 
95
 
 
96
int
 
97
ospf_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
 
117
      ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
 
118
       ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
 
119
 
 
120
#ifdef HAVE_SNMP
 
121
  ospf_snmp_if_delete (ifp);
 
122
#endif /* HAVE_SNMP */
 
123
 
 
124
  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
 
125
    if (rn->info)
 
126
      ospf_if_free ((struct ospf_interface *) rn->info);
 
127
 
 
128
  return 0;
 
129
}
 
130
 
 
131
struct interface *
 
132
zebra_interface_if_lookup (struct stream *s)
 
133
{
 
134
  struct interface *ifp;
 
135
  u_char ifname_tmp[INTERFACE_NAMSIZ];
 
136
 
 
137
  /* Read interface name. */
 
138
  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
 
139
 
 
140
  /* Lookup this by interface index. */
 
141
  ifp = if_lookup_by_name (ifname_tmp);
 
142
 
 
143
  /* If such interface does not exist, indicate an error */
 
144
  if (!ifp)
 
145
    return NULL;
 
146
 
 
147
  return ifp;
 
148
}
 
149
 
 
150
void
 
151
zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
 
152
{
 
153
  /* Read interface's index. */
 
154
  ifp->ifindex = stream_getl (s);
 
155
 
 
156
  /* Read interface's value. */
 
157
  ifp->status = stream_getc (s);
 
158
  ifp->flags = stream_getl (s);
 
159
  ifp->metric = stream_getl (s);
 
160
  ifp->mtu = stream_getl (s);
 
161
  ifp->bandwidth = stream_getl (s);
 
162
}
 
163
 
 
164
int
 
165
ospf_interface_state_up (int command, struct zclient *zclient,
 
166
                         zebra_size_t length)
 
167
{
 
168
  struct interface *ifp;
 
169
  struct interface if_tmp;
 
170
  struct ospf_interface *oi;
 
171
  struct route_node *rn;
 
172
 
 
173
  ifp = zebra_interface_if_lookup (zclient->ibuf);
 
174
 
 
175
  if (ifp == NULL)
 
176
    return 0;
 
177
 
 
178
  /* Interface is already up. */
 
179
  if (if_is_operative (ifp))
 
180
    {
 
181
      /* Temporarily keep ifp values. */
 
182
      memcpy (&if_tmp, ifp, sizeof (struct interface));
 
183
 
 
184
      zebra_interface_if_set_value (zclient->ibuf, ifp);
 
185
 
 
186
      if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
 
187
        zlog_info ("Zebra: Interface[%s] state update.", ifp->name);
 
188
 
 
189
      if (if_tmp.bandwidth != ifp->bandwidth)
 
190
        {
 
191
          if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
 
192
            zlog_info ("Zebra: Interface[%s] bandwidth change %d -> %d.",
 
193
                       ifp->name, if_tmp.bandwidth, ifp->bandwidth);
 
194
 
 
195
          ospf_if_recalculate_output_cost (ifp);
 
196
        }
 
197
      return 0;
 
198
    }
 
199
 
 
200
  zebra_interface_if_set_value (zclient->ibuf, ifp);
 
201
 
 
202
  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
 
203
    zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);
 
204
 
 
205
  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
 
206
    {
 
207
      if ((oi = rn->info) == NULL)
 
208
        continue;
 
209
 
 
210
      ospf_if_up (oi);
 
211
    }
 
212
 
 
213
  return 0;
 
214
}
 
215
 
 
216
int
 
217
ospf_interface_state_down (int command, struct zclient *zclient,
 
218
                           zebra_size_t length)
 
219
{
 
220
  struct interface *ifp;
 
221
  struct ospf_interface *oi;
 
222
  struct route_node *node;
 
223
 
 
224
  ifp = zebra_interface_state_read (zclient->ibuf);
 
225
 
 
226
  if (ifp == NULL)
 
227
    return 0;
 
228
 
 
229
  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
 
230
    zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);
 
231
 
 
232
  for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
 
233
    {
 
234
      if ((oi = node->info) == NULL)
 
235
        continue;
 
236
      ospf_if_down (oi);
 
237
    }
 
238
 
 
239
  return 0;
 
240
}
 
241
 
 
242
int
 
243
ospf_interface_address_add (int command, struct zclient *zclient,
 
244
                            zebra_size_t length)
 
245
{
 
246
  struct ospf *ospf;
 
247
  struct connected *c;
 
248
 
 
249
  c = zebra_interface_address_add_read (zclient->ibuf);
 
250
 
 
251
  if (c == NULL)
 
252
    return 0;
 
253
 
 
254
  ospf = ospf_lookup ();
 
255
  if (ospf != NULL)
 
256
    ospf_if_update (ospf);
 
257
 
 
258
#ifdef HAVE_SNMP
 
259
  ospf_snmp_if_update (c->ifp);
 
260
#endif /* HAVE_SNMP */
 
261
 
 
262
  return 0;
 
263
}
 
264
 
 
265
int
 
266
ospf_interface_address_delete (int command, struct zclient *zclient,
 
267
                               zebra_size_t length)
 
268
{
 
269
  struct ospf *ospf;
 
270
  struct connected *c;
 
271
  struct interface *ifp;
 
272
  struct ospf_interface *oi;
 
273
  struct route_node *rn;
 
274
  struct prefix p;
 
275
 
 
276
  c = zebra_interface_address_delete_read (zclient->ibuf);
 
277
 
 
278
  if (c == NULL)
 
279
    return 0;
 
280
 
 
281
  ifp = c->ifp;
 
282
  p = *c->address;
 
283
  p.prefixlen = IPV4_MAX_PREFIXLEN;
 
284
 
 
285
  rn = route_node_lookup (IF_OIFS (ifp), &p);
 
286
  if (!rn)
 
287
    return 0;
 
288
 
 
289
  assert (rn->info);
 
290
  oi = rn->info;
 
291
 
 
292
  /* Call interface hook functions to clean up */
 
293
  ospf_if_free (oi);
 
294
 
 
295
#ifdef HAVE_SNMP
 
296
  ospf_snmp_if_update (c->ifp);
 
297
#endif /* HAVE_SNMP */
 
298
 
 
299
  connected_free (c);
 
300
 
 
301
  ospf = ospf_lookup ();
 
302
  if (ospf != NULL)
 
303
    ospf_if_update (ospf);
 
304
 
 
305
  return 0;
 
306
}
 
307
 
 
308
void
 
309
ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
 
310
{
 
311
  u_char message;
 
312
  u_char distance;
 
313
  u_char flags;
 
314
  int psize;
 
315
  struct stream *s;
 
316
  struct ospf_path *path;
 
317
  listnode node;
 
318
 
 
319
  if (zclient->redist[ZEBRA_ROUTE_OSPF])
 
320
    {
 
321
      message = 0;
 
322
      flags = 0;
 
323
 
 
324
      /* OSPF pass nexthop and metric */
 
325
      SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
 
326
      SET_FLAG (message, ZAPI_MESSAGE_METRIC);
 
327
 
 
328
      /* Distance value. */
 
329
      distance = ospf_distance_apply (p, or);
 
330
      if (distance)
 
331
        SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
 
332
 
 
333
      /* Make packet. */
 
334
      s = zclient->obuf;
 
335
      stream_reset (s);
 
336
 
 
337
      /* Length place holder. */
 
338
      stream_putw (s, 0);
 
339
 
 
340
      /* Put command, type, flags, message. */
 
341
      stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
 
342
      stream_putc (s, ZEBRA_ROUTE_OSPF);
 
343
      stream_putc (s, flags);
 
344
      stream_putc (s, message);
 
345
 
 
346
      /* Put prefix information. */
 
347
      psize = PSIZE (p->prefixlen);
 
348
      stream_putc (s, p->prefixlen);
 
349
      stream_write (s, (u_char *) & p->prefix, psize);
 
350
 
 
351
      /* Nexthop count. */
 
352
      stream_putc (s, or->paths->count);
 
353
 
 
354
      /* Nexthop, ifindex, distance and metric information. */
 
355
      for (node = listhead (or->paths); node; nextnode (node))
 
356
        {
 
357
          path = getdata (node);
 
358
 
 
359
          if (path->nexthop.s_addr != INADDR_ANY)
 
360
            {
 
361
              stream_putc (s, ZEBRA_NEXTHOP_IPV4);
 
362
              stream_put_in_addr (s, &path->nexthop);
 
363
            }
 
364
          else
 
365
            {
 
366
              stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
367
              if (path->oi)
 
368
                stream_putl (s, path->oi->ifp->ifindex);
 
369
              else
 
370
                stream_putl (s, 0);
 
371
            }
 
372
 
 
373
          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
374
            {
 
375
              zlog_info ("Zebra: Route add %s/%d nexthop %s",
 
376
                         inet_ntoa (p->prefix),
 
377
                         p->prefixlen, inet_ntoa (path->nexthop));
 
378
            }
 
379
        }
 
380
 
 
381
      if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
 
382
        stream_putc (s, distance);
 
383
      if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
 
384
        {
 
385
          if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
 
386
            stream_putl (s, or->cost + or->u.ext.type2_cost);
 
387
          else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
 
388
            stream_putl (s, or->u.ext.type2_cost);
 
389
          else
 
390
            stream_putl (s, or->cost);
 
391
        }
 
392
 
 
393
      stream_putw_at (s, 0, stream_get_endp (s));
 
394
 
 
395
      writen (zclient->sock, s->data, stream_get_endp (s));
 
396
    }
 
397
}
 
398
 
 
399
void
 
400
ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
 
401
{
 
402
  struct zapi_ipv4 api;
 
403
  struct ospf_path *path;
 
404
  struct in_addr *nexthop;
 
405
  listnode node;
 
406
 
 
407
  if (zclient->redist[ZEBRA_ROUTE_OSPF])
 
408
    {
 
409
      api.type = ZEBRA_ROUTE_OSPF;
 
410
      api.flags = 0;
 
411
      api.message = 0;
 
412
      api.ifindex_num = 0;
 
413
      api.nexthop_num = 0;
 
414
 
 
415
      for (node = listhead (or->paths); node; nextnode (node))
 
416
        {
 
417
          path = getdata (node);
 
418
 
 
419
          if (path->nexthop.s_addr != INADDR_ANY)
 
420
            {
 
421
              SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
 
422
              api.nexthop_num = 1;
 
423
              nexthop = &path->nexthop;
 
424
              api.nexthop = &nexthop;
 
425
            }
 
426
          else if (ospf_if_exists(path->oi) && (path->oi->ifp))
 
427
            {
 
428
              SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
 
429
              api.ifindex_num = 1;
 
430
              api.ifindex = &path->oi->ifp->ifindex;
 
431
            }
 
432
          else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
 
433
            {
 
434
              zlog_info("Zebra: no ifp %s %d",
 
435
                         inet_ntoa(p->prefix),
 
436
                         p->prefixlen);
 
437
            }
 
438
 
 
439
          zapi_ipv4_delete (zclient, p, &api);
 
440
 
 
441
          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
 
442
            {
 
443
              zlog_info ("Zebra: Route delete %s/%d nexthop %s",
 
444
                         inet_ntoa (p->prefix),
 
445
                         p->prefixlen, inet_ntoa (**api.nexthop));
 
446
            }
 
447
          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
 
448
            {
 
449
              zlog_info ("Zebra: Route delete %s/%d ifindex %d",
 
450
                         inet_ntoa (p->prefix),
 
451
                         p->prefixlen, *api.ifindex);
 
452
            }
 
453
        }
 
454
    }
 
455
}
 
456
 
 
457
void
 
458
ospf_zebra_add_discard (struct prefix_ipv4 *p)
 
459
{
 
460
  struct zapi_ipv4 api;
 
461
 
 
462
  if (zclient->redist[ZEBRA_ROUTE_OSPF])
 
463
    {
 
464
      api.type = ZEBRA_ROUTE_OSPF;
 
465
      api.flags = ZEBRA_FLAG_BLACKHOLE;
 
466
      api.message = 0;
 
467
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
 
468
      api.nexthop_num = 0;
 
469
      api.ifindex_num = 0;
 
470
 
 
471
      zapi_ipv4_add (zclient, p, &api);
 
472
    }
 
473
}
 
474
 
 
475
void
 
476
ospf_zebra_delete_discard (struct prefix_ipv4 *p)
 
477
{
 
478
  struct zapi_ipv4 api;
 
479
 
 
480
  if (zclient->redist[ZEBRA_ROUTE_OSPF])
 
481
    {
 
482
      api.type = ZEBRA_ROUTE_OSPF;
 
483
      api.flags = ZEBRA_FLAG_BLACKHOLE;
 
484
      api.message = 0;
 
485
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
 
486
      api.nexthop_num = 0;
 
487
      api.ifindex_num = 0;
 
488
 
 
489
      zapi_ipv4_delete (zclient, p, &api);
 
490
 
 
491
      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
492
        zlog_info ("Zebra: Route delete discard %s/%d",
 
493
                   inet_ntoa (p->prefix), p->prefixlen);
 
494
 
 
495
    }
 
496
}
 
497
 
 
498
int
 
499
ospf_is_type_redistributed (int type)
 
500
{
 
501
  return (DEFAULT_ROUTE_TYPE (type)) ?
 
502
    zclient->default_information : zclient->redist[type];
 
503
}
 
504
 
 
505
int
 
506
ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
 
507
{
 
508
  int force = 0;
 
509
 
 
510
  if (ospf_is_type_redistributed (type))
 
511
    {
 
512
      if (mtype != ospf->dmetric[type].type)
 
513
        {
 
514
          ospf->dmetric[type].type = mtype;
 
515
          force = LSA_REFRESH_FORCE;
 
516
        }
 
517
      if (mvalue != ospf->dmetric[type].value)
 
518
        {
 
519
          ospf->dmetric[type].value = mvalue;
 
520
          force = LSA_REFRESH_FORCE;
 
521
        }
 
522
 
 
523
      ospf_external_lsa_refresh_type (ospf, type, force);
 
524
 
 
525
      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
526
        zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
 
527
                   LOOKUP (ospf_redistributed_proto, type),
 
528
                   metric_type (ospf, type), metric_value (ospf, type));
 
529
 
 
530
      return CMD_SUCCESS;
 
531
    }
 
532
 
 
533
  ospf->dmetric[type].type = mtype;
 
534
  ospf->dmetric[type].value = mvalue;
 
535
 
 
536
  zclient_redistribute_set (zclient, type);
 
537
 
 
538
  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
539
    zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
 
540
               LOOKUP (ospf_redistributed_proto, type),
 
541
               metric_type (ospf, type), metric_value (ospf, type));
 
542
 
 
543
  ospf_asbr_status_update (ospf, ++ospf->redistribute);
 
544
 
 
545
  return CMD_SUCCESS;
 
546
}
 
547
 
 
548
int
 
549
ospf_redistribute_unset (struct ospf *ospf, int type)
 
550
{
 
551
  if (type == zclient->redist_default)
 
552
    return CMD_SUCCESS;
 
553
 
 
554
  if (!ospf_is_type_redistributed (type))
 
555
    return CMD_SUCCESS;
 
556
 
 
557
  zclient_redistribute_unset (zclient, type);
 
558
 
 
559
  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
560
    zlog_info ("Redistribute[%s]: Stop",
 
561
               LOOKUP (ospf_redistributed_proto, type));
 
562
 
 
563
  ospf->dmetric[type].type = -1;
 
564
  ospf->dmetric[type].value = -1;
 
565
 
 
566
  /* Remove the routes from OSPF table. */
 
567
  ospf_redistribute_withdraw (type);
 
568
 
 
569
  ospf_asbr_status_update (ospf, --ospf->redistribute);
 
570
 
 
571
  return CMD_SUCCESS;
 
572
}
 
573
 
 
574
int
 
575
ospf_redistribute_default_set (struct ospf *ospf, int originate,
 
576
                               int mtype, int mvalue)
 
577
{
 
578
  int force = 0;
 
579
 
 
580
  if (ospf_is_type_redistributed (DEFAULT_ROUTE))
 
581
    {
 
582
      if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)
 
583
        {
 
584
          ospf->dmetric[DEFAULT_ROUTE].type = mtype;
 
585
          force = 1;
 
586
        }
 
587
      if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)
 
588
        {
 
589
          force = 1;
 
590
          ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 
591
        }
 
592
 
 
593
      ospf_external_lsa_refresh_default (ospf);
 
594
 
 
595
      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
596
        zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
 
597
                   LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),
 
598
                   metric_type (ospf, DEFAULT_ROUTE),
 
599
                   metric_value (ospf, DEFAULT_ROUTE));
 
600
      return CMD_SUCCESS;
 
601
    }
 
602
 
 
603
  ospf->default_originate = originate;
 
604
  ospf->dmetric[DEFAULT_ROUTE].type = mtype;
 
605
  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 
606
 
 
607
  zclient_redistribute_default_set (zclient);
 
608
 
 
609
  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
610
    zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
 
611
               metric_type (ospf, DEFAULT_ROUTE),
 
612
               metric_value (ospf, DEFAULT_ROUTE));
 
613
 
 
614
  if (ospf->router_id.s_addr == 0)
 
615
    ospf->external_origin |= (1 << DEFAULT_ROUTE);
 
616
  else
 
617
    thread_add_timer (master, ospf_default_originate_timer,
 
618
                      &ospf->default_originate, 1);
 
619
 
 
620
  ospf_asbr_status_update (ospf, ++ospf->redistribute);
 
621
 
 
622
  return CMD_SUCCESS;
 
623
}
 
624
 
 
625
int
 
626
ospf_redistribute_default_unset (struct ospf *ospf)
 
627
{
 
628
  if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
 
629
    return CMD_SUCCESS;
 
630
 
 
631
  ospf->default_originate = DEFAULT_ORIGINATE_NONE;
 
632
  ospf->dmetric[DEFAULT_ROUTE].type = -1;
 
633
  ospf->dmetric[DEFAULT_ROUTE].value = -1;
 
634
 
 
635
  zclient_redistribute_default_unset (zclient);
 
636
 
 
637
  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
638
    zlog_info ("Redistribute[DEFAULT]: Stop");
 
639
 
 
640
  ospf_asbr_status_update (ospf, --ospf->redistribute);
 
641
 
 
642
  return CMD_SUCCESS;
 
643
}
 
644
 
 
645
int
 
646
ospf_external_lsa_originate_check (struct ospf *ospf,
 
647
                                   struct external_info *ei)
 
648
{
 
649
  /* If prefix is multicast, then do not originate LSA. */
 
650
  if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
 
651
    {
 
652
      zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
 
653
                 "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
 
654
      return 0;
 
655
    }
 
656
 
 
657
  /* Take care of default-originate. */
 
658
  if (is_prefix_default (&ei->p))
 
659
    if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
 
660
      {
 
661
        zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
 
662
                   "for default");
 
663
        return 0;
 
664
      }
 
665
 
 
666
  return 1;
 
667
}
 
668
 
 
669
/* If connected prefix is OSPF enable interface, then do not announce. */
 
670
int
 
671
ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
 
672
{
 
673
  struct route_node *rn;
 
674
 
 
675
  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
 
676
    if (rn->info != NULL)
 
677
      if (prefix_match (&rn->p, (struct prefix *) &ei->p))
 
678
        {
 
679
          route_unlock_node (rn);
 
680
          return 0;
 
681
        }
 
682
 
 
683
  return 1;
 
684
}
 
685
 
 
686
/* return 1 if external LSA must be originated, 0 otherwise */
 
687
int
 
688
ospf_redistribute_check (struct ospf *ospf,
 
689
                         struct external_info *ei, int *changed)
 
690
{
 
691
  struct route_map_set_values save_values;
 
692
  struct prefix_ipv4 *p = &ei->p;
 
693
  u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
 
694
 
 
695
  if (changed)
 
696
    *changed = 0;
 
697
 
 
698
  if (!ospf_external_lsa_originate_check (ospf, ei))
 
699
    return 0;
 
700
 
 
701
  /* Take care connected route. */
 
702
  if (type == ZEBRA_ROUTE_CONNECT &&
 
703
      !ospf_distribute_check_connected (ospf, ei))
 
704
    return 0;
 
705
 
 
706
  if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
 
707
    /* distirbute-list exists, but access-list may not? */
 
708
    if (DISTRIBUTE_LIST (ospf, type))
 
709
      if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
 
710
        {
 
711
          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
712
            zlog_info ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
 
713
                       LOOKUP (ospf_redistributed_proto, type),
 
714
                       inet_ntoa (p->prefix), p->prefixlen);
 
715
          return 0;
 
716
        }
 
717
 
 
718
  save_values = ei->route_map_set;
 
719
  ospf_reset_route_map_set_values (&ei->route_map_set);
 
720
 
 
721
  /* apply route-map if needed */
 
722
  if (ROUTEMAP_NAME (ospf, type))
 
723
    {
 
724
      int ret;
 
725
 
 
726
      ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
 
727
                             RMAP_OSPF, ei);
 
728
 
 
729
      if (ret == RMAP_DENYMATCH)
 
730
        {
 
731
          ei->route_map_set = save_values;
 
732
          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 
733
            zlog_info ("Redistribute[%s]: %s/%d filtered by route-map.",
 
734
                       LOOKUP (ospf_redistributed_proto, type),
 
735
                       inet_ntoa (p->prefix), p->prefixlen);
 
736
          return 0;
 
737
        }
 
738
 
 
739
      /* check if 'route-map set' changed something */
 
740
      if (changed)
 
741
        *changed = !ospf_route_map_set_compare (&ei->route_map_set,
 
742
                                                &save_values);
 
743
    }
 
744
 
 
745
  return 1;
 
746
}
 
747
 
 
748
/* OSPF route-map set for redistribution */
 
749
void
 
750
ospf_routemap_set (struct ospf *ospf, int type, char *name)
 
751
{
 
752
  if (ROUTEMAP_NAME (ospf, type))
 
753
    free (ROUTEMAP_NAME (ospf, type));
 
754
 
 
755
  ROUTEMAP_NAME (ospf, type) = strdup (name);
 
756
  ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
 
757
}
 
758
 
 
759
void
 
760
ospf_routemap_unset (struct ospf *ospf, int type)
 
761
{
 
762
  if (ROUTEMAP_NAME (ospf, type))
 
763
    free (ROUTEMAP_NAME (ospf, type));
 
764
 
 
765
  ROUTEMAP_NAME (ospf, type) = NULL;
 
766
  ROUTEMAP (ospf, type) = NULL;
 
767
}
 
768
 
 
769
/* Zebra route add and delete treatment. */
 
770
int
 
771
ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
 
772
                      zebra_size_t length)
 
773
{
 
774
  struct stream *s;
 
775
  struct zapi_ipv4 api;
 
776
  unsigned long ifindex;
 
777
  struct in_addr nexthop;
 
778
  struct prefix_ipv4 p;
 
779
  struct external_info *ei;
 
780
  struct ospf *ospf;
 
781
 
 
782
  s = zclient->ibuf;
 
783
  ifindex = 0;
 
784
  nexthop.s_addr = 0;
 
785
 
 
786
  /* Type, flags, message. */
 
787
  api.type = stream_getc (s);
 
788
  api.flags = stream_getc (s);
 
789
  api.message = stream_getc (s);
 
790
 
 
791
  /* IPv4 prefix. */
 
792
  memset (&p, 0, sizeof (struct prefix_ipv4));
 
793
  p.family = AF_INET;
 
794
  p.prefixlen = stream_getc (s);
 
795
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));
 
796
 
 
797
  if (IPV4_NET127(ntohl(p.prefix.s_addr)))
 
798
    return 0;
 
799
 
 
800
  /* Nexthop, ifindex, distance, metric. */
 
801
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
 
802
    {
 
803
      api.nexthop_num = stream_getc (s);
 
804
      nexthop.s_addr = stream_get_ipv4 (s);
 
805
    }
 
806
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
 
807
    {
 
808
      api.ifindex_num = stream_getc (s);
 
809
      /* XXX assert(api.ifindex_num == 1); */
 
810
      ifindex = stream_getl (s);
 
811
    }
 
812
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
 
813
    api.distance = stream_getc (s);
 
814
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
 
815
    api.metric = stream_getl (s);
 
816
 
 
817
  ospf = ospf_lookup ();
 
818
  if (ospf == NULL)
 
819
    return 0;
 
820
 
 
821
  if (command == ZEBRA_IPV4_ROUTE_ADD)
 
822
    {
 
823
      /* XXX|HACK|TODO|FIXME:
 
824
       * Maybe we should ignore reject/blackhole routes? Testing shows that
 
825
       * there is no problems though and this is only way to "summarize"
 
826
       * routes in ASBR at the moment. Maybe we need just a better generalised
 
827
       * solution for these types?
 
828
       *
 
829
       * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
 
830
       *     || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
 
831
       * return 0;
 
832
       */
 
833
        
 
834
      ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
 
835
 
 
836
      if (ospf->router_id.s_addr == 0)
 
837
        /* Set flags to generate AS-external-LSA originate event
 
838
           for each redistributed protocols later. */
 
839
        ospf->external_origin |= (1 << api.type);
 
840
      else
 
841
        {
 
842
          if (ei)
 
843
            {
 
844
              if (is_prefix_default (&p))
 
845
                ospf_external_lsa_refresh_default (ospf);
 
846
              else
 
847
                {
 
848
                  struct ospf_lsa *current;
 
849
 
 
850
                  current = ospf_external_info_find_lsa (ospf, &ei->p);
 
851
                  if (!current)
 
852
                    ospf_external_lsa_originate (ospf, ei);
 
853
                  else if (IS_LSA_MAXAGE (current))
 
854
                    ospf_external_lsa_refresh (ospf, current,
 
855
                                               ei, LSA_REFRESH_FORCE);
 
856
                  else
 
857
                    zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
 
858
                               inet_ntoa (p.prefix));
 
859
                }
 
860
            }
 
861
        }
 
862
    }
 
863
  else                          /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
 
864
    {
 
865
      ospf_external_info_delete (api.type, p);
 
866
      if (is_prefix_default (&p))
 
867
        ospf_external_lsa_refresh_default (ospf);
 
868
      else
 
869
        ospf_external_lsa_flush (ospf, api.type, &p, ifindex, nexthop);
 
870
    }
 
871
 
 
872
  return 0;
 
873
}
 
874
 
 
875
 
 
876
int
 
877
ospf_distribute_list_out_set (struct ospf *ospf, int type, char *name)
 
878
{
 
879
  /* Lookup access-list for distribute-list. */
 
880
  DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
 
881
 
 
882
  /* Clear previous distribute-name. */
 
883
  if (DISTRIBUTE_NAME (ospf, type))
 
884
    free (DISTRIBUTE_NAME (ospf, type));
 
885
 
 
886
  /* Set distribute-name. */
 
887
  DISTRIBUTE_NAME (ospf, type) = strdup (name);
 
888
 
 
889
  /* If access-list have been set, schedule update timer. */
 
890
  if (DISTRIBUTE_LIST (ospf, type))
 
891
    ospf_distribute_list_update (ospf, type);
 
892
 
 
893
  return CMD_SUCCESS;
 
894
}
 
895
 
 
896
int
 
897
ospf_distribute_list_out_unset (struct ospf *ospf, int type, char *name)
 
898
{
 
899
  /* Schedule update timer. */
 
900
  if (DISTRIBUTE_LIST (ospf, type))
 
901
    ospf_distribute_list_update (ospf, type);
 
902
 
 
903
  /* Unset distribute-list. */
 
904
  DISTRIBUTE_LIST (ospf, type) = NULL;
 
905
 
 
906
  /* Clear distribute-name. */
 
907
  if (DISTRIBUTE_NAME (ospf, type))
 
908
    free (DISTRIBUTE_NAME (ospf, type));
 
909
 
 
910
  DISTRIBUTE_NAME (ospf, type) = NULL;
 
911
 
 
912
  return CMD_SUCCESS;
 
913
}
 
914
 
 
915
/* distribute-list update timer. */
 
916
int
 
917
ospf_distribute_list_update_timer (struct thread *thread)
 
918
{
 
919
  struct route_node *rn;
 
920
  struct external_info *ei;
 
921
  struct route_table *rt;
 
922
  struct ospf_lsa *lsa;
 
923
  u_char type;
 
924
  struct ospf *ospf;
 
925
 
 
926
  type = (int) THREAD_ARG (thread);
 
927
  rt = EXTERNAL_INFO (type);
 
928
 
 
929
  ospf = ospf_lookup ();
 
930
  if (ospf == NULL)
 
931
    return 0;
 
932
 
 
933
  ospf->t_distribute_update = NULL;
 
934
 
 
935
  zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
 
936
 
 
937
  /* foreach all external info. */
 
938
  if (rt)
 
939
    for (rn = route_top (rt); rn; rn = route_next (rn))
 
940
      if ((ei = rn->info) != NULL)
 
941
        {
 
942
          if (is_prefix_default (&ei->p))
 
943
            ospf_external_lsa_refresh_default (ospf);
 
944
          else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
 
945
            ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
 
946
          else
 
947
            ospf_external_lsa_originate (ospf, ei);
 
948
        }
 
949
  return 0;
 
950
}
 
951
 
 
952
#define OSPF_DISTRIBUTE_UPDATE_DELAY 5
 
953
 
 
954
/* Update distribute-list and set timer to apply access-list. */
 
955
void
 
956
ospf_distribute_list_update (struct ospf *ospf, int type)
 
957
{
 
958
  struct route_table *rt;
 
959
 
 
960
  /* External info does not exist. */
 
961
  if (!(rt = EXTERNAL_INFO (type)))
 
962
    return;
 
963
 
 
964
  /* If exists previously invoked thread, then cancel it. */
 
965
  if (ospf->t_distribute_update)
 
966
    OSPF_TIMER_OFF (ospf->t_distribute_update);
 
967
 
 
968
  /* Set timer. */
 
969
  ospf->t_distribute_update =
 
970
    thread_add_timer (master, ospf_distribute_list_update_timer,
 
971
                      (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
 
972
}
 
973
 
 
974
/* If access-list is updated, apply some check. */
 
975
void
 
976
ospf_filter_update (struct access_list *access)
 
977
{
 
978
  struct ospf *ospf;
 
979
  int type;
 
980
  int abr_inv = 0;
 
981
  struct ospf_area *area;
 
982
  listnode node;
 
983
 
 
984
  /* If OSPF instatnce does not exist, return right now. */
 
985
  ospf = ospf_lookup ();
 
986
  if (ospf == NULL)
 
987
    return;
 
988
 
 
989
  /* Update distribute-list, and apply filter. */
 
990
  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
991
    {
 
992
      if (ROUTEMAP (ospf, type) != NULL)
 
993
        {
 
994
          /* if route-map is not NULL it may be using this access list */
 
995
          ospf_distribute_list_update (ospf, type);
 
996
          continue;
 
997
        }
 
998
 
 
999
 
 
1000
      if (DISTRIBUTE_NAME (ospf, type))
 
1001
        {
 
1002
          /* Keep old access-list for distribute-list. */
 
1003
          struct access_list *old = DISTRIBUTE_LIST (ospf, type);
 
1004
 
 
1005
          /* Update access-list for distribute-list. */
 
1006
          DISTRIBUTE_LIST (ospf, type) =
 
1007
            access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
 
1008
 
 
1009
          /* No update for this distribute type. */
 
1010
          if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
 
1011
            continue;
 
1012
 
 
1013
          /* Schedule distribute-list update timer. */
 
1014
          if (DISTRIBUTE_LIST (ospf, type) == NULL ||
 
1015
              strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
 
1016
            ospf_distribute_list_update (ospf, type);
 
1017
        }
 
1018
    }
 
1019
 
 
1020
  /* Update Area access-list. */
 
1021
  for (node = listhead (ospf->areas); node; nextnode (node))
 
1022
    if ((area = getdata (node)) != NULL)
 
1023
      {
 
1024
        if (EXPORT_NAME (area))
 
1025
          {
 
1026
            EXPORT_LIST (area) = NULL;
 
1027
            abr_inv++;
 
1028
          }
 
1029
 
 
1030
        if (IMPORT_NAME (area))
 
1031
          {
 
1032
            IMPORT_LIST (area) = NULL;
 
1033
            abr_inv++;
 
1034
          }
 
1035
      }
 
1036
 
 
1037
  /* Schedule ABR tasks -- this will be changed -- takada. */
 
1038
  if (IS_OSPF_ABR (ospf) && abr_inv)
 
1039
    ospf_schedule_abr_task (ospf);
 
1040
}
 
1041
 
 
1042
 
 
1043
struct ospf_distance *
 
1044
ospf_distance_new ()
 
1045
{
 
1046
  struct ospf_distance *new;
 
1047
  new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
 
1048
  memset (new, 0, sizeof (struct ospf_distance));
 
1049
  return new;
 
1050
}
 
1051
 
 
1052
void
 
1053
ospf_distance_free (struct ospf_distance *odistance)
 
1054
{
 
1055
  XFREE (MTYPE_OSPF_DISTANCE, odistance);
 
1056
}
 
1057
 
 
1058
int
 
1059
ospf_distance_set (struct vty *vty, struct ospf *ospf, char *distance_str,
 
1060
                   char *ip_str, char *access_list_str)
 
1061
{
 
1062
  int ret;
 
1063
  struct prefix_ipv4 p;
 
1064
  u_char distance;
 
1065
  struct route_node *rn;
 
1066
  struct ospf_distance *odistance;
 
1067
 
 
1068
  ret = str2prefix_ipv4 (ip_str, &p);
 
1069
  if (ret == 0)
 
1070
    {
 
1071
      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
 
1072
      return CMD_WARNING;
 
1073
    }
 
1074
 
 
1075
  distance = atoi (distance_str);
 
1076
 
 
1077
  /* Get OSPF distance node. */
 
1078
  rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
 
1079
  if (rn->info)
 
1080
    {
 
1081
      odistance = rn->info;
 
1082
      route_unlock_node (rn);
 
1083
    }
 
1084
  else
 
1085
    {
 
1086
      odistance = ospf_distance_new ();
 
1087
      rn->info = odistance;
 
1088
    }
 
1089
 
 
1090
  /* Set distance value. */
 
1091
  odistance->distance = distance;
 
1092
 
 
1093
  /* Reset access-list configuration. */
 
1094
  if (odistance->access_list)
 
1095
    {
 
1096
      free (odistance->access_list);
 
1097
      odistance->access_list = NULL;
 
1098
    }
 
1099
  if (access_list_str)
 
1100
    odistance->access_list = strdup (access_list_str);
 
1101
 
 
1102
  return CMD_SUCCESS;
 
1103
}
 
1104
 
 
1105
int
 
1106
ospf_distance_unset (struct vty *vty, struct ospf *ospf, char *distance_str,
 
1107
                     char *ip_str, char *access_list_str)
 
1108
{
 
1109
  int ret;
 
1110
  struct prefix_ipv4 p;
 
1111
  u_char distance;
 
1112
  struct route_node *rn;
 
1113
  struct ospf_distance *odistance;
 
1114
 
 
1115
  ret = str2prefix_ipv4 (ip_str, &p);
 
1116
  if (ret == 0)
 
1117
    {
 
1118
      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
 
1119
      return CMD_WARNING;
 
1120
    }
 
1121
 
 
1122
  distance = atoi (distance_str);
 
1123
 
 
1124
  rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
 
1125
  if (!rn)
 
1126
    {
 
1127
      vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
 
1128
      return CMD_WARNING;
 
1129
    }
 
1130
 
 
1131
  odistance = rn->info;
 
1132
 
 
1133
  if (odistance->access_list)
 
1134
    free (odistance->access_list);
 
1135
  ospf_distance_free (odistance);
 
1136
 
 
1137
  rn->info = NULL;
 
1138
  route_unlock_node (rn);
 
1139
  route_unlock_node (rn);
 
1140
 
 
1141
  return CMD_SUCCESS;
 
1142
}
 
1143
 
 
1144
void
 
1145
ospf_distance_reset (struct ospf *ospf)
 
1146
{
 
1147
  struct route_node *rn;
 
1148
  struct ospf_distance *odistance;
 
1149
 
 
1150
  for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
 
1151
    if ((odistance = rn->info) != NULL)
 
1152
      {
 
1153
        if (odistance->access_list)
 
1154
          free (odistance->access_list);
 
1155
        ospf_distance_free (odistance);
 
1156
        rn->info = NULL;
 
1157
        route_unlock_node (rn);
 
1158
      }
 
1159
}
 
1160
 
 
1161
u_char
 
1162
ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
 
1163
{
 
1164
  struct ospf *ospf;
 
1165
 
 
1166
  ospf = ospf_lookup ();
 
1167
  if (ospf == NULL)
 
1168
    return 0;
 
1169
 
 
1170
  if (ospf->distance_intra)
 
1171
    if (or->path_type == OSPF_PATH_INTRA_AREA)
 
1172
      return ospf->distance_intra;
 
1173
 
 
1174
  if (ospf->distance_inter)
 
1175
    if (or->path_type == OSPF_PATH_INTER_AREA)
 
1176
      return ospf->distance_inter;
 
1177
 
 
1178
  if (ospf->distance_external)
 
1179
    if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
 
1180
        || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
 
1181
      return ospf->distance_external;
 
1182
 
 
1183
  if (ospf->distance_all)
 
1184
    return ospf->distance_all;
 
1185
 
 
1186
  return 0;
 
1187
}
 
1188
 
 
1189
void
 
1190
ospf_zebra_init ()
 
1191
{
 
1192
  /* Allocate zebra structure. */
 
1193
  zclient = zclient_new ();
 
1194
  zclient_init (zclient, ZEBRA_ROUTE_OSPF);
 
1195
  zclient->interface_add = ospf_interface_add;
 
1196
  zclient->interface_delete = ospf_interface_delete;
 
1197
  zclient->interface_up = ospf_interface_state_up;
 
1198
  zclient->interface_down = ospf_interface_state_down;
 
1199
  zclient->interface_address_add = ospf_interface_address_add;
 
1200
  zclient->interface_address_delete = ospf_interface_address_delete;
 
1201
  zclient->ipv4_route_add = ospf_zebra_read_ipv4;
 
1202
  zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
 
1203
 
 
1204
  access_list_add_hook (ospf_filter_update);
 
1205
  access_list_delete_hook (ospf_filter_update);
 
1206
}