if.c 21 KB

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