3 * Copyright (C) 2014 6WIND S.A.
5 * This file is part of GNU Zebra.
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.
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.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 DEFINE_MTYPE_STATIC(LIB
, VRF
, "VRF")
33 DEFINE_MTYPE_STATIC(LIB
, VRF_BITMAP
, "VRF bit-map")
37 static __inline
int vrf_id_compare (struct vrf
*, struct vrf
*);
38 static __inline
int vrf_name_compare (struct vrf
*, struct vrf
*);
40 RB_GENERATE (vrf_id_head
, vrf
, id_entry
, vrf_id_compare
)
41 RB_GENERATE (vrf_name_head
, vrf
, name_entry
, vrf_name_compare
)
43 struct vrf_id_head vrfs_by_id
= RB_INITIALIZER (&vrfs_by_id
);
44 struct vrf_name_head vrfs_by_name
= RB_INITIALIZER (&vrfs_by_name
);
47 * Turn on/off debug code
52 /* Holding VRF hooks */
55 int (*vrf_new_hook
) (struct vrf
*);
56 int (*vrf_delete_hook
) (struct vrf
*);
57 int (*vrf_enable_hook
) (struct vrf
*);
58 int (*vrf_disable_hook
) (struct vrf
*);
61 static int vrf_is_enabled (struct vrf
*vrf
);
62 static void vrf_disable (struct vrf
*vrf
);
64 /* VRF list existance check by name. */
66 vrf_lookup_by_name (const char *name
)
69 strlcpy (vrf
.name
, name
, sizeof (vrf
.name
));
70 return (RB_FIND (vrf_name_head
, &vrfs_by_name
, &vrf
));
74 vrf_id_compare (struct vrf
*a
, struct vrf
*b
)
76 return (a
->vrf_id
- b
->vrf_id
);
80 vrf_name_compare (struct vrf
*a
, struct vrf
*b
)
82 return strcmp (a
->name
, b
->name
);
85 /* Get a VRF. If not found, create one.
87 * name - The name of the vrf. May be NULL if unknown.
88 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
89 * Description: Please note that this routine can be called with just the name
93 vrf_get (vrf_id_t vrf_id
, const char *name
)
95 struct vrf
*vrf
= NULL
;
99 zlog_debug ("VRF_GET: %s(%d)", name
, vrf_id
);
101 /* Nothing to see, move along here */
102 if (!name
&& vrf_id
== VRF_UNKNOWN
)
105 /* Try to find VRF both by ID and name */
106 if (vrf_id
!= VRF_UNKNOWN
)
107 vrf
= vrf_lookup_by_id (vrf_id
);
109 vrf
= vrf_lookup_by_name (name
);
113 vrf
= XCALLOC (MTYPE_VRF
, sizeof (struct vrf
));
114 vrf
->vrf_id
= VRF_UNKNOWN
;
115 if_init (&vrf
->iflist
);
120 zlog_debug ("VRF(%u) %s is created.",
121 vrf_id
, (name
) ? name
: "(NULL)");
125 if (vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
== VRF_UNKNOWN
)
127 vrf
->vrf_id
= vrf_id
;
128 RB_INSERT (vrf_id_head
, &vrfs_by_id
, vrf
);
132 if (name
&& vrf
->name
[0] != '\0' && strcmp (name
, vrf
->name
))
134 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
135 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
136 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
138 else if (name
&& vrf
->name
[0] == '\0')
140 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
141 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
144 if (new && vrf_master
.vrf_new_hook
)
145 (*vrf_master
.vrf_new_hook
) (vrf
);
150 /* Delete a VRF. This is called in vrf_terminate(). */
152 vrf_delete (struct vrf
*vrf
)
155 zlog_debug ("VRF %u is to be deleted.", vrf
->vrf_id
);
157 if (vrf_is_enabled (vrf
))
160 if (vrf_master
.vrf_delete_hook
)
161 (*vrf_master
.vrf_delete_hook
) (vrf
);
164 if_terminate (&vrf
->iflist
);
166 if (vrf
->vrf_id
!= VRF_UNKNOWN
)
167 RB_REMOVE (vrf_id_head
, &vrfs_by_id
, vrf
);
168 if (vrf
->name
[0] != '\0')
169 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
171 XFREE (MTYPE_VRF
, vrf
);
174 /* Look up a VRF by identifier. */
176 vrf_lookup_by_id (vrf_id_t vrf_id
)
180 return (RB_FIND (vrf_id_head
, &vrfs_by_id
, &vrf
));
184 * Check whether the VRF is enabled.
187 vrf_is_enabled (struct vrf
*vrf
)
189 return vrf
&& CHECK_FLAG (vrf
->status
, VRF_ACTIVE
);
193 * Enable a VRF - that is, let the VRF be ready to use.
194 * The VRF_ENABLE_HOOK callback will be called to inform
195 * that they can allocate resources in this VRF.
197 * RETURN: 1 - enabled successfully; otherwise, 0.
200 vrf_enable (struct vrf
*vrf
)
202 if (vrf_is_enabled (vrf
))
206 zlog_debug ("VRF %u is enabled.", vrf
->vrf_id
);
208 SET_FLAG (vrf
->status
, VRF_ACTIVE
);
210 if (vrf_master
.vrf_enable_hook
)
211 (*vrf_master
.vrf_enable_hook
) (vrf
);
217 * Disable a VRF - that is, let the VRF be unusable.
218 * The VRF_DELETE_HOOK callback will be called to inform
219 * that they must release the resources in the VRF.
222 vrf_disable (struct vrf
*vrf
)
224 if (! vrf_is_enabled (vrf
))
227 UNSET_FLAG (vrf
->status
, VRF_ACTIVE
);
230 zlog_debug ("VRF %u is to be disabled.", vrf
->vrf_id
);
232 /* Till now, nothing to be done for the default VRF. */
233 //Pending: see why this statement.
235 if (vrf_master
.vrf_disable_hook
)
236 (*vrf_master
.vrf_disable_hook
) (vrf
);
240 /* Add a VRF hook. Please add hooks before calling vrf_init(). */
242 vrf_add_hook (int type
, int (*func
)(struct vrf
*))
245 zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__
,
250 vrf_master
.vrf_new_hook
= func
;
252 case VRF_DELETE_HOOK
:
253 vrf_master
.vrf_delete_hook
= func
;
255 case VRF_ENABLE_HOOK
:
256 vrf_master
.vrf_enable_hook
= func
;
258 case VRF_DISABLE_HOOK
:
259 vrf_master
.vrf_disable_hook
= func
;
267 vrf_name_to_id (const char *name
)
270 vrf_id_t vrf_id
= VRF_DEFAULT
; //Pending: need a way to return invalid id/ routine not used.
272 vrf
= vrf_lookup_by_name (name
);
274 vrf_id
= vrf
->vrf_id
;
279 /* Get the data pointer of the specified VRF. If not found, create one. */
281 vrf_info_get (vrf_id_t vrf_id
)
283 struct vrf
*vrf
= vrf_get (vrf_id
, NULL
);
287 /* Look up the data pointer of the specified VRF. */
289 vrf_info_lookup (vrf_id_t vrf_id
)
291 struct vrf
*vrf
= vrf_lookup_by_id (vrf_id
);
292 return vrf
? vrf
->info
: NULL
;
295 /* Look up the interface list in a VRF. */
297 vrf_iflist (vrf_id_t vrf_id
)
299 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
300 return vrf
? vrf
->iflist
: NULL
;
303 /* Get the interface list of the specified VRF. Create one if not find. */
305 vrf_iflist_get (vrf_id_t vrf_id
)
307 struct vrf
* vrf
= vrf_get (vrf_id
, NULL
);
311 /* Create the interface list for the specified VRF, if needed. */
313 vrf_iflist_create (vrf_id_t vrf_id
)
315 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
316 if (vrf
&& !vrf
->iflist
)
317 if_init (&vrf
->iflist
);
320 /* Free the interface list of the specified VRF. */
322 vrf_iflist_terminate (vrf_id_t vrf_id
)
324 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
325 if (vrf
&& vrf
->iflist
)
326 if_terminate (&vrf
->iflist
);
333 #define VRF_BITMAP_NUM_OF_GROUPS 8
334 #define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
335 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
336 #define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
337 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
339 #define VRF_BITMAP_GROUP(_id) \
340 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
341 #define VRF_BITMAP_BIT_OFFSET(_id) \
342 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
344 #define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
345 ((_bit_offset) / CHAR_BIT)
346 #define VRF_BITMAP_FLAG(_bit_offset) \
347 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
351 u_char
*groups
[VRF_BITMAP_NUM_OF_GROUPS
];
355 vrf_bitmap_init (void)
357 return (vrf_bitmap_t
) XCALLOC (MTYPE_VRF_BITMAP
, sizeof (struct vrf_bitmap
));
361 vrf_bitmap_free (vrf_bitmap_t bmap
)
363 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
366 if (bmap
== VRF_BITMAP_NULL
)
369 for (i
= 0; i
< VRF_BITMAP_NUM_OF_GROUPS
; i
++)
371 XFREE (MTYPE_VRF_BITMAP
, bm
->groups
[i
]);
373 XFREE (MTYPE_VRF_BITMAP
, bm
);
377 vrf_bitmap_set (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
379 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
380 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
381 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
383 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
)
386 if (bm
->groups
[group
] == NULL
)
387 bm
->groups
[group
] = XCALLOC (MTYPE_VRF_BITMAP
,
388 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP
);
390 SET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
391 VRF_BITMAP_FLAG (offset
));
395 vrf_bitmap_unset (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
397 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
398 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
399 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
401 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
402 bm
->groups
[group
] == NULL
)
405 UNSET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
406 VRF_BITMAP_FLAG (offset
));
410 vrf_bitmap_check (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
412 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
413 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
414 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
416 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
417 bm
->groups
[group
] == NULL
)
420 return CHECK_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
421 VRF_BITMAP_FLAG (offset
)) ? 1 : 0;
424 /* Initialize VRF module. */
428 struct vrf
*default_vrf
;
431 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__
);
433 /* The default VRF always exists. */
434 default_vrf
= vrf_get (VRF_DEFAULT
, VRF_DEFAULT_NAME
);
437 zlog_err ("vrf_init: failed to create the default VRF!");
441 /* Enable the default VRF. */
442 if (!vrf_enable (default_vrf
))
444 zlog_err ("vrf_init: failed to enable the default VRF!");
449 /* Terminate VRF module. */
456 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__
);
458 while ((vrf
= RB_ROOT (&vrfs_by_id
)) != NULL
)
460 while ((vrf
= RB_ROOT (&vrfs_by_name
)) != NULL
)
464 /* Create a socket for the VRF. */
466 vrf_socket (int domain
, int type
, int protocol
, vrf_id_t vrf_id
)
470 ret
= socket (domain
, type
, protocol
);
475 /* vrf CLI commands */
479 "Select a VRF to configure\n"
483 const char *vrfname
= argv
[idx_name
]->arg
;
486 if (strlen(vrfname
) > VRF_NAMSIZ
)
488 vty_out (vty
, "%% VRF name %s is invalid: length exceeds "
490 vrfname
, VRF_NAMSIZ
, VTY_NEWLINE
);
494 vrfp
= vrf_get (VRF_UNKNOWN
, vrfname
);
496 VTY_PUSH_CONTEXT (VRF_NODE
, vrfp
);
505 "Delete a pseudo VRF's configuration\n"
508 const char *vrfname
= argv
[2]->arg
;
512 vrfp
= vrf_lookup_by_name (vrfname
);
516 vty_out (vty
, "%% VRF %s does not exist%s", vrfname
, VTY_NEWLINE
);
520 if (CHECK_FLAG (vrfp
->status
, VRF_ACTIVE
))
522 vty_out (vty
, "%% Only inactive VRFs can be deleted%s",
533 struct cmd_node vrf_node
=
541 * Debug CLI for vrf's
567 vrf_write_host (struct vty
*vty
)
570 vty_out (vty
, "debug vrf%s", VTY_NEWLINE
);
575 static struct cmd_node vrf_debug_node
=
583 vrf_install_commands (void)
585 install_node (&vrf_debug_node
, vrf_write_host
);
587 install_element (CONFIG_NODE
, &vrf_debug_cmd
);
588 install_element (ENABLE_NODE
, &vrf_debug_cmd
);
589 install_element (CONFIG_NODE
, &no_vrf_debug_cmd
);
590 install_element (ENABLE_NODE
, &no_vrf_debug_cmd
);
594 vrf_cmd_init (int (*writefunc
)(struct vty
*vty
))
596 install_element (CONFIG_NODE
, &vrf_cmd
);
597 install_element (CONFIG_NODE
, &no_vrf_cmd
);
598 install_node (&vrf_node
, writefunc
);
599 install_default (VRF_NODE
);