if.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  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 "vrf.h"
  28. #include "if.h"
  29. #include "sockunion.h"
  30. #include "prefix.h"
  31. #include "memory.h"
  32. #include "table.h"
  33. #include "buffer.h"
  34. #include "str.h"
  35. #include "log.h"
  36. /* List of interfaces in only the default VRF */
  37. struct list *iflist;
  38. /* One for each program. This structure is needed to store hooks. */
  39. struct if_master
  40. {
  41. int (*if_new_hook) (struct interface *);
  42. int (*if_delete_hook) (struct interface *);
  43. } if_master = {0,};
  44. /* Compare interface names, returning an integer greater than, equal to, or
  45. * less than 0, (following the strcmp convention), according to the
  46. * relationship between ifp1 and ifp2. Interface names consist of an
  47. * alphabetic prefix and a numeric suffix. The primary sort key is
  48. * lexicographic by name, and then numeric by number. No number sorts
  49. * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
  50. * devpty0, de0 < del0
  51. */
  52. int
  53. if_cmp_func (struct interface *ifp1, struct interface *ifp2)
  54. {
  55. unsigned int l1, l2;
  56. long int x1, x2;
  57. char *p1, *p2;
  58. int res;
  59. p1 = ifp1->name;
  60. p2 = ifp2->name;
  61. while (*p1 && *p2) {
  62. /* look up to any number */
  63. l1 = strcspn(p1, "0123456789");
  64. l2 = strcspn(p2, "0123456789");
  65. /* name lengths are different -> compare names */
  66. if (l1 != l2)
  67. return (strcmp(p1, p2));
  68. /* Note that this relies on all numbers being less than all letters, so
  69. * that de0 < del0.
  70. */
  71. res = strncmp(p1, p2, l1);
  72. /* names are different -> compare them */
  73. if (res)
  74. return res;
  75. /* with identical name part, go to numeric part */
  76. p1 += l1;
  77. p2 += l1;
  78. if (!*p1)
  79. return -1;
  80. if (!*p2)
  81. return 1;
  82. x1 = strtol(p1, &p1, 10);
  83. x2 = strtol(p2, &p2, 10);
  84. /* let's compare numbers now */
  85. if (x1 < x2)
  86. return -1;
  87. if (x1 > x2)
  88. return 1;
  89. /* numbers were equal, lets do it again..
  90. (it happens with name like "eth123.456:789") */
  91. }
  92. if (*p1)
  93. return 1;
  94. if (*p2)
  95. return -1;
  96. return 0;
  97. }
  98. /* Create new interface structure. */
  99. struct interface *
  100. if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
  101. {
  102. struct interface *ifp;
  103. struct list *intf_list = vrf_iflist_get (vrf_id);
  104. ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
  105. ifp->ifindex = IFINDEX_INTERNAL;
  106. assert (name);
  107. assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
  108. strncpy (ifp->name, name, namelen);
  109. ifp->name[namelen] = '\0';
  110. ifp->vrf_id = vrf_id;
  111. if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
  112. listnode_add_sort (intf_list, ifp);
  113. else
  114. zlog_err("if_create(%s): corruption detected -- interface with this "
  115. "name exists already in VRF %u!", ifp->name, vrf_id);
  116. ifp->connected = list_new ();
  117. ifp->connected->del = (void (*) (void *)) connected_free;
  118. if (if_master.if_new_hook)
  119. (*if_master.if_new_hook) (ifp);
  120. return ifp;
  121. }
  122. struct interface *
  123. if_create (const char *name, int namelen)
  124. {
  125. return if_create_vrf (name, namelen, VRF_DEFAULT);
  126. }
  127. /* Delete interface structure. */
  128. void
  129. if_delete_retain (struct interface *ifp)
  130. {
  131. if (if_master.if_delete_hook)
  132. (*if_master.if_delete_hook) (ifp);
  133. /* Free connected address list */
  134. list_delete_all_node (ifp->connected);
  135. }
  136. /* Delete and free interface structure. */
  137. void
  138. if_delete (struct interface *ifp)
  139. {
  140. listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
  141. if_delete_retain(ifp);
  142. list_free (ifp->connected);
  143. if_link_params_free (ifp);
  144. XFREE (MTYPE_IF, ifp);
  145. }
  146. /* Add hook to interface master. */
  147. void
  148. if_add_hook (int type, int (*func)(struct interface *ifp))
  149. {
  150. switch (type) {
  151. case IF_NEW_HOOK:
  152. if_master.if_new_hook = func;
  153. break;
  154. case IF_DELETE_HOOK:
  155. if_master.if_delete_hook = func;
  156. break;
  157. default:
  158. break;
  159. }
  160. }
  161. /* Interface existance check by index. */
  162. struct interface *
  163. if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
  164. {
  165. struct listnode *node;
  166. struct interface *ifp;
  167. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  168. {
  169. if (ifp->ifindex == ifindex)
  170. return ifp;
  171. }
  172. return NULL;
  173. }
  174. struct interface *
  175. if_lookup_by_index (ifindex_t ifindex)
  176. {
  177. return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
  178. }
  179. const char *
  180. ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
  181. {
  182. struct interface *ifp;
  183. return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
  184. ifp->name : "unknown";
  185. }
  186. const char *
  187. ifindex2ifname (ifindex_t ifindex)
  188. {
  189. return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
  190. }
  191. ifindex_t
  192. ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
  193. {
  194. struct interface *ifp;
  195. return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
  196. : IFINDEX_INTERNAL;
  197. }
  198. ifindex_t
  199. ifname2ifindex (const char *name)
  200. {
  201. return ifname2ifindex_vrf (name, VRF_DEFAULT);
  202. }
  203. /* Interface existance check by interface name. */
  204. struct interface *
  205. if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
  206. {
  207. struct listnode *node;
  208. struct interface *ifp;
  209. if (name)
  210. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  211. {
  212. if (strcmp(name, ifp->name) == 0)
  213. return ifp;
  214. }
  215. return NULL;
  216. }
  217. struct interface *
  218. if_lookup_by_name (const char *name)
  219. {
  220. return if_lookup_by_name_vrf (name, VRF_DEFAULT);
  221. }
  222. struct interface *
  223. if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
  224. {
  225. struct listnode *node;
  226. struct interface *ifp;
  227. if (namelen > INTERFACE_NAMSIZ)
  228. return NULL;
  229. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  230. {
  231. if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
  232. return ifp;
  233. }
  234. return NULL;
  235. }
  236. struct interface *
  237. if_lookup_by_name_len(const char *name, size_t namelen)
  238. {
  239. return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
  240. }
  241. /* Lookup interface by IPv4 address. */
  242. struct interface *
  243. if_lookup_exact_address_vrf (struct in_addr src, vrf_id_t vrf_id)
  244. {
  245. struct listnode *node;
  246. struct listnode *cnode;
  247. struct interface *ifp;
  248. struct prefix *p;
  249. struct connected *c;
  250. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  251. {
  252. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  253. {
  254. p = c->address;
  255. if (p && p->family == AF_INET)
  256. {
  257. if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
  258. return ifp;
  259. }
  260. }
  261. }
  262. return NULL;
  263. }
  264. struct interface *
  265. if_lookup_exact_address (struct in_addr src)
  266. {
  267. return if_lookup_exact_address_vrf (src, VRF_DEFAULT);
  268. }
  269. /* Lookup interface by IPv4 address. */
  270. struct interface *
  271. if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
  272. {
  273. struct listnode *node;
  274. struct prefix addr;
  275. int bestlen = 0;
  276. struct listnode *cnode;
  277. struct interface *ifp;
  278. struct connected *c;
  279. struct interface *match;
  280. addr.family = AF_INET;
  281. addr.u.prefix4 = src;
  282. addr.prefixlen = IPV4_MAX_BITLEN;
  283. match = NULL;
  284. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  285. {
  286. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  287. {
  288. if (c->address && (c->address->family == AF_INET) &&
  289. prefix_match(CONNECTED_PREFIX(c), &addr) &&
  290. (c->address->prefixlen > bestlen))
  291. {
  292. bestlen = c->address->prefixlen;
  293. match = ifp;
  294. }
  295. }
  296. }
  297. return match;
  298. }
  299. struct interface *
  300. if_lookup_address (struct in_addr src)
  301. {
  302. return if_lookup_address_vrf (src, VRF_DEFAULT);
  303. }
  304. /* Lookup interface by prefix */
  305. struct interface *
  306. if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
  307. {
  308. struct listnode *node;
  309. struct listnode *cnode;
  310. struct interface *ifp;
  311. struct connected *c;
  312. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  313. {
  314. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  315. {
  316. if (prefix_cmp(c->address, prefix) == 0)
  317. {
  318. return ifp;
  319. }
  320. }
  321. }
  322. return NULL;
  323. }
  324. struct interface *
  325. if_lookup_prefix (struct prefix *prefix)
  326. {
  327. return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
  328. }
  329. /* Get interface by name if given name interface doesn't exist create
  330. one. */
  331. struct interface *
  332. if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
  333. {
  334. struct interface *ifp;
  335. return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
  336. if_create_vrf (name, strlen(name), vrf_id);
  337. }
  338. struct interface *
  339. if_get_by_name (const char *name)
  340. {
  341. return if_get_by_name_vrf (name, VRF_DEFAULT);
  342. }
  343. struct interface *
  344. if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
  345. {
  346. struct interface *ifp;
  347. return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \
  348. ifp : if_create_vrf (name, namelen, vrf_id);
  349. }
  350. struct interface *
  351. if_get_by_name_len (const char *name, size_t namelen)
  352. {
  353. return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT);
  354. }
  355. /* Does interface up ? */
  356. int
  357. if_is_up (struct interface *ifp)
  358. {
  359. return ifp->flags & IFF_UP;
  360. }
  361. /* Is interface running? */
  362. int
  363. if_is_running (struct interface *ifp)
  364. {
  365. return ifp->flags & IFF_RUNNING;
  366. }
  367. /* Is the interface operative, eg. either UP & RUNNING
  368. or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
  369. int
  370. if_is_operative (struct interface *ifp)
  371. {
  372. return ((ifp->flags & IFF_UP) &&
  373. (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
  374. }
  375. /* Is this loopback interface ? */
  376. int
  377. if_is_loopback (struct interface *ifp)
  378. {
  379. /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
  380. * but Y on platform N?
  381. */
  382. return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
  383. }
  384. /* Does this interface support broadcast ? */
  385. int
  386. if_is_broadcast (struct interface *ifp)
  387. {
  388. return ifp->flags & IFF_BROADCAST;
  389. }
  390. /* Does this interface support broadcast ? */
  391. int
  392. if_is_pointopoint (struct interface *ifp)
  393. {
  394. return ifp->flags & IFF_POINTOPOINT;
  395. }
  396. /* Does this interface support multicast ? */
  397. int
  398. if_is_multicast (struct interface *ifp)
  399. {
  400. return ifp->flags & IFF_MULTICAST;
  401. }
  402. /* Printout flag information into log */
  403. const char *
  404. if_flag_dump (unsigned long flag)
  405. {
  406. int separator = 0;
  407. static char logbuf[BUFSIZ];
  408. #define IFF_OUT_LOG(X,STR) \
  409. if (flag & (X)) \
  410. { \
  411. if (separator) \
  412. strlcat (logbuf, ",", BUFSIZ); \
  413. else \
  414. separator = 1; \
  415. strlcat (logbuf, STR, BUFSIZ); \
  416. }
  417. strlcpy (logbuf, "<", BUFSIZ);
  418. IFF_OUT_LOG (IFF_UP, "UP");
  419. IFF_OUT_LOG (IFF_BROADCAST, "BROADCAST");
  420. IFF_OUT_LOG (IFF_DEBUG, "DEBUG");
  421. IFF_OUT_LOG (IFF_LOOPBACK, "LOOPBACK");
  422. IFF_OUT_LOG (IFF_POINTOPOINT, "POINTOPOINT");
  423. IFF_OUT_LOG (IFF_NOTRAILERS, "NOTRAILERS");
  424. IFF_OUT_LOG (IFF_RUNNING, "RUNNING");
  425. IFF_OUT_LOG (IFF_NOARP, "NOARP");
  426. IFF_OUT_LOG (IFF_PROMISC, "PROMISC");
  427. IFF_OUT_LOG (IFF_ALLMULTI, "ALLMULTI");
  428. IFF_OUT_LOG (IFF_OACTIVE, "OACTIVE");
  429. IFF_OUT_LOG (IFF_SIMPLEX, "SIMPLEX");
  430. IFF_OUT_LOG (IFF_LINK0, "LINK0");
  431. IFF_OUT_LOG (IFF_LINK1, "LINK1");
  432. IFF_OUT_LOG (IFF_LINK2, "LINK2");
  433. IFF_OUT_LOG (IFF_MULTICAST, "MULTICAST");
  434. IFF_OUT_LOG (IFF_NOXMIT, "NOXMIT");
  435. IFF_OUT_LOG (IFF_NORTEXCH, "NORTEXCH");
  436. IFF_OUT_LOG (IFF_VIRTUAL, "VIRTUAL");
  437. IFF_OUT_LOG (IFF_IPV4, "IPv4");
  438. IFF_OUT_LOG (IFF_IPV6, "IPv6");
  439. strlcat (logbuf, ">", BUFSIZ);
  440. return logbuf;
  441. #undef IFF_OUT_LOG
  442. }
  443. /* For debugging */
  444. static void
  445. if_dump (const struct interface *ifp)
  446. {
  447. struct listnode *node;
  448. struct connected *c __attribute__((unused));
  449. for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
  450. zlog_info ("Interface %s vrf %u index %d metric %d mtu %d "
  451. #ifdef HAVE_IPV6
  452. "mtu6 %d "
  453. #endif /* HAVE_IPV6 */
  454. "%s",
  455. ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, ifp->mtu,
  456. #ifdef HAVE_IPV6
  457. ifp->mtu6,
  458. #endif /* HAVE_IPV6 */
  459. if_flag_dump (ifp->flags));
  460. }
  461. /* Interface printing for all interface. */
  462. void
  463. if_dump_all (void)
  464. {
  465. struct list *intf_list;
  466. struct listnode *node;
  467. void *p;
  468. vrf_iter_t iter;
  469. for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
  470. if ((intf_list = vrf_iter2iflist (iter)) != NULL)
  471. for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
  472. if_dump (p);
  473. }
  474. DEFUN (interface_desc,
  475. interface_desc_cmd,
  476. "description .LINE",
  477. "Interface specific description\n"
  478. "Characters describing this interface\n")
  479. {
  480. struct interface *ifp;
  481. if (argc == 0)
  482. return CMD_SUCCESS;
  483. ifp = vty->index;
  484. if (ifp->desc)
  485. XFREE (MTYPE_TMP, ifp->desc);
  486. ifp->desc = argv_concat(argv, argc, 0);
  487. return CMD_SUCCESS;
  488. }
  489. DEFUN (no_interface_desc,
  490. no_interface_desc_cmd,
  491. "no description",
  492. NO_STR
  493. "Interface specific description\n")
  494. {
  495. struct interface *ifp;
  496. ifp = vty->index;
  497. if (ifp->desc)
  498. XFREE (MTYPE_TMP, ifp->desc);
  499. ifp->desc = NULL;
  500. return CMD_SUCCESS;
  501. }
  502. #ifdef SUNOS_5
  503. /* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created
  504. * a seperate struct interface for each logical interface, so config
  505. * file may be full of 'interface fooX:Y'. Solaris however does not
  506. * expose logical interfaces via PF_ROUTE, so trying to track logical
  507. * interfaces can be fruitless, for that reason Quagga only tracks
  508. * the primary IP interface.
  509. *
  510. * We try accomodate SUNWzebra by:
  511. * - looking up the interface name, to see whether it exists, if so
  512. * its useable
  513. * - for protocol daemons, this could only because zebra told us of
  514. * the interface
  515. * - for zebra, only because it learnt from kernel
  516. * - if not:
  517. * - search the name to see if it contains a sub-ipif / logical interface
  518. * seperator, the ':' char. If it does:
  519. * - text up to that char must be the primary name - get that name.
  520. * if not:
  521. * - no idea, just get the name in its entirety.
  522. */
  523. static struct interface *
  524. if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
  525. {
  526. struct interface *ifp;
  527. size_t seppos = 0;
  528. if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
  529. return ifp;
  530. /* hunt the primary interface name... */
  531. while (seppos < nlen && name[seppos] != ':')
  532. seppos++;
  533. /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
  534. if (seppos < nlen)
  535. return if_get_by_name_len_vrf (name, seppos, vrf_id);
  536. else
  537. return if_get_by_name_len_vrf (name, nlen, vrf_id);
  538. }
  539. #endif /* SUNOS_5 */
  540. DEFUN (interface,
  541. interface_cmd,
  542. "interface IFNAME",
  543. "Select an interface to configure\n"
  544. "Interface's name\n")
  545. {
  546. struct interface *ifp;
  547. size_t sl;
  548. vrf_id_t vrf_id = VRF_DEFAULT;
  549. if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
  550. {
  551. vty_out (vty, "%% Interface name %s is invalid: length exceeds "
  552. "%d characters%s",
  553. argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
  554. return CMD_WARNING;
  555. }
  556. if (argc > 1)
  557. VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
  558. #ifdef SUNOS_5
  559. ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
  560. #else
  561. ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id);
  562. #endif /* SUNOS_5 */
  563. vty->index = ifp;
  564. vty->node = INTERFACE_NODE;
  565. return CMD_SUCCESS;
  566. }
  567. ALIAS (interface,
  568. interface_vrf_cmd,
  569. "interface IFNAME " VRF_CMD_STR,
  570. "Select an interface to configure\n"
  571. "Interface's name\n"
  572. VRF_CMD_HELP_STR)
  573. DEFUN_NOSH (no_interface,
  574. no_interface_cmd,
  575. "no interface IFNAME",
  576. NO_STR
  577. "Delete a pseudo interface's configuration\n"
  578. "Interface's name\n")
  579. {
  580. // deleting interface
  581. struct interface *ifp;
  582. vrf_id_t vrf_id = VRF_DEFAULT;
  583. if (argc > 1)
  584. VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
  585. ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
  586. if (ifp == NULL)
  587. {
  588. vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
  589. return CMD_WARNING;
  590. }
  591. if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  592. {
  593. vty_out (vty, "%% Only inactive interfaces can be deleted%s",
  594. VTY_NEWLINE);
  595. return CMD_WARNING;
  596. }
  597. if_delete(ifp);
  598. return CMD_SUCCESS;
  599. }
  600. ALIAS (no_interface,
  601. no_interface_vrf_cmd,
  602. "no interface IFNAME " VRF_CMD_STR,
  603. NO_STR
  604. "Delete a pseudo interface's configuration\n"
  605. "Interface's name\n"
  606. VRF_CMD_HELP_STR)
  607. /* For debug purpose. */
  608. DEFUN (show_address,
  609. show_address_cmd,
  610. "show address",
  611. SHOW_STR
  612. "address\n")
  613. {
  614. struct listnode *node;
  615. struct listnode *node2;
  616. struct interface *ifp;
  617. struct connected *ifc;
  618. struct prefix *p;
  619. vrf_id_t vrf_id = VRF_DEFAULT;
  620. if (argc > 0)
  621. VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  622. for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
  623. {
  624. for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
  625. {
  626. p = ifc->address;
  627. if (p->family == AF_INET)
  628. vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
  629. VTY_NEWLINE);
  630. }
  631. }
  632. return CMD_SUCCESS;
  633. }
  634. ALIAS (show_address,
  635. show_address_vrf_cmd,
  636. "show address " VRF_CMD_STR,
  637. SHOW_STR
  638. "address\n"
  639. VRF_CMD_HELP_STR)
  640. DEFUN (show_address_vrf_all,
  641. show_address_vrf_all_cmd,
  642. "show address " VRF_ALL_CMD_STR,
  643. SHOW_STR
  644. "address\n"
  645. VRF_ALL_CMD_HELP_STR)
  646. {
  647. struct list *intf_list;
  648. struct listnode *node;
  649. struct listnode *node2;
  650. struct interface *ifp;
  651. struct connected *ifc;
  652. struct prefix *p;
  653. vrf_iter_t iter;
  654. for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
  655. {
  656. intf_list = vrf_iter2iflist (iter);
  657. if (!intf_list || !listcount (intf_list))
  658. continue;
  659. vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
  660. VTY_NEWLINE, VTY_NEWLINE);
  661. for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
  662. {
  663. for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
  664. {
  665. p = ifc->address;
  666. if (p->family == AF_INET)
  667. vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
  668. VTY_NEWLINE);
  669. }
  670. }
  671. }
  672. return CMD_SUCCESS;
  673. }
  674. /* Allocate connected structure. */
  675. struct connected *
  676. connected_new (void)
  677. {
  678. return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
  679. }
  680. /* Free connected structure. */
  681. void
  682. connected_free (struct connected *connected)
  683. {
  684. if (connected->address)
  685. prefix_free (connected->address);
  686. if (connected->destination)
  687. prefix_free (connected->destination);
  688. if (connected->label)
  689. XFREE (MTYPE_CONNECTED_LABEL, connected->label);
  690. XFREE (MTYPE_CONNECTED, connected);
  691. }
  692. /* Print if_addr structure. */
  693. static void __attribute__ ((unused))
  694. connected_log (struct connected *connected, char *str)
  695. {
  696. struct prefix *p;
  697. struct interface *ifp;
  698. char logbuf[BUFSIZ];
  699. char buf[BUFSIZ];
  700. ifp = connected->ifp;
  701. p = connected->address;
  702. snprintf (logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ",
  703. str, ifp->name, ifp->vrf_id, prefix_family_str (p),
  704. inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  705. p->prefixlen);
  706. p = connected->destination;
  707. if (p)
  708. {
  709. strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  710. BUFSIZ - strlen(logbuf));
  711. }
  712. zlog (NULL, LOG_INFO, "%s", logbuf);
  713. }
  714. /* If two connected address has same prefix return 1. */
  715. static int
  716. connected_same_prefix (struct prefix *p1, struct prefix *p2)
  717. {
  718. if (p1->family == p2->family)
  719. {
  720. if (p1->family == AF_INET &&
  721. IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
  722. return 1;
  723. #ifdef HAVE_IPV6
  724. if (p1->family == AF_INET6 &&
  725. IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
  726. return 1;
  727. #endif /* HAVE_IPV6 */
  728. }
  729. return 0;
  730. }
  731. struct connected *
  732. connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
  733. {
  734. struct listnode *node;
  735. struct listnode *next;
  736. struct connected *ifc;
  737. /* In case of same prefix come, replace it with new one. */
  738. for (node = listhead (ifp->connected); node; node = next)
  739. {
  740. ifc = listgetdata (node);
  741. next = node->next;
  742. if (connected_same_prefix (ifc->address, p))
  743. {
  744. listnode_delete (ifp->connected, ifc);
  745. return ifc;
  746. }
  747. }
  748. return NULL;
  749. }
  750. /* Find the IPv4 address on our side that will be used when packets
  751. are sent to dst. */
  752. struct connected *
  753. connected_lookup_address (struct interface *ifp, struct in_addr dst)
  754. {
  755. struct prefix addr;
  756. struct listnode *cnode;
  757. struct connected *c;
  758. struct connected *match;
  759. addr.family = AF_INET;
  760. addr.u.prefix4 = dst;
  761. addr.prefixlen = IPV4_MAX_BITLEN;
  762. match = NULL;
  763. for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
  764. {
  765. if (c->address && (c->address->family == AF_INET) &&
  766. prefix_match(CONNECTED_PREFIX(c), &addr) &&
  767. (!match || (c->address->prefixlen > match->address->prefixlen)))
  768. match = c;
  769. }
  770. return match;
  771. }
  772. struct connected *
  773. connected_add_by_prefix (struct interface *ifp, struct prefix *p,
  774. struct prefix *destination)
  775. {
  776. struct connected *ifc;
  777. /* Allocate new connected address. */
  778. ifc = connected_new ();
  779. ifc->ifp = ifp;
  780. /* Fetch interface address */
  781. ifc->address = prefix_new();
  782. memcpy (ifc->address, p, sizeof(struct prefix));
  783. /* Fetch dest address */
  784. if (destination)
  785. {
  786. ifc->destination = prefix_new();
  787. memcpy (ifc->destination, destination, sizeof(struct prefix));
  788. }
  789. /* Add connected address to the interface. */
  790. listnode_add (ifp->connected, ifc);
  791. return ifc;
  792. }
  793. #ifndef HAVE_IF_NAMETOINDEX
  794. ifindex_t
  795. if_nametoindex (const char *name)
  796. {
  797. struct interface *ifp;
  798. return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
  799. ? ifp->ifindex : 0;
  800. }
  801. #endif
  802. #ifndef HAVE_IF_INDEXTONAME
  803. char *
  804. if_indextoname (ifindex_t ifindex, char *name)
  805. {
  806. struct interface *ifp;
  807. if (!(ifp = if_lookup_by_index(ifindex)))
  808. return NULL;
  809. strncpy (name, ifp->name, IFNAMSIZ);
  810. return ifp->name;
  811. }
  812. #endif
  813. #if 0 /* this route_table of struct connected's is unused
  814. * however, it would be good to use a route_table rather than
  815. * a list..
  816. */
  817. /* Interface looking up by interface's address. */
  818. /* Interface's IPv4 address reverse lookup table. */
  819. struct route_table *ifaddr_ipv4_table;
  820. /* struct route_table *ifaddr_ipv6_table; */
  821. static void
  822. ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
  823. {
  824. struct route_node *rn;
  825. struct prefix_ipv4 p;
  826. p.family = AF_INET;
  827. p.prefixlen = IPV4_MAX_PREFIXLEN;
  828. p.prefix = *ifaddr;
  829. rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
  830. if (rn)
  831. {
  832. route_unlock_node (rn);
  833. zlog_info ("ifaddr_ipv4_add(): address %s is already added",
  834. inet_ntoa (*ifaddr));
  835. return;
  836. }
  837. rn->info = ifp;
  838. }
  839. static void
  840. ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
  841. {
  842. struct route_node *rn;
  843. struct prefix_ipv4 p;
  844. p.family = AF_INET;
  845. p.prefixlen = IPV4_MAX_PREFIXLEN;
  846. p.prefix = *ifaddr;
  847. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  848. if (! rn)
  849. {
  850. zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
  851. inet_ntoa (*ifaddr));
  852. return;
  853. }
  854. rn->info = NULL;
  855. route_unlock_node (rn);
  856. route_unlock_node (rn);
  857. }
  858. /* Lookup interface by interface's IP address or interface index. */
  859. static struct interface *
  860. ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
  861. {
  862. struct prefix_ipv4 p;
  863. struct route_node *rn;
  864. struct interface *ifp;
  865. if (addr)
  866. {
  867. p.family = AF_INET;
  868. p.prefixlen = IPV4_MAX_PREFIXLEN;
  869. p.prefix = *addr;
  870. rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
  871. if (! rn)
  872. return NULL;
  873. ifp = rn->info;
  874. route_unlock_node (rn);
  875. return ifp;
  876. }
  877. else
  878. return if_lookup_by_index(ifindex);
  879. }
  880. #endif /* ifaddr_ipv4_table */
  881. /* Initialize interface list. */
  882. void
  883. if_init (vrf_id_t vrf_id, struct list **intf_list)
  884. {
  885. *intf_list = list_new ();
  886. #if 0
  887. ifaddr_ipv4_table = route_table_init ();
  888. #endif /* ifaddr_ipv4_table */
  889. (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
  890. if (vrf_id == VRF_DEFAULT)
  891. iflist = *intf_list;
  892. }
  893. void
  894. if_terminate (vrf_id_t vrf_id, struct list **intf_list)
  895. {
  896. for (;;)
  897. {
  898. struct interface *ifp;
  899. ifp = listnode_head (*intf_list);
  900. if (ifp == NULL)
  901. break;
  902. if_delete (ifp);
  903. }
  904. list_delete (*intf_list);
  905. *intf_list = NULL;
  906. if (vrf_id == VRF_DEFAULT)
  907. iflist = NULL;
  908. }
  909. const char *
  910. if_link_type_str (enum zebra_link_type llt)
  911. {
  912. switch (llt)
  913. {
  914. #define llts(T,S) case (T): return (S)
  915. llts(ZEBRA_LLT_UNKNOWN, "Unknown");
  916. llts(ZEBRA_LLT_ETHER, "Ethernet");
  917. llts(ZEBRA_LLT_EETHER, "Experimental Ethernet");
  918. llts(ZEBRA_LLT_AX25, "AX.25 Level 2");
  919. llts(ZEBRA_LLT_PRONET, "PROnet token ring");
  920. llts(ZEBRA_LLT_IEEE802, "IEEE 802.2 Ethernet/TR/TB");
  921. llts(ZEBRA_LLT_ARCNET, "ARCnet");
  922. llts(ZEBRA_LLT_APPLETLK, "AppleTalk");
  923. llts(ZEBRA_LLT_DLCI, "Frame Relay DLCI");
  924. llts(ZEBRA_LLT_ATM, "ATM");
  925. llts(ZEBRA_LLT_METRICOM, "Metricom STRIP");
  926. llts(ZEBRA_LLT_IEEE1394, "IEEE 1394 IPv4");
  927. llts(ZEBRA_LLT_EUI64, "EUI-64");
  928. llts(ZEBRA_LLT_INFINIBAND, "InfiniBand");
  929. llts(ZEBRA_LLT_SLIP, "SLIP");
  930. llts(ZEBRA_LLT_CSLIP, "Compressed SLIP");
  931. llts(ZEBRA_LLT_SLIP6, "SLIPv6");
  932. llts(ZEBRA_LLT_CSLIP6, "Compressed SLIPv6");
  933. llts(ZEBRA_LLT_ROSE, "ROSE packet radio");
  934. llts(ZEBRA_LLT_X25, "CCITT X.25");
  935. llts(ZEBRA_LLT_PPP, "PPP");
  936. llts(ZEBRA_LLT_CHDLC, "Cisco HDLC");
  937. llts(ZEBRA_LLT_RAWHDLC, "Raw HDLC");
  938. llts(ZEBRA_LLT_LAPB, "LAPB");
  939. llts(ZEBRA_LLT_IPIP, "IPIP Tunnel");
  940. llts(ZEBRA_LLT_IPIP6, "IPIP6 Tunnel");
  941. llts(ZEBRA_LLT_FRAD, "FRAD");
  942. llts(ZEBRA_LLT_SKIP, "SKIP vif");
  943. llts(ZEBRA_LLT_LOOPBACK, "Loopback");
  944. llts(ZEBRA_LLT_LOCALTLK, "Localtalk");
  945. llts(ZEBRA_LLT_FDDI, "FDDI");
  946. llts(ZEBRA_LLT_SIT, "IPv6-in-IPv4 SIT");
  947. llts(ZEBRA_LLT_IPDDP, "IP-in-DDP tunnel");
  948. llts(ZEBRA_LLT_IPGRE, "GRE over IP");
  949. llts(ZEBRA_LLT_PIMREG, "PIMSM registration");
  950. llts(ZEBRA_LLT_HIPPI, "HiPPI");
  951. llts(ZEBRA_LLT_IRDA, "IrDA");
  952. llts(ZEBRA_LLT_FCPP, "Fibre-Channel PtP");
  953. llts(ZEBRA_LLT_FCAL, "Fibre-Channel Arbitrated Loop");
  954. llts(ZEBRA_LLT_FCPL, "Fibre-Channel Public Loop");
  955. llts(ZEBRA_LLT_FCFABRIC, "Fibre-Channel Fabric");
  956. llts(ZEBRA_LLT_IEEE802_TR, "IEEE 802.2 Token Ring");
  957. llts(ZEBRA_LLT_IEEE80211, "IEEE 802.11");
  958. llts(ZEBRA_LLT_IEEE80211_RADIOTAP, "IEEE 802.11 Radiotap");
  959. llts(ZEBRA_LLT_IEEE802154, "IEEE 802.15.4");
  960. llts(ZEBRA_LLT_IEEE802154_PHY, "IEEE 802.15.4 Phy");
  961. default:
  962. zlog_warn ("Unknown value %d", llt);
  963. return "Unknown type!";
  964. #undef llts
  965. }
  966. return NULL;
  967. }
  968. struct if_link_params *
  969. if_link_params_get (struct interface *ifp)
  970. {
  971. int i;
  972. if (ifp->link_params != NULL)
  973. return ifp->link_params;
  974. struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
  975. sizeof (struct if_link_params));
  976. if (iflp == NULL) return NULL;
  977. /* Set TE metric == standard metric */
  978. iflp->te_metric = ifp->metric;
  979. /* Compute default bandwidth based on interface */
  980. int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
  981. * TE_KILO_BIT / TE_BYTE);
  982. /* Set Max, Reservable and Unreserved Bandwidth */
  983. iflp->max_bw = bw;
  984. iflp->max_rsv_bw = bw;
  985. for (i = 0; i < MAX_CLASS_TYPE; i++)
  986. iflp->unrsv_bw[i] = bw;
  987. /* Update Link parameters status */
  988. iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
  989. /* Finally attach newly created Link Parameters */
  990. ifp->link_params = iflp;
  991. return iflp;
  992. }
  993. void
  994. if_link_params_free (struct interface *ifp)
  995. {
  996. if (ifp->link_params == NULL) return;
  997. XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
  998. ifp->link_params = NULL;
  999. }