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 along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "ospfd/ospfd.h"
35 #include "ospfd/ospf_interface.h"
36 #include "ospfd/ospf_asbr.h"
37 #include "ospfd/ospf_lsa.h"
38 #include "ospfd/ospf_lsdb.h"
39 #include "ospfd/ospf_neighbor.h"
40 #include "ospfd/ospf_spf.h"
41 #include "ospfd/ospf_flood.h"
42 #include "ospfd/ospf_route.h"
43 #include "ospfd/ospf_zebra.h"
44 #include "ospfd/ospf_dump.h"
47 /* Remove external route. */
49 ospf_external_route_remove (struct ospf
*ospf
, struct prefix_ipv4
*p
)
51 struct route_node
*rn
;
52 struct ospf_route
*or;
54 rn
= route_node_lookup (ospf
->old_external_route
, (struct prefix
*) p
);
58 zlog_info ("Route[%s/%d]: external path deleted",
59 inet_ntoa (p
->prefix
), p
->prefixlen
);
61 /* Remove route from zebra. */
62 if (or->type
== OSPF_DESTINATION_NETWORK
)
63 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
, or);
68 route_unlock_node (rn
);
69 route_unlock_node (rn
);
73 zlog_info ("Route[%s/%d]: no such external path",
74 inet_ntoa (p
->prefix
), p
->prefixlen
);
77 /* Lookup external route. */
79 ospf_external_route_lookup (struct ospf
*ospf
,
80 struct prefix_ipv4
*p
)
82 struct route_node
*rn
;
84 rn
= route_node_lookup (ospf
->old_external_route
, (struct prefix
*) p
);
87 route_unlock_node (rn
);
92 zlog_warn ("Route[%s/%d]: lookup, no such prefix",
93 inet_ntoa (p
->prefix
), p
->prefixlen
);
99 /* Add an External info for AS-external-LSA. */
100 struct external_info
*
101 ospf_external_info_new (u_char type
, u_short instance
)
103 struct external_info
*new;
105 new = (struct external_info
*)
106 XCALLOC (MTYPE_OSPF_EXTERNAL_INFO
, sizeof (struct external_info
));
108 new->instance
= instance
;
110 ospf_reset_route_map_set_values (&new->route_map_set
);
115 ospf_external_info_free (struct external_info
*ei
)
117 XFREE (MTYPE_OSPF_EXTERNAL_INFO
, ei
);
121 ospf_reset_route_map_set_values (struct route_map_set_values
*values
)
124 values
->metric_type
= -1;
128 ospf_route_map_set_compare (struct route_map_set_values
*values1
,
129 struct route_map_set_values
*values2
)
131 return values1
->metric
== values2
->metric
&&
132 values1
->metric_type
== values2
->metric_type
;
135 /* Add an External info for AS-external-LSA. */
136 struct external_info
*
137 ospf_external_info_add (u_char type
, u_short instance
, struct prefix_ipv4 p
,
138 ifindex_t ifindex
, struct in_addr nexthop
,
141 struct external_info
*new;
142 struct route_node
*rn
;
143 struct ospf_external
*ext
;
144 char inetbuf
[INET6_BUFSIZ
];
146 ext
= ospf_external_lookup(type
, instance
);
148 ext
= ospf_external_add(type
, instance
);
150 rn
= route_node_get (EXTERNAL_INFO (ext
), (struct prefix
*) &p
);
151 /* If old info exists, -- discard new one or overwrite with new one? */
156 if ((new->ifindex
== ifindex
) &&
157 (new->nexthop
.s_addr
== nexthop
.s_addr
) && (new->tag
== tag
))
159 route_unlock_node(rn
);
160 return NULL
; /* NULL => no LSA to refresh */
163 inet_ntop(AF_INET
, (void *)&nexthop
.s_addr
, inetbuf
, INET6_BUFSIZ
);
164 zlog_warn ("Redistribute[%s][%d]: %s/%d discarding old info with NH %s.",
165 ospf_redist_string(type
), instance
,
166 inet_ntoa (p
.prefix
), p
.prefixlen
, inetbuf
);
167 XFREE (MTYPE_OSPF_EXTERNAL_INFO
, rn
->info
);
171 /* Create new External info instance. */
172 new = ospf_external_info_new (type
, instance
);
174 new->ifindex
= ifindex
;
175 new->nexthop
= nexthop
;
178 /* we don't unlock rn from the get() because we're attaching the info */
182 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
184 inet_ntop(AF_INET
, (void *)&nexthop
.s_addr
, inetbuf
, INET6_BUFSIZ
);
185 zlog_debug ("Redistribute[%s]: %s/%d external info created, with NH %s",
186 ospf_redist_string(type
),
187 inet_ntoa (p
.prefix
), p
.prefixlen
, inetbuf
);
193 ospf_external_info_delete (u_char type
, u_short instance
, struct prefix_ipv4 p
)
195 struct route_node
*rn
;
196 struct ospf_external
*ext
;
198 ext
= ospf_external_lookup(type
, instance
);
202 rn
= route_node_lookup (EXTERNAL_INFO (ext
), (struct prefix
*) &p
);
205 ospf_external_info_free (rn
->info
);
207 route_unlock_node (rn
);
208 route_unlock_node (rn
);
212 struct external_info
*
213 ospf_external_info_lookup (u_char type
, u_short instance
, struct prefix_ipv4
*p
)
215 struct route_node
*rn
;
216 struct ospf_external
*ext
;
218 ext
= ospf_external_lookup(type
, instance
);
222 rn
= route_node_lookup (EXTERNAL_INFO (ext
), (struct prefix
*) p
);
225 route_unlock_node (rn
);
234 ospf_external_info_find_lsa (struct ospf
*ospf
,
235 struct prefix_ipv4
*p
)
237 struct ospf_lsa
*lsa
;
238 struct as_external_lsa
*al
;
239 struct in_addr mask
, id
;
241 lsa
= ospf_lsdb_lookup_by_id (ospf
->lsdb
, OSPF_AS_EXTERNAL_LSA
,
242 p
->prefix
, ospf
->router_id
);
247 al
= (struct as_external_lsa
*) lsa
->data
;
249 masklen2ip (p
->prefixlen
, &mask
);
251 if (mask
.s_addr
!= al
->mask
.s_addr
)
253 id
.s_addr
= p
->prefix
.s_addr
| (~mask
.s_addr
);
254 lsa
= ospf_lsdb_lookup_by_id (ospf
->lsdb
, OSPF_AS_EXTERNAL_LSA
,
255 id
, ospf
->router_id
);
264 /* Update ASBR status. */
266 ospf_asbr_status_update (struct ospf
*ospf
, u_char status
)
268 zlog_info ("ASBR[Status:%d]: Update", status
);
274 if (IS_OSPF_ASBR (ospf
))
276 zlog_info ("ASBR[Status:%d]: Already ASBR", status
);
279 SET_FLAG (ospf
->flags
, OSPF_FLAG_ASBR
);
283 /* Already non ASBR. */
284 if (! IS_OSPF_ASBR (ospf
))
286 zlog_info ("ASBR[Status:%d]: Already non ASBR", status
);
289 UNSET_FLAG (ospf
->flags
, OSPF_FLAG_ASBR
);
292 /* Transition from/to status ASBR, schedule timer. */
293 ospf_spf_calculate_schedule (ospf
, SPF_FLAG_ASBR_STATUS_CHANGE
);
294 ospf_router_lsa_update (ospf
);
298 ospf_redistribute_withdraw (struct ospf
*ospf
, u_char type
, u_short instance
)
300 struct route_node
*rn
;
301 struct external_info
*ei
;
302 struct ospf_external
*ext
;
304 ext
= ospf_external_lookup(type
, instance
);
308 /* Delete external info for specified type. */
309 if (EXTERNAL_INFO (ext
))
310 for (rn
= route_top (EXTERNAL_INFO (ext
)); rn
; rn
= route_next (rn
))
312 if (ospf_external_info_find_lsa (ospf
, &ei
->p
))
314 if (is_prefix_default (&ei
->p
) &&
315 ospf
->default_originate
!= DEFAULT_ORIGINATE_NONE
)
317 ospf_external_lsa_flush (ospf
, type
, &ei
->p
,
318 ei
->ifindex
/*, ei->nexthop */);
320 ospf_external_info_free (ei
);
321 route_unlock_node (rn
);