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"
28 #include "vtysh/vtysh_user.h"
32 extern int vtysh_writeconfig_integrated
;
36 /* Configuration node name. */
39 /* Configuration string line. */
42 /* Configuration can be nest. */
43 struct config
*config
;
45 /* Index of this config. */
49 struct list
*config_top
;
52 line_cmp (char *c1
, char *c2
)
54 return strcmp (c1
, c2
);
60 XFREE (MTYPE_VTYSH_CONFIG_LINE
, line
);
63 static struct config
*
66 struct config
*config
;
67 config
= XCALLOC (MTYPE_VTYSH_CONFIG
, sizeof (struct config
));
72 config_cmp (struct config
*c1
, struct config
*c2
)
74 return strcmp (c1
->name
, c2
->name
);
78 config_del (struct config
* config
)
80 list_delete (config
->line
);
82 XFREE (MTYPE_VTYSH_CONFIG_LINE
, config
->name
);
83 XFREE (MTYPE_VTYSH_CONFIG
, config
);
86 static struct config
*
87 config_get (int index
, const char *line
)
89 struct config
*config
;
90 struct config
*config_loop
;
92 struct listnode
*node
, *nnode
;
94 config
= config_loop
= NULL
;
96 master
= vector_lookup_ensure (configvec
, index
);
100 master
= list_new ();
101 master
->del
= (void (*) (void *))config_del
;
102 master
->cmp
= (int (*)(void *, void *)) config_cmp
;
103 vector_set_index (configvec
, index
, master
);
106 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config_loop
))
108 if (strcmp (config_loop
->name
, line
) == 0)
109 config
= config_loop
;
114 config
= config_new ();
115 config
->line
= list_new ();
116 config
->line
->del
= (void (*) (void *))line_del
;
117 config
->line
->cmp
= (int (*)(void *, void *)) line_cmp
;
118 config
->name
= XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
);
119 config
->index
= index
;
120 listnode_add (master
, config
);
126 config_add_line (struct list
*config
, const char *line
)
128 listnode_add (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
132 config_add_line_uniq (struct list
*config
, const char *line
)
134 struct listnode
*node
, *nnode
;
137 for (ALL_LIST_ELEMENTS (config
, node
, nnode
, pnt
))
139 if (strcmp (pnt
, line
) == 0)
142 listnode_add_sort (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
146 vtysh_config_parse_line (const char *line
)
149 static struct config
*config
= NULL
;
159 /* printf ("[%s]\n", line); */
163 /* Suppress exclamation points ! and commented lines. The !s are generated
164 * dynamically in vtysh_config_dump() */
169 /* Store line to current configuration. */
172 if (config
->index
== RMAP_NODE
||
173 config
->index
== INTERFACE_NODE
||
174 config
->index
== VRF_NODE
||
175 config
->index
== VTY_NODE
)
176 config_add_line_uniq (config
->line
, line
);
178 config_add_line (config
->line
, line
);
181 config_add_line (config_top
, line
);
184 if (strncmp (line
, "interface", strlen ("interface")) == 0)
185 config
= config_get (INTERFACE_NODE
, line
);
186 else if (strncmp (line
, "vrf", strlen ("vrf")) == 0)
187 config
= config_get (VRF_NODE
, line
);
188 else if (strncmp (line
, "router-id", strlen ("router-id")) == 0)
189 config
= config_get (ZEBRA_NODE
, line
);
190 else if (strncmp (line
, "router rip", strlen ("router rip")) == 0)
191 config
= config_get (RIP_NODE
, line
);
192 else if (strncmp (line
, "router ripng", strlen ("router ripng")) == 0)
193 config
= config_get (RIPNG_NODE
, line
);
194 else if (strncmp (line
, "router ospf", strlen ("router ospf")) == 0)
195 config
= config_get (OSPF_NODE
, line
);
196 else if (strncmp (line
, "router ospf6", strlen ("router ospf6")) == 0)
197 config
= config_get (OSPF6_NODE
, line
);
198 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
199 config
= config_get (BGP_NODE
, line
);
200 else if (strncmp (line
, "router isis", strlen ("router isis")) == 0)
201 config
= config_get (ISIS_NODE
, line
);
202 else if (strncmp (line
, "route-map", strlen ("route-map")) == 0)
203 config
= config_get (RMAP_NODE
, line
);
204 else if (strncmp (line
, "access-list", strlen ("access-list")) == 0)
205 config
= config_get (ACCESS_NODE
, line
);
206 else if (strncmp (line
, "ipv6 access-list",
207 strlen ("ipv6 access-list")) == 0)
208 config
= config_get (ACCESS_IPV6_NODE
, line
);
209 else if (strncmp (line
, "ip prefix-list",
210 strlen ("ip prefix-list")) == 0)
211 config
= config_get (PREFIX_NODE
, line
);
212 else if (strncmp (line
, "ipv6 prefix-list",
213 strlen ("ipv6 prefix-list")) == 0)
214 config
= config_get (PREFIX_IPV6_NODE
, line
);
215 else if (strncmp (line
, "ip as-path access-list",
216 strlen ("ip as-path access-list")) == 0)
217 config
= config_get (AS_LIST_NODE
, line
);
218 else if (strncmp (line
, "ip community-list", strlen ("ip community-list")) == 0 ||
219 strncmp (line
, "ip extcommunity-list", strlen ("ip extcommunity-list")) == 0)
220 config
= config_get (COMMUNITY_LIST_NODE
, line
);
221 else if (strncmp (line
, "ip route", strlen ("ip route")) == 0)
222 config
= config_get (IP_NODE
, line
);
223 else if (strncmp (line
, "ipv6 route", strlen ("ipv6 route")) == 0)
224 config
= config_get (IP_NODE
, line
);
225 else if (strncmp (line
, "key", strlen ("key")) == 0)
226 config
= config_get (KEYCHAIN_NODE
, line
);
227 else if (strncmp (line
, "line", strlen ("line")) == 0)
228 config
= config_get (VTY_NODE
, line
);
229 else if ( (strncmp (line
, "ipv6 forwarding",
230 strlen ("ipv6 forwarding")) == 0)
231 || (strncmp (line
, "ip forwarding",
232 strlen ("ip forwarding")) == 0) )
233 config
= config_get (FORWARDING_NODE
, line
);
234 else if (strncmp (line
, "service", strlen ("service")) == 0)
235 config
= config_get (SERVICE_NODE
, line
);
236 else if (strncmp (line
, "debug vrf", strlen ("debug vrf")) == 0)
237 config
= config_get (VRF_DEBUG_NODE
, line
);
238 else if (strncmp (line
, "debug", strlen ("debug")) == 0)
239 config
= config_get (DEBUG_NODE
, line
);
240 else if (strncmp (line
, "password", strlen ("password")) == 0
241 || strncmp (line
, "enable password",
242 strlen ("enable password")) == 0)
243 config
= config_get (AAA_NODE
, line
);
244 else if (strncmp (line
, "ip protocol", strlen ("ip protocol")) == 0)
245 config
= config_get (PROTOCOL_NODE
, line
);
246 else if (strncmp (line
, "ipv6 protocol", strlen ("ipv6 protocol")) == 0)
247 config
= config_get (PROTOCOL_NODE
, line
);
248 else if (strncmp (line
, "ip nht", strlen ("ip nht")) == 0)
249 config
= config_get (PROTOCOL_NODE
, line
);
250 else if (strncmp (line
, "ipv6 nht", strlen ("ipv6 nht")) == 0)
251 config
= config_get (PROTOCOL_NODE
, line
);
254 if (strncmp (line
, "log", strlen ("log")) == 0
255 || strncmp (line
, "hostname", strlen ("hostname")) == 0
257 config_add_line_uniq (config_top
, line
);
259 config_add_line (config_top
, line
);
267 vtysh_config_parse (char *line
)
279 vtysh_config_parse_line (begin
);
289 /* Macro to check delimiter is needed between each configuration line
291 #define NO_DELIMITER(I) \
292 ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
293 || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
294 (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
295 || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
296 || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE)
298 /* Display configuration to file pointer. */
300 vtysh_config_dump (FILE *fp
)
302 struct listnode
*node
, *nnode
;
303 struct listnode
*mnode
, *mnnode
;
304 struct config
*config
;
309 for (ALL_LIST_ELEMENTS (config_top
, node
, nnode
, line
))
311 fprintf (fp
, "%s\n", line
);
317 for (i
= 0; i
< vector_active (configvec
); i
++)
318 if ((master
= vector_slot (configvec
, i
)) != NULL
)
320 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config
))
322 fprintf (fp
, "%s\n", config
->name
);
325 for (ALL_LIST_ELEMENTS (config
->line
, mnode
, mnnode
, line
))
327 fprintf (fp
, "%s\n", line
);
330 if (! NO_DELIMITER (i
))
336 if (NO_DELIMITER (i
))
343 for (i
= 0; i
< vector_active (configvec
); i
++)
344 if ((master
= vector_slot (configvec
, i
)) != NULL
)
346 list_delete (master
);
347 vector_slot (configvec
, i
) = NULL
;
349 list_delete_all_node (config_top
);
352 /* Read up configuration file from file_name. */
354 vtysh_read_file (FILE *confp
)
360 vty
->fd
= 0; /* stdout */
361 vty
->type
= VTY_TERM
;
362 vty
->node
= CONFIG_NODE
;
364 vtysh_execute_no_pager ("enable");
365 vtysh_execute_no_pager ("configure terminal");
367 /* Execute configuration file. */
368 ret
= vtysh_config_from_file (vty
, confp
);
370 vtysh_execute_no_pager ("end");
371 vtysh_execute_no_pager ("disable");
378 /* Read up configuration file from config_default_dir. */
380 vtysh_read_config (const char *config_default_dir
)
385 host_config_set (config_default_dir
);
386 confp
= fopen (config_default_dir
, "r");
389 fprintf (stderr
, "%% Can't open configuration file %s due to '%s'.\n",
390 config_default_dir
, safe_strerror (errno
));
391 return (CMD_ERR_NO_FILE
);
394 ret
= vtysh_read_file (confp
);
400 /* We don't write vtysh specific into file from vtysh. vtysh.conf should
401 * be edited by hand. So, we handle only "write terminal" case here and
402 * integrate vtysh specific conf with conf from daemons.
405 vtysh_config_write ()
408 extern struct host host
;
412 sprintf (line
, "hostname %s", host
.name
);
413 vtysh_config_parse_line(line
);
415 if (vtysh_writeconfig_integrated
)
416 vtysh_config_parse_line ("service integrated-vtysh-config");
418 user_config_write ();
424 config_top
= list_new ();
425 config_top
->del
= (void (*) (void *))line_del
;
426 configvec
= vector_init (1);