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