]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_neighbor.c
2 * OSPF Neighbor functions.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
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.
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_nsm.h"
41 #include "ospfd/ospf_packet.h"
42 #include "ospfd/ospf_network.h"
43 #include "ospfd/ospf_flood.h"
44 #include "ospfd/ospf_dump.h"
46 struct ospf_neighbor
*
47 ospf_nbr_new (struct ospf_interface
*oi
)
49 struct ospf_neighbor
*nbr
;
51 /* Allcate new neighbor. */
52 nbr
= XMALLOC (MTYPE_OSPF_NEIGHBOR
, sizeof (struct ospf_neighbor
));
53 memset (nbr
, 0, sizeof (struct ospf_neighbor
));
55 /* Relate neighbor to the interface. */
58 /* Set default values. */
59 nbr
->state
= NSM_Down
;
61 /* Set inheritance values. */
62 nbr
->v_inactivity
= OSPF_IF_PARAM (oi
, v_wait
);
63 nbr
->v_db_desc
= OSPF_IF_PARAM (oi
, retransmit_interval
);
64 nbr
->v_ls_req
= OSPF_IF_PARAM (oi
, retransmit_interval
);
65 nbr
->v_ls_upd
= OSPF_IF_PARAM (oi
, retransmit_interval
);
69 nbr
->dd_flags
= OSPF_DD_FLAG_MS
|OSPF_DD_FLAG_M
|OSPF_DD_FLAG_I
;
71 /* Last received and sent DD. */
72 nbr
->last_send
= NULL
;
76 ospf_lsdb_init (&nbr
->db_sum
);
77 ospf_lsdb_init (&nbr
->ls_rxmt
);
78 ospf_lsdb_init (&nbr
->ls_req
);
80 nbr
->crypt_seqnum
= 0;
86 ospf_nbr_free (struct ospf_neighbor
*nbr
)
88 /* Free DB summary list. */
89 if (ospf_db_summary_count (nbr
))
90 ospf_db_summary_clear (nbr
);
91 /* ospf_db_summary_delete_all (nbr); */
93 /* Free ls request list. */
94 if (ospf_ls_request_count (nbr
))
95 ospf_ls_request_delete_all (nbr
);
97 /* Free retransmit list. */
98 if (ospf_ls_retransmit_count (nbr
))
99 ospf_ls_retransmit_clear (nbr
);
102 ospf_lsdb_cleanup (&nbr
->db_sum
);
103 ospf_lsdb_cleanup (&nbr
->ls_req
);
104 ospf_lsdb_cleanup (&nbr
->ls_rxmt
);
106 /* Clear last send packet. */
108 ospf_packet_free (nbr
->last_send
);
112 nbr
->nbr_nbma
->nbr
= NULL
;
113 nbr
->nbr_nbma
= NULL
;
116 /* Cancel all timers. */
117 OSPF_NSM_TIMER_OFF (nbr
->t_inactivity
);
118 OSPF_NSM_TIMER_OFF (nbr
->t_db_desc
);
119 OSPF_NSM_TIMER_OFF (nbr
->t_ls_req
);
120 OSPF_NSM_TIMER_OFF (nbr
->t_ls_upd
);
122 /* Cancel all events. *//* Thread lookup cost would be negligible. */
123 thread_cancel_event (master
, nbr
);
125 XFREE (MTYPE_OSPF_NEIGHBOR
, nbr
);
128 /* Delete specified OSPF neighbor from interface. */
130 ospf_nbr_delete (struct ospf_neighbor
*nbr
)
132 struct ospf_interface
*oi
;
133 struct route_node
*rn
;
138 /* Unlink ospf neighbor from the interface. */
140 p
.prefixlen
= IPV4_MAX_BITLEN
;
142 /* vlinks are indexed by router-id */
143 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
144 p
.u
.prefix4
= nbr
->router_id
;
146 p
.u
.prefix4
= nbr
->src
;
148 rn
= route_node_lookup (oi
->nbrs
, &p
);
154 route_unlock_node (rn
);
157 zlog_info ("Can't find neighbor %s in the interface %s",
158 inet_ntoa (nbr
->src
), IF_NAME (oi
));
160 route_unlock_node (rn
);
163 /* Free ospf_neighbor structure. */
167 /* Check myself is in the neighbor list. */
169 ospf_nbr_bidirectional (struct in_addr
*router_id
,
170 struct in_addr
*neighbors
, int size
)
175 max
= size
/ sizeof (struct in_addr
);
177 for (i
= 0; i
< max
; i
++)
178 if (IPV4_ADDR_SAME (router_id
, &neighbors
[i
]))
184 /* Add self to nbr list. */
186 ospf_nbr_add_self (struct ospf_interface
*oi
)
188 struct ospf_neighbor
*nbr
;
190 struct route_node
*rn
;
194 p
.u
.prefix4
= oi
->address
->u
.prefix4
;
196 rn
= route_node_get (oi
->nbrs
, &p
);
199 /* There is already pseudo neighbor. */
201 route_unlock_node (rn
);
204 rn
->info
= oi
->nbr_self
;
207 /* Get neighbor count by status.
208 Specify status = 0, get all neighbor other than myself. */
210 ospf_nbr_count (struct ospf_interface
*oi
, int state
)
212 struct ospf_neighbor
*nbr
;
213 struct route_node
*rn
;
216 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
217 if ((nbr
= rn
->info
))
218 if (!IPV4_ADDR_SAME (&nbr
->router_id
, &oi
->ospf
->router_id
))
219 if (state
== 0 || nbr
->state
== state
)
225 #ifdef HAVE_OPAQUE_LSA
227 ospf_nbr_count_opaque_capable (struct ospf_interface
*oi
)
229 struct ospf_neighbor
*nbr
;
230 struct route_node
*rn
;
233 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
234 if ((nbr
= rn
->info
))
235 if (!IPV4_ADDR_SAME (&nbr
->router_id
, &oi
->ospf
->router_id
))
236 if (nbr
->state
== NSM_Full
)
237 if (CHECK_FLAG (nbr
->options
, OSPF_OPTION_O
))
242 #endif /* HAVE_OPAQUE_LSA */
244 /* lookup nbr by address - use this only if you know you must
245 * otherwise use the ospf_nbr_lookup() wrapper, which deals
246 * with virtual link neighbours
248 struct ospf_neighbor
*
249 ospf_nbr_lookup_by_addr (struct route_table
*nbrs
,
250 struct in_addr
*addr
)
253 struct route_node
*rn
;
254 struct ospf_neighbor
*nbr
;
257 p
.prefixlen
= IPV4_MAX_BITLEN
;
260 rn
= route_node_lookup (nbrs
, &p
);
264 if (rn
->info
== NULL
)
266 route_unlock_node (rn
);
270 nbr
= (struct ospf_neighbor
*) rn
->info
;
271 route_unlock_node (rn
);
276 struct ospf_neighbor
*
277 ospf_nbr_lookup_by_routerid (struct route_table
*nbrs
,
280 struct route_node
*rn
;
281 struct ospf_neighbor
*nbr
;
283 for (rn
= route_top (nbrs
); rn
; rn
= route_next (rn
))
284 if ((nbr
= rn
->info
) != NULL
)
285 if (IPV4_ADDR_SAME (&nbr
->router_id
, id
))
287 route_unlock_node(rn
);
295 ospf_renegotiate_optional_capabilities (struct ospf
*top
)
298 struct ospf_interface
*oi
;
299 struct route_table
*nbrs
;
300 struct route_node
*rn
;
301 struct ospf_neighbor
*nbr
;
303 /* At first, flush self-originated LSAs from routing domain. */
304 ospf_flush_self_originated_lsas_now (top
);
306 /* Revert all neighbor status to ExStart. */
307 for (node
= listhead (top
->oiflist
); node
; nextnode (node
))
309 if ((oi
= getdata (node
)) == NULL
|| (nbrs
= oi
->nbrs
) == NULL
)
312 for (rn
= route_top (nbrs
); rn
; rn
= route_next (rn
))
314 if ((nbr
= rn
->info
) == NULL
|| nbr
== oi
->nbr_self
)
317 if (nbr
->state
< NSM_ExStart
)
320 if (IS_DEBUG_OSPF_EVENT
)
321 zlog_info ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr
->router_id
));
323 OSPF_NSM_EVENT_SCHEDULE (nbr
, NSM_SeqNumberMismatch
);
331 struct ospf_neighbor
*
332 ospf_nbr_lookup (struct ospf_interface
*oi
, struct ip
*iph
,
333 struct ospf_header
*ospfh
)
335 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
336 return (ospf_nbr_lookup_by_routerid (oi
->nbrs
, &ospfh
->router_id
));
338 return (ospf_nbr_lookup_by_addr (oi
->nbrs
, &iph
->ip_src
));
341 struct ospf_neighbor
*
342 ospf_nbr_add (struct ospf_interface
*oi
, struct ospf_header
*ospfh
,
345 struct ospf_neighbor
*nbr
;
347 nbr
= ospf_nbr_new (oi
);
348 nbr
->state
= NSM_Down
;
349 nbr
->src
= p
->u
.prefix4
;
350 memcpy (&nbr
->address
, p
, sizeof (struct prefix
));
352 nbr
->nbr_nbma
= NULL
;
353 if (oi
->type
== OSPF_IFTYPE_NBMA
)
355 struct ospf_nbr_nbma
*nbr_nbma
;
358 for (node
= listhead (oi
->nbr_nbma
); node
; nextnode (node
))
360 nbr_nbma
= getdata (node
);
363 if (IPV4_ADDR_SAME(&nbr_nbma
->addr
, &nbr
->src
))
366 nbr
->nbr_nbma
= nbr_nbma
;
368 if (nbr_nbma
->t_poll
)
369 OSPF_POLL_TIMER_OFF (nbr_nbma
->t_poll
);
371 nbr
->state_change
= nbr_nbma
->state_change
+ 1;
376 /* New nbr, save the crypto sequence number if necessary */
377 if (ntohs (ospfh
->auth_type
) == OSPF_AUTH_CRYPTOGRAPHIC
)
378 nbr
->crypt_seqnum
= ospfh
->u
.crypt
.crypt_seqnum
;
380 if (IS_DEBUG_OSPF_EVENT
)
381 zlog_info ("NSM[%s:%s]: start", IF_NAME (nbr
->oi
),
382 inet_ntoa (nbr
->router_id
));
387 struct ospf_neighbor
*
388 ospf_nbr_get (struct ospf_interface
*oi
, struct ospf_header
*ospfh
,
389 struct ip
*iph
, struct prefix
*p
)
391 struct route_node
*rn
;
393 struct ospf_neighbor
*nbr
;
395 key
.family
= AF_INET
;
396 key
.prefixlen
= IPV4_MAX_BITLEN
;
398 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
399 key
.u
.prefix4
= ospfh
->router_id
; /* index vlink nbrs by router-id */
401 key
.u
.prefix4
= iph
->ip_src
;
403 rn
= route_node_get (oi
->nbrs
, &key
);
406 route_unlock_node (rn
);
409 if (oi
->type
== OSPF_IFTYPE_NBMA
&& nbr
->state
== NSM_Attempt
)
411 nbr
->src
= iph
->ip_src
;
412 memcpy (&nbr
->address
, p
, sizeof (struct prefix
));
417 rn
->info
= nbr
= ospf_nbr_add (oi
, ospfh
, p
);
420 nbr
->router_id
= ospfh
->router_id
;