1/* 2 * OSPF Neighbor functions. 3 * Copyright (C) 1999, 2000 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 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. 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 "linklist.h" 26#include "prefix.h" 27#include "memory.h" 28#include "command.h" 29#include "thread.h" 30#include "stream.h" 31#include "table.h" 32#include "log.h" 33 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" 45 46struct ospf_neighbor * 47ospf_nbr_new (struct ospf_interface *oi) 48{ 49 struct ospf_neighbor *nbr; 50 51 /* Allcate new neighbor. */ 52 nbr = XMALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor)); 53 memset (nbr, 0, sizeof (struct ospf_neighbor)); 54 55 /* Relate neighbor to the interface. */ 56 nbr->oi = oi; 57 58 /* Set default values. */ 59 nbr->state = NSM_Down; 60 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); 66 nbr->priority = -1; 67 68 /* DD flags. */ 69 nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I; 70 71 /* Last received and sent DD. */ 72 nbr->last_send = NULL; 73 74 nbr->nbr_nbma = NULL; 75 76 ospf_lsdb_init (&nbr->db_sum); 77 ospf_lsdb_init (&nbr->ls_rxmt); 78 ospf_lsdb_init (&nbr->ls_req); 79 80 nbr->crypt_seqnum = 0; 81 82 return nbr; 83} 84 85void 86ospf_nbr_free (struct ospf_neighbor *nbr) 87{ 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); */ 92 93 /* Free ls request list. */ 94 if (ospf_ls_request_count (nbr)) 95 ospf_ls_request_delete_all (nbr); 96 97 /* Free retransmit list. */ 98 if (ospf_ls_retransmit_count (nbr)) 99 ospf_ls_retransmit_clear (nbr); 100 101 /* Cleanup LSDBs. */ 102 ospf_lsdb_cleanup (&nbr->db_sum); 103 ospf_lsdb_cleanup (&nbr->ls_req); 104 ospf_lsdb_cleanup (&nbr->ls_rxmt); 105 106 /* Clear last send packet. */ 107 if (nbr->last_send) 108 ospf_packet_free (nbr->last_send); 109 110 if (nbr->nbr_nbma) 111 { 112 nbr->nbr_nbma->nbr = NULL; 113 nbr->nbr_nbma = NULL; 114 } 115 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); 121 122 XFREE (MTYPE_OSPF_NEIGHBOR, nbr); 123} 124 125/* Delete specified OSPF neighbor from interface. */ 126void 127ospf_nbr_delete (struct ospf_neighbor *nbr) 128{ 129 struct ospf_interface *oi; 130 struct route_node *rn; 131 struct prefix p; 132 133 oi = nbr->oi; 134 135 /* Unlink ospf neighbor from the interface. */ 136 p.family = AF_INET; 137 p.prefixlen = IPV4_MAX_BITLEN; 138 p.u.prefix4 = nbr->src; 139 140 rn = route_node_lookup (oi->nbrs, &p); 141 if (rn) 142 { 143 if (rn->info) 144 { 145 rn->info = NULL; 146 route_unlock_node (rn); 147 } 148 else 149 zlog_info ("Can't find neighbor %s in the interface %s", 150 inet_ntoa (nbr->src), IF_NAME (oi)); 151 152 route_unlock_node (rn); 153 } 154 155 /* Free ospf_neighbor structure. */ 156 ospf_nbr_free (nbr); 157} 158 159/* Check myself is in the neighbor list. */ 160int 161ospf_nbr_bidirectional (struct in_addr *router_id, 162 struct in_addr *neighbors, int size) 163{ 164 int i; 165 int max; 166 167 max = size / sizeof (struct in_addr); 168 169 for (i = 0; i < max; i ++) 170 if (IPV4_ADDR_SAME (router_id, &neighbors[i])) 171 return 1; 172 173 return 0; 174} 175 176/* Add self to nbr list. */ 177void 178ospf_nbr_add_self (struct ospf_interface *oi) 179{ 180 struct ospf_neighbor *nbr; 181 struct prefix p; 182 struct route_node *rn; 183 184 p.family = AF_INET; 185 p.prefixlen = 32; 186 p.u.prefix4 = oi->address->u.prefix4; 187 188 rn = route_node_get (oi->nbrs, &p); 189 if (rn->info) 190 { 191 /* There is already pseudo neighbor. */ 192 nbr = rn->info; 193 route_unlock_node (rn); 194 } 195 else 196 rn->info = oi->nbr_self; 197} 198 199/* Get neighbor count by status. 200 Specify status = 0, get all neighbor other than myself. */ 201int 202ospf_nbr_count (struct route_table *nbrs, int state) 203{ 204 struct route_node *rn; 205 struct ospf_neighbor *nbr; 206 int count = 0; 207 208 /* Sanity check. */ 209 if (nbrs == NULL) 210 return 0; 211 212 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 213 if ((nbr = rn->info) != NULL) 214 /* Ignore myself. */ 215 if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id)) 216 if (state == 0 || nbr->state == state) 217 count++; 218 219 return count; 220} 221 222#ifdef HAVE_OPAQUE_LSA 223int 224ospf_opaque_capable_nbr_count (struct route_table *nbrs, int state) 225{ 226 struct route_node *rn; 227 struct ospf_neighbor *nbr; 228 int count = 0; 229 230 /* Sanity check. */ 231 if (nbrs == NULL) 232 return 0; 233 234 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 235 if ((nbr = rn->info) != NULL) 236 /* Ignore myself. */ 237 if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id)) 238 if ((state == 0 || nbr->state == state) 239 && CHECK_FLAG (nbr->options, OSPF_OPTION_O)) 240 count++; 241 242 return count; 243} 244#endif /* HAVE_OPAQUE_LSA */ 245 246struct ospf_neighbor * 247ospf_nbr_lookup_by_addr (struct route_table *nbrs, 248 struct in_addr *addr) 249{ 250 struct prefix p; 251 struct route_node *rn; 252 struct ospf_neighbor *nbr; 253 254 p.family = AF_INET; 255 p.prefixlen = IPV4_MAX_BITLEN; 256 p.u.prefix4 = *addr; 257 258 rn = route_node_lookup (nbrs, &p); 259 if (! rn) 260 return NULL; 261 262 if (rn->info == NULL) 263 { 264 route_unlock_node (rn); 265 return NULL; 266 } 267 268 nbr = (struct ospf_neighbor *) rn->info; 269 route_unlock_node (rn); 270 271 return nbr; 272} 273 274struct ospf_neighbor * 275ospf_nbr_lookup_by_routerid (struct route_table *nbrs, 276 struct in_addr *id) 277{ 278 struct route_node *rn; 279 struct ospf_neighbor *nbr; 280 281 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 282 if ((nbr = rn->info) != NULL) 283 if (IPV4_ADDR_SAME (&nbr->router_id, id)) 284 { 285 route_unlock_node(rn); 286 return nbr; 287 } 288 289 return NULL; 290} 291 292void 293ospf_renegotiate_optional_capabilities (struct ospf *top) 294{ 295 listnode node; 296 struct ospf_interface *oi; 297 struct route_table *nbrs; 298 struct route_node *rn; 299 struct ospf_neighbor *nbr; 300 301 /* At first, flush self-originated LSAs from routing domain. */ 302 ospf_flush_self_originated_lsas_now (top); 303 304 /* Revert all neighbor status to ExStart. */ 305 for (node = listhead (top->oiflist); node; nextnode (node)) 306 { 307 if ((oi = getdata (node)) == NULL || (nbrs = oi->nbrs) == NULL) 308 continue; 309 310 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 311 { 312 if ((nbr = rn->info) == NULL || nbr == oi->nbr_self) 313 continue; 314 315 if (nbr->state < NSM_ExStart) 316 continue; 317 318 if (IS_DEBUG_OSPF_EVENT) 319 zlog_info ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id)); 320 321 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); 322 } 323 } 324 325 return; 326} 327