ospf_interface.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279
  1. /*
  2. * OSPF Interface 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. #include <zebra.h>
  23. #include "thread.h"
  24. #include "linklist.h"
  25. #include "prefix.h"
  26. #include "if.h"
  27. #include "table.h"
  28. #include "memory.h"
  29. #include "command.h"
  30. #include "stream.h"
  31. #include "log.h"
  32. #include "ospfd/ospfd.h"
  33. #include "ospfd/ospf_spf.h"
  34. #include "ospfd/ospf_interface.h"
  35. #include "ospfd/ospf_ism.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_abr.h"
  43. #include "ospfd/ospf_network.h"
  44. #include "ospfd/ospf_dump.h"
  45. #ifdef HAVE_SNMP
  46. #include "ospfd/ospf_snmp.h"
  47. #endif /* HAVE_SNMP */
  48. int
  49. ospf_if_get_output_cost (struct ospf_interface *oi)
  50. {
  51. /* If all else fails, use default OSPF cost */
  52. u_int32_t cost;
  53. u_int32_t bw, refbw;
  54. bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
  55. refbw = oi->ospf->ref_bandwidth;
  56. /* A specifed ip ospf cost overrides a calculated one. */
  57. if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
  58. OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd))
  59. cost = OSPF_IF_PARAM (oi, output_cost_cmd);
  60. /* See if a cost can be calculated from the zebra processes
  61. interface bandwidth field. */
  62. else
  63. {
  64. cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
  65. if (cost < 1)
  66. cost = 1;
  67. else if (cost > 65535)
  68. cost = 65535;
  69. }
  70. return cost;
  71. }
  72. void
  73. ospf_if_recalculate_output_cost (struct interface *ifp)
  74. {
  75. u_int32_t newcost;
  76. struct route_node *rn;
  77. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  78. {
  79. struct ospf_interface *oi;
  80. if ( (oi = rn->info) == NULL)
  81. continue;
  82. newcost = ospf_if_get_output_cost (oi);
  83. /* Is actual output cost changed? */
  84. if (oi->output_cost != newcost)
  85. {
  86. oi->output_cost = newcost;
  87. ospf_router_lsa_update_area (oi->area);
  88. }
  89. }
  90. }
  91. /* Simulate down/up on the interface. This is needed, for example, when
  92. the MTU changes. */
  93. void
  94. ospf_if_reset(struct interface *ifp)
  95. {
  96. struct route_node *rn;
  97. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  98. {
  99. struct ospf_interface *oi;
  100. if ( (oi = rn->info) == NULL)
  101. continue;
  102. ospf_if_down(oi);
  103. ospf_if_up(oi);
  104. }
  105. }
  106. void
  107. ospf_if_reset_variables (struct ospf_interface *oi)
  108. {
  109. /* Set default values. */
  110. /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */
  111. if (oi->vl_data)
  112. oi->type = OSPF_IFTYPE_VIRTUALLINK;
  113. else
  114. /* preserve network-type */
  115. if (oi->type != OSPF_IFTYPE_NBMA)
  116. oi->type = OSPF_IFTYPE_BROADCAST;
  117. oi->state = ISM_Down;
  118. oi->crypt_seqnum = 0;
  119. /* This must be short, (less than RxmtInterval)
  120. - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being
  121. held back for too long - MAG */
  122. oi->v_ls_ack = 1;
  123. }
  124. void
  125. ospf_if_reset_type (struct interface *ifp, u_char type)
  126. {
  127. struct route_node *rn;
  128. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  129. {
  130. struct ospf_interface *oi = rn->info;
  131. u_char orig_ism_state;
  132. if (!oi)
  133. continue;
  134. orig_ism_state = oi->state;
  135. OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  136. oi->type = IF_DEF_PARAMS (ifp)->type;
  137. if (orig_ism_state > ISM_Down)
  138. OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp);
  139. }
  140. }
  141. /* lookup oi for specified prefix/ifp */
  142. struct ospf_interface *
  143. ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix)
  144. {
  145. struct prefix p;
  146. struct route_node *rn;
  147. struct ospf_interface *rninfo = NULL;
  148. p = *prefix;
  149. p.prefixlen = IPV4_MAX_PREFIXLEN;
  150. /* route_node_get implicitely locks */
  151. if ((rn = route_node_lookup (IF_OIFS (ifp), &p)))
  152. {
  153. rninfo = (struct ospf_interface *) rn->info;
  154. route_unlock_node (rn);
  155. }
  156. return rninfo;
  157. }
  158. static void
  159. ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi)
  160. {
  161. struct route_node *rn;
  162. struct prefix p;
  163. p = *oi->address;
  164. p.prefixlen = IPV4_MAX_PREFIXLEN;
  165. rn = route_node_get (IF_OIFS (ifp), &p);
  166. /* rn->info should either be NULL or equal to this oi
  167. * as route_node_get may return an existing node
  168. */
  169. assert (!rn->info || rn->info == oi);
  170. rn->info = oi;
  171. }
  172. static void
  173. ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi)
  174. {
  175. struct route_node *rn;
  176. struct prefix p;
  177. p = *oi->address;
  178. p.prefixlen = IPV4_MAX_PREFIXLEN;
  179. rn = route_node_lookup (IF_OIFS (oi->ifp), &p);
  180. assert (rn);
  181. assert (rn->info);
  182. rn->info = NULL;
  183. route_unlock_node (rn);
  184. route_unlock_node (rn);
  185. }
  186. struct ospf_interface *
  187. ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
  188. {
  189. struct ospf_interface *oi;
  190. if ((oi = ospf_if_table_lookup (ifp, p)) == NULL)
  191. {
  192. oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
  193. memset (oi, 0, sizeof (struct ospf_interface));
  194. }
  195. else
  196. return oi;
  197. /* Set zebra interface pointer. */
  198. oi->ifp = ifp;
  199. oi->address = p;
  200. ospf_add_to_if (ifp, oi);
  201. listnode_add (ospf->oiflist, oi);
  202. /* Initialize neighbor list. */
  203. oi->nbrs = route_table_init ();
  204. /* Initialize static neighbor list. */
  205. oi->nbr_nbma = list_new ();
  206. /* Initialize Link State Acknowledgment list. */
  207. oi->ls_ack = list_new ();
  208. oi->ls_ack_direct.ls_ack = list_new ();
  209. /* Set default values. */
  210. ospf_if_reset_variables (oi);
  211. /* Set pseudo neighbor to Null */
  212. oi->nbr_self = NULL;
  213. oi->ls_upd_queue = route_table_init ();
  214. oi->t_ls_upd_event = NULL;
  215. oi->t_ls_ack_direct = NULL;
  216. oi->crypt_seqnum = time (NULL);
  217. ospf_opaque_type9_lsa_init (oi);
  218. oi->ospf = ospf;
  219. return oi;
  220. }
  221. /* Restore an interface to its pre UP state
  222. Used from ism_interface_down only */
  223. void
  224. ospf_if_cleanup (struct ospf_interface *oi)
  225. {
  226. struct route_node *rn;
  227. struct listnode *node, *nnode;
  228. struct ospf_neighbor *nbr;
  229. struct ospf_nbr_nbma *nbr_nbma;
  230. struct ospf_lsa *lsa;
  231. /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
  232. /* delete all static neighbors attached to this interface */
  233. for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma))
  234. {
  235. OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
  236. if (nbr_nbma->nbr)
  237. {
  238. nbr_nbma->nbr->nbr_nbma = NULL;
  239. nbr_nbma->nbr = NULL;
  240. }
  241. nbr_nbma->oi = NULL;
  242. listnode_delete (oi->nbr_nbma, nbr_nbma);
  243. }
  244. /* send Neighbor event KillNbr to all associated neighbors. */
  245. for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  246. if ((nbr = rn->info) != NULL)
  247. if (nbr != oi->nbr_self)
  248. OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);
  249. /* Cleanup Link State Acknowlegdment list. */
  250. for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa))
  251. ospf_lsa_unlock (&lsa); /* oi->ls_ack */
  252. list_delete_all_node (oi->ls_ack);
  253. oi->crypt_seqnum = 0;
  254. /* Empty link state update queue */
  255. ospf_ls_upd_queue_empty (oi);
  256. /* Reset pseudo neighbor. */
  257. ospf_nbr_self_reset (oi);
  258. }
  259. void
  260. ospf_if_free (struct ospf_interface *oi)
  261. {
  262. ospf_if_down (oi);
  263. assert (oi->state == ISM_Down);
  264. ospf_opaque_type9_lsa_term (oi);
  265. /* Free Pseudo Neighbour */
  266. ospf_nbr_delete (oi->nbr_self);
  267. route_table_finish (oi->nbrs);
  268. route_table_finish (oi->ls_upd_queue);
  269. /* Free any lists that should be freed */
  270. list_free (oi->nbr_nbma);
  271. list_free (oi->ls_ack);
  272. list_free (oi->ls_ack_direct.ls_ack);
  273. ospf_delete_from_if (oi->ifp, oi);
  274. listnode_delete (oi->ospf->oiflist, oi);
  275. listnode_delete (oi->area->oiflist, oi);
  276. thread_cancel_event (master, oi);
  277. memset (oi, 0, sizeof (*oi));
  278. XFREE (MTYPE_OSPF_IF, oi);
  279. }
  280. /*
  281. * check if interface with given address is configured and
  282. * return it if yes. special treatment for PtP networks.
  283. */
  284. struct ospf_interface *
  285. ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
  286. {
  287. struct listnode *node, *nnode;
  288. struct ospf_interface *oi;
  289. struct prefix_ipv4 addr;
  290. addr.family = AF_INET;
  291. addr.prefix = *address;
  292. addr.prefixlen = IPV4_MAX_PREFIXLEN;
  293. for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
  294. if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  295. {
  296. if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  297. {
  298. /* special leniency: match if addr is anywhere on peer subnet */
  299. if (prefix_match(CONNECTED_PREFIX(oi->connected),
  300. (struct prefix *)&addr))
  301. return oi;
  302. }
  303. else
  304. {
  305. if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
  306. return oi;
  307. }
  308. }
  309. return NULL;
  310. }
  311. int
  312. ospf_if_is_up (struct ospf_interface *oi)
  313. {
  314. return if_is_up (oi->ifp);
  315. }
  316. struct ospf_interface *
  317. ospf_if_exists (struct ospf_interface *oic)
  318. {
  319. struct listnode *node;
  320. struct ospf *ospf;
  321. struct ospf_interface *oi;
  322. if ((ospf = ospf_lookup ()) == NULL)
  323. return NULL;
  324. for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  325. if (oi == oic)
  326. return oi;
  327. return NULL;
  328. }
  329. /* Lookup OSPF interface by router LSA posistion */
  330. struct ospf_interface *
  331. ospf_if_lookup_by_lsa_pos (struct ospf_area *area, int lsa_pos)
  332. {
  333. struct listnode *node;
  334. struct ospf_interface *oi;
  335. for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
  336. {
  337. if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end)
  338. return oi;
  339. }
  340. return NULL;
  341. }
  342. struct ospf_interface *
  343. ospf_if_lookup_by_local_addr (struct ospf *ospf,
  344. struct interface *ifp, struct in_addr address)
  345. {
  346. struct listnode *node;
  347. struct ospf_interface *oi;
  348. for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  349. if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  350. {
  351. if (ifp && oi->ifp != ifp)
  352. continue;
  353. if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
  354. return oi;
  355. }
  356. return NULL;
  357. }
  358. struct ospf_interface *
  359. ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
  360. {
  361. struct listnode *node;
  362. struct ospf_interface *oi;
  363. /* Check each Interface. */
  364. for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  365. {
  366. if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  367. {
  368. struct prefix ptmp;
  369. prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected));
  370. apply_mask (&ptmp);
  371. if (prefix_same (&ptmp, (struct prefix *) p))
  372. return oi;
  373. }
  374. }
  375. return NULL;
  376. }
  377. /* determine receiving interface by ifp and source address */
  378. struct ospf_interface *
  379. ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
  380. struct interface *ifp)
  381. {
  382. struct route_node *rn;
  383. struct prefix_ipv4 addr;
  384. struct ospf_interface *oi, *match;
  385. addr.family = AF_INET;
  386. addr.prefix = src;
  387. addr.prefixlen = IPV4_MAX_BITLEN;
  388. match = NULL;
  389. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  390. {
  391. oi = rn->info;
  392. if (!oi) /* oi can be NULL for PtP aliases */
  393. continue;
  394. if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
  395. continue;
  396. if (if_is_loopback (oi->ifp))
  397. continue;
  398. if (prefix_match (CONNECTED_PREFIX(oi->connected),
  399. (struct prefix *) &addr))
  400. {
  401. if ( (match == NULL) ||
  402. (match->address->prefixlen < oi->address->prefixlen)
  403. )
  404. match = oi;
  405. }
  406. }
  407. return match;
  408. }
  409. void
  410. ospf_if_stream_set (struct ospf_interface *oi)
  411. {
  412. /* set output fifo queue. */
  413. if (oi->obuf == NULL)
  414. oi->obuf = ospf_fifo_new ();
  415. }
  416. void
  417. ospf_if_stream_unset (struct ospf_interface *oi)
  418. {
  419. struct ospf *ospf = oi->ospf;
  420. if (oi->obuf)
  421. {
  422. ospf_fifo_free (oi->obuf);
  423. oi->obuf = NULL;
  424. if (oi->on_write_q)
  425. {
  426. listnode_delete (ospf->oi_write_q, oi);
  427. if (list_isempty(ospf->oi_write_q))
  428. OSPF_TIMER_OFF (ospf->t_write);
  429. oi->on_write_q = 0;
  430. }
  431. }
  432. }
  433. static struct ospf_if_params *
  434. ospf_new_if_params (void)
  435. {
  436. struct ospf_if_params *oip;
  437. oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
  438. if (!oip)
  439. return NULL;
  440. UNSET_IF_PARAM (oip, output_cost_cmd);
  441. UNSET_IF_PARAM (oip, transmit_delay);
  442. UNSET_IF_PARAM (oip, retransmit_interval);
  443. UNSET_IF_PARAM (oip, passive_interface);
  444. UNSET_IF_PARAM (oip, v_hello);
  445. UNSET_IF_PARAM (oip, fast_hello);
  446. UNSET_IF_PARAM (oip, v_wait);
  447. UNSET_IF_PARAM (oip, priority);
  448. UNSET_IF_PARAM (oip, type);
  449. UNSET_IF_PARAM (oip, auth_simple);
  450. UNSET_IF_PARAM (oip, auth_crypt);
  451. UNSET_IF_PARAM (oip, auth_type);
  452. oip->auth_crypt = list_new ();
  453. oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
  454. return oip;
  455. }
  456. void
  457. ospf_del_if_params (struct ospf_if_params *oip)
  458. {
  459. list_delete (oip->auth_crypt);
  460. XFREE (MTYPE_OSPF_IF_PARAMS, oip);
  461. }
  462. void
  463. ospf_free_if_params (struct interface *ifp, struct in_addr addr)
  464. {
  465. struct ospf_if_params *oip;
  466. struct prefix_ipv4 p;
  467. struct route_node *rn;
  468. p.family = AF_INET;
  469. p.prefixlen = IPV4_MAX_PREFIXLEN;
  470. p.prefix = addr;
  471. rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  472. if (!rn || !rn->info)
  473. return;
  474. oip = rn->info;
  475. route_unlock_node (rn);
  476. if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
  477. !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
  478. !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
  479. !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
  480. !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
  481. !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
  482. !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
  483. !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
  484. !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
  485. !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
  486. !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
  487. listcount (oip->auth_crypt) == 0 &&
  488. ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
  489. {
  490. ospf_del_if_params (oip);
  491. rn->info = NULL;
  492. route_unlock_node (rn);
  493. }
  494. }
  495. struct ospf_if_params *
  496. ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
  497. {
  498. struct prefix_ipv4 p;
  499. struct route_node *rn;
  500. p.family = AF_INET;
  501. p.prefixlen = IPV4_MAX_PREFIXLEN;
  502. p.prefix = addr;
  503. rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  504. if (rn)
  505. {
  506. route_unlock_node (rn);
  507. return rn->info;
  508. }
  509. return NULL;
  510. }
  511. struct ospf_if_params *
  512. ospf_get_if_params (struct interface *ifp, struct in_addr addr)
  513. {
  514. struct prefix_ipv4 p;
  515. struct route_node *rn;
  516. p.family = AF_INET;
  517. p.prefixlen = IPV4_MAX_PREFIXLEN;
  518. p.prefix = addr;
  519. rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  520. if (rn->info == NULL)
  521. rn->info = ospf_new_if_params ();
  522. else
  523. route_unlock_node (rn);
  524. return rn->info;
  525. }
  526. void
  527. ospf_if_update_params (struct interface *ifp, struct in_addr addr)
  528. {
  529. struct route_node *rn;
  530. struct ospf_interface *oi;
  531. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  532. {
  533. if ((oi = rn->info) == NULL)
  534. continue;
  535. if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
  536. oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
  537. }
  538. }
  539. int
  540. ospf_if_new_hook (struct interface *ifp)
  541. {
  542. int rc = 0;
  543. ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
  544. IF_OIFS (ifp) = route_table_init ();
  545. IF_OIFS_PARAMS (ifp) = route_table_init ();
  546. IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
  547. SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
  548. IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
  549. SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
  550. IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
  551. SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
  552. IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
  553. IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
  554. SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
  555. IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
  556. SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
  557. IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
  558. SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
  559. IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
  560. SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
  561. memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
  562. SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
  563. IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
  564. rc = ospf_opaque_new_if (ifp);
  565. return rc;
  566. }
  567. static int
  568. ospf_if_delete_hook (struct interface *ifp)
  569. {
  570. int rc = 0;
  571. struct route_node *rn;
  572. rc = ospf_opaque_del_if (ifp);
  573. route_table_finish (IF_OIFS (ifp));
  574. for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
  575. if (rn->info)
  576. ospf_del_if_params (rn->info);
  577. route_table_finish (IF_OIFS_PARAMS (ifp));
  578. ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
  579. XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
  580. ifp->info = NULL;
  581. return rc;
  582. }
  583. int
  584. ospf_if_is_enable (struct ospf_interface *oi)
  585. {
  586. if (!if_is_loopback (oi->ifp))
  587. if (if_is_up (oi->ifp))
  588. return 1;
  589. return 0;
  590. }
  591. void
  592. ospf_if_set_multicast(struct ospf_interface *oi)
  593. {
  594. if ((oi->state > ISM_Loopback) &&
  595. (oi->type != OSPF_IFTYPE_LOOPBACK) &&
  596. (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
  597. (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  598. {
  599. /* The interface should belong to the OSPF-all-routers group. */
  600. if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
  601. (ospf_if_add_allspfrouters(oi->ospf, oi->address,
  602. oi->ifp->ifindex) >= 0))
  603. /* Set the flag only if the system call to join succeeded. */
  604. OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
  605. }
  606. else
  607. {
  608. /* The interface should NOT belong to the OSPF-all-routers group. */
  609. if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
  610. {
  611. /* Only actually drop if this is the last reference */
  612. if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
  613. ospf_if_drop_allspfrouters (oi->ospf, oi->address,
  614. oi->ifp->ifindex);
  615. /* Unset the flag regardless of whether the system call to leave
  616. the group succeeded, since it's much safer to assume that
  617. we are not a member. */
  618. OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
  619. }
  620. }
  621. if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
  622. (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
  623. ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
  624. (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  625. {
  626. /* The interface should belong to the OSPF-designated-routers group. */
  627. if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
  628. (ospf_if_add_alldrouters(oi->ospf, oi->address,
  629. oi->ifp->ifindex) >= 0))
  630. /* Set the flag only if the system call to join succeeded. */
  631. OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
  632. }
  633. else
  634. {
  635. /* The interface should NOT belong to the OSPF-designated-routers group */
  636. if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
  637. {
  638. /* drop only if last reference */
  639. if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
  640. ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
  641. /* Unset the flag regardless of whether the system call to leave
  642. the group succeeded, since it's much safer to assume that
  643. we are not a member. */
  644. OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
  645. }
  646. }
  647. }
  648. int
  649. ospf_if_up (struct ospf_interface *oi)
  650. {
  651. if (oi == NULL)
  652. return 0;
  653. if (oi->type == OSPF_IFTYPE_LOOPBACK)
  654. OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
  655. else
  656. {
  657. struct ospf *ospf = ospf_lookup ();
  658. if (ospf != NULL)
  659. ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
  660. else
  661. zlog_warn ("%s: ospf_lookup() returned NULL", __func__);
  662. ospf_if_stream_set (oi);
  663. OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
  664. }
  665. return 1;
  666. }
  667. int
  668. ospf_if_down (struct ospf_interface *oi)
  669. {
  670. if (oi == NULL)
  671. return 0;
  672. OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  673. /* delete position in router LSA */
  674. oi->lsa_pos_beg = 0;
  675. oi->lsa_pos_end = 0;
  676. /* Shutdown packet reception and sending */
  677. ospf_if_stream_unset (oi);
  678. return 1;
  679. }
  680. /* Virtual Link related functions. */
  681. struct ospf_vl_data *
  682. ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
  683. {
  684. struct ospf_vl_data *vl_data;
  685. vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
  686. vl_data->vl_peer.s_addr = vl_peer.s_addr;
  687. vl_data->vl_area_id = area->area_id;
  688. vl_data->format = area->format;
  689. return vl_data;
  690. }
  691. void
  692. ospf_vl_data_free (struct ospf_vl_data *vl_data)
  693. {
  694. XFREE (MTYPE_OSPF_VL_DATA, vl_data);
  695. }
  696. u_int vlink_count = 0;
  697. struct ospf_interface *
  698. ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
  699. {
  700. struct ospf_interface * voi;
  701. struct interface * vi;
  702. char ifname[INTERFACE_NAMSIZ + 1];
  703. struct ospf_area *area;
  704. struct in_addr area_id;
  705. struct connected *co;
  706. struct prefix_ipv4 *p;
  707. if (IS_DEBUG_OSPF_EVENT)
  708. zlog_debug ("ospf_vl_new(): Start");
  709. if (vlink_count == OSPF_VL_MAX_COUNT)
  710. {
  711. if (IS_DEBUG_OSPF_EVENT)
  712. zlog_debug ("ospf_vl_new(): Alarm: "
  713. "cannot create more than OSPF_MAX_VL_COUNT virtual links");
  714. return NULL;
  715. }
  716. if (IS_DEBUG_OSPF_EVENT)
  717. zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
  718. snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
  719. vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
  720. /* Ensure that linkdetection is not enabled on the stub interfaces
  721. * created for OSPF virtual links. */
  722. UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
  723. co = connected_new ();
  724. co->ifp = vi;
  725. listnode_add (vi->connected, co);
  726. p = prefix_ipv4_new ();
  727. p->family = AF_INET;
  728. p->prefix.s_addr = 0;
  729. p->prefixlen = 0;
  730. co->address = (struct prefix *)p;
  731. voi = ospf_if_new (ospf, vi, co->address);
  732. if (voi == NULL)
  733. {
  734. if (IS_DEBUG_OSPF_EVENT)
  735. zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
  736. return NULL;
  737. }
  738. voi->connected = co;
  739. voi->vl_data = vl_data;
  740. voi->ifp->mtu = OSPF_VL_MTU;
  741. voi->type = OSPF_IFTYPE_VIRTUALLINK;
  742. vlink_count++;
  743. if (IS_DEBUG_OSPF_EVENT)
  744. zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
  745. if (IS_DEBUG_OSPF_EVENT)
  746. zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);
  747. area_id.s_addr = 0;
  748. area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  749. voi->area = area;
  750. if (IS_DEBUG_OSPF_EVENT)
  751. zlog_debug ("ospf_vl_new(): set associated area to the backbone");
  752. /* Add pseudo neighbor. */
  753. ospf_nbr_self_reset (voi);
  754. ospf_area_add_if (voi->area, voi);
  755. ospf_if_stream_set (voi);
  756. if (IS_DEBUG_OSPF_EVENT)
  757. zlog_debug ("ospf_vl_new(): Stop");
  758. return voi;
  759. }
  760. static void
  761. ospf_vl_if_delete (struct ospf_vl_data *vl_data)
  762. {
  763. struct interface *ifp = vl_data->vl_oi->ifp;
  764. vl_data->vl_oi->address->u.prefix4.s_addr = 0;
  765. vl_data->vl_oi->address->prefixlen = 0;
  766. ospf_if_free (vl_data->vl_oi);
  767. if_delete (ifp);
  768. vlink_count--;
  769. }
  770. /* Look up vl_data for given peer, optionally qualified to be in the
  771. * specified area. NULL area returns first found..
  772. */
  773. struct ospf_vl_data *
  774. ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
  775. struct in_addr vl_peer)
  776. {
  777. struct ospf_vl_data *vl_data;
  778. struct listnode *node;
  779. if (IS_DEBUG_OSPF_EVENT)
  780. {
  781. zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
  782. if (area)
  783. zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
  784. }
  785. for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
  786. {
  787. if (IS_DEBUG_OSPF_EVENT)
  788. zlog_debug ("%s: VL %s, peer %s", __func__,
  789. vl_data->vl_oi->ifp->name,
  790. inet_ntoa (vl_data->vl_peer));
  791. if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  792. continue;
  793. if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
  794. return vl_data;
  795. }
  796. return NULL;
  797. }
  798. static void
  799. ospf_vl_shutdown (struct ospf_vl_data *vl_data)
  800. {
  801. struct ospf_interface *oi;
  802. if ((oi = vl_data->vl_oi) == NULL)
  803. return;
  804. oi->address->u.prefix4.s_addr = 0;
  805. oi->address->prefixlen = 0;
  806. UNSET_FLAG (oi->ifp->flags, IFF_UP);
  807. /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
  808. OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  809. }
  810. void
  811. ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
  812. {
  813. listnode_add (ospf->vlinks, vl_data);
  814. #ifdef HAVE_SNMP
  815. ospf_snmp_vl_add (vl_data);
  816. #endif /* HAVE_SNMP */
  817. }
  818. void
  819. ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
  820. {
  821. ospf_vl_shutdown (vl_data);
  822. ospf_vl_if_delete (vl_data);
  823. #ifdef HAVE_SNMP
  824. ospf_snmp_vl_delete (vl_data);
  825. #endif /* HAVE_SNMP */
  826. listnode_delete (ospf->vlinks, vl_data);
  827. ospf_vl_data_free (vl_data);
  828. }
  829. static int
  830. ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
  831. {
  832. int changed = 0;
  833. struct ospf_interface *voi;
  834. struct listnode *node;
  835. struct vertex_parent *vp = NULL;
  836. unsigned int i;
  837. struct router_lsa *rl;
  838. voi = vl_data->vl_oi;
  839. if (voi->output_cost != v->distance)
  840. {
  841. voi->output_cost = v->distance;
  842. changed = 1;
  843. }
  844. for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
  845. {
  846. vl_data->nexthop.oi = vp->nexthop->oi;
  847. vl_data->nexthop.router = vp->nexthop->router;
  848. if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
  849. &vl_data->nexthop.oi->address->u.prefix4))
  850. changed = 1;
  851. voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
  852. voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;
  853. break; /* We take the first interface. */
  854. }
  855. rl = (struct router_lsa *)v->lsa;
  856. /* use SPF determined backlink index in struct vertex
  857. * for virtual link destination address
  858. */
  859. if (vp && vp->backlink >= 0)
  860. {
  861. if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
  862. &rl->link[vp->backlink].link_data))
  863. changed = 1;
  864. vl_data->peer_addr = rl->link[vp->backlink].link_data;
  865. }
  866. else
  867. {
  868. /* This is highly odd, there is no backlink index
  869. * there should be due to the ospf_spf_has_link() check
  870. * in SPF. Lets warn and try pick a link anyway.
  871. */
  872. zlog_warn ("ospf_vl_set_params: No backlink for %s!",
  873. vl_data->vl_oi->ifp->name);
  874. for (i = 0; i < ntohs (rl->links); i++)
  875. {
  876. switch (rl->link[i].type)
  877. {
  878. case LSA_LINK_TYPE_VIRTUALLINK:
  879. if (IS_DEBUG_OSPF_EVENT)
  880. zlog_debug ("found back link through VL");
  881. case LSA_LINK_TYPE_TRANSIT:
  882. case LSA_LINK_TYPE_POINTOPOINT:
  883. if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
  884. &rl->link[i].link_data))
  885. changed = 1;
  886. vl_data->peer_addr = rl->link[i].link_data;
  887. }
  888. }
  889. }
  890. if (IS_DEBUG_OSPF_EVENT)
  891. zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
  892. vl_data->vl_oi->ifp->name,
  893. inet_ntoa(vl_data->peer_addr),
  894. voi->output_cost,
  895. (changed ? " " : " un"));
  896. return changed;
  897. }
  898. void
  899. ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
  900. struct vertex *v)
  901. {
  902. struct ospf *ospf = area->ospf;
  903. struct listnode *node;
  904. struct ospf_vl_data *vl_data;
  905. struct ospf_interface *oi;
  906. if (IS_DEBUG_OSPF_EVENT)
  907. {
  908. zlog_debug ("ospf_vl_up_check(): Start");
  909. zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
  910. zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
  911. }
  912. for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
  913. {
  914. if (IS_DEBUG_OSPF_EVENT)
  915. {
  916. zlog_debug ("%s: considering VL, %s in area %s", __func__,
  917. vl_data->vl_oi->ifp->name,
  918. inet_ntoa (vl_data->vl_area_id));
  919. zlog_debug ("%s: peer ID: %s", __func__,
  920. inet_ntoa (vl_data->vl_peer));
  921. }
  922. if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
  923. IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  924. {
  925. oi = vl_data->vl_oi;
  926. SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
  927. if (IS_DEBUG_OSPF_EVENT)
  928. zlog_debug ("ospf_vl_up_check(): this VL matched");
  929. if (oi->state == ISM_Down)
  930. {
  931. if (IS_DEBUG_OSPF_EVENT)
  932. zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
  933. SET_FLAG (oi->ifp->flags, IFF_UP);
  934. OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
  935. }
  936. if (ospf_vl_set_params (vl_data, v))
  937. {
  938. if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
  939. zlog_debug ("ospf_vl_up_check: VL cost change,"
  940. " scheduling router lsa refresh");
  941. if (ospf->backbone)
  942. ospf_router_lsa_update_area (ospf->backbone);
  943. else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
  944. zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
  945. }
  946. }
  947. }
  948. }
  949. void
  950. ospf_vl_unapprove (struct ospf *ospf)
  951. {
  952. struct listnode *node;
  953. struct ospf_vl_data *vl_data;
  954. for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
  955. UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
  956. }
  957. void
  958. ospf_vl_shut_unapproved (struct ospf *ospf)
  959. {
  960. struct listnode *node, *nnode;
  961. struct ospf_vl_data *vl_data;
  962. for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
  963. if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
  964. ospf_vl_shutdown (vl_data);
  965. }
  966. int
  967. ospf_full_virtual_nbrs (struct ospf_area *area)
  968. {
  969. if (IS_DEBUG_OSPF_EVENT)
  970. {
  971. zlog_debug ("counting fully adjacent virtual neighbors in area %s",
  972. inet_ntoa (area->area_id));
  973. zlog_debug ("there are %d of them", area->full_vls);
  974. }
  975. return area->full_vls;
  976. }
  977. int
  978. ospf_vls_in_area (struct ospf_area *area)
  979. {
  980. struct listnode *node;
  981. struct ospf_vl_data *vl_data;
  982. int c = 0;
  983. for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
  984. if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  985. c++;
  986. return c;
  987. }
  988. struct crypt_key *
  989. ospf_crypt_key_new ()
  990. {
  991. return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
  992. }
  993. void
  994. ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
  995. {
  996. listnode_add (crypt, ck);
  997. }
  998. struct crypt_key *
  999. ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
  1000. {
  1001. struct listnode *node;
  1002. struct crypt_key *ck;
  1003. for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
  1004. if (ck->key_id == key_id)
  1005. return ck;
  1006. return NULL;
  1007. }
  1008. int
  1009. ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
  1010. {
  1011. struct listnode *node, *nnode;
  1012. struct crypt_key *ck;
  1013. for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
  1014. {
  1015. if (ck->key_id == key_id)
  1016. {
  1017. listnode_delete (auth_crypt, ck);
  1018. XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
  1019. return 1;
  1020. }
  1021. }
  1022. return 0;
  1023. }
  1024. u_char
  1025. ospf_default_iftype(struct interface *ifp)
  1026. {
  1027. if (if_is_pointopoint (ifp))
  1028. return OSPF_IFTYPE_POINTOPOINT;
  1029. else if (if_is_loopback (ifp))
  1030. return OSPF_IFTYPE_LOOPBACK;
  1031. else
  1032. return OSPF_IFTYPE_BROADCAST;
  1033. }
  1034. void
  1035. ospf_if_init ()
  1036. {
  1037. /* Initialize Zebra interface data structure. */
  1038. om->iflist = iflist;
  1039. if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
  1040. if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
  1041. }