File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / vrf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (8 years ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /*
    2:  * VRF functions.
    3:  * Copyright (C) 2014 6WIND S.A.
    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: 
   23: #include <zebra.h>
   24: 
   25: #ifdef HAVE_NETNS
   26: #undef  _GNU_SOURCE
   27: #define _GNU_SOURCE
   28: 
   29: #include <sched.h>
   30: #endif
   31: 
   32: #include "if.h"
   33: #include "vrf.h"
   34: #include "prefix.h"
   35: #include "table.h"
   36: #include "log.h"
   37: #include "memory.h"
   38: #include "command.h"
   39: #include "vty.h"
   40: 
   41: 
   42: #ifndef CLONE_NEWNET
   43: #define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
   44: #endif
   45: 
   46: #ifndef HAVE_SETNS
   47: static inline int setns(int fd, int nstype)
   48: {
   49: #ifdef __NR_setns
   50:   return syscall(__NR_setns, fd, nstype);
   51: #else
   52:   errno = ENOSYS;
   53:   return -1;
   54: #endif
   55: }
   56: #endif /* HAVE_SETNS */
   57: 
   58: #define VRF_RUN_DIR         "/var/run/netns"
   59: 
   60: #ifdef HAVE_NETNS
   61: 
   62: #define VRF_DEFAULT_NAME    "/proc/self/ns/net"
   63: static int have_netns_enabled = -1;
   64: 
   65: #else /* !HAVE_NETNS */
   66: 
   67: #define VRF_DEFAULT_NAME    "Default-IP-Routing-Table"
   68: 
   69: #endif /* HAVE_NETNS */
   70: 
   71: static int have_netns(void)
   72: {
   73: #ifdef HAVE_NETNS
   74:   if (have_netns_enabled < 0)
   75:     {
   76:         int fd = open (VRF_DEFAULT_NAME, O_RDONLY);
   77: 
   78:         if (fd < 0)
   79:           have_netns_enabled = 0;
   80:         else
   81:           {
   82:             have_netns_enabled = 1;
   83:             close(fd);
   84:           }
   85:     }
   86:   return have_netns_enabled;
   87: #else
   88:   return 0;
   89: #endif
   90: }
   91: 
   92: struct vrf
   93: {
   94:   /* Identifier, same as the vector index */
   95:   vrf_id_t vrf_id;
   96:   /* Name */
   97:   char *name;
   98:   /* File descriptor */
   99:   int fd;
  100: 
  101:   /* Master list of interfaces belonging to this VRF */
  102:   struct list *iflist;
  103: 
  104:   /* User data */
  105:   void *info;
  106: };
  107: 
  108: /* Holding VRF hooks  */
  109: struct vrf_master
  110: {
  111:   int (*vrf_new_hook) (vrf_id_t, void **);
  112:   int (*vrf_delete_hook) (vrf_id_t, void **);
  113:   int (*vrf_enable_hook) (vrf_id_t, void **);
  114:   int (*vrf_disable_hook) (vrf_id_t, void **);
  115: } vrf_master = {0,};
  116: 
  117: /* VRF table */
  118: struct route_table *vrf_table = NULL;
  119: 
  120: static int vrf_is_enabled (struct vrf *vrf);
  121: static int vrf_enable (struct vrf *vrf);
  122: static void vrf_disable (struct vrf *vrf);
  123: 
  124: 
  125: /* Build the table key */
  126: static void
  127: vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
  128: {
  129:   p->family = AF_INET;
  130:   p->prefixlen = IPV4_MAX_BITLEN;
  131:   p->u.prefix4.s_addr = vrf_id;
  132: }
  133: 
  134: /* Get a VRF. If not found, create one. */
  135: static struct vrf *
  136: vrf_get (vrf_id_t vrf_id)
  137: {
  138:   struct prefix p;
  139:   struct route_node *rn;
  140:   struct vrf *vrf;
  141: 
  142:   vrf_build_key (vrf_id, &p);
  143:   rn = route_node_get (vrf_table, &p);
  144:   if (rn->info)
  145:     {
  146:       vrf = (struct vrf *)rn->info;
  147:       route_unlock_node (rn); /* get */
  148:       return vrf;
  149:     }
  150: 
  151:   vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
  152:   vrf->vrf_id = vrf_id;
  153:   vrf->fd = -1;
  154:   rn->info = vrf;
  155: 
  156:   /* Initialize interfaces. */
  157:   if_init (vrf_id, &vrf->iflist);
  158: 
  159:   zlog_info ("VRF %u is created.", vrf_id);
  160: 
  161:   if (vrf_master.vrf_new_hook)
  162:     (*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
  163: 
  164:   return vrf;
  165: }
  166: 
  167: /* Delete a VRF. This is called in vrf_terminate(). */
  168: static void
  169: vrf_delete (struct vrf *vrf)
  170: {
  171:   zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
  172: 
  173:   vrf_disable (vrf);
  174: 
  175:   if (vrf_master.vrf_delete_hook)
  176:     (*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
  177: 
  178:   if_terminate (vrf->vrf_id, &vrf->iflist);
  179: 
  180:   if (vrf->name)
  181:     XFREE (MTYPE_VRF_NAME, vrf->name);
  182: 
  183:   XFREE (MTYPE_VRF, vrf);
  184: }
  185: 
  186: /* Look up a VRF by identifier. */
  187: static struct vrf *
  188: vrf_lookup (vrf_id_t vrf_id)
  189: {
  190:   struct prefix p;
  191:   struct route_node *rn;
  192:   struct vrf *vrf = NULL;
  193: 
  194:   vrf_build_key (vrf_id, &p);
  195:   rn = route_node_lookup (vrf_table, &p);
  196:   if (rn)
  197:     {
  198:       vrf = (struct vrf *)rn->info;
  199:       route_unlock_node (rn); /* lookup */
  200:     }
  201:   return vrf;
  202: }
  203: 
  204: /*
  205:  * Check whether the VRF is enabled - that is, whether the VRF
  206:  * is ready to allocate resources. Currently there's only one
  207:  * type of resource: socket.
  208:  */
  209: static int
  210: vrf_is_enabled (struct vrf *vrf)
  211: {
  212:   if (have_netns())
  213:       return vrf && vrf->fd >= 0;
  214:   else
  215:       return vrf && vrf->fd == -2 && vrf->vrf_id == VRF_DEFAULT;
  216: }
  217: 
  218: /*
  219:  * Enable a VRF - that is, let the VRF be ready to use.
  220:  * The VRF_ENABLE_HOOK callback will be called to inform
  221:  * that they can allocate resources in this VRF.
  222:  *
  223:  * RETURN: 1 - enabled successfully; otherwise, 0.
  224:  */
  225: static int
  226: vrf_enable (struct vrf *vrf)
  227: {
  228: 
  229:   if (!vrf_is_enabled (vrf))
  230:     {
  231:       if (have_netns()) {
  232:         vrf->fd = open (vrf->name, O_RDONLY);
  233:       } else {
  234:         vrf->fd = -2; /* Remember that vrf_enable_hook has been called */
  235:         errno = -ENOTSUP;
  236:       }
  237: 
  238:       if (!vrf_is_enabled (vrf))
  239:         {
  240:           zlog_err ("Can not enable VRF %u: %s!",
  241:                     vrf->vrf_id, safe_strerror (errno));
  242:           return 0;
  243:         }
  244: 
  245:       if (have_netns())
  246:         zlog_info ("VRF %u is associated with NETNS %s.",
  247:                    vrf->vrf_id, vrf->name);
  248: 
  249:       zlog_info ("VRF %u is enabled.", vrf->vrf_id);
  250:       if (vrf_master.vrf_enable_hook)
  251:         (*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
  252:     }
  253: 
  254:   return 1;
  255: }
  256: 
  257: /*
  258:  * Disable a VRF - that is, let the VRF be unusable.
  259:  * The VRF_DELETE_HOOK callback will be called to inform
  260:  * that they must release the resources in the VRF.
  261:  */
  262: static void
  263: vrf_disable (struct vrf *vrf)
  264: {
  265:   if (vrf_is_enabled (vrf))
  266:     {
  267:       zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
  268: 
  269:       if (vrf_master.vrf_disable_hook)
  270:         (*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
  271: 
  272:       if (have_netns())
  273:         close (vrf->fd);
  274: 
  275:       vrf->fd = -1;
  276:     }
  277: }
  278: 
  279: 
  280: /* Add a VRF hook. Please add hooks before calling vrf_init(). */
  281: void
  282: vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
  283: {
  284:   switch (type) {
  285:   case VRF_NEW_HOOK:
  286:     vrf_master.vrf_new_hook = func;
  287:     break;
  288:   case VRF_DELETE_HOOK:
  289:     vrf_master.vrf_delete_hook = func;
  290:     break;
  291:   case VRF_ENABLE_HOOK:
  292:     vrf_master.vrf_enable_hook = func;
  293:     break;
  294:   case VRF_DISABLE_HOOK:
  295:     vrf_master.vrf_disable_hook = func;
  296:     break;
  297:   default:
  298:     break;
  299:   }
  300: }
  301: 
  302: /* Return the iterator of the first VRF. */
  303: vrf_iter_t
  304: vrf_first (void)
  305: {
  306:   struct route_node *rn;
  307: 
  308:   for (rn = route_top (vrf_table); rn; rn = route_next (rn))
  309:     if (rn->info)
  310:       {
  311:         route_unlock_node (rn); /* top/next */
  312:         return (vrf_iter_t)rn;
  313:       }
  314:   return VRF_ITER_INVALID;
  315: }
  316: 
  317: /* Return the next VRF iterator to the given iterator. */
  318: vrf_iter_t
  319: vrf_next (vrf_iter_t iter)
  320: {
  321:   struct route_node *rn = NULL;
  322: 
  323:   /* Lock it first because route_next() will unlock it. */
  324:   if (iter != VRF_ITER_INVALID)
  325:     rn = route_next (route_lock_node ((struct route_node *)iter));
  326: 
  327:   for (; rn; rn = route_next (rn))
  328:     if (rn->info)
  329:       {
  330:         route_unlock_node (rn); /* next */
  331:         return (vrf_iter_t)rn;
  332:       }
  333:   return VRF_ITER_INVALID;
  334: }
  335: 
  336: /* Return the VRF iterator of the given VRF ID. If it does not exist,
  337:  * the iterator of the next existing VRF is returned. */
  338: vrf_iter_t
  339: vrf_iterator (vrf_id_t vrf_id)
  340: {
  341:   struct prefix p;
  342:   struct route_node *rn;
  343: 
  344:   vrf_build_key (vrf_id, &p);
  345:   rn = route_node_get (vrf_table, &p);
  346:   if (rn->info)
  347:     {
  348:       /* OK, the VRF exists. */
  349:       route_unlock_node (rn); /* get */
  350:       return (vrf_iter_t)rn;
  351:     }
  352: 
  353:   /* Find the next VRF. */
  354:   for (rn = route_next (rn); rn; rn = route_next (rn))
  355:     if (rn->info)
  356:       {
  357:         route_unlock_node (rn); /* next */
  358:         return (vrf_iter_t)rn;
  359:       }
  360: 
  361:   return VRF_ITER_INVALID;
  362: }
  363: 
  364: /* Obtain the VRF ID from the given VRF iterator. */
  365: vrf_id_t
  366: vrf_iter2id (vrf_iter_t iter)
  367: {
  368:   struct route_node *rn = (struct route_node *) iter;
  369:   return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
  370: }
  371: 
  372: /* Obtain the data pointer from the given VRF iterator. */
  373: void *
  374: vrf_iter2info (vrf_iter_t iter)
  375: {
  376:   struct route_node *rn = (struct route_node *) iter;
  377:   return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
  378: }
  379: 
  380: /* Obtain the interface list from the given VRF iterator. */
  381: struct list *
  382: vrf_iter2iflist (vrf_iter_t iter)
  383: {
  384:   struct route_node *rn = (struct route_node *) iter;
  385:   return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
  386: }
  387: 
  388: /* Get the data pointer of the specified VRF. If not found, create one. */
  389: void *
  390: vrf_info_get (vrf_id_t vrf_id)
  391: {
  392:   struct vrf *vrf = vrf_get (vrf_id);
  393:   return vrf->info;
  394: }
  395: 
  396: /* Look up the data pointer of the specified VRF. */
  397: void *
  398: vrf_info_lookup (vrf_id_t vrf_id)
  399: {
  400:   struct vrf *vrf = vrf_lookup (vrf_id);
  401:   return vrf ? vrf->info : NULL;
  402: }
  403: 
  404: /* Look up the interface list in a VRF. */
  405: struct list *
  406: vrf_iflist (vrf_id_t vrf_id)
  407: {
  408:    struct vrf * vrf = vrf_lookup (vrf_id);
  409:    return vrf ? vrf->iflist : NULL;
  410: }
  411: 
  412: /* Get the interface list of the specified VRF. Create one if not find. */
  413: struct list *
  414: vrf_iflist_get (vrf_id_t vrf_id)
  415: {
  416:    struct vrf * vrf = vrf_get (vrf_id);
  417:    return vrf->iflist;
  418: }
  419: 
  420: /*
  421:  * VRF bit-map
  422:  */
  423: 
  424: #define VRF_BITMAP_NUM_OF_GROUPS            8
  425: #define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
  426:     (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
  427: #define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
  428:     (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
  429: 
  430: #define VRF_BITMAP_GROUP(_id) \
  431:     ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
  432: #define VRF_BITMAP_BIT_OFFSET(_id) \
  433:     ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
  434: 
  435: #define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
  436:     ((_bit_offset) / CHAR_BIT)
  437: #define VRF_BITMAP_FLAG(_bit_offset) \
  438:     (((u_char)1) << ((_bit_offset) % CHAR_BIT))
  439: 
  440: struct vrf_bitmap
  441: {
  442:   u_char *groups[VRF_BITMAP_NUM_OF_GROUPS];
  443: };
  444: 
  445: vrf_bitmap_t
  446: vrf_bitmap_init (void)
  447: {
  448:   return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
  449: }
  450: 
  451: void
  452: vrf_bitmap_free (vrf_bitmap_t bmap)
  453: {
  454:   struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
  455:   int i;
  456: 
  457:   if (bmap == VRF_BITMAP_NULL)
  458:     return;
  459: 
  460:   for (i = 0; i < VRF_BITMAP_NUM_OF_GROUPS; i++)
  461:     if (bm->groups[i])
  462:       XFREE (MTYPE_VRF_BITMAP, bm->groups[i]);
  463: 
  464:   XFREE (MTYPE_VRF_BITMAP, bm);
  465: }
  466: 
  467: void
  468: vrf_bitmap_set (vrf_bitmap_t bmap, vrf_id_t vrf_id)
  469: {
  470:   struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
  471:   u_char group = VRF_BITMAP_GROUP (vrf_id);
  472:   u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
  473: 
  474:   if (bmap == VRF_BITMAP_NULL)
  475:     return;
  476: 
  477:   if (bm->groups[group] == NULL)
  478:     bm->groups[group] = XCALLOC (MTYPE_VRF_BITMAP,
  479:                                  VRF_BITMAP_NUM_OF_BYTES_IN_GROUP);
  480: 
  481:   SET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
  482:             VRF_BITMAP_FLAG (offset));
  483: }
  484: 
  485: void
  486: vrf_bitmap_unset (vrf_bitmap_t bmap, vrf_id_t vrf_id)
  487: {
  488:   struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
  489:   u_char group = VRF_BITMAP_GROUP (vrf_id);
  490:   u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
  491: 
  492:   if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
  493:     return;
  494: 
  495:   UNSET_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
  496:               VRF_BITMAP_FLAG (offset));
  497: }
  498: 
  499: int
  500: vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
  501: {
  502:   struct vrf_bitmap *bm = (struct vrf_bitmap *) bmap;
  503:   u_char group = VRF_BITMAP_GROUP (vrf_id);
  504:   u_char offset = VRF_BITMAP_BIT_OFFSET (vrf_id);
  505: 
  506:   if (bmap == VRF_BITMAP_NULL || bm->groups[group] == NULL)
  507:     return 0;
  508: 
  509:   return CHECK_FLAG (bm->groups[group][VRF_BITMAP_INDEX_IN_GROUP (offset)],
  510:                      VRF_BITMAP_FLAG (offset)) ? 1 : 0;
  511: }
  512: 
  513: /*
  514:  * VRF realization with NETNS
  515:  */
  516: 
  517: static char *
  518: vrf_netns_pathname (struct vty *vty, const char *name)
  519: {
  520:   static char pathname[PATH_MAX];
  521:   char *result;
  522: 
  523:   if (name[0] == '/') /* absolute pathname */
  524:     result = realpath (name, pathname);
  525:   else /* relevant pathname */
  526:     {
  527:       char tmp_name[PATH_MAX];
  528:       snprintf (tmp_name, PATH_MAX, "%s/%s", VRF_RUN_DIR, name);
  529:       result = realpath (tmp_name, pathname);
  530:     }
  531: 
  532:   if (! result)
  533:     {
  534:       vty_out (vty, "Invalid pathname: %s%s", safe_strerror (errno),
  535:                VTY_NEWLINE);
  536:       return NULL;
  537:     }
  538:   return pathname;
  539: }
  540: 
  541: DEFUN (vrf_netns,
  542:        vrf_netns_cmd,
  543:        "vrf <1-65535> netns NAME",
  544:        "Enable a VRF\n"
  545:        "Specify the VRF identifier\n"
  546:        "Associate with a NETNS\n"
  547:        "The file name in " VRF_RUN_DIR ", or a full pathname\n")
  548: {
  549:   vrf_id_t vrf_id = VRF_DEFAULT;
  550:   struct vrf *vrf = NULL;
  551:   char *pathname = vrf_netns_pathname (vty, argv[1]);
  552: 
  553:   if (!pathname)
  554:     return CMD_WARNING;
  555: 
  556:   VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  557:   vrf = vrf_get (vrf_id);
  558: 
  559:   if (vrf->name && strcmp (vrf->name, pathname) != 0)
  560:     {
  561:       vty_out (vty, "VRF %u is already configured with NETNS %s%s",
  562:                vrf->vrf_id, vrf->name, VTY_NEWLINE);
  563:       return CMD_WARNING;
  564:     }
  565: 
  566:   if (!vrf->name)
  567:     vrf->name = XSTRDUP (MTYPE_VRF_NAME, pathname);
  568: 
  569:   if (!vrf_enable (vrf))
  570:     {
  571:       vty_out (vty, "Can not associate VRF %u with NETNS %s%s",
  572:                vrf->vrf_id, vrf->name, VTY_NEWLINE);
  573:       return CMD_WARNING;
  574:     }
  575: 
  576:   return CMD_SUCCESS;
  577: }
  578: 
  579: DEFUN (no_vrf_netns,
  580:        no_vrf_netns_cmd,
  581:        "no vrf <1-65535> netns NAME",
  582:        NO_STR
  583:        "Enable a VRF\n"
  584:        "Specify the VRF identifier\n"
  585:        "Associate with a NETNS\n"
  586:        "The file name in " VRF_RUN_DIR ", or a full pathname\n")
  587: {
  588:   vrf_id_t vrf_id = VRF_DEFAULT;
  589:   struct vrf *vrf = NULL;
  590:   char *pathname = vrf_netns_pathname (vty, argv[1]);
  591: 
  592:   if (!pathname)
  593:     return CMD_WARNING;
  594: 
  595:   VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  596:   vrf = vrf_lookup (vrf_id);
  597: 
  598:   if (!vrf)
  599:     {
  600:       vty_out (vty, "VRF %u is not found%s", vrf_id, VTY_NEWLINE);
  601:       return CMD_SUCCESS;
  602:     }
  603: 
  604:   if (vrf->name && strcmp (vrf->name, pathname) != 0)
  605:     {
  606:       vty_out (vty, "Incorrect NETNS file name%s", VTY_NEWLINE);
  607:       return CMD_WARNING;
  608:     }
  609: 
  610:   vrf_disable (vrf);
  611: 
  612:   if (vrf->name)
  613:     {
  614:       XFREE (MTYPE_VRF_NAME, vrf->name);
  615:       vrf->name = NULL;
  616:     }
  617: 
  618:   return CMD_SUCCESS;
  619: }
  620: 
  621: /* VRF node. */
  622: static struct cmd_node vrf_node =
  623: {
  624:   VRF_NODE,
  625:   "",       /* VRF node has no interface. */
  626:   1
  627: };
  628: 
  629: /* VRF configuration write function. */
  630: static int
  631: vrf_config_write (struct vty *vty)
  632: {
  633:   struct route_node *rn;
  634:   struct vrf *vrf;
  635:   int write = 0;
  636: 
  637:   for (rn = route_top (vrf_table); rn; rn = route_next (rn))
  638:     if ((vrf = rn->info) != NULL &&
  639:         vrf->vrf_id != VRF_DEFAULT && vrf->name)
  640:       {
  641:         vty_out (vty, "vrf %u netns %s%s", vrf->vrf_id, vrf->name, VTY_NEWLINE);
  642:         write++;
  643:       }
  644: 
  645:   return write;
  646: }
  647: 
  648: /* Initialize VRF module. */
  649: void
  650: vrf_init (void)
  651: {
  652:   struct vrf *default_vrf;
  653: 
  654:   /* Allocate VRF table.  */
  655:   vrf_table = route_table_init ();
  656: 
  657:   /* The default VRF always exists. */
  658:   default_vrf = vrf_get (VRF_DEFAULT);
  659:   if (!default_vrf)
  660:     {
  661:       zlog_err ("vrf_init: failed to create the default VRF!");
  662:       exit (1);
  663:     }
  664: 
  665:   /* Set the default VRF name. */
  666:   default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, VRF_DEFAULT_NAME);
  667: 
  668:   /* Enable the default VRF. */
  669:   if (!vrf_enable (default_vrf))
  670:     {
  671:       zlog_err ("vrf_init: failed to enable the default VRF!");
  672:       exit (1);
  673:     }
  674: 
  675:   if (have_netns())
  676:     {
  677:       /* Install VRF commands. */
  678:       install_node (&vrf_node, vrf_config_write);
  679:       install_element (CONFIG_NODE, &vrf_netns_cmd);
  680:       install_element (CONFIG_NODE, &no_vrf_netns_cmd);
  681:     }
  682: }
  683: 
  684: /* Terminate VRF module. */
  685: void
  686: vrf_terminate (void)
  687: {
  688:   struct route_node *rn;
  689:   struct vrf *vrf;
  690: 
  691:   for (rn = route_top (vrf_table); rn; rn = route_next (rn))
  692:     if ((vrf = rn->info) != NULL)
  693:       vrf_delete (vrf);
  694: 
  695:   route_table_finish (vrf_table);
  696:   vrf_table = NULL;
  697: }
  698: 
  699: /* Create a socket for the VRF. */
  700: int
  701: vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
  702: {
  703:   struct vrf *vrf = vrf_lookup (vrf_id);
  704:   int ret = -1;
  705: 
  706:   if (!vrf_is_enabled (vrf))
  707:     {
  708:       errno = ENOSYS;
  709:       return -1;
  710:     }
  711: 
  712:   if (have_netns())
  713:     {
  714:       ret = (vrf_id != VRF_DEFAULT) ? setns (vrf->fd, CLONE_NEWNET) : 0;
  715:       if (ret >= 0)
  716:         {
  717:           ret = socket (domain, type, protocol);
  718:           if (vrf_id != VRF_DEFAULT)
  719:             setns (vrf_lookup (VRF_DEFAULT)->fd, CLONE_NEWNET);
  720:         }
  721:     }
  722:   else
  723:     ret = socket (domain, type, protocol);
  724: 
  725:   return ret;
  726: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>