]> git.proxmox.com Git - mirror_frr.git/blob - lib/logicalrouter.c
lib: split logicalrouter and vrf netns feature
[mirror_frr.git] / lib / logicalrouter.c
1 /*
2 * Logical Router functions.
3 * Copyright (C) 2018 6WIND S.A.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <zebra.h>
21
22 #include "ns.h"
23 #include "log.h"
24 #include "memory.h"
25
26 #include "command.h"
27 #include "vty.h"
28 #include "logicalrouter.h"
29
30 /* Comment that useless define to avoid compilation error
31 * in order to use it, one could provide the kind of NETNS to NS backend
32 * so that the allocation will match the logical router
33 * DEFINE_MTYPE_STATIC(LIB, LOGICALROUTER, "LogicalRouter Context")
34 */
35 DEFINE_MTYPE_STATIC(LIB, LOGICALROUTER_NAME, "Logical Router Name")
36
37 /* Logical Router node has no interface. */
38 static struct cmd_node logicalrouter_node = {LOGICALROUTER_NODE, "",
39 1};
40
41 static int logicalrouter_backend;
42
43 /* Get a NS. If not found, create one. */
44 static struct ns *logicalrouter_get(ns_id_t ns_id)
45 {
46 struct ns *ns;
47
48 ns = ns_lookup(ns_id);
49 if (ns)
50 return (ns);
51 ns = ns_get_created(ns, NULL, ns_id);
52 return ns;
53 }
54
55 static int logicalrouter_is_backend_netns(void)
56 {
57 return (logicalrouter_backend == LOGICALROUTER_BACKEND_NETNS);
58 }
59
60
61 DEFUN_NOSH (logicalrouter,
62 logicalrouter_cmd,
63 "logical-router (1-65535) ns NAME",
64 "Enable a logical-router\n"
65 "Specify the logical-router indentifier\n"
66 "The Name Space\n"
67 "The file name in " NS_RUN_DIR ", or a full pathname\n")
68 {
69 int idx_number = 1;
70 int idx_name = 3;
71 ns_id_t ns_id;
72 struct ns *ns = NULL;
73 char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
74
75 if (!pathname)
76 return CMD_WARNING_CONFIG_FAILED;
77
78 ns_id = strtoul(argv[idx_number]->arg, NULL, 10);
79 ns = logicalrouter_get(ns_id);
80
81 if (ns->name && strcmp(ns->name, pathname) != 0) {
82 vty_out(vty, "NS %u is already configured with NETNS %s\n",
83 ns->ns_id, ns->name);
84 return CMD_WARNING;
85 }
86
87 if (!ns->name)
88 ns->name = XSTRDUP(MTYPE_LOGICALROUTER_NAME, pathname);
89
90 if (!ns_enable(ns, NULL)) {
91 vty_out(vty, "Can not associate NS %u with NETNS %s\n",
92 ns->ns_id, ns->name);
93 return CMD_WARNING_CONFIG_FAILED;
94 }
95
96 return CMD_SUCCESS;
97 }
98
99 DEFUN (no_logicalrouter,
100 no_logicalrouter_cmd,
101 "no logical-router (1-65535) ns NAME",
102 NO_STR
103 "Enable a Logical-Router\n"
104 "Specify the Logical-Router identifier\n"
105 "The Name Space\n"
106 "The file name in " NS_RUN_DIR ", or a full pathname\n")
107 {
108 int idx_number = 2;
109 int idx_name = 4;
110 ns_id_t ns_id;
111 struct ns *ns = NULL;
112 char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
113
114 if (!pathname)
115 return CMD_WARNING_CONFIG_FAILED;
116
117 ns_id = strtoul(argv[idx_number]->arg, NULL, 10);
118 ns = ns_lookup(ns_id);
119
120 if (!ns) {
121 vty_out(vty, "NS %u is not found\n", ns_id);
122 return CMD_SUCCESS;
123 }
124
125 if (ns->name && strcmp(ns->name, pathname) != 0) {
126 vty_out(vty, "Incorrect NETNS file name\n");
127 return CMD_WARNING_CONFIG_FAILED;
128 }
129
130 ns_disable(ns);
131
132 if (ns->name) {
133 XFREE(MTYPE_LOGICALROUTER_NAME, ns->name);
134 ns->name = NULL;
135 }
136
137 return CMD_SUCCESS;
138 }
139
140 /* Initialize NS module. */
141 void logicalrouter_init(int (*writefunc)(struct vty *vty))
142 {
143 if (ns_have_netns() && logicalrouter_is_backend_netns()) {
144 /* Install LogicalRouter commands. */
145 install_node(&logicalrouter_node, writefunc);
146 install_element(CONFIG_NODE, &logicalrouter_cmd);
147 install_element(CONFIG_NODE, &no_logicalrouter_cmd);
148 }
149 }
150
151 void logicalrouter_terminate(void)
152 {
153 ns_terminate();
154 }
155
156 void logicalrouter_configure_backend(int backend_netns)
157 {
158 logicalrouter_backend = backend_netns;
159 }