summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/vrf.c102
-rw-r--r--lib/vrf.h9
2 files changed, 110 insertions, 1 deletions
diff --git a/lib/vrf.c b/lib/vrf.c
index ea14fd3c..d11a9826 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -29,6 +29,8 @@
#include "log.h"
#include "memory.h"
+#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
+
struct vrf
{
/* Identifier, same as the vector index */
@@ -48,11 +50,18 @@ struct vrf_master
{
int (*vrf_new_hook) (vrf_id_t, void **);
int (*vrf_delete_hook) (vrf_id_t, void **);
+ int (*vrf_enable_hook) (vrf_id_t, void **);
+ int (*vrf_disable_hook) (vrf_id_t, void **);
} vrf_master = {0,};
/* VRF table */
struct route_table *vrf_table = NULL;
+static int vrf_is_enabled (struct vrf *vrf);
+static int vrf_enable (struct vrf *vrf);
+static void vrf_disable (struct vrf *vrf);
+
+
/* Build the table key */
static void
vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
@@ -100,6 +109,9 @@ vrf_delete (struct vrf *vrf)
{
zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
+ if (vrf_is_enabled (vrf))
+ vrf_disable (vrf);
+
if (vrf_master.vrf_delete_hook)
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
@@ -129,6 +141,61 @@ vrf_lookup (vrf_id_t vrf_id)
return vrf;
}
+/*
+ * Check whether the VRF is enabled - that is, whether the VRF
+ * is ready to allocate resources. Currently there's only one
+ * type of resource: socket.
+ */
+static int
+vrf_is_enabled (struct vrf *vrf)
+{
+ return vrf && vrf->vrf_id == VRF_DEFAULT;
+}
+
+/*
+ * Enable a VRF - that is, let the VRF be ready to use.
+ * The VRF_ENABLE_HOOK callback will be called to inform
+ * that they can allocate resources in this VRF.
+ *
+ * RETURN: 1 - enabled successfully; otherwise, 0.
+ */
+static int
+vrf_enable (struct vrf *vrf)
+{
+ /* Till now, only the default VRF can be enabled. */
+ if (vrf->vrf_id == VRF_DEFAULT)
+ {
+ zlog_info ("VRF %u is enabled.", vrf->vrf_id);
+
+ if (vrf_master.vrf_enable_hook)
+ (*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Disable a VRF - that is, let the VRF be unusable.
+ * The VRF_DELETE_HOOK callback will be called to inform
+ * that they must release the resources in the VRF.
+ */
+static void
+vrf_disable (struct vrf *vrf)
+{
+ if (vrf_is_enabled (vrf))
+ {
+ zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
+
+ /* Till now, nothing to be done for the default VRF. */
+
+ if (vrf_master.vrf_disable_hook)
+ (*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
+ }
+}
+
+
/* Add a VRF hook. Please add hooks before calling vrf_init(). */
void
vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
@@ -140,6 +207,12 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
case VRF_DELETE_HOOK:
vrf_master.vrf_delete_hook = func;
break;
+ case VRF_ENABLE_HOOK:
+ vrf_master.vrf_enable_hook = func;
+ break;
+ case VRF_DISABLE_HOOK:
+ vrf_master.vrf_disable_hook = func;
+ break;
default:
break;
}
@@ -281,7 +354,14 @@ vrf_init (void)
}
/* Set the default VRF name. */
- default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, "Default-IP-Routing-Table");
+ default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, VRF_DEFAULT_NAME);
+
+ /* Enable the default VRF. */
+ if (!vrf_enable (default_vrf))
+ {
+ zlog_err ("vrf_init: failed to enable the default VRF!");
+ exit (1);
+ }
}
/* Terminate VRF module. */
@@ -299,3 +379,23 @@ vrf_terminate (void)
vrf_table = NULL;
}
+/* Create a socket for the VRF. */
+int
+vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
+{
+ int ret = -1;
+
+ if (!vrf_is_enabled (vrf_lookup (vrf_id)))
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ if (vrf_id == VRF_DEFAULT)
+ ret = socket (domain, type, protocol);
+ else
+ errno = ENOSYS;
+
+ return ret;
+}
+
diff --git a/lib/vrf.h b/lib/vrf.h
index d7b79987..653fabf9 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -44,6 +44,8 @@
#define VRF_NEW_HOOK 0 /* a new VRF is just created */
#define VRF_DELETE_HOOK 1 /* a VRF is to be deleted */
+#define VRF_ENABLE_HOOK 2 /* a VRF is ready to use */
+#define VRF_DISABLE_HOOK 3 /* a VRF is to be unusable */
/*
* Add a specific hook to VRF module.
@@ -114,5 +116,12 @@ extern struct list *vrf_iflist_get (vrf_id_t);
extern void vrf_init (void);
extern void vrf_terminate (void);
+/*
+ * VRF utilities
+ */
+
+/* Create a socket serving for the given VRF */
+extern int vrf_socket (int, int, int, vrf_id_t);
+
#endif /*_ZEBRA_VRF_H*/