2 * OSPF AS Boundary Router functions.
3 * Copyright (C) 1999, 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 Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include "ospfd/ospfd.h"
36 #include "ospfd/ospf_interface.h"
37 #include "ospfd/ospf_asbr.h"
38 #include "ospfd/ospf_lsa.h"
39 #include "ospfd/ospf_lsdb.h"
40 #include "ospfd/ospf_neighbor.h"
41 #include "ospfd/ospf_spf.h"
42 #include "ospfd/ospf_flood.h"
43 #include "ospfd/ospf_route.h"
44 #include "ospfd/ospf_zebra.h"
45 #include "ospfd/ospf_dump.h"
48 /* Remove external route. */
50 ospf_external_route_remove (struct ospf
*ospf
, struct prefix_ipv4
*p
)
52 struct route_node
*rn
;
53 struct ospf_route
*or;
55 rn
= route_node_lookup (ospf
->old_external_route
, (struct prefix
*) p
);
59 zlog_info ("Route[%s/%d]: external path deleted",
60 inet_ntoa (p
->prefix
), p
->prefixlen
);
62 /* Remove route from zebra. */
63 if (or->type
== OSPF_DESTINATION_NETWORK
)
64 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
, or);
69 route_unlock_node (rn
);
70 route_unlock_node (rn
);
74 zlog_info ("Route[%s/%d]: no such external path",
75 inet_ntoa (p
->prefix
), p
->prefixlen
);
78 /* Lookup external route. */
80 ospf_external_route_lookup (struct ospf
*ospf
,
81 struct prefix_ipv4
*p
)
83 struct route_node
*rn
;
85 rn
= route_node_lookup (ospf
->old_external_route
, (struct prefix
*) p
);
88 route_unlock_node (rn
);
93 zlog_warn ("Route[%s/%d]: lookup, no such prefix",
94 inet_ntoa (p
->prefix
), p
->prefixlen
);
100 /* Add an External info for AS-external-LSA. */
101 struct external_info
*
102 ospf_external_info_new (u_char type
)
104 struct external_info
*new;
106 new = (struct external_info
*)
107 XMALLOC (MTYPE_OSPF_EXTERNAL_INFO
, sizeof (struct external_info
));
108 memset (new, 0, sizeof (struct external_info
));
111 ospf_reset_route_map_set_values (&new->route_map_set
);
116 ospf_external_info_free (struct external_info
*ei
)
118 XFREE (MTYPE_OSPF_EXTERNAL_INFO
, ei
);
122 ospf_reset_route_map_set_values (struct route_map_set_values
*values
)
125 values
->metric_type
= -1;
129 ospf_route_map_set_compare (struct route_map_set_values
*values1
,
130 struct route_map_set_values
*values2
)
132 return values1
->metric
== values2
->metric
&&
133 values1
->metric_type
== values2
->metric_type
;
136 /* Add an External info for AS-external-LSA. */
137 struct external_info
*
138 ospf_external_info_add (u_char type
, struct prefix_ipv4 p
,
139 unsigned int ifindex
, struct in_addr nexthop
)
141 struct external_info
*new;
142 struct route_node
*rn
;
144 /* Initialize route table. */
145 if (EXTERNAL_INFO (type
) == NULL
)
146 EXTERNAL_INFO (type
) = route_table_init ();
148 rn
= route_node_get (EXTERNAL_INFO (type
), (struct prefix
*) &p
);
149 /* If old info exists, -- discard new one or overwrite with new one? */
153 route_unlock_node (rn
);
154 zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
155 LOOKUP (ospf_redistributed_proto
, type
),
156 inet_ntoa (p
.prefix
), p
.prefixlen
);
157 /* XFREE (MTYPE_OSPF_TMP, rn->info); */
161 /* Create new External info instance. */
162 new = ospf_external_info_new (type
);
164 new->ifindex
= ifindex
;
165 new->nexthop
= nexthop
;
170 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
171 zlog_info ("Redistribute[%s]: %s/%d external info created.",
172 LOOKUP (ospf_redistributed_proto
, type
),
173 inet_ntoa (p
.prefix
), p
.prefixlen
);
178 ospf_external_info_delete (u_char type
, struct prefix_ipv4 p
)
180 struct route_node
*rn
;
182 rn
= route_node_lookup (EXTERNAL_INFO (type
), (struct prefix
*) &p
);
185 ospf_external_info_free (rn
->info
);
187 route_unlock_node (rn
);
188 route_unlock_node (rn
);
192 struct external_info
*
193 ospf_external_info_lookup (u_char type
, struct prefix_ipv4
*p
)
195 struct route_node
*rn
;
196 rn
= route_node_lookup (EXTERNAL_INFO (type
), (struct prefix
*) p
);
199 route_unlock_node (rn
);
208 ospf_external_info_find_lsa (struct ospf
*ospf
,
209 struct prefix_ipv4
*p
)
211 struct ospf_lsa
*lsa
;
212 struct as_external_lsa
*al
;
213 struct in_addr mask
, id
;
215 lsa
= ospf_lsdb_lookup_by_id (ospf
->lsdb
, OSPF_AS_EXTERNAL_LSA
,
216 p
->prefix
, ospf
->router_id
);
221 al
= (struct as_external_lsa
*) lsa
->data
;
223 masklen2ip (p
->prefixlen
, &mask
);
225 if (mask
.s_addr
!= al
->mask
.s_addr
)
227 id
.s_addr
= p
->prefix
.s_addr
| (~mask
.s_addr
);
228 lsa
= ospf_lsdb_lookup_by_id (ospf
->lsdb
, OSPF_AS_EXTERNAL_LSA
,
229 id
, ospf
->router_id
);
238 /* Update ASBR status. */
240 ospf_asbr_status_update (struct ospf
*ospf
, u_char status
)
242 zlog_info ("ASBR[Status:%d]: Update", status
);
248 if (IS_OSPF_ASBR (ospf
))
250 zlog_info ("ASBR[Status:%d]: Already ASBR", status
);
253 SET_FLAG (ospf
->flags
, OSPF_FLAG_ASBR
);
257 /* Already non ASBR. */
258 if (! IS_OSPF_ASBR (ospf
))
260 zlog_info ("ASBR[Status:%d]: Already non ASBR", status
);
263 UNSET_FLAG (ospf
->flags
, OSPF_FLAG_ASBR
);
266 /* Transition from/to status ASBR, schedule timer. */
267 ospf_spf_calculate_schedule (ospf
);
268 OSPF_TIMER_ON (ospf
->t_router_lsa_update
,
269 ospf_router_lsa_update_timer
, OSPF_LSA_UPDATE_DELAY
);
273 ospf_redistribute_withdraw (u_char type
)
276 struct route_node
*rn
;
277 struct external_info
*ei
;
279 ospf
= ospf_lookup ();
281 /* Delete external info for specified type. */
282 if (EXTERNAL_INFO (type
))
283 for (rn
= route_top (EXTERNAL_INFO (type
)); rn
; rn
= route_next (rn
))
285 if (ospf_external_info_find_lsa (ospf
, &ei
->p
))
287 if (is_prefix_default (&ei
->p
) &&
288 ospf
->default_originate
!= DEFAULT_ORIGINATE_NONE
)
290 ospf_external_lsa_flush (ospf
, type
, &ei
->p
, ei
->ifindex
, ei
->nexthop
);
291 ospf_external_info_delete (type
, ei
->p
);