2
* Zebra connect library for OSPFd
3
* Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
5
* This file is part of GNU Zebra.
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
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.
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.
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"
48
#include "ospfd/ospf_snmp.h"
49
#endif /* HAVE_SNMP */
51
/* Zebra structure to hold current status. */
52
struct zclient *zclient = NULL;
54
/* For registering threads. */
55
extern struct thread_master *master;
57
/* Inteface addition message from zebra. */
59
ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
61
struct interface *ifp;
64
ifp = zebra_interface_add_read (zclient->ibuf);
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);
72
if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
74
SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
75
IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
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;
85
ospf = ospf_lookup ();
87
ospf_if_update (ospf);
90
ospf_snmp_if_update (ifp);
91
#endif /* HAVE_SNMP */
97
ospf_interface_delete (int command, struct zclient *zclient,
100
struct interface *ifp;
102
struct route_node *rn;
105
/* zebra_interface_state_read() updates interface structure in iflist */
106
ifp = zebra_interface_state_read (s);
112
zlog_warn ("Zebra: got delete of %s, but interface is still up",
115
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
117
("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
118
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
121
ospf_snmp_if_delete (ifp);
122
#endif /* HAVE_SNMP */
124
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
126
ospf_if_free ((struct ospf_interface *) rn->info);
132
zebra_interface_if_lookup (struct stream *s)
134
struct interface *ifp;
135
u_char ifname_tmp[INTERFACE_NAMSIZ];
137
/* Read interface name. */
138
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
140
/* Lookup this by interface index. */
141
ifp = if_lookup_by_name (ifname_tmp);
143
/* If such interface does not exist, indicate an error */
151
zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
153
/* Read interface's index. */
154
ifp->ifindex = stream_getl (s);
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);
165
ospf_interface_state_up (int command, struct zclient *zclient,
168
struct interface *ifp;
169
struct interface if_tmp;
170
struct ospf_interface *oi;
171
struct route_node *rn;
173
ifp = zebra_interface_if_lookup (zclient->ibuf);
178
/* Interface is already up. */
179
if (if_is_operative (ifp))
181
/* Temporarily keep ifp values. */
182
memcpy (&if_tmp, ifp, sizeof (struct interface));
184
zebra_interface_if_set_value (zclient->ibuf, ifp);
186
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
187
zlog_info ("Zebra: Interface[%s] state update.", ifp->name);
189
if (if_tmp.bandwidth != ifp->bandwidth)
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);
195
ospf_if_recalculate_output_cost (ifp);
200
zebra_interface_if_set_value (zclient->ibuf, ifp);
202
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
203
zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);
205
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
207
if ((oi = rn->info) == NULL)
217
ospf_interface_state_down (int command, struct zclient *zclient,
220
struct interface *ifp;
221
struct ospf_interface *oi;
222
struct route_node *node;
224
ifp = zebra_interface_state_read (zclient->ibuf);
229
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
230
zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);
232
for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
234
if ((oi = node->info) == NULL)
243
ospf_interface_address_add (int command, struct zclient *zclient,
249
c = zebra_interface_address_add_read (zclient->ibuf);
254
ospf = ospf_lookup ();
256
ospf_if_update (ospf);
259
ospf_snmp_if_update (c->ifp);
260
#endif /* HAVE_SNMP */
266
ospf_interface_address_delete (int command, struct zclient *zclient,
271
struct interface *ifp;
272
struct ospf_interface *oi;
273
struct route_node *rn;
276
c = zebra_interface_address_delete_read (zclient->ibuf);
283
p.prefixlen = IPV4_MAX_PREFIXLEN;
285
rn = route_node_lookup (IF_OIFS (ifp), &p);
292
/* Call interface hook functions to clean up */
296
ospf_snmp_if_update (c->ifp);
297
#endif /* HAVE_SNMP */
301
ospf = ospf_lookup ();
303
ospf_if_update (ospf);
309
ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
316
struct ospf_path *path;
319
if (zclient->redist[ZEBRA_ROUTE_OSPF])
324
/* OSPF pass nexthop and metric */
325
SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
326
SET_FLAG (message, ZAPI_MESSAGE_METRIC);
328
/* Distance value. */
329
distance = ospf_distance_apply (p, or);
331
SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
337
/* Length place holder. */
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);
346
/* Put prefix information. */
347
psize = PSIZE (p->prefixlen);
348
stream_putc (s, p->prefixlen);
349
stream_write (s, (u_char *) & p->prefix, psize);
352
stream_putc (s, or->paths->count);
354
/* Nexthop, ifindex, distance and metric information. */
355
for (node = listhead (or->paths); node; nextnode (node))
357
path = getdata (node);
359
if (path->nexthop.s_addr != INADDR_ANY)
361
stream_putc (s, ZEBRA_NEXTHOP_IPV4);
362
stream_put_in_addr (s, &path->nexthop);
366
stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
368
stream_putl (s, path->oi->ifp->ifindex);
373
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
375
zlog_info ("Zebra: Route add %s/%d nexthop %s",
376
inet_ntoa (p->prefix),
377
p->prefixlen, inet_ntoa (path->nexthop));
381
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
382
stream_putc (s, distance);
383
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
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);
390
stream_putl (s, or->cost);
393
stream_putw_at (s, 0, stream_get_endp (s));
395
writen (zclient->sock, s->data, stream_get_endp (s));
400
ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
402
struct zapi_ipv4 api;
403
struct ospf_path *path;
404
struct in_addr *nexthop;
407
if (zclient->redist[ZEBRA_ROUTE_OSPF])
409
api.type = ZEBRA_ROUTE_OSPF;
415
for (node = listhead (or->paths); node; nextnode (node))
417
path = getdata (node);
419
if (path->nexthop.s_addr != INADDR_ANY)
421
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
423
nexthop = &path->nexthop;
424
api.nexthop = &nexthop;
426
else if (ospf_if_exists(path->oi) && (path->oi->ifp))
428
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
430
api.ifindex = &path->oi->ifp->ifindex;
432
else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
434
zlog_info("Zebra: no ifp %s %d",
435
inet_ntoa(p->prefix),
439
zapi_ipv4_delete (zclient, p, &api);
441
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
443
zlog_info ("Zebra: Route delete %s/%d nexthop %s",
444
inet_ntoa (p->prefix),
445
p->prefixlen, inet_ntoa (**api.nexthop));
447
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
449
zlog_info ("Zebra: Route delete %s/%d ifindex %d",
450
inet_ntoa (p->prefix),
451
p->prefixlen, *api.ifindex);
458
ospf_zebra_add_discard (struct prefix_ipv4 *p)
460
struct zapi_ipv4 api;
462
if (zclient->redist[ZEBRA_ROUTE_OSPF])
464
api.type = ZEBRA_ROUTE_OSPF;
465
api.flags = ZEBRA_FLAG_BLACKHOLE;
467
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
471
zapi_ipv4_add (zclient, p, &api);
476
ospf_zebra_delete_discard (struct prefix_ipv4 *p)
478
struct zapi_ipv4 api;
480
if (zclient->redist[ZEBRA_ROUTE_OSPF])
482
api.type = ZEBRA_ROUTE_OSPF;
483
api.flags = ZEBRA_FLAG_BLACKHOLE;
485
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
489
zapi_ipv4_delete (zclient, p, &api);
491
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
492
zlog_info ("Zebra: Route delete discard %s/%d",
493
inet_ntoa (p->prefix), p->prefixlen);
499
ospf_is_type_redistributed (int type)
501
return (DEFAULT_ROUTE_TYPE (type)) ?
502
zclient->default_information : zclient->redist[type];
506
ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
510
if (ospf_is_type_redistributed (type))
512
if (mtype != ospf->dmetric[type].type)
514
ospf->dmetric[type].type = mtype;
515
force = LSA_REFRESH_FORCE;
517
if (mvalue != ospf->dmetric[type].value)
519
ospf->dmetric[type].value = mvalue;
520
force = LSA_REFRESH_FORCE;
523
ospf_external_lsa_refresh_type (ospf, type, force);
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));
533
ospf->dmetric[type].type = mtype;
534
ospf->dmetric[type].value = mvalue;
536
zclient_redistribute_set (zclient, type);
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));
543
ospf_asbr_status_update (ospf, ++ospf->redistribute);
549
ospf_redistribute_unset (struct ospf *ospf, int type)
551
if (type == zclient->redist_default)
554
if (!ospf_is_type_redistributed (type))
557
zclient_redistribute_unset (zclient, type);
559
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
560
zlog_info ("Redistribute[%s]: Stop",
561
LOOKUP (ospf_redistributed_proto, type));
563
ospf->dmetric[type].type = -1;
564
ospf->dmetric[type].value = -1;
566
/* Remove the routes from OSPF table. */
567
ospf_redistribute_withdraw (type);
569
ospf_asbr_status_update (ospf, --ospf->redistribute);
575
ospf_redistribute_default_set (struct ospf *ospf, int originate,
576
int mtype, int mvalue)
580
if (ospf_is_type_redistributed (DEFAULT_ROUTE))
582
if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)
584
ospf->dmetric[DEFAULT_ROUTE].type = mtype;
587
if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)
590
ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
593
ospf_external_lsa_refresh_default (ospf);
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));
603
ospf->default_originate = originate;
604
ospf->dmetric[DEFAULT_ROUTE].type = mtype;
605
ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
607
zclient_redistribute_default_set (zclient);
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));
614
if (ospf->router_id.s_addr == 0)
615
ospf->external_origin |= (1 << DEFAULT_ROUTE);
617
thread_add_timer (master, ospf_default_originate_timer,
618
&ospf->default_originate, 1);
620
ospf_asbr_status_update (ospf, ++ospf->redistribute);
626
ospf_redistribute_default_unset (struct ospf *ospf)
628
if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
631
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
632
ospf->dmetric[DEFAULT_ROUTE].type = -1;
633
ospf->dmetric[DEFAULT_ROUTE].value = -1;
635
zclient_redistribute_default_unset (zclient);
637
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
638
zlog_info ("Redistribute[DEFAULT]: Stop");
640
ospf_asbr_status_update (ospf, --ospf->redistribute);
646
ospf_external_lsa_originate_check (struct ospf *ospf,
647
struct external_info *ei)
649
/* If prefix is multicast, then do not originate LSA. */
650
if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
652
zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
653
"Prefix belongs multicast", inet_ntoa (ei->p.prefix));
657
/* Take care of default-originate. */
658
if (is_prefix_default (&ei->p))
659
if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
661
zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
669
/* If connected prefix is OSPF enable interface, then do not announce. */
671
ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
673
struct route_node *rn;
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))
679
route_unlock_node (rn);
686
/* return 1 if external LSA must be originated, 0 otherwise */
688
ospf_redistribute_check (struct ospf *ospf,
689
struct external_info *ei, int *changed)
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;
698
if (!ospf_external_lsa_originate_check (ospf, ei))
701
/* Take care connected route. */
702
if (type == ZEBRA_ROUTE_CONNECT &&
703
!ospf_distribute_check_connected (ospf, ei))
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)
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);
718
save_values = ei->route_map_set;
719
ospf_reset_route_map_set_values (&ei->route_map_set);
721
/* apply route-map if needed */
722
if (ROUTEMAP_NAME (ospf, type))
726
ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
729
if (ret == RMAP_DENYMATCH)
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);
739
/* check if 'route-map set' changed something */
741
*changed = !ospf_route_map_set_compare (&ei->route_map_set,
748
/* OSPF route-map set for redistribution */
750
ospf_routemap_set (struct ospf *ospf, int type, char *name)
752
if (ROUTEMAP_NAME (ospf, type))
753
free (ROUTEMAP_NAME (ospf, type));
755
ROUTEMAP_NAME (ospf, type) = strdup (name);
756
ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
760
ospf_routemap_unset (struct ospf *ospf, int type)
762
if (ROUTEMAP_NAME (ospf, type))
763
free (ROUTEMAP_NAME (ospf, type));
765
ROUTEMAP_NAME (ospf, type) = NULL;
766
ROUTEMAP (ospf, type) = NULL;
769
/* Zebra route add and delete treatment. */
771
ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
775
struct zapi_ipv4 api;
776
unsigned long ifindex;
777
struct in_addr nexthop;
778
struct prefix_ipv4 p;
779
struct external_info *ei;
786
/* Type, flags, message. */
787
api.type = stream_getc (s);
788
api.flags = stream_getc (s);
789
api.message = stream_getc (s);
792
memset (&p, 0, sizeof (struct prefix_ipv4));
794
p.prefixlen = stream_getc (s);
795
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
797
if (IPV4_NET127(ntohl(p.prefix.s_addr)))
800
/* Nexthop, ifindex, distance, metric. */
801
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
803
api.nexthop_num = stream_getc (s);
804
nexthop.s_addr = stream_get_ipv4 (s);
806
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
808
api.ifindex_num = stream_getc (s);
809
/* XXX assert(api.ifindex_num == 1); */
810
ifindex = stream_getl (s);
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);
817
ospf = ospf_lookup ();
821
if (command == ZEBRA_IPV4_ROUTE_ADD)
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?
829
* if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
830
* || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
834
ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
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);
844
if (is_prefix_default (&p))
845
ospf_external_lsa_refresh_default (ospf);
848
struct ospf_lsa *current;
850
current = ospf_external_info_find_lsa (ospf, &ei->p);
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);
857
zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
858
inet_ntoa (p.prefix));
863
else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
865
ospf_external_info_delete (api.type, p);
866
if (is_prefix_default (&p))
867
ospf_external_lsa_refresh_default (ospf);
869
ospf_external_lsa_flush (ospf, api.type, &p, ifindex, nexthop);
877
ospf_distribute_list_out_set (struct ospf *ospf, int type, char *name)
879
/* Lookup access-list for distribute-list. */
880
DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
882
/* Clear previous distribute-name. */
883
if (DISTRIBUTE_NAME (ospf, type))
884
free (DISTRIBUTE_NAME (ospf, type));
886
/* Set distribute-name. */
887
DISTRIBUTE_NAME (ospf, type) = strdup (name);
889
/* If access-list have been set, schedule update timer. */
890
if (DISTRIBUTE_LIST (ospf, type))
891
ospf_distribute_list_update (ospf, type);
897
ospf_distribute_list_out_unset (struct ospf *ospf, int type, char *name)
899
/* Schedule update timer. */
900
if (DISTRIBUTE_LIST (ospf, type))
901
ospf_distribute_list_update (ospf, type);
903
/* Unset distribute-list. */
904
DISTRIBUTE_LIST (ospf, type) = NULL;
906
/* Clear distribute-name. */
907
if (DISTRIBUTE_NAME (ospf, type))
908
free (DISTRIBUTE_NAME (ospf, type));
910
DISTRIBUTE_NAME (ospf, type) = NULL;
915
/* distribute-list update timer. */
917
ospf_distribute_list_update_timer (struct thread *thread)
919
struct route_node *rn;
920
struct external_info *ei;
921
struct route_table *rt;
922
struct ospf_lsa *lsa;
926
type = (int) THREAD_ARG (thread);
927
rt = EXTERNAL_INFO (type);
929
ospf = ospf_lookup ();
933
ospf->t_distribute_update = NULL;
935
zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
937
/* foreach all external info. */
939
for (rn = route_top (rt); rn; rn = route_next (rn))
940
if ((ei = rn->info) != NULL)
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);
947
ospf_external_lsa_originate (ospf, ei);
952
#define OSPF_DISTRIBUTE_UPDATE_DELAY 5
954
/* Update distribute-list and set timer to apply access-list. */
956
ospf_distribute_list_update (struct ospf *ospf, int type)
958
struct route_table *rt;
960
/* External info does not exist. */
961
if (!(rt = EXTERNAL_INFO (type)))
964
/* If exists previously invoked thread, then cancel it. */
965
if (ospf->t_distribute_update)
966
OSPF_TIMER_OFF (ospf->t_distribute_update);
969
ospf->t_distribute_update =
970
thread_add_timer (master, ospf_distribute_list_update_timer,
971
(void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
974
/* If access-list is updated, apply some check. */
976
ospf_filter_update (struct access_list *access)
981
struct ospf_area *area;
984
/* If OSPF instatnce does not exist, return right now. */
985
ospf = ospf_lookup ();
989
/* Update distribute-list, and apply filter. */
990
for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
992
if (ROUTEMAP (ospf, type) != NULL)
994
/* if route-map is not NULL it may be using this access list */
995
ospf_distribute_list_update (ospf, type);
1000
if (DISTRIBUTE_NAME (ospf, type))
1002
/* Keep old access-list for distribute-list. */
1003
struct access_list *old = DISTRIBUTE_LIST (ospf, type);
1005
/* Update access-list for distribute-list. */
1006
DISTRIBUTE_LIST (ospf, type) =
1007
access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
1009
/* No update for this distribute type. */
1010
if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
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);
1020
/* Update Area access-list. */
1021
for (node = listhead (ospf->areas); node; nextnode (node))
1022
if ((area = getdata (node)) != NULL)
1024
if (EXPORT_NAME (area))
1026
EXPORT_LIST (area) = NULL;
1030
if (IMPORT_NAME (area))
1032
IMPORT_LIST (area) = NULL;
1037
/* Schedule ABR tasks -- this will be changed -- takada. */
1038
if (IS_OSPF_ABR (ospf) && abr_inv)
1039
ospf_schedule_abr_task (ospf);
1043
struct ospf_distance *
1044
ospf_distance_new ()
1046
struct ospf_distance *new;
1047
new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1048
memset (new, 0, sizeof (struct ospf_distance));
1053
ospf_distance_free (struct ospf_distance *odistance)
1055
XFREE (MTYPE_OSPF_DISTANCE, odistance);
1059
ospf_distance_set (struct vty *vty, struct ospf *ospf, char *distance_str,
1060
char *ip_str, char *access_list_str)
1063
struct prefix_ipv4 p;
1065
struct route_node *rn;
1066
struct ospf_distance *odistance;
1068
ret = str2prefix_ipv4 (ip_str, &p);
1071
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1075
distance = atoi (distance_str);
1077
/* Get OSPF distance node. */
1078
rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
1081
odistance = rn->info;
1082
route_unlock_node (rn);
1086
odistance = ospf_distance_new ();
1087
rn->info = odistance;
1090
/* Set distance value. */
1091
odistance->distance = distance;
1093
/* Reset access-list configuration. */
1094
if (odistance->access_list)
1096
free (odistance->access_list);
1097
odistance->access_list = NULL;
1099
if (access_list_str)
1100
odistance->access_list = strdup (access_list_str);
1106
ospf_distance_unset (struct vty *vty, struct ospf *ospf, char *distance_str,
1107
char *ip_str, char *access_list_str)
1110
struct prefix_ipv4 p;
1112
struct route_node *rn;
1113
struct ospf_distance *odistance;
1115
ret = str2prefix_ipv4 (ip_str, &p);
1118
vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1122
distance = atoi (distance_str);
1124
rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
1127
vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1131
odistance = rn->info;
1133
if (odistance->access_list)
1134
free (odistance->access_list);
1135
ospf_distance_free (odistance);
1138
route_unlock_node (rn);
1139
route_unlock_node (rn);
1145
ospf_distance_reset (struct ospf *ospf)
1147
struct route_node *rn;
1148
struct ospf_distance *odistance;
1150
for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
1151
if ((odistance = rn->info) != NULL)
1153
if (odistance->access_list)
1154
free (odistance->access_list);
1155
ospf_distance_free (odistance);
1157
route_unlock_node (rn);
1162
ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1166
ospf = ospf_lookup ();
1170
if (ospf->distance_intra)
1171
if (or->path_type == OSPF_PATH_INTRA_AREA)
1172
return ospf->distance_intra;
1174
if (ospf->distance_inter)
1175
if (or->path_type == OSPF_PATH_INTER_AREA)
1176
return ospf->distance_inter;
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;
1183
if (ospf->distance_all)
1184
return ospf->distance_all;
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;
1204
access_list_add_hook (ospf_filter_update);
1205
access_list_delete_hook (ospf_filter_update);