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
33 DEFINE_MTYPE_STATIC(LIB
, VRF
, "VRF")
34 DEFINE_MTYPE_STATIC(LIB
, VRF_BITMAP
, "VRF bit-map")
38 static __inline
int vrf_id_compare (const struct vrf
*, const struct vrf
*);
39 static __inline
int vrf_name_compare (const struct vrf
*, const struct vrf
*);
41 RB_GENERATE (vrf_id_head
, vrf
, id_entry
, vrf_id_compare
);
42 RB_GENERATE (vrf_name_head
, vrf
, name_entry
, vrf_name_compare
);
44 struct vrf_id_head vrfs_by_id
= RB_INITIALIZER (&vrfs_by_id
);
45 struct vrf_name_head vrfs_by_name
= RB_INITIALIZER (&vrfs_by_name
);
48 * Turn on/off debug code
53 /* Holding VRF hooks */
56 int (*vrf_new_hook
) (struct vrf
*);
57 int (*vrf_delete_hook
) (struct vrf
*);
58 int (*vrf_enable_hook
) (struct vrf
*);
59 int (*vrf_disable_hook
) (struct vrf
*);
62 static int vrf_is_enabled (struct vrf
*vrf
);
63 static void vrf_disable (struct vrf
*vrf
);
65 /* VRF list existance check by name. */
67 vrf_lookup_by_name (const char *name
)
70 strlcpy (vrf
.name
, name
, sizeof (vrf
.name
));
71 return (RB_FIND (vrf_name_head
, &vrfs_by_name
, &vrf
));
75 vrf_id_compare (const struct vrf
*a
, const struct vrf
*b
)
77 return (a
->vrf_id
- b
->vrf_id
);
81 vrf_name_compare (const struct vrf
*a
, const struct vrf
*b
)
83 return strcmp (a
->name
, b
->name
);
86 /* Get a VRF. If not found, create one.
88 * name - The name of the vrf. May be NULL if unknown.
89 * vrf_id - The vrf_id of the vrf. May be VRF_UNKNOWN if unknown
90 * Description: Please note that this routine can be called with just the name
94 vrf_get (vrf_id_t vrf_id
, const char *name
)
96 struct vrf
*vrf
= NULL
;
100 zlog_debug ("VRF_GET: %s(%d)", name
, vrf_id
);
102 /* Nothing to see, move along here */
103 if (!name
&& vrf_id
== VRF_UNKNOWN
)
106 /* Try to find VRF both by ID and name */
107 if (vrf_id
!= VRF_UNKNOWN
)
108 vrf
= vrf_lookup_by_id (vrf_id
);
110 vrf
= vrf_lookup_by_name (name
);
114 vrf
= XCALLOC (MTYPE_VRF
, sizeof (struct vrf
));
115 vrf
->vrf_id
= VRF_UNKNOWN
;
116 if_init (&vrf
->iflist
);
121 zlog_debug ("VRF(%u) %s is created.",
122 vrf_id
, (name
) ? name
: "(NULL)");
126 if (vrf_id
!= VRF_UNKNOWN
&& vrf
->vrf_id
== VRF_UNKNOWN
)
128 vrf
->vrf_id
= vrf_id
;
129 RB_INSERT (vrf_id_head
, &vrfs_by_id
, vrf
);
133 if (name
&& vrf
->name
[0] != '\0' && strcmp (name
, vrf
->name
))
135 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
136 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
137 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
139 else if (name
&& vrf
->name
[0] == '\0')
141 strlcpy (vrf
->name
, name
, sizeof (vrf
->name
));
142 RB_INSERT (vrf_name_head
, &vrfs_by_name
, vrf
);
145 if (new && vrf_master
.vrf_new_hook
)
146 (*vrf_master
.vrf_new_hook
) (vrf
);
151 /* Delete a VRF. This is called in vrf_terminate(). */
153 vrf_delete (struct vrf
*vrf
)
156 zlog_debug ("VRF %u is to be deleted.", vrf
->vrf_id
);
158 if (vrf_is_enabled (vrf
))
161 if (vrf_master
.vrf_delete_hook
)
162 (*vrf_master
.vrf_delete_hook
) (vrf
);
165 if_terminate (&vrf
->iflist
);
167 if (vrf
->vrf_id
!= VRF_UNKNOWN
)
168 RB_REMOVE (vrf_id_head
, &vrfs_by_id
, vrf
);
169 if (vrf
->name
[0] != '\0')
170 RB_REMOVE (vrf_name_head
, &vrfs_by_name
, vrf
);
172 XFREE (MTYPE_VRF
, vrf
);
175 /* Look up a VRF by identifier. */
177 vrf_lookup_by_id (vrf_id_t vrf_id
)
181 return (RB_FIND (vrf_id_head
, &vrfs_by_id
, &vrf
));
185 * Check whether the VRF is enabled.
188 vrf_is_enabled (struct vrf
*vrf
)
190 return vrf
&& CHECK_FLAG (vrf
->status
, VRF_ACTIVE
);
194 * Enable a VRF - that is, let the VRF be ready to use.
195 * The VRF_ENABLE_HOOK callback will be called to inform
196 * that they can allocate resources in this VRF.
198 * RETURN: 1 - enabled successfully; otherwise, 0.
201 vrf_enable (struct vrf
*vrf
)
203 if (vrf_is_enabled (vrf
))
207 zlog_debug ("VRF %u is enabled.", vrf
->vrf_id
);
209 SET_FLAG (vrf
->status
, VRF_ACTIVE
);
211 if (vrf_master
.vrf_enable_hook
)
212 (*vrf_master
.vrf_enable_hook
) (vrf
);
218 * Disable a VRF - that is, let the VRF be unusable.
219 * The VRF_DELETE_HOOK callback will be called to inform
220 * that they must release the resources in the VRF.
223 vrf_disable (struct vrf
*vrf
)
225 if (! vrf_is_enabled (vrf
))
228 UNSET_FLAG (vrf
->status
, VRF_ACTIVE
);
231 zlog_debug ("VRF %u is to be disabled.", vrf
->vrf_id
);
233 /* Till now, nothing to be done for the default VRF. */
234 //Pending: see why this statement.
236 if (vrf_master
.vrf_disable_hook
)
237 (*vrf_master
.vrf_disable_hook
) (vrf
);
241 vrf_name_to_id (const char *name
)
244 vrf_id_t vrf_id
= VRF_DEFAULT
; //Pending: need a way to return invalid id/ routine not used.
246 vrf
= vrf_lookup_by_name (name
);
248 vrf_id
= vrf
->vrf_id
;
253 /* Get the data pointer of the specified VRF. If not found, create one. */
255 vrf_info_get (vrf_id_t vrf_id
)
257 struct vrf
*vrf
= vrf_get (vrf_id
, NULL
);
261 /* Look up the data pointer of the specified VRF. */
263 vrf_info_lookup (vrf_id_t vrf_id
)
265 struct vrf
*vrf
= vrf_lookup_by_id (vrf_id
);
266 return vrf
? vrf
->info
: NULL
;
269 /* Look up the interface list in a VRF. */
271 vrf_iflist (vrf_id_t vrf_id
)
273 struct vrf
* vrf
= vrf_lookup_by_id (vrf_id
);
274 return vrf
? vrf
->iflist
: NULL
;
277 /* Get the interface list of the specified VRF. Create one if not find. */
279 vrf_iflist_get (vrf_id_t vrf_id
)
281 struct vrf
* vrf
= vrf_get (vrf_id
, NULL
);
289 #define VRF_BITMAP_NUM_OF_GROUPS 8
290 #define VRF_BITMAP_NUM_OF_BITS_IN_GROUP \
291 (UINT16_MAX / VRF_BITMAP_NUM_OF_GROUPS)
292 #define VRF_BITMAP_NUM_OF_BYTES_IN_GROUP \
293 (VRF_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
295 #define VRF_BITMAP_GROUP(_id) \
296 ((_id) / VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
297 #define VRF_BITMAP_BIT_OFFSET(_id) \
298 ((_id) % VRF_BITMAP_NUM_OF_BITS_IN_GROUP)
300 #define VRF_BITMAP_INDEX_IN_GROUP(_bit_offset) \
301 ((_bit_offset) / CHAR_BIT)
302 #define VRF_BITMAP_FLAG(_bit_offset) \
303 (((u_char)1) << ((_bit_offset) % CHAR_BIT))
307 u_char
*groups
[VRF_BITMAP_NUM_OF_GROUPS
];
311 vrf_bitmap_init (void)
313 return (vrf_bitmap_t
) XCALLOC (MTYPE_VRF_BITMAP
, sizeof (struct vrf_bitmap
));
317 vrf_bitmap_free (vrf_bitmap_t bmap
)
319 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
322 if (bmap
== VRF_BITMAP_NULL
)
325 for (i
= 0; i
< VRF_BITMAP_NUM_OF_GROUPS
; i
++)
327 XFREE (MTYPE_VRF_BITMAP
, bm
->groups
[i
]);
329 XFREE (MTYPE_VRF_BITMAP
, bm
);
333 vrf_bitmap_set (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
335 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
336 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
337 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
339 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
)
342 if (bm
->groups
[group
] == NULL
)
343 bm
->groups
[group
] = XCALLOC (MTYPE_VRF_BITMAP
,
344 VRF_BITMAP_NUM_OF_BYTES_IN_GROUP
);
346 SET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
347 VRF_BITMAP_FLAG (offset
));
351 vrf_bitmap_unset (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
353 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
354 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
355 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
357 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
358 bm
->groups
[group
] == NULL
)
361 UNSET_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
362 VRF_BITMAP_FLAG (offset
));
366 vrf_bitmap_check (vrf_bitmap_t bmap
, vrf_id_t vrf_id
)
368 struct vrf_bitmap
*bm
= (struct vrf_bitmap
*) bmap
;
369 u_char group
= VRF_BITMAP_GROUP (vrf_id
);
370 u_char offset
= VRF_BITMAP_BIT_OFFSET (vrf_id
);
372 if (bmap
== VRF_BITMAP_NULL
|| vrf_id
== VRF_UNKNOWN
||
373 bm
->groups
[group
] == NULL
)
376 return CHECK_FLAG (bm
->groups
[group
][VRF_BITMAP_INDEX_IN_GROUP (offset
)],
377 VRF_BITMAP_FLAG (offset
)) ? 1 : 0;
381 vrf_autocomplete (vector comps
, struct cmd_token
*token
)
383 struct vrf
*vrf
= NULL
;
385 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
387 if (vrf
->vrf_id
!= 0)
388 vector_set (comps
, XSTRDUP (MTYPE_COMPLETION
, vrf
->name
));
392 static const struct cmd_variable_handler vrf_var_handlers
[] = {
395 .completions
= vrf_autocomplete
,
402 /* Initialize VRF module. */
404 vrf_init (int (*create
)(struct vrf
*),
405 int (*enable
)(struct vrf
*),
406 int (*disable
)(struct vrf
*),
407 int (*delete)(struct vrf
*))
409 struct vrf
*default_vrf
;
412 zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__
);
414 vrf_master
.vrf_new_hook
= create
;
415 vrf_master
.vrf_enable_hook
= enable
;
416 vrf_master
.vrf_disable_hook
= disable
;
417 vrf_master
.vrf_delete_hook
= delete;
419 /* The default VRF always exists. */
420 default_vrf
= vrf_get (VRF_DEFAULT
, VRF_DEFAULT_NAME
);
423 zlog_err ("vrf_init: failed to create the default VRF!");
427 /* Enable the default VRF. */
428 if (!vrf_enable (default_vrf
))
430 zlog_err ("vrf_init: failed to enable the default VRF!");
434 cmd_variable_handler_register (vrf_var_handlers
);
437 /* Terminate VRF module. */
444 zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__
);
446 while ((vrf
= RB_ROOT (vrf_id_head
, &vrfs_by_id
)) != NULL
)
448 while ((vrf
= RB_ROOT (vrf_name_head
, &vrfs_by_name
)) != NULL
)
452 /* Create a socket for the VRF. */
454 vrf_socket (int domain
, int type
, int protocol
, vrf_id_t vrf_id
)
458 ret
= socket (domain
, type
, protocol
);
463 /* vrf CLI commands */
467 "Select a VRF to configure\n"
471 const char *vrfname
= argv
[idx_name
]->arg
;
474 if (strlen(vrfname
) > VRF_NAMSIZ
)
476 vty_out (vty
, "%% VRF name %s is invalid: length exceeds "
478 vrfname
, VRF_NAMSIZ
, VTY_NEWLINE
);
482 vrfp
= vrf_get (VRF_UNKNOWN
, vrfname
);
484 VTY_PUSH_CONTEXT (VRF_NODE
, vrfp
);
493 "Delete a pseudo VRF's configuration\n"
496 const char *vrfname
= argv
[2]->arg
;
500 vrfp
= vrf_lookup_by_name (vrfname
);
504 vty_out (vty
, "%% VRF %s does not exist%s", vrfname
, VTY_NEWLINE
);
508 if (CHECK_FLAG (vrfp
->status
, VRF_ACTIVE
))
510 vty_out (vty
, "%% Only inactive VRFs can be deleted%s",
521 struct cmd_node vrf_node
=
529 * Debug CLI for vrf's
555 vrf_write_host (struct vty
*vty
)
558 vty_out (vty
, "debug vrf%s", VTY_NEWLINE
);
563 static struct cmd_node vrf_debug_node
=
571 vrf_install_commands (void)
573 install_node (&vrf_debug_node
, vrf_write_host
);
575 install_element (CONFIG_NODE
, &vrf_debug_cmd
);
576 install_element (ENABLE_NODE
, &vrf_debug_cmd
);
577 install_element (CONFIG_NODE
, &no_vrf_debug_cmd
);
578 install_element (ENABLE_NODE
, &no_vrf_debug_cmd
);
582 vrf_cmd_init (int (*writefunc
)(struct vty
*vty
))
584 install_element (CONFIG_NODE
, &vrf_cmd
);
585 install_element (CONFIG_NODE
, &no_vrf_cmd
);
586 install_node (&vrf_node
, writefunc
);
587 install_default (VRF_NODE
);