1 /* Configuration generator.
2 Copyright (C) 2000 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #include "vtysh/vtysh.h"
31 extern int vtysh_writeconfig_integrated;
35 /* Configuration node name. */
38 /* Configuration string line. */
41 /* Configuration can be nest. */
42 struct config *config;
44 /* Index of this config. */
48 struct list *config_top;
51 line_cmp (char *c1, char *c2)
53 return strcmp (c1, c2);
59 XFREE (MTYPE_VTYSH_CONFIG_LINE, line);
62 static struct config *
65 struct config *config;
66 config = XCALLOC (MTYPE_VTYSH_CONFIG, sizeof (struct config));
71 config_cmp (struct config *c1, struct config *c2)
73 return strcmp (c1->name, c2->name);
77 config_del (struct config* config)
79 list_delete (config->line);
81 XFREE (MTYPE_VTYSH_CONFIG_LINE, config->name);
82 XFREE (MTYPE_VTYSH_CONFIG, config);
85 static struct config *
86 config_get (int index, const char *line)
88 struct config *config;
89 struct config *config_loop;
91 struct listnode *node, *nnode;
93 config = config_loop = NULL;
95 master = vector_lookup_ensure (configvec, index);
100 master->del = (void (*) (void *))config_del;
101 master->cmp = (int (*)(void *, void *)) config_cmp;
102 vector_set_index (configvec, index, master);
105 for (ALL_LIST_ELEMENTS (master, node, nnode, config_loop))
107 if (strcmp (config_loop->name, line) == 0)
108 config = config_loop;
113 config = config_new ();
114 config->line = list_new ();
115 config->line->del = (void (*) (void *))line_del;
116 config->line->cmp = (int (*)(void *, void *)) line_cmp;
117 config->name = XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line);
118 config->index = index;
119 listnode_add (master, config);
125 config_add_line (struct list *config, const char *line)
127 listnode_add (config, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line));
131 config_add_line_uniq (struct list *config, const char *line)
133 struct listnode *node, *nnode;
136 for (ALL_LIST_ELEMENTS (config, node, nnode, pnt))
138 if (strcmp (pnt, line) == 0)
141 listnode_add_sort (config, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line));
145 vtysh_config_parse_line (const char *line)
148 static struct config *config = NULL;
158 /* printf ("[%s]\n", line); */
166 /* Store line to current configuration. */
169 if (strncmp (line, " address-family vpnv4",
170 strlen (" address-family vpnv4")) == 0)
171 config = config_get (BGP_VPNV4_NODE, line);
172 else if (strncmp (line, " address-family vpn6",
173 strlen (" address-family vpn6")) == 0)
174 config = config_get (BGP_VPNV6_NODE, line);
175 else if (strncmp (line, " address-family encapv6",
176 strlen (" address-family encapv6")) == 0)
177 config = config_get (BGP_ENCAPV6_NODE, line);
178 else if (strncmp (line, " address-family encap",
179 strlen (" address-family encap")) == 0)
180 config = config_get (BGP_ENCAP_NODE, line);
181 else if (strncmp (line, " address-family ipv4 multicast",
182 strlen (" address-family ipv4 multicast")) == 0)
183 config = config_get (BGP_IPV4M_NODE, line);
184 else if (strncmp (line, " address-family ipv6",
185 strlen (" address-family ipv6")) == 0)
186 config = config_get (BGP_IPV6_NODE, line);
187 else if (strncmp (line, " link-params", strlen (" link-params")) == 0)
189 config_add_line (config->line, line);
190 config->index = LINK_PARAMS_NODE;
192 else if (config->index == LINK_PARAMS_NODE &&
193 strncmp (line, " exit-link-params", strlen (" exit")) == 0)
195 config_add_line (config->line, line);
196 config->index = INTERFACE_NODE;
198 else if (config->index == RMAP_NODE ||
199 config->index == INTERFACE_NODE ||
200 config->index == VTY_NODE)
201 config_add_line_uniq (config->line, line);
203 config_add_line (config->line, line);
206 config_add_line (config_top, line);
209 if (strncmp (line, "interface", strlen ("interface")) == 0)
210 config = config_get (INTERFACE_NODE, line);
211 else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
212 config = config_get (ZEBRA_NODE, line);
213 else if (strncmp (line, "router rip", strlen ("router rip")) == 0)
214 config = config_get (RIP_NODE, line);
215 else if (strncmp (line, "router ripng", strlen ("router ripng")) == 0)
216 config = config_get (RIPNG_NODE, line);
217 else if (strncmp (line, "router ospf", strlen ("router ospf")) == 0)
218 config = config_get (OSPF_NODE, line);
219 else if (strncmp (line, "router ospf6", strlen ("router ospf6")) == 0)
220 config = config_get (OSPF6_NODE, line);
221 else if (strncmp (line, "router bgp", strlen ("router bgp")) == 0)
222 config = config_get (BGP_NODE, line);
223 else if (strncmp (line, "router isis", strlen ("router isis")) == 0)
224 config = config_get (ISIS_NODE, line);
225 else if (strncmp (line, "router bgp", strlen ("router bgp")) == 0)
226 config = config_get (BGP_NODE, line);
227 else if (strncmp (line, "route-map", strlen ("route-map")) == 0)
228 config = config_get (RMAP_NODE, line);
229 else if (strncmp (line, "access-list", strlen ("access-list")) == 0)
230 config = config_get (ACCESS_NODE, line);
231 else if (strncmp (line, "ipv6 access-list",
232 strlen ("ipv6 access-list")) == 0)
233 config = config_get (ACCESS_IPV6_NODE, line);
234 else if (strncmp (line, "ip prefix-list",
235 strlen ("ip prefix-list")) == 0)
236 config = config_get (PREFIX_NODE, line);
237 else if (strncmp (line, "ipv6 prefix-list",
238 strlen ("ipv6 prefix-list")) == 0)
239 config = config_get (PREFIX_IPV6_NODE, line);
240 else if (strncmp (line, "ip as-path access-list",
241 strlen ("ip as-path access-list")) == 0)
242 config = config_get (AS_LIST_NODE, line);
243 else if (strncmp (line, "ip community-list",
244 strlen ("ip community-list")) == 0)
245 config = config_get (COMMUNITY_LIST_NODE, line);
246 else if (strncmp (line, "ip route", strlen ("ip route")) == 0)
247 config = config_get (IP_NODE, line);
248 else if (strncmp (line, "ipv6 route", strlen ("ipv6 route")) == 0)
249 config = config_get (IP_NODE, line);
250 else if (strncmp (line, "key", strlen ("key")) == 0)
251 config = config_get (KEYCHAIN_NODE, line);
252 else if (strncmp (line, "line", strlen ("line")) == 0)
253 config = config_get (VTY_NODE, line);
254 else if ( (strncmp (line, "ipv6 forwarding",
255 strlen ("ipv6 forwarding")) == 0)
256 || (strncmp (line, "ip forwarding",
257 strlen ("ip forwarding")) == 0) )
258 config = config_get (FORWARDING_NODE, line);
259 else if (strncmp (line, "service", strlen ("service")) == 0)
260 config = config_get (SERVICE_NODE, line);
261 else if (strncmp (line, "debug", strlen ("debug")) == 0)
262 config = config_get (DEBUG_NODE, line);
263 else if (strncmp (line, "password", strlen ("password")) == 0
264 || strncmp (line, "enable password",
265 strlen ("enable password")) == 0)
266 config = config_get (AAA_NODE, line);
267 else if (strncmp (line, "ip protocol", strlen ("ip protocol")) == 0)
268 config = config_get (PROTOCOL_NODE, line);
271 if (strncmp (line, "log", strlen ("log")) == 0
272 || strncmp (line, "hostname", strlen ("hostname")) == 0
274 config_add_line_uniq (config_top, line);
276 config_add_line (config_top, line);
284 vtysh_config_parse (char *line)
296 vtysh_config_parse_line (begin);
306 /* Macro to check delimiter is needed between each configuration line
308 #define NO_DELIMITER(I) \
309 ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
310 || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
311 (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
312 || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
315 /* Display configuration to file pointer. */
317 vtysh_config_dump (FILE *fp)
319 struct listnode *node, *nnode;
320 struct listnode *mnode, *mnnode;
321 struct config *config;
326 for (ALL_LIST_ELEMENTS (config_top, node, nnode, line))
328 fprintf (fp, "%s\n", line);
334 for (i = 0; i < vector_active (configvec); i++)
335 if ((master = vector_slot (configvec, i)) != NULL)
337 for (ALL_LIST_ELEMENTS (master, node, nnode, config))
339 fprintf (fp, "%s\n", config->name);
342 for (ALL_LIST_ELEMENTS (config->line, mnode, mnnode, line))
344 fprintf (fp, "%s\n", line);
347 if (! NO_DELIMITER (i))
353 if (NO_DELIMITER (i))
360 for (i = 0; i < vector_active (configvec); i++)
361 if ((master = vector_slot (configvec, i)) != NULL)
363 list_delete (master);
364 vector_slot (configvec, i) = NULL;
366 list_delete_all_node (config_top);
369 /* Read up configuration file from file_name. */
371 vtysh_read_file (FILE *confp)
377 vty->fd = 0; /* stdout */
378 vty->type = VTY_TERM;
379 vty->node = CONFIG_NODE;
381 vtysh_execute_no_pager ("enable");
382 vtysh_execute_no_pager ("configure terminal");
384 /* Execute configuration file. */
385 ret = vtysh_config_from_file (vty, confp);
387 vtysh_execute_no_pager ("end");
388 vtysh_execute_no_pager ("disable");
392 if (ret != CMD_SUCCESS)
396 case CMD_ERR_AMBIGUOUS:
397 fprintf (stderr, "Ambiguous command.\n");
399 case CMD_ERR_NO_MATCH:
400 fprintf (stderr, "There is no such command.\n");
403 fprintf (stderr, "Error occurred during reading below line.\n%s\n",
409 /* Read up configuration file from config_default_dir. */
411 vtysh_read_config (char *config_default_dir)
415 confp = fopen (config_default_dir, "r");
419 vtysh_read_file (confp);
421 host_config_set (config_default_dir);
426 /* We don't write vtysh specific into file from vtysh. vtysh.conf should
427 * be edited by hand. So, we handle only "write terminal" case here and
428 * integrate vtysh specific conf with conf from daemons.
431 vtysh_config_write ()
434 extern struct host host;
438 sprintf (line, "hostname %s", host.name);
439 vtysh_config_parse_line(line);
441 if (vtysh_writeconfig_integrated)
442 vtysh_config_parse_line ("service integrated-vtysh-config");
448 config_top = list_new ();
449 config_top->del = (void (*) (void *))line_del;
450 configvec = vector_init (1);