if.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /*
  2. * Interface functions.
  3. * Copyright (C) 1997, 98 Kunihiro Ishiguro
  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 "linklist.h"
  24. #include "vector.h"
  25. #include "vty.h"
  26. #include "command.h"
  27. #include "if.h"
  28. #include "sockunion.h"
  29. #include "prefix.h"
  30. #include "memory.h"
  31. #include "table.h"
  32. #include "buffer.h"
  33. #include "str.h"
  34. #include "log.h"
  35. /* Master list of interfaces. */
  36. struct list *iflist;
  37. /* One for each program. This structure is needed to store hooks. */
  38. struct if_master
  39. {
  40. int (*if_new_hook) (struct interface *);
  41. int (*if_delete_hook) (struct interface *);
  42. } if_master;
  43. /* Compare interface names, returning an integer greater than, equal to, or
  44. * less than 0, (following the strcmp convention), according to the
  45. * relationship between ifp1 and ifp2. Interface names consist of an
  46. * alphabetic prefix and a numeric suffix. The primary sort key is
  47. * lexicographic by name, and then numeric by number. No number sorts
  48. * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
  49. * devpty0, de0 < del0
  50. */
  51. int
  52. if_cmp_func (struct interface *ifp1, struct interface *ifp2)
  53. {
  54. unsigned int l1, l2;
  55. long int x1, x2;
  56. char *p1, *p2;
  57. int res;
  58. p1 = ifp1->name;
  59. p2 = ifp2->name;
  60. while (*p1 && *p2) {
  61. /* look up to any number */
  62. l1 = strcspn(p1, "0123456789");
  63. l2 = strcspn(p2, "0123456789");
  64. /* name lengths are different -> compare names */
  65. if (l1 != l2)
  66. return (strcmp(p1, p2));
  67. /* Note that this relies on all numbers being less than all letters, so
  68. * that de0 < del0.
  69. */
  70. res = strncmp(p1, p2, l1);
  71. /* names are different -> compare them */
  72. if (res)
  73. return res;
  74. /* with identical name part, go to numeric part */
  75. p1 += l1;
  76. p2 += l1;
  77. if (!*p1)
  78. return -1;
  79. if (!*p2)
  80. return 1;
  81. x1 = strtol(p1, &p1, 10);
  82. x2 = strtol(p2, &p2, 10);
  83. /* let's compare numbers now */
  84. if (x1 < x2)
  85. return -1;
  86. if (x1 > x2)
  87. return 1;
  88. /* numbers were equal, lets do it again..
  89. (it happens with name like "eth123.456:789") */
  90. }
  91. if (*p1)
  92. return 1;
  93. if (*p2)
  94. return -1;
  95. return 0;
  96. }
  97. /* Create new interface structure. */
  98. struct interface *
  99. if_create (const char *name, int namelen)
  100. {
  101. struct interface *ifp;
  102. ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
  103. ifp->ifindex = IFINDEX_INTERNAL;
  104. assert (name);
  105. assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
  106. strncpy (ifp->name, name, namelen);
  107. ifp->name[namelen] = '\0';
  108. if (if_lookup_by_name(ifp->name) == NULL)
  109. listnode_add_sort (iflist, ifp);
  110. else
  111. zlog_err("if_create(%s): corruption detected -- interface with this "
  112. "name exists already!", ifp->name);
  113. ifp->connected = list_new ();
  114. ifp->connected->del = (void (*) (void *)) connected_free;
  115. if (if_master.if_new_hook)
  116. (*if_master.if_new_hook) (ifp);
  117. return ifp;
  118. }
  119. /* Delete interface structure. */
  120. void
  121. if_delete_retain (struct interface *ifp)
  122. {
  123. if (if_master.if_delete_hook)
  124. (*if_master.if_delete_hook) (ifp);
  125. /* Free connected address list */
  126. list_delete (ifp->connected);
  127. }
  128. /* Delete and free interface structure. */
  129. void
  130. if_delete (struct interface *ifp)
  131. {
  132. listnode_delete (iflist, ifp);
  133. if_delete_retain(ifp);
  134. XFREE (MTYPE_IF, ifp);
  135. }
  136. /* Add hook to interface master. */
  137. void
  138. if_add_hook (int type, int (*func)(struct interface *ifp))
  139. {
  140. switch (type) {
  141. case IF_NEW_HOOK:
  142. if_master.if_new_hook = func;
  143. break;
  144. case IF_DELETE_HOOK:
  145. if_master.if_delete_hook = func;
  146. break;
  147. default:
  148. break;
  149. }
  150. }
  151. /* Interface existance check by index. */
  152. struct interface *
  153. if_lookup_by_index (unsigned int index)
  154. {
  155. struct listnode *node;
  156. struct interface *ifp;
  157. for (node = listhead (iflist); node; nextnode (node))
  158. {
  159. ifp = getdata (node);
  160. if (ifp->ifindex == index)
  161. return ifp;
  162. }
  163. return NULL;
  164. }
  165. char *
  166. ifindex2ifname (unsigned int index)
  167. {
  168. struct interface *ifp;
  169. return ((ifp = if_lookup_by_index(index)) != NULL) ?
  170. ifp->name : (char *)"unknown";
  171. }
  172. unsigned int
  173. ifname2ifindex (const char *name)
  174. {
  175. struct interface *ifp;
  176. return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp->ifindex : 0;
  177. }
  178. /* Interface existance check by interface name. */
  179. struct interface *
  180. if_lookup_by_name (const char *name)
  181. {
  182. struct listnode *node;
  183. struct interface *ifp;
  184. for (node = listhead (iflist); node; nextnode (node))
  185. {
  186. ifp = getdata (node);
  187. if (strcmp(name, ifp->name) == 0)
  188. return ifp;
  189. }
  190. return NULL;
  191. }
  192. struct interface *
  193. if_lookup_by_name_len(const char *name, size_t namelen)
  194. {
  195. struct listnode *node;
  196. if (namelen > INTERFACE_NAMSIZ)
  197. return NULL;
  198. for (node = listhead (iflist); node; nextnode (node))
  199. {
  200. struct interface *ifp;
  201. ifp = getdata (node);
  202. if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
  203. return ifp;
  204. }
  205. return NULL;
  206. }
  207. /* Lookup interface by IPv4 address. */
  208. struct interface *
  209. if_lookup_exact_address (struct in_addr src)
  210. {
  211. struct listnode *node;
  212. struct listnode *cnode;
  213. struct interface *ifp;
  214. struct prefix *p;
  215. struct connected *c;
  216. for (node = listhead (iflist); node; nextnode (node))
  217. {
  218. ifp = getdata (node);
  219. for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  220. {
  221. c = getdata (cnode);
  222. p = c->address;
  223. if (p && p->family == AF_INET)
  224. {
  225. if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
  226. return ifp;
  227. }
  228. }
  229. }
  230. return NULL;
  231. }
  232. /* Lookup interface by IPv4 address. */
  233. struct interface *
  234. if_lookup_address (struct in_addr src)
  235. {
  236. struct listnode *node;
  237. struct prefix addr;
  238. int bestlen = 0;
  239. struct listnode *cnode;
  240. struct interface *ifp;
  241. struct prefix *p;
  242. struct connected *c;
  243. struct interface *match;
  244. addr.family = AF_INET;
  245. addr.u.prefix4 = src;
  246. addr.prefixlen = IPV4_MAX_BITLEN;
  247. match = NULL;
  248. for (node = listhead (iflist); node; nextnode (node))
  249. {
  250. ifp = getdata (node);
  251. for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  252. {
  253. c = getdata (cnode);
  254. if (c->address && (c->address->family == AF_INET))
  255. {
  256. if (CONNECTED_POINTOPOINT_HOST(c))
  257. {
  258. /* PTP links are conventionally identified
  259. by the address of the far end - MAG */
  260. if (IPV4_ADDR_SAME (&c->destination->u.prefix4, &src))
  261. return ifp;
  262. }
  263. else
  264. {
  265. p = c->address;
  266. if (prefix_match (p, &addr) && p->prefixlen > bestlen)
  267. {
  268. bestlen = p->prefixlen;
  269. match = ifp;
  270. }
  271. }
  272. }
  273. }
  274. }
  275. return match;
  276. }
  277. /* Get interface by name if given name interface doesn't exist create
  278. one. */
  279. struct interface *
  280. if_get_by_name (const char *name)
  281. {
  282. struct interface *ifp;
  283. return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp :
  284. if_create(name, strlen(name));
  285. }
  286. struct interface *
  287. if_get_by_name_len(const char *name, size_t namelen)
  288. {
  289. struct interface *ifp;
  290. return ((ifp = if_lookup_by_name_len(name, namelen)) != NULL) ? ifp :
  291. if_create(name, namelen);
  292. }
  293. /* Does interface up ? */
  294. int
  295. if_is_up (struct interface *ifp)
  296. {
  297. return ifp->flags & IFF_UP;
  298. }
  299. /* Is interface running? */
  300. int
  301. if_is_running (struct interface *ifp)
  302. {
  303. return ifp->flags & IFF_RUNNING;
  304. }
  305. /* Is the interface operative, eg. either UP & RUNNING
  306. or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
  307. int
  308. if_is_operative (struct interface *ifp)
  309. {
  310. return ((ifp->flags & IFF_UP) &&
  311. (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
  312. }
  313. /* Is this loopback interface ? */
  314. int
  315. if_is_loopback (struct interface *ifp)
  316. {
  317. /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
  318. * but Y on platform N?
  319. */
  320. return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
  321. }
  322. /* Does this interface support broadcast ? */
  323. int
  324. if_is_broadcast (struct interface *ifp)
  325. {
  326. return ifp->flags & IFF_BROADCAST;
  327. }
  328. /* Does this interface support broadcast ? */
  329. int
  330. if_is_pointopoint (struct interface *ifp)
  331. {
  332. return ifp->flags & IFF_POINTOPOINT;
  333. }
  334. /* Does this interface support multicast ? */
  335. int
  336. if_is_multicast (struct interface *ifp)
  337. {
  338. return ifp->flags & IFF_MULTICAST;
  339. }
  340. /* Printout flag information into log */
  341. const char *
  342. if_flag_dump (unsigned long flag)
  343. {
  344. int separator = 0;
  345. static char logbuf[BUFSIZ];
  346. #define IFF_OUT_LOG(X,STR) \
  347. if (flag & (X)) \
  348. { \
  349. if (separator) \
  350. strlcat (logbuf, ",", BUFSIZ); \
  351. else \
  352. separator = 1; \
  353. strlcat (logbuf, STR, BUFSIZ); \
  354. }
  355. strlcpy (logbuf, " <", BUFSIZ);
  356. IFF_OUT_LOG (IFF_UP, "UP");
  357. IFF_OUT_LOG (IFF_BROADCAST, "BROADCAST");
  358. IFF_OUT_LOG (IFF_DEBUG, "DEBUG");
  359. IFF_OUT_LOG (IFF_LOOPBACK, "LOOPBACK");
  360. IFF_OUT_LOG (IFF_POINTOPOINT, "POINTOPOINT");
  361. IFF_OUT_LOG (IFF_NOTRAILERS, "NOTRAILERS");
  362. IFF_OUT_LOG (IFF_RUNNING, "RUNNING");
  363. IFF_OUT_LOG (IFF_NOARP, "NOARP");
  364. IFF_OUT_LOG (IFF_PROMISC, "PROMISC");
  365. IFF_OUT_LOG (IFF_ALLMULTI, "ALLMULTI");
  366. IFF_OUT_LOG (IFF_OACTIVE, "OACTIVE");
  367. IFF_OUT_LOG (IFF_SIMPLEX, "SIMPLEX");
  368. IFF_OUT_LOG (IFF_LINK0, "LINK0");
  369. IFF_OUT_LOG (IFF_LINK1, "LINK1");
  370. IFF_OUT_LOG (IFF_LINK2, "LINK2");
  371. IFF_OUT_LOG (IFF_MULTICAST, "MULTICAST");
  372. IFF_OUT_LOG (IFF_NOXMIT, "NOXMIT");
  373. IFF_OUT_LOG (IFF_NORTEXCH, "NORTEXCH");
  374. IFF_OUT_LOG (IFF_VIRTUAL, "VIRTUAL");
  375. IFF_OUT_LOG (IFF_IPV4, "IPv4");
  376. IFF_OUT_LOG (IFF_IPV6, "IPv6");
  377. strlcat (logbuf, ">", BUFSIZ);
  378. return logbuf;
  379. }
  380. /* For debugging */
  381. void
  382. if_dump (struct interface *ifp)
  383. {
  384. struct listnode *node;
  385. zlog_info ("Interface %s index %d metric %d mtu %d "
  386. #ifdef HAVE_IPV6
  387. "mtu6 %d "
  388. #endif /* HAVE_IPV6 */
  389. "%s",
  390. ifp->name, ifp->ifindex, ifp->metric, ifp->mtu,
  391. #ifdef HAVE_IPV6
  392. ifp->mtu6,
  393. #endif /* HAVE_IPV6 */
  394. if_flag_dump (ifp->flags));
  395. for (node = listhead (ifp->connected); node; nextnode (node))
  396. ;
  397. }
  398. /* Interface printing for all interface. */
  399. void
  400. if_dump_all ()
  401. {
  402. struct listnode *node;
  403. for (node = listhead (iflist); node; nextnode (node))
  404. if_dump (getdata (node));
  405. }
  406. DEFUN (interface_desc,
  407. interface_desc_cmd,
  408. "description .LINE",
  409. "Interface specific description\n"
  410. "Characters describing this interface\n")
  411. {
  412. struct interface *ifp;
  413. if (argc == 0)
  414. return CMD_SUCCESS;
  415. ifp = vty->index;
  416. if (ifp->desc)
  417. XFREE (MTYPE_TMP, ifp->desc);
  418. ifp->desc = argv_concat(argv, argc, 0);
  419. return CMD_SUCCESS;
  420. }
  421. DEFUN (no_interface_desc,
  422. no_interface_desc_cmd,
  423. "no description",
  424. NO_STR
  425. "Interface specific description\n")
  426. {
  427. struct interface *ifp;
  428. ifp = vty->index;
  429. if (ifp->desc)
  430. XFREE (0, ifp->desc);
  431. ifp->desc = NULL;
  432. return CMD_SUCCESS;
  433. }
  434. /* See also wrapper function zebra_interface() in zebra/interface.c */
  435. DEFUN (interface,
  436. interface_cmd,
  437. "interface IFNAME",
  438. "Select an interface to configure\n"
  439. "Interface's name\n")
  440. {
  441. struct interface *ifp;
  442. size_t sl;
  443. if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
  444. {
  445. vty_out (vty, "%% Interface name %s is invalid: length exceeds "
  446. "%d characters%s",
  447. argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
  448. return CMD_WARNING;
  449. }
  450. ifp = if_get_by_name_len(argv[0], sl);
  451. vty->index = ifp;
  452. vty->node = INTERFACE_NODE;
  453. return CMD_SUCCESS;
  454. }
  455. DEFUN_NOSH (no_interface,
  456. no_interface_cmd,
  457. "no interface IFNAME",
  458. NO_STR
  459. "Delete a pseudo interface's configuration\n"
  460. "Interface's name\n")
  461. {
  462. // deleting interface
  463. struct interface *ifp;
  464. ifp = if_lookup_by_name (argv[0]);
  465. if (ifp == NULL)
  466. {
  467. vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
  468. return CMD_WARNING;
  469. }
  470. if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  471. {
  472. vty_out (vty, "%% Only inactive interfaces can be deleted%s",
  473. VTY_NEWLINE);
  474. return CMD_WARNING;
  475. }
  476. if_delete(ifp);
  477. return CMD_SUCCESS;
  478. }
  479. /* For debug purpose. */
  480. DEFUN (show_address,
  481. show_address_cmd,
  482. "show address",
  483. SHOW_STR
  484. "address\n")
  485. {
  486. struct listnode *node;
  487. struct listnode *node2;
  488. struct interface *ifp;
  489. struct connected *ifc;
  490. struct prefix *p;
  491. for (node = listhead (iflist); node; nextnode (node))
  492. {
  493. ifp = getdata (node);
  494. for (node2 = listhead (ifp->connected); node2; nextnode (node2))
  495. {
  496. ifc = getdata (node2);
  497. p = ifc->address;
  498. if (p->family == AF_INET)
  499. vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
  500. VTY_NEWLINE);
  501. }
  502. }
  503. return CMD_SUCCESS;
  504. }
  505. /* Allocate connected structure. */
  506. struct connected *
  507. connected_new ()
  508. {
  509. struct connected *new = XMALLOC (MTYPE_CONNECTED, sizeof (struct connected));
  510. memset (new, 0, sizeof (struct connected));
  511. return new;
  512. }
  513. /* Free connected structure. */
  514. void
  515. connected_free (struct connected *connected)
  516. {
  517. if (connected->address)
  518. prefix_free (connected->address);
  519. if (connected->destination)
  520. prefix_free (connected->destination);
  521. if (connected->label)
  522. free (connected->label);
  523. XFREE (MTYPE_CONNECTED, connected);
  524. }
  525. /* Print if_addr structure. */
  526. void
  527. connected_log (struct connected *connected, char *str)
  528. {
  529. struct prefix *p;
  530. struct interface *ifp;
  531. char logbuf[BUFSIZ];
  532. char buf[BUFSIZ];
  533. ifp = connected->ifp;
  534. p = connected->address;
  535. snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ",
  536. str, ifp->name, prefix_family_str (p),
  537. inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  538. p->prefixlen);
  539. p = connected->destination;
  540. if (p)
  541. {
  542. strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  543. BUFSIZ - strlen(logbuf));
  544. }
  545. zlog (NULL, LOG_INFO, logbuf);
  546. }
  547. /* If two connected address has same prefix return 1. */
  548. int
  549. connected_same_prefix (struct prefix *p1, struct prefix *p2)
  550. {
  551. if (p1->family == p2->family)
  552. {
  553. if (p1->family == AF_INET &&
  554. IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
  555. return 1;
  556. #ifdef HAVE_IPV6
  557. if (p1->family == AF_INET6 &&
  558. IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
  559. return 1;
  560. #endif /* HAVE_IPV6 */
  561. }
  562. return 0;
  563. }
  564. struct connected *
  565. connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
  566. {
  567. struct listnode *node;
  568. struct listnode *next;
  569. struct connected *ifc;
  570. /* In case of same prefix come, replace it with new one. */
  571. for (node = listhead (ifp->connected); node; node = next)
  572. {
  573. ifc = getdata (node);
  574. next = node->next;
  575. if (connected_same_prefix (ifc->address, p))
  576. {
  577. listnode_delete (ifp->connected, ifc);
  578. return ifc;
  579. }
  580. }
  581. return NULL;
  582. }
  583. /* Find the IPv4 address on our side that will be used when packets
  584. are sent to dst. */
  585. struct connected *
  586. connected_lookup_address (struct interface *ifp, struct in_addr dst)
  587. {
  588. struct prefix addr;
  589. struct listnode *cnode;
  590. struct prefix *p;
  591. struct connected *c;
  592. struct connected *match;
  593. addr.family = AF_INET;
  594. addr.u.prefix4 = dst;
  595. addr.prefixlen = IPV4_MAX_BITLEN;
  596. match = NULL;
  597. for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  598. {
  599. c = getdata (cnode);
  600. if (c->address && (c->address->family == AF_INET))
  601. {
  602. if (CONNECTED_POINTOPOINT_HOST(c))
  603. {
  604. /* PTP links are conventionally identified
  605. by the address of the far end - MAG */
  606. if (IPV4_ADDR_SAME (&c->destination->u.prefix4, &dst))
  607. return c;
  608. }
  609. else
  610. {
  611. p = c->address;
  612. if (prefix_match (p, &addr) &&
  613. (!match || (p->prefixlen > match->address->prefixlen)))
  614. match = c;
  615. }
  616. }
  617. }
  618. return match;
  619. }
  620. struct connected *
  621. connected_add_by_prefix (struct interface *ifp, struct prefix *p,
  622. struct prefix *destination)
  623. {
  624. struct connected *ifc;
  625. /* Allocate new connected address. */
  626. ifc = connected_new ();
  627. ifc->ifp = ifp;
  628. /* Fetch interface address */
  629. ifc->address = prefix_new();
  630. memcpy (ifc->address, p, sizeof(struct prefix));
  631. /* Fetch dest address */
  632. if (destination)
  633. {
  634. ifc->destination = prefix_new();
  635. memcpy (ifc->destination, destination, sizeof(struct prefix));
  636. }
  637. /* Add connected address to the interface. */
  638. listnode_add (ifp->connected, ifc);
  639. return ifc;
  640. }
  641. #ifndef HAVE_IF_NAMETOINDEX
  642. unsigned int
  643. if_nametoindex (const char *name)
  644. {
  645. struct interface *ifp;
  646. return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
  647. ? ifp->ifindex : 0;
  648. }
  649. #endif
  650. #ifndef HAVE_IF_INDEXTONAME
  651. char *
  652. if_indextoname (unsigned int ifindex, char *name)
  653. {
  654. struct interface *ifp;
  655. if (!(ifp = if_lookup_by_index(ifindex)))
  656. return NULL;
  657. strncpy (name, ifp->name, IFNAMSIZ);
  658. return ifp->name;
  659. }
  660. #endif
  661. /* Interface looking up by interface's address. */
  662. /* Interface's IPv4 address reverse lookup table. */
  663. struct route_table *ifaddr_ipv4_table;
  664. /* struct route_table *ifaddr_ipv6_table; */
  665. void
  666. ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
  667. {
  668. struct route_node *rn;
  669. struct prefix_ipv4 p;
  670. p.family = AF_INET;
  671. p.prefixlen = IPV4_MAX_PREFIXLEN;
  672. p.prefix = *ifaddr;
  673. rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
  674. if (rn)
  675. {
  676. route_unlock_node (rn);
  677. zlog_info ("ifaddr_ipv4_add(): address %s is already added",
  678. inet_ntoa (*ifaddr));
  679. return;
  680. }
  681. rn->info = ifp;
  682. }
  683. void
  684. ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
  685. {
  686. struct route_node *rn;
  687. struct prefix_ipv4 p;
  688. p.family = AF_INET;
  689. p.prefixlen = IPV4_MAX_PREFIXLEN;
  690. p.prefix = *ifaddr;
  691. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  692. if (! rn)
  693. {
  694. zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
  695. inet_ntoa (*ifaddr));
  696. return;
  697. }
  698. rn->info = NULL;
  699. route_unlock_node (rn);
  700. route_unlock_node (rn);
  701. }
  702. /* Lookup interface by interface's IP address or interface index. */
  703. struct interface *
  704. ifaddr_ipv4_lookup (struct in_addr *addr, unsigned int ifindex)
  705. {
  706. struct prefix_ipv4 p;
  707. struct route_node *rn;
  708. struct interface *ifp;
  709. struct listnode *node;
  710. if (addr)
  711. {
  712. p.family = AF_INET;
  713. p.prefixlen = IPV4_MAX_PREFIXLEN;
  714. p.prefix = *addr;
  715. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  716. if (! rn)
  717. return NULL;
  718. ifp = rn->info;
  719. route_unlock_node (rn);
  720. return ifp;
  721. }
  722. else
  723. return if_lookup_by_index(ifindex);
  724. }
  725. /* Initialize interface list. */
  726. void
  727. if_init ()
  728. {
  729. iflist = list_new ();
  730. ifaddr_ipv4_table = route_table_init ();
  731. if (iflist) {
  732. iflist->cmp = (int (*)(void *, void *))if_cmp_func;
  733. return;
  734. }
  735. memset (&if_master, 0, sizeof if_master);
  736. }