2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2016-09-04 02:45:35 +02:00
|
|
|
/*
|
|
|
|
* NS related header.
|
|
|
|
* Copyright (C) 2014 6WIND S.A.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _ZEBRA_NS_H
|
|
|
|
#define _ZEBRA_NS_H
|
|
|
|
|
2016-10-29 03:03:35 +02:00
|
|
|
#include "openbsd-tree.h"
|
2016-09-04 02:45:35 +02:00
|
|
|
#include "linklist.h"
|
2017-12-13 11:04:31 +01:00
|
|
|
#include "vty.h"
|
2016-09-04 02:45:35 +02:00
|
|
|
|
2019-02-07 23:10:31 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
typedef uint32_t ns_id_t;
|
2016-09-04 02:45:35 +02:00
|
|
|
|
2018-01-10 14:13:50 +01:00
|
|
|
/* the default NS ID */
|
|
|
|
#define NS_UNKNOWN UINT32_MAX
|
2016-09-04 02:45:35 +02:00
|
|
|
|
2016-10-26 16:58:32 +02:00
|
|
|
/* Default netns directory (Linux) */
|
2014-07-03 12:24:34 +02:00
|
|
|
#define NS_RUN_DIR "/var/run/netns"
|
2016-09-04 02:45:35 +02:00
|
|
|
|
zebra: upon startup, a NSID is assigned to default netns
when the netns backend is selected for VRF, the default VRF is being
assigned a NSID. This avoids the need to handle the case where if the
incoming NSID was 0 for a non default VRF, then a specific handling had
to be done to keep 0 value for default VRF.
In most cases, as the first NETNS to get a NSID will be the default VRF,
most probably the default VRF will be assigned to 0, while the other
ones will have their value incremented. On some cases, where the NSID is
already assigned for NETNS, including default VRF, then the default VRF
value will be the one derived from the NSID of default VRF, thus keeping
consistency between VRF IDs and NETNS IDs.
Default NS is attempted to be created. Actually, some VMs may have the
netns feature, but the NS initialisation fails because that folder is
not present.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-01-16 13:59:58 +01:00
|
|
|
#ifdef HAVE_NETNS
|
|
|
|
#define NS_DEFAULT_NAME "/proc/self/ns/net"
|
|
|
|
#else /* !HAVE_NETNS */
|
2019-08-02 16:10:11 +02:00
|
|
|
#define NS_DEFAULT_NAME "default-netns"
|
zebra: upon startup, a NSID is assigned to default netns
when the netns backend is selected for VRF, the default VRF is being
assigned a NSID. This avoids the need to handle the case where if the
incoming NSID was 0 for a non default VRF, then a specific handling had
to be done to keep 0 value for default VRF.
In most cases, as the first NETNS to get a NSID will be the default VRF,
most probably the default VRF will be assigned to 0, while the other
ones will have their value incremented. On some cases, where the NSID is
already assigned for NETNS, including default VRF, then the default VRF
value will be the one derived from the NSID of default VRF, thus keeping
consistency between VRF IDs and NETNS IDs.
Default NS is attempted to be created. Actually, some VMs may have the
netns feature, but the NS initialisation fails because that folder is
not present.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-01-16 13:59:58 +01:00
|
|
|
#endif /* HAVE_NETNS */
|
|
|
|
|
2016-10-29 02:32:07 +02:00
|
|
|
struct ns {
|
2016-10-29 03:03:35 +02:00
|
|
|
RB_ENTRY(ns) entry;
|
|
|
|
|
2016-10-29 02:32:07 +02:00
|
|
|
/* Identifier, same as the vector index */
|
|
|
|
ns_id_t ns_id;
|
2016-10-29 03:03:35 +02:00
|
|
|
|
2018-03-26 12:22:18 +02:00
|
|
|
/* Identifier, mapped on the NSID value */
|
|
|
|
ns_id_t internal_ns_id;
|
|
|
|
|
2019-10-02 13:34:40 +02:00
|
|
|
/* Identifier, value of NSID of default netns,
|
|
|
|
* relative value in that local netns
|
|
|
|
*/
|
|
|
|
ns_id_t relative_default_ns;
|
|
|
|
|
2016-10-29 02:32:07 +02:00
|
|
|
/* Name */
|
|
|
|
char *name;
|
2016-10-29 03:03:35 +02:00
|
|
|
|
2016-10-29 02:32:07 +02:00
|
|
|
/* File descriptor */
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
/* Master list of interfaces belonging to this NS */
|
|
|
|
struct list *iflist;
|
|
|
|
|
2017-12-06 12:03:59 +01:00
|
|
|
/* Back Pointer to VRF */
|
|
|
|
void *vrf_ctxt;
|
|
|
|
|
2016-10-29 02:32:07 +02:00
|
|
|
/* User data */
|
|
|
|
void *info;
|
|
|
|
};
|
2016-10-29 03:03:35 +02:00
|
|
|
RB_HEAD(ns_head, ns);
|
|
|
|
RB_PROTOTYPE(ns_head, ns, entry, ns_compare)
|
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/*
|
|
|
|
* API for managing NETNS. eg from zebra daemon
|
|
|
|
* one want to manage the list of NETNS, etc...
|
|
|
|
*/
|
|
|
|
|
2016-09-04 02:45:35 +02:00
|
|
|
/*
|
|
|
|
* NS hooks
|
|
|
|
*/
|
|
|
|
|
2019-08-02 16:10:11 +02:00
|
|
|
#define NS_NEW_HOOK 0 /* a new netns is just created */
|
|
|
|
#define NS_DELETE_HOOK 1 /* a netns is to be deleted */
|
|
|
|
#define NS_ENABLE_HOOK 2 /* a netns is ready to use */
|
|
|
|
#define NS_DISABLE_HOOK 3 /* a netns is to be unusable */
|
2016-09-04 02:45:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Add a specific hook ns module.
|
|
|
|
* @param1: hook type
|
|
|
|
* @param2: the callback function
|
|
|
|
* - param 1: the NS ID
|
|
|
|
* - param 2: the address of the user data pointer (the user data
|
|
|
|
* can be stored in or freed from there)
|
|
|
|
*/
|
2017-12-07 18:27:31 +01:00
|
|
|
extern void ns_add_hook(int type, int (*)(struct ns *));
|
2016-09-04 02:45:35 +02:00
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
|
2016-09-04 02:45:35 +02:00
|
|
|
/*
|
|
|
|
* NS initializer/destructor
|
|
|
|
*/
|
2018-02-05 16:23:42 +01:00
|
|
|
|
2016-09-04 02:45:35 +02:00
|
|
|
extern void ns_terminate(void);
|
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/* API to initialize NETNS managerment
|
|
|
|
* parameter is the default ns_id
|
|
|
|
*/
|
2018-03-26 12:22:18 +02:00
|
|
|
extern void ns_init_management(ns_id_t ns_id, ns_id_t internal_ns_idx);
|
2018-02-05 16:23:42 +01:00
|
|
|
|
|
|
|
|
2016-09-04 02:45:35 +02:00
|
|
|
/*
|
|
|
|
* NS utilities
|
|
|
|
*/
|
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/* Create a socket serving for the given NS
|
|
|
|
*/
|
|
|
|
int ns_socket(int domain, int type, int protocol, ns_id_t ns_id);
|
|
|
|
|
|
|
|
/* return the path of the NETNS */
|
2017-12-13 11:04:31 +01:00
|
|
|
extern char *ns_netns_pathname(struct vty *vty, const char *name);
|
2018-02-05 16:23:42 +01:00
|
|
|
|
|
|
|
/* Parse and execute a function on all the NETNS */
|
2019-12-20 17:51:37 +01:00
|
|
|
#define NS_WALK_CONTINUE 0
|
|
|
|
#define NS_WALK_STOP 1
|
|
|
|
|
|
|
|
extern void ns_walk_func(int (*func)(struct ns *,
|
|
|
|
void *,
|
|
|
|
void **),
|
|
|
|
void *param_in,
|
|
|
|
void **param_out);
|
2018-02-05 16:23:42 +01:00
|
|
|
|
|
|
|
/* API to get the NETNS name, from the ns pointer */
|
2017-12-07 15:58:48 +01:00
|
|
|
extern const char *ns_get_name(struct ns *ns);
|
2018-02-05 16:23:42 +01:00
|
|
|
|
|
|
|
/* only called from vrf ( when removing netns from vrf)
|
2019-08-02 16:10:11 +02:00
|
|
|
* or at VRF termination
|
2018-02-05 16:23:42 +01:00
|
|
|
*/
|
|
|
|
extern void ns_delete(struct ns *ns);
|
|
|
|
|
|
|
|
/* return > 0 if netns is available
|
|
|
|
* called by VRF to check netns backend is available for VRF
|
|
|
|
*/
|
|
|
|
extern int ns_have_netns(void);
|
|
|
|
|
|
|
|
/* API to get context information of a NS */
|
|
|
|
extern void *ns_info_lookup(ns_id_t ns_id);
|
|
|
|
|
2018-03-26 12:22:18 +02:00
|
|
|
/* API to map internal ns id value with
|
|
|
|
* user friendly ns id external value
|
|
|
|
*/
|
2018-04-12 16:33:49 +02:00
|
|
|
extern ns_id_t ns_map_nsid_with_external(ns_id_t ns_id, bool map);
|
2018-03-26 12:22:18 +02:00
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/*
|
|
|
|
* NS init routine
|
|
|
|
* should be called from backendx
|
|
|
|
*/
|
|
|
|
extern void ns_init(void);
|
|
|
|
|
2020-08-24 18:01:15 +02:00
|
|
|
#define NS_DEFAULT 0
|
2018-02-05 16:23:42 +01:00
|
|
|
|
|
|
|
/* API that can be used to change from NS */
|
2017-12-20 12:29:21 +01:00
|
|
|
extern int ns_switchback_to_initial(void);
|
|
|
|
extern int ns_switch_to_netns(const char *netns_name);
|
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/*
|
|
|
|
* NS handling routines.
|
|
|
|
* called by modules that use NS backend
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* API to search for already present NETNS */
|
|
|
|
extern struct ns *ns_lookup(ns_id_t ns_id);
|
|
|
|
extern struct ns *ns_lookup_name(const char *name);
|
zebra: upon startup, a NSID is assigned to default netns
when the netns backend is selected for VRF, the default VRF is being
assigned a NSID. This avoids the need to handle the case where if the
incoming NSID was 0 for a non default VRF, then a specific handling had
to be done to keep 0 value for default VRF.
In most cases, as the first NETNS to get a NSID will be the default VRF,
most probably the default VRF will be assigned to 0, while the other
ones will have their value incremented. On some cases, where the NSID is
already assigned for NETNS, including default VRF, then the default VRF
value will be the one derived from the NSID of default VRF, thus keeping
consistency between VRF IDs and NETNS IDs.
Default NS is attempted to be created. Actually, some VMs may have the
netns feature, but the NS initialisation fails because that folder is
not present.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-01-16 13:59:58 +01:00
|
|
|
|
2018-02-05 16:23:42 +01:00
|
|
|
/* API to handle NS : creation, enable, disable
|
|
|
|
* for enable, a callback function is passed as parameter
|
|
|
|
* the callback belongs to the module that uses NS as backend
|
|
|
|
* upon enabling the NETNS, the upper layer is informed
|
|
|
|
*/
|
|
|
|
extern int ns_enable(struct ns *ns, void (*func)(ns_id_t, void *));
|
|
|
|
extern struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id);
|
2019-10-02 13:37:11 +02:00
|
|
|
extern ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid);
|
2018-02-05 16:23:42 +01:00
|
|
|
extern void ns_disable(struct ns *ns);
|
zebra, lib: add an internal API to get relative default nsid in other ns
as remind, the netns identifiers are local to a namespace. that is to
say that for instance, a vrf <vrfx> will have a netns id value in one
netns, and have an other netns id value in one other netns.
There is a need for zebra daemon to collect some cross information, like
the LINK_NETNSID information from interfaces having link layer in an
other network namespace. For that, it is needed to have a global
overview instead of a relative overview per namespace.
The first brick of this change is an API that sticks to netlink API,
that uses NETNSA_TARGET_NSID. from a given vrf vrfX, and a new vrf
created vrfY, the API returns the value of nsID from vrfX, inside the
new vrf vrfY.
The brick also gets the ns id value of default namespace in each other
namespace. An additional value in ns.h is offered, that permits to
retrieve the default namespace context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2019-10-02 12:14:13 +02:00
|
|
|
extern struct ns *ns_get_default(void);
|
zebra: upon startup, a NSID is assigned to default netns
when the netns backend is selected for VRF, the default VRF is being
assigned a NSID. This avoids the need to handle the case where if the
incoming NSID was 0 for a non default VRF, then a specific handling had
to be done to keep 0 value for default VRF.
In most cases, as the first NETNS to get a NSID will be the default VRF,
most probably the default VRF will be assigned to 0, while the other
ones will have their value incremented. On some cases, where the NSID is
already assigned for NETNS, including default VRF, then the default VRF
value will be the one derived from the NSID of default VRF, thus keeping
consistency between VRF IDs and NETNS IDs.
Default NS is attempted to be created. Actually, some VMs may have the
netns feature, but the NS initialisation fails because that folder is
not present.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-01-16 13:59:58 +01:00
|
|
|
|
2019-02-07 23:10:31 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-09-04 02:45:35 +02:00
|
|
|
#endif /*_ZEBRA_NS_H*/
|