]>
Commit | Line | Data |
---|---|---|
fe18ee2d DS |
1 | /* zebra NS Routines |
2 | * Copyright (C) 2016 Cumulus Networks, Inc. | |
3 | * Donald Sharp | |
b95c1883 | 4 | * Copyright (C) 2017/2018 6WIND |
fe18ee2d DS |
5 | * |
6 | * This file is part of Quagga. | |
7 | * | |
8 | * Quagga is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2, or (at your option) any | |
11 | * later version. | |
12 | * | |
13 | * Quagga is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
896014f4 DL |
18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; see the file COPYING; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
fe18ee2d DS |
21 | */ |
22 | #include "zebra.h" | |
23 | ||
13460c44 | 24 | #include "lib/ns.h" |
fe18ee2d | 25 | #include "lib/vrf.h" |
736d41ad | 26 | #include "lib/logicalrouter.h" |
fe18ee2d DS |
27 | #include "lib/prefix.h" |
28 | #include "lib/memory.h" | |
29 | ||
30 | #include "rtadv.h" | |
31 | #include "zebra_ns.h" | |
7c551956 | 32 | #include "zebra_vrf.h" |
4a1ab8e4 | 33 | #include "zebra_memory.h" |
05f7f5db | 34 | #include "rt.h" |
b7cfce93 | 35 | #include "zebra_vxlan.h" |
3347430b | 36 | #include "debug.h" |
e27dec3c | 37 | #include "zebra_netns_notify.h" |
ec31f30d | 38 | #include "zebra_netns_id.h" |
43fe6a2a | 39 | #include "zebra_pbr.h" |
47a08aa9 | 40 | #include "rib.h" |
8288a24f | 41 | #include "table_manager.h" |
ec31f30d PG |
42 | |
43 | extern struct zebra_privs_t zserv_privs; | |
4a1ab8e4 | 44 | |
d62a17ae | 45 | DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") |
fe18ee2d | 46 | |
337960dd | 47 | static struct zebra_ns *dzns; |
fe18ee2d | 48 | |
736d41ad PG |
49 | static int logicalrouter_config_write(struct vty *vty); |
50 | ||
d62a17ae | 51 | struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) |
fe18ee2d | 52 | { |
ff705b15 PG |
53 | if (ns_id == NS_DEFAULT) |
54 | return dzns; | |
55 | struct zebra_ns *info = (struct zebra_ns *)ns_info_lookup(ns_id); | |
56 | ||
57 | return (info == NULL) ? dzns : info; | |
fe18ee2d DS |
58 | } |
59 | ||
3347430b PG |
60 | static struct zebra_ns *zebra_ns_alloc(void) |
61 | { | |
62 | return XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns)); | |
63 | } | |
64 | ||
65 | static int zebra_ns_new(struct ns *ns) | |
66 | { | |
67 | struct zebra_ns *zns; | |
68 | ||
69 | if (IS_ZEBRA_DEBUG_EVENT) | |
70 | zlog_info("ZNS %s with id %u (created)", ns->name, ns->ns_id); | |
71 | ||
72 | zns = zebra_ns_alloc(); | |
73 | ns->info = zns; | |
74 | zns->ns = ns; | |
ff705b15 PG |
75 | |
76 | /* Do any needed per-NS data structure allocation. */ | |
77 | zns->if_table = route_table_init(); | |
78 | zebra_vxlan_ns_init(zns); | |
79 | ||
3347430b PG |
80 | return 0; |
81 | } | |
82 | ||
83 | static int zebra_ns_delete(struct ns *ns) | |
84 | { | |
996c9314 | 85 | struct zebra_ns *zns = (struct zebra_ns *)ns->info; |
3347430b PG |
86 | |
87 | if (IS_ZEBRA_DEBUG_EVENT) | |
88 | zlog_info("ZNS %s with id %u (deleted)", ns->name, ns->ns_id); | |
89 | if (!zns) | |
90 | return 0; | |
91 | XFREE(MTYPE_ZEBRA_NS, zns); | |
92 | return 0; | |
93 | } | |
94 | ||
95 | static int zebra_ns_enabled(struct ns *ns) | |
96 | { | |
97 | struct zebra_ns *zns = ns->info; | |
98 | ||
99 | if (IS_ZEBRA_DEBUG_EVENT) | |
100 | zlog_info("ZNS %s with id %u (enabled)", ns->name, ns->ns_id); | |
101 | if (!zns) | |
102 | return 0; | |
103 | return zebra_ns_enable(ns->ns_id, (void **)&zns); | |
104 | } | |
105 | ||
ff705b15 | 106 | int zebra_ns_disabled(struct ns *ns) |
3347430b PG |
107 | { |
108 | struct zebra_ns *zns = ns->info; | |
109 | ||
110 | if (IS_ZEBRA_DEBUG_EVENT) | |
111 | zlog_info("ZNS %s with id %u (disabled)", ns->name, ns->ns_id); | |
112 | if (!zns) | |
113 | return 0; | |
114 | return zebra_ns_disable(ns->ns_id, (void **)&zns); | |
115 | } | |
116 | ||
84915b0a | 117 | /* Do global enable actions - open sockets, read kernel config etc. */ |
d62a17ae | 118 | int zebra_ns_enable(ns_id_t ns_id, void **info) |
fe18ee2d | 119 | { |
d62a17ae | 120 | struct zebra_ns *zns = (struct zebra_ns *)(*info); |
fe18ee2d | 121 | |
ff705b15 PG |
122 | zns->ns_id = ns_id; |
123 | ||
d62a17ae | 124 | #if defined(HAVE_RTADV) |
125 | rtadv_init(zns); | |
fe18ee2d DS |
126 | #endif |
127 | ||
d62a17ae | 128 | kernel_init(zns); |
129 | interface_list(zns); | |
130 | route_read(zns); | |
fe18ee2d | 131 | |
8288a24f PG |
132 | /* Initiate Table Manager per ZNS */ |
133 | table_manager_enable(ns_id); | |
134 | ||
d62a17ae | 135 | return 0; |
fe18ee2d DS |
136 | } |
137 | ||
d62a17ae | 138 | int zebra_ns_disable(ns_id_t ns_id, void **info) |
fe18ee2d | 139 | { |
d62a17ae | 140 | struct zebra_ns *zns = (struct zebra_ns *)(*info); |
fe18ee2d | 141 | |
d62a17ae | 142 | route_table_finish(zns->if_table); |
b7cfce93 | 143 | zebra_vxlan_ns_disable(zns); |
d62a17ae | 144 | #if defined(HAVE_RTADV) |
145 | rtadv_terminate(zns); | |
fe18ee2d DS |
146 | #endif |
147 | ||
d62a17ae | 148 | kernel_terminate(zns); |
fe18ee2d | 149 | |
8288a24f PG |
150 | table_manager_disable(zns->ns_id); |
151 | ||
ff705b15 PG |
152 | zns->ns_id = NS_DEFAULT; |
153 | ||
d62a17ae | 154 | return 0; |
fe18ee2d DS |
155 | } |
156 | ||
5335613b | 157 | |
d62a17ae | 158 | int zebra_ns_init(void) |
fe18ee2d | 159 | { |
ec31f30d | 160 | ns_id_t ns_id; |
03aff2d8 | 161 | ns_id_t ns_id_external; |
ec31f30d | 162 | |
3347430b PG |
163 | dzns = zebra_ns_alloc(); |
164 | ||
01b9e3fd DL |
165 | frr_elevate_privs(&zserv_privs) { |
166 | ns_id = zebra_ns_id_get_default(); | |
167 | } | |
03aff2d8 PG |
168 | ns_id_external = ns_map_nsid_with_external(ns_id, true); |
169 | ns_init_management(ns_id_external, ns_id); | |
736d41ad PG |
170 | |
171 | logicalrouter_init(logicalrouter_config_write); | |
13460c44 | 172 | |
84915b0a | 173 | /* Do any needed per-NS data structure allocation. */ |
174 | dzns->if_table = route_table_init(); | |
175 | zebra_vxlan_ns_init(dzns); | |
176 | ||
177 | /* Register zebra VRF callbacks, create and activate default VRF. */ | |
d62a17ae | 178 | zebra_vrf_init(); |
fe18ee2d | 179 | |
84915b0a | 180 | /* Default NS is activated */ |
03aff2d8 | 181 | zebra_ns_enable(ns_id_external, (void **)&dzns); |
fe18ee2d | 182 | |
3347430b PG |
183 | if (vrf_is_backend_netns()) { |
184 | ns_add_hook(NS_NEW_HOOK, zebra_ns_new); | |
185 | ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled); | |
186 | ns_add_hook(NS_DISABLE_HOOK, zebra_ns_disabled); | |
187 | ns_add_hook(NS_DELETE_HOOK, zebra_ns_delete); | |
e27dec3c PG |
188 | zebra_ns_notify_parse(); |
189 | zebra_ns_notify_init(); | |
3347430b | 190 | } |
7f0ea8a4 | 191 | |
d62a17ae | 192 | return 0; |
fe18ee2d | 193 | } |
b95c1883 | 194 | |
736d41ad PG |
195 | static int logicalrouter_config_write(struct vty *vty) |
196 | { | |
197 | struct ns *ns; | |
198 | int write = 0; | |
199 | ||
996c9314 | 200 | RB_FOREACH (ns, ns_head, &ns_tree) { |
736d41ad PG |
201 | if (ns->ns_id == NS_DEFAULT || ns->name == NULL) |
202 | continue; | |
203 | vty_out(vty, "logical-router %u netns %s\n", ns->ns_id, | |
204 | ns->name); | |
205 | write = 1; | |
206 | } | |
207 | return write; | |
208 | } | |
209 | ||
b95c1883 PG |
210 | int zebra_ns_config_write(struct vty *vty, struct ns *ns) |
211 | { | |
212 | if (ns && ns->name != NULL) | |
213 | vty_out(vty, " netns %s\n", ns->name); | |
214 | return 0; | |
215 | } |