if.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  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 (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
  158. {
  159. if (ifp->ifindex == index)
  160. return ifp;
  161. }
  162. return NULL;
  163. }
  164. const char *
  165. ifindex2ifname (unsigned int index)
  166. {
  167. struct interface *ifp;
  168. return ((ifp = if_lookup_by_index(index)) != NULL) ?
  169. ifp->name : "unknown";
  170. }
  171. unsigned int
  172. ifname2ifindex (const char *name)
  173. {
  174. struct interface *ifp;
  175. return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp->ifindex : 0;
  176. }
  177. /* Interface existance check by interface name. */
  178. struct interface *
  179. if_lookup_by_name (const char *name)
  180. {
  181. struct listnode *node;
  182. struct interface *ifp;
  183. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  184. {
  185. if (strcmp(name, ifp->name) == 0)
  186. return ifp;
  187. }
  188. return NULL;
  189. }
  190. struct interface *
  191. if_lookup_by_name_len(const char *name, size_t namelen)
  192. {
  193. struct listnode *node;
  194. struct interface *ifp;
  195. if (namelen > INTERFACE_NAMSIZ)
  196. return NULL;
  197. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  198. {
  199. if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
  200. return ifp;
  201. }
  202. return NULL;
  203. }
  204. /* Lookup interface by IPv4 address. */
  205. struct interface *
  206. if_lookup_exact_address (struct in_addr src)
  207. {
  208. struct listnode *node;
  209. struct listnode *cnode;
  210. struct interface *ifp;
  211. struct prefix *p;
  212. struct connected *c;
  213. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  214. {
  215. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  216. {
  217. p = c->address;
  218. if (p && p->family == AF_INET)
  219. {
  220. if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
  221. return ifp;
  222. }
  223. }
  224. }
  225. return NULL;
  226. }
  227. /* Lookup interface by IPv4 address. */
  228. struct interface *
  229. if_lookup_address (struct in_addr src)
  230. {
  231. struct listnode *node;
  232. struct prefix addr;
  233. int bestlen = 0;
  234. struct listnode *cnode;
  235. struct interface *ifp;
  236. struct connected *c;
  237. struct interface *match;
  238. addr.family = AF_INET;
  239. addr.u.prefix4 = src;
  240. addr.prefixlen = IPV4_MAX_BITLEN;
  241. match = NULL;
  242. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  243. {
  244. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  245. {
  246. if (c->address && (c->address->family == AF_INET) &&
  247. prefix_match(CONNECTED_PREFIX(c), &addr) &&
  248. (c->address->prefixlen > bestlen))
  249. {
  250. bestlen = c->address->prefixlen;
  251. match = ifp;
  252. }
  253. }
  254. }
  255. return match;
  256. }
  257. /* Get interface by name if given name interface doesn't exist create
  258. one. */
  259. struct interface *
  260. if_get_by_name (const char *name)
  261. {
  262. struct interface *ifp;
  263. return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp :
  264. if_create(name, strlen(name));
  265. }
  266. struct interface *
  267. if_get_by_name_len(const char *name, size_t namelen)
  268. {
  269. struct interface *ifp;
  270. return ((ifp = if_lookup_by_name_len(name, namelen)) != NULL) ? ifp :
  271. if_create(name, namelen);
  272. }
  273. /* Does interface up ? */
  274. int
  275. if_is_up (struct interface *ifp)
  276. {
  277. return ifp->flags & IFF_UP;
  278. }
  279. /* Is interface running? */
  280. int
  281. if_is_running (struct interface *ifp)
  282. {
  283. return ifp->flags & IFF_RUNNING;
  284. }
  285. /* Is the interface operative, eg. either UP & RUNNING
  286. or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
  287. int
  288. if_is_operative (struct interface *ifp)
  289. {
  290. return ((ifp->flags & IFF_UP) &&
  291. (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
  292. }
  293. /* Is this loopback interface ? */
  294. int
  295. if_is_loopback (struct interface *ifp)
  296. {
  297. /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
  298. * but Y on platform N?
  299. */
  300. return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
  301. }
  302. /* Does this interface support broadcast ? */
  303. int
  304. if_is_broadcast (struct interface *ifp)
  305. {
  306. return ifp->flags & IFF_BROADCAST;
  307. }
  308. /* Does this interface support broadcast ? */
  309. int
  310. if_is_pointopoint (struct interface *ifp)
  311. {
  312. return ifp->flags & IFF_POINTOPOINT;
  313. }
  314. /* Does this interface support multicast ? */
  315. int
  316. if_is_multicast (struct interface *ifp)
  317. {
  318. return ifp->flags & IFF_MULTICAST;
  319. }
  320. /* Printout flag information into log */
  321. const char *
  322. if_flag_dump (unsigned long flag)
  323. {
  324. int separator = 0;
  325. static char logbuf[BUFSIZ];
  326. #define IFF_OUT_LOG(X,STR) \
  327. if (flag & (X)) \
  328. { \
  329. if (separator) \
  330. strlcat (logbuf, ",", BUFSIZ); \
  331. else \
  332. separator = 1; \
  333. strlcat (logbuf, STR, BUFSIZ); \
  334. }
  335. strlcpy (logbuf, "<", BUFSIZ);
  336. IFF_OUT_LOG (IFF_UP, "UP");
  337. IFF_OUT_LOG (IFF_BROADCAST, "BROADCAST");
  338. IFF_OUT_LOG (IFF_DEBUG, "DEBUG");
  339. IFF_OUT_LOG (IFF_LOOPBACK, "LOOPBACK");
  340. IFF_OUT_LOG (IFF_POINTOPOINT, "POINTOPOINT");
  341. IFF_OUT_LOG (IFF_NOTRAILERS, "NOTRAILERS");
  342. IFF_OUT_LOG (IFF_RUNNING, "RUNNING");
  343. IFF_OUT_LOG (IFF_NOARP, "NOARP");
  344. IFF_OUT_LOG (IFF_PROMISC, "PROMISC");
  345. IFF_OUT_LOG (IFF_ALLMULTI, "ALLMULTI");
  346. IFF_OUT_LOG (IFF_OACTIVE, "OACTIVE");
  347. IFF_OUT_LOG (IFF_SIMPLEX, "SIMPLEX");
  348. IFF_OUT_LOG (IFF_LINK0, "LINK0");
  349. IFF_OUT_LOG (IFF_LINK1, "LINK1");
  350. IFF_OUT_LOG (IFF_LINK2, "LINK2");
  351. IFF_OUT_LOG (IFF_MULTICAST, "MULTICAST");
  352. IFF_OUT_LOG (IFF_NOXMIT, "NOXMIT");
  353. IFF_OUT_LOG (IFF_NORTEXCH, "NORTEXCH");
  354. IFF_OUT_LOG (IFF_VIRTUAL, "VIRTUAL");
  355. IFF_OUT_LOG (IFF_IPV4, "IPv4");
  356. IFF_OUT_LOG (IFF_IPV6, "IPv6");
  357. strlcat (logbuf, ">", BUFSIZ);
  358. return logbuf;
  359. #undef IFF_OUT_LOG
  360. }
  361. /* For debugging */
  362. static void
  363. if_dump (struct interface *ifp)
  364. {
  365. struct listnode *node;
  366. struct connected *c;
  367. zlog_info ("Interface %s index %d metric %d mtu %d "
  368. #ifdef HAVE_IPV6
  369. "mtu6 %d "
  370. #endif /* HAVE_IPV6 */
  371. "%s",
  372. ifp->name, ifp->ifindex, ifp->metric, ifp->mtu,
  373. #ifdef HAVE_IPV6
  374. ifp->mtu6,
  375. #endif /* HAVE_IPV6 */
  376. if_flag_dump (ifp->flags));
  377. for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
  378. ;
  379. }
  380. /* Interface printing for all interface. */
  381. void
  382. if_dump_all ()
  383. {
  384. struct listnode *node;
  385. void *p;
  386. for (ALL_LIST_ELEMENTS_RO (iflist, node, p))
  387. if_dump (p);
  388. }
  389. DEFUN (interface_desc,
  390. interface_desc_cmd,
  391. "description .LINE",
  392. "Interface specific description\n"
  393. "Characters describing this interface\n")
  394. {
  395. struct interface *ifp;
  396. if (argc == 0)
  397. return CMD_SUCCESS;
  398. ifp = vty->index;
  399. if (ifp->desc)
  400. XFREE (MTYPE_TMP, ifp->desc);
  401. ifp->desc = argv_concat(argv, argc, 0);
  402. return CMD_SUCCESS;
  403. }
  404. DEFUN (no_interface_desc,
  405. no_interface_desc_cmd,
  406. "no description",
  407. NO_STR
  408. "Interface specific description\n")
  409. {
  410. struct interface *ifp;
  411. ifp = vty->index;
  412. if (ifp->desc)
  413. XFREE (MTYPE_TMP, ifp->desc);
  414. ifp->desc = NULL;
  415. return CMD_SUCCESS;
  416. }
  417. #ifdef SUNOS_5
  418. /* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created
  419. * a seperate struct interface for each logical interface, so config
  420. * file may be full of 'interface fooX:Y'. Solaris however does not
  421. * expose logical interfaces via PF_ROUTE, so trying to track logical
  422. * interfaces can be fruitless, for that reason Quagga only tracks
  423. * the primary IP interface.
  424. *
  425. * We try accomodate SUNWzebra by:
  426. * - looking up the interface name, to see whether it exists, if so
  427. * its useable
  428. * - for protocol daemons, this could only because zebra told us of
  429. * the interface
  430. * - for zebra, only because it learnt from kernel
  431. * - if not:
  432. * - search the name to see if it contains a sub-ipif / logical interface
  433. * seperator, the ':' char. If it does:
  434. * - text up to that char must be the primary name - get that name.
  435. * if not:
  436. * - no idea, just get the name in its entirety.
  437. */
  438. static struct interface *
  439. if_sunwzebra_get (const char *name, size_t nlen)
  440. {
  441. struct interface *ifp;
  442. size_t seppos = 0;
  443. if ( (ifp = if_lookup_by_name_len(name, nlen)) != NULL)
  444. return ifp;
  445. /* hunt the primary interface name... */
  446. while (seppos < nlen && name[seppos] != ':')
  447. seppos++;
  448. /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
  449. if (seppos < nlen)
  450. return if_get_by_name_len (name, seppos);
  451. else
  452. return if_get_by_name_len (name, nlen);
  453. }
  454. #endif /* SUNOS_5 */
  455. DEFUN (interface,
  456. interface_cmd,
  457. "interface IFNAME",
  458. "Select an interface to configure\n"
  459. "Interface's name\n")
  460. {
  461. struct interface *ifp;
  462. size_t sl;
  463. if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
  464. {
  465. vty_out (vty, "%% Interface name %s is invalid: length exceeds "
  466. "%d characters%s",
  467. argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
  468. return CMD_WARNING;
  469. }
  470. #ifdef SUNOS_5
  471. ifp = if_sunwzebra_get (argv[0], sl);
  472. #else
  473. ifp = if_get_by_name_len(argv[0], sl);
  474. #endif /* SUNOS_5 */
  475. vty->index = ifp;
  476. vty->node = INTERFACE_NODE;
  477. return CMD_SUCCESS;
  478. }
  479. DEFUN_NOSH (no_interface,
  480. no_interface_cmd,
  481. "no interface IFNAME",
  482. NO_STR
  483. "Delete a pseudo interface's configuration\n"
  484. "Interface's name\n")
  485. {
  486. // deleting interface
  487. struct interface *ifp;
  488. ifp = if_lookup_by_name (argv[0]);
  489. if (ifp == NULL)
  490. {
  491. vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
  492. return CMD_WARNING;
  493. }
  494. if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  495. {
  496. vty_out (vty, "%% Only inactive interfaces can be deleted%s",
  497. VTY_NEWLINE);
  498. return CMD_WARNING;
  499. }
  500. if_delete(ifp);
  501. return CMD_SUCCESS;
  502. }
  503. /* For debug purpose. */
  504. DEFUN (show_address,
  505. show_address_cmd,
  506. "show address",
  507. SHOW_STR
  508. "address\n")
  509. {
  510. struct listnode *node;
  511. struct listnode *node2;
  512. struct interface *ifp;
  513. struct connected *ifc;
  514. struct prefix *p;
  515. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  516. {
  517. for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
  518. {
  519. p = ifc->address;
  520. if (p->family == AF_INET)
  521. vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
  522. VTY_NEWLINE);
  523. }
  524. }
  525. return CMD_SUCCESS;
  526. }
  527. /* Allocate connected structure. */
  528. struct connected *
  529. connected_new (void)
  530. {
  531. struct connected *new = XMALLOC (MTYPE_CONNECTED, sizeof (struct connected));
  532. memset (new, 0, sizeof (struct connected));
  533. return new;
  534. }
  535. /* Free connected structure. */
  536. void
  537. connected_free (struct connected *connected)
  538. {
  539. if (connected->address)
  540. prefix_free (connected->address);
  541. if (connected->destination)
  542. prefix_free (connected->destination);
  543. if (connected->label)
  544. XFREE (MTYPE_CONNECTED_LABEL, connected->label);
  545. XFREE (MTYPE_CONNECTED, connected);
  546. }
  547. /* Print if_addr structure. */
  548. static void __attribute__ ((unused))
  549. connected_log (struct connected *connected, char *str)
  550. {
  551. struct prefix *p;
  552. struct interface *ifp;
  553. char logbuf[BUFSIZ];
  554. char buf[BUFSIZ];
  555. ifp = connected->ifp;
  556. p = connected->address;
  557. snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ",
  558. str, ifp->name, prefix_family_str (p),
  559. inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  560. p->prefixlen);
  561. p = connected->destination;
  562. if (p)
  563. {
  564. strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  565. BUFSIZ - strlen(logbuf));
  566. }
  567. zlog (NULL, LOG_INFO, logbuf);
  568. }
  569. /* If two connected address has same prefix return 1. */
  570. static int
  571. connected_same_prefix (struct prefix *p1, struct prefix *p2)
  572. {
  573. if (p1->family == p2->family)
  574. {
  575. if (p1->family == AF_INET &&
  576. IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
  577. return 1;
  578. #ifdef HAVE_IPV6
  579. if (p1->family == AF_INET6 &&
  580. IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
  581. return 1;
  582. #endif /* HAVE_IPV6 */
  583. }
  584. return 0;
  585. }
  586. struct connected *
  587. connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
  588. {
  589. struct listnode *node;
  590. struct listnode *next;
  591. struct connected *ifc;
  592. /* In case of same prefix come, replace it with new one. */
  593. for (node = listhead (ifp->connected); node; node = next)
  594. {
  595. ifc = listgetdata (node);
  596. next = node->next;
  597. if (connected_same_prefix (ifc->address, p))
  598. {
  599. listnode_delete (ifp->connected, ifc);
  600. return ifc;
  601. }
  602. }
  603. return NULL;
  604. }
  605. /* Find the IPv4 address on our side that will be used when packets
  606. are sent to dst. */
  607. struct connected *
  608. connected_lookup_address (struct interface *ifp, struct in_addr dst)
  609. {
  610. struct prefix addr;
  611. struct listnode *cnode;
  612. struct connected *c;
  613. struct connected *match;
  614. addr.family = AF_INET;
  615. addr.u.prefix4 = dst;
  616. addr.prefixlen = IPV4_MAX_BITLEN;
  617. match = NULL;
  618. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  619. {
  620. if (c->address && (c->address->family == AF_INET) &&
  621. prefix_match(CONNECTED_PREFIX(c), &addr) &&
  622. (!match || (c->address->prefixlen > match->address->prefixlen)))
  623. match = c;
  624. }
  625. return match;
  626. }
  627. struct connected *
  628. connected_add_by_prefix (struct interface *ifp, struct prefix *p,
  629. struct prefix *destination)
  630. {
  631. struct connected *ifc;
  632. /* Allocate new connected address. */
  633. ifc = connected_new ();
  634. ifc->ifp = ifp;
  635. /* Fetch interface address */
  636. ifc->address = prefix_new();
  637. memcpy (ifc->address, p, sizeof(struct prefix));
  638. /* Fetch dest address */
  639. if (destination)
  640. {
  641. ifc->destination = prefix_new();
  642. memcpy (ifc->destination, destination, sizeof(struct prefix));
  643. }
  644. /* Add connected address to the interface. */
  645. listnode_add (ifp->connected, ifc);
  646. return ifc;
  647. }
  648. #ifndef HAVE_IF_NAMETOINDEX
  649. unsigned int
  650. if_nametoindex (const char *name)
  651. {
  652. struct interface *ifp;
  653. return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
  654. ? ifp->ifindex : 0;
  655. }
  656. #endif
  657. #ifndef HAVE_IF_INDEXTONAME
  658. char *
  659. if_indextoname (unsigned int ifindex, char *name)
  660. {
  661. struct interface *ifp;
  662. if (!(ifp = if_lookup_by_index(ifindex)))
  663. return NULL;
  664. strncpy (name, ifp->name, IFNAMSIZ);
  665. return ifp->name;
  666. }
  667. #endif
  668. #if 0 /* this route_table of struct connected's is unused
  669. * however, it would be good to use a route_table rather than
  670. * a list..
  671. */
  672. /* Interface looking up by interface's address. */
  673. /* Interface's IPv4 address reverse lookup table. */
  674. struct route_table *ifaddr_ipv4_table;
  675. /* struct route_table *ifaddr_ipv6_table; */
  676. static void
  677. ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
  678. {
  679. struct route_node *rn;
  680. struct prefix_ipv4 p;
  681. p.family = AF_INET;
  682. p.prefixlen = IPV4_MAX_PREFIXLEN;
  683. p.prefix = *ifaddr;
  684. rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
  685. if (rn)
  686. {
  687. route_unlock_node (rn);
  688. zlog_info ("ifaddr_ipv4_add(): address %s is already added",
  689. inet_ntoa (*ifaddr));
  690. return;
  691. }
  692. rn->info = ifp;
  693. }
  694. static void
  695. ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
  696. {
  697. struct route_node *rn;
  698. struct prefix_ipv4 p;
  699. p.family = AF_INET;
  700. p.prefixlen = IPV4_MAX_PREFIXLEN;
  701. p.prefix = *ifaddr;
  702. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  703. if (! rn)
  704. {
  705. zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
  706. inet_ntoa (*ifaddr));
  707. return;
  708. }
  709. rn->info = NULL;
  710. route_unlock_node (rn);
  711. route_unlock_node (rn);
  712. }
  713. /* Lookup interface by interface's IP address or interface index. */
  714. static struct interface *
  715. ifaddr_ipv4_lookup (struct in_addr *addr, unsigned int ifindex)
  716. {
  717. struct prefix_ipv4 p;
  718. struct route_node *rn;
  719. struct interface *ifp;
  720. if (addr)
  721. {
  722. p.family = AF_INET;
  723. p.prefixlen = IPV4_MAX_PREFIXLEN;
  724. p.prefix = *addr;
  725. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  726. if (! rn)
  727. return NULL;
  728. ifp = rn->info;
  729. route_unlock_node (rn);
  730. return ifp;
  731. }
  732. else
  733. return if_lookup_by_index(ifindex);
  734. }
  735. #endif /* ifaddr_ipv4_table */
  736. /* Initialize interface list. */
  737. void
  738. if_init (void)
  739. {
  740. iflist = list_new ();
  741. #if 0
  742. ifaddr_ipv4_table = route_table_init ();
  743. #endif /* ifaddr_ipv4_table */
  744. if (iflist) {
  745. iflist->cmp = (int (*)(void *, void *))if_cmp_func;
  746. return;
  747. }
  748. memset (&if_master, 0, sizeof if_master);
  749. }