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
setns(int fd,int nstype)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 
have_netns(void)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
vrf_build_key(vrf_id_t vrf_id,struct prefix * p)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 *
vrf_get(vrf_id_t vrf_id)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
vrf_delete(struct vrf * vrf)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 *
vrf_lookup(vrf_id_t vrf_id)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
vrf_is_enabled(struct vrf * vrf)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
vrf_enable(struct vrf * vrf)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
vrf_disable(struct vrf * vrf)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
vrf_add_hook(int type,int (* func)(vrf_id_t,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
vrf_first(void)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
vrf_next(vrf_iter_t iter)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
vrf_iterator(vrf_id_t vrf_id)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
vrf_iter2id(vrf_iter_t iter)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 *
vrf_iter2info(vrf_iter_t iter)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 *
vrf_iter2iflist(vrf_iter_t iter)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 *
vrf_info_get(vrf_id_t vrf_id)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 *
vrf_info_lookup(vrf_id_t vrf_id)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 *
vrf_iflist(vrf_id_t vrf_id)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 *
vrf_iflist_get(vrf_id_t vrf_id)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
vrf_bitmap_init(void)446 vrf_bitmap_init (void)
447 {
448   return (vrf_bitmap_t) XCALLOC (MTYPE_VRF_BITMAP, sizeof (struct vrf_bitmap));
449 }
450 
451 void
vrf_bitmap_free(vrf_bitmap_t bmap)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
vrf_bitmap_set(vrf_bitmap_t bmap,vrf_id_t vrf_id)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
vrf_bitmap_unset(vrf_bitmap_t bmap,vrf_id_t vrf_id)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
vrf_bitmap_check(vrf_bitmap_t bmap,vrf_id_t vrf_id)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 *
vrf_netns_pathname(struct vty * vty,const char * name)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
vrf_config_write(struct vty * vty)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
vrf_init(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
vrf_terminate(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
vrf_socket(int domain,int type,int protocol,vrf_id_t vrf_id)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 }
727