1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Cumulus Networks, Inc.
5 * Copyright (C) 2017/2018 6WIND
11 #include "lib/prefix.h"
12 #include "lib/memory.h"
15 #include "zebra_vrf.h"
17 #include "zebra_vxlan.h"
19 #include "zebra_netns_notify.h"
20 #include "zebra_netns_id.h"
21 #include "zebra_pbr.h"
24 #include "table_manager.h"
25 #include "zebra_errors.h"
27 extern struct zebra_privs_t zserv_privs
;
29 DEFINE_MTYPE_STATIC(ZEBRA
, ZEBRA_NS
, "Zebra Name Space");
31 static struct zebra_ns
*dzns
;
33 static int zebra_ns_disable_internal(struct zebra_ns
*zns
, bool complete
);
35 struct zebra_ns
*zebra_ns_lookup(ns_id_t ns_id
)
37 if (ns_id
== NS_DEFAULT
)
39 struct zebra_ns
*info
= (struct zebra_ns
*)ns_info_lookup(ns_id
);
41 return (info
== NULL
) ? dzns
: info
;
44 static struct zebra_ns
*zebra_ns_alloc(void)
46 return XCALLOC(MTYPE_ZEBRA_NS
, sizeof(struct zebra_ns
));
49 static int zebra_ns_new(struct ns
*ns
)
56 if (IS_ZEBRA_DEBUG_EVENT
)
57 zlog_info("ZNS %s with id %u (created)", ns
->name
, ns
->ns_id
);
59 zns
= zebra_ns_alloc();
62 zns
->ns_id
= ns
->ns_id
;
64 /* Do any needed per-NS data structure allocation. */
65 zns
->if_table
= route_table_init();
70 static int zebra_ns_delete(struct ns
*ns
)
72 struct zebra_ns
*zns
= (struct zebra_ns
*)ns
->info
;
74 if (IS_ZEBRA_DEBUG_EVENT
)
75 zlog_info("ZNS %s with id %u (deleted)", ns
->name
, ns
->ns_id
);
78 XFREE(MTYPE_ZEBRA_NS
, ns
->info
);
82 static int zebra_ns_enabled(struct ns
*ns
)
84 struct zebra_ns
*zns
= ns
->info
;
86 if (IS_ZEBRA_DEBUG_EVENT
)
87 zlog_info("ZNS %s with id %u (enabled)", ns
->name
, ns
->ns_id
);
90 return zebra_ns_enable(ns
->ns_id
, (void **)&zns
);
93 int zebra_ns_disabled(struct ns
*ns
)
95 struct zebra_ns
*zns
= ns
->info
;
97 if (IS_ZEBRA_DEBUG_EVENT
)
98 zlog_info("ZNS %s with id %u (disabled)", ns
->name
, ns
->ns_id
);
101 return zebra_ns_disable_internal(zns
, true);
104 /* Do global enable actions - open sockets, read kernel config etc. */
105 int zebra_ns_enable(ns_id_t ns_id
, void **info
)
107 struct zebra_ns
*zns
= (struct zebra_ns
*)(*info
);
112 zebra_dplane_ns_enable(zns
, true);
117 kernel_read_pbr_rules(zns
);
118 kernel_read_tc_qdisc(zns
);
123 /* Common handler for ns disable - this can be called during ns config,
124 * or during zebra shutdown.
126 static int zebra_ns_disable_internal(struct zebra_ns
*zns
, bool complete
)
129 route_table_finish(zns
->if_table
);
130 zns
->if_table
= NULL
;
132 zebra_dplane_ns_enable(zns
, false /*Disable*/);
134 kernel_terminate(zns
, complete
);
136 zns
->ns_id
= NS_DEFAULT
;
141 /* During zebra shutdown, do partial cleanup while the async dataplane
144 int zebra_ns_early_shutdown(struct ns
*ns
,
145 void *param_in
__attribute__((unused
)),
146 void **param_out
__attribute__((unused
)))
148 struct zebra_ns
*zns
= ns
->info
;
153 zebra_ns_disable_internal(zns
, false);
154 return NS_WALK_CONTINUE
;
157 /* During zebra shutdown, do final cleanup
158 * after all dataplane work is complete.
160 int zebra_ns_final_shutdown(struct ns
*ns
,
161 void *param_in
__attribute__((unused
)),
162 void **param_out
__attribute__((unused
)))
164 struct zebra_ns
*zns
= ns
->info
;
169 kernel_terminate(zns
, true);
171 return NS_WALK_CONTINUE
;
174 int zebra_ns_init(void)
176 struct ns
*default_ns
;
178 ns_id_t ns_id_external
;
181 frr_with_privs(&zserv_privs
) {
182 ns_id
= zebra_ns_id_get_default();
184 ns_id_external
= ns_map_nsid_with_external(ns_id
, true);
185 ns_init_management(ns_id_external
, ns_id
);
186 ns
= ns_get_default();
188 ns
->relative_default_ns
= ns_id
;
190 default_ns
= ns_lookup(NS_DEFAULT
);
192 flog_err(EC_ZEBRA_NS_NO_DEFAULT
,
193 "%s: failed to find default ns", __func__
);
194 exit(EXIT_FAILURE
); /* This is non-recoverable */
197 /* Do any needed per-NS data structure allocation. */
198 zebra_ns_new(default_ns
);
199 dzns
= default_ns
->info
;
201 /* Register zebra VRF callbacks, create and activate default VRF. */
204 /* Default NS is activated */
205 zebra_ns_enable(ns_id_external
, (void **)&dzns
);
207 if (vrf_is_backend_netns()) {
208 ns_add_hook(NS_NEW_HOOK
, zebra_ns_new
);
209 ns_add_hook(NS_ENABLE_HOOK
, zebra_ns_enabled
);
210 ns_add_hook(NS_DISABLE_HOOK
, zebra_ns_disabled
);
211 ns_add_hook(NS_DELETE_HOOK
, zebra_ns_delete
);
212 zebra_ns_notify_parse();
213 zebra_ns_notify_init();
219 int zebra_ns_config_write(struct vty
*vty
, struct ns
*ns
)
221 if (ns
&& ns
->name
!= NULL
)
222 vty_out(vty
, " netns %s\n", ns
->name
);