Annotation of embedaddon/quagga/lib/vrf.c, revision 1.1.1.1

1.1       misho       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>