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"
30 * Compiler is warning about prototypes not being declared.
31 * The DEFUNSH and DEFUN macro's are messing with the
32 * compiler I believe. This is just to make it happy.
34 int line_cmp(char *, char*);
35 void line_del(char *);
36 struct config
*config_new(void);
37 int config_cmp(struct config
*, struct config
*);
38 void config_del(struct config
*);
39 struct config
*config_get(int, const char *);
40 void config_add_line(struct list
*, const char *);
41 void config_add_line_uniq(struct list
*, const char *);
42 void vtysh_config_parse_line(const char *);
46 extern int vtysh_writeconfig_integrated
;
50 /* Configuration node name. */
53 /* Configuration string line. */
56 /* Configuration can be nest. */
57 struct config
*config
;
59 /* Index of this config. */
63 struct list
*config_top
;
66 line_cmp (char *c1
, char *c2
)
68 return strcmp (c1
, c2
);
74 XFREE (MTYPE_VTYSH_CONFIG_LINE
, line
);
80 struct config
*config
;
81 config
= XCALLOC (MTYPE_VTYSH_CONFIG
, sizeof (struct config
));
86 config_cmp (struct config
*c1
, struct config
*c2
)
88 return strcmp (c1
->name
, c2
->name
);
92 config_del (struct config
* config
)
94 list_delete (config
->line
);
96 XFREE (MTYPE_VTYSH_CONFIG_LINE
, config
->name
);
97 XFREE (MTYPE_VTYSH_CONFIG
, config
);
101 config_get (int index
, const char *line
)
103 struct config
*config
;
104 struct config
*config_loop
;
106 struct listnode
*node
, *nnode
;
108 config
= config_loop
= NULL
;
110 master
= vector_lookup_ensure (configvec
, index
);
114 master
= list_new ();
115 master
->del
= (void (*) (void *))config_del
;
116 master
->cmp
= (int (*)(void *, void *)) config_cmp
;
117 vector_set_index (configvec
, index
, master
);
120 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config_loop
))
122 if (strcmp (config_loop
->name
, line
) == 0)
123 config
= config_loop
;
128 config
= config_new ();
129 config
->line
= list_new ();
130 config
->line
->del
= (void (*) (void *))line_del
;
131 config
->line
->cmp
= (int (*)(void *, void *)) line_cmp
;
132 config
->name
= XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
);
133 config
->index
= index
;
134 listnode_add (master
, config
);
140 config_add_line (struct list
*config
, const char *line
)
142 listnode_add (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
146 config_add_line_uniq (struct list
*config
, const char *line
)
148 struct listnode
*node
, *nnode
;
151 for (ALL_LIST_ELEMENTS (config
, node
, nnode
, pnt
))
153 if (strcmp (pnt
, line
) == 0)
156 listnode_add_sort (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
160 vtysh_config_parse_line (const char *line
)
163 static struct config
*config
= NULL
;
173 /* printf ("[%s]\n", line); */
181 /* Store line to current configuration. */
184 if (strncmp (line
, " address-family vpnv4",
185 strlen (" address-family vpnv4")) == 0)
186 config
= config_get (BGP_VPNV4_NODE
, line
);
187 else if (strncmp (line
, " address-family ipv4 multicast",
188 strlen (" address-family ipv4 multicast")) == 0)
189 config
= config_get (BGP_IPV4M_NODE
, line
);
190 else if (strncmp (line
, " address-family ipv6",
191 strlen (" address-family ipv6")) == 0)
192 config
= config_get (BGP_IPV6_NODE
, line
);
193 else if (config
->index
== RMAP_NODE
||
194 config
->index
== INTERFACE_NODE
||
195 config
->index
== VTY_NODE
)
196 config_add_line_uniq (config
->line
, line
);
198 config_add_line (config
->line
, line
);
201 config_add_line (config_top
, line
);
204 if (strncmp (line
, "interface", strlen ("interface")) == 0)
205 config
= config_get (INTERFACE_NODE
, line
);
206 else if (strncmp (line
, "router-id", strlen ("router-id")) == 0)
207 config
= config_get (ZEBRA_NODE
, line
);
208 else if (strncmp (line
, "router rip", strlen ("router rip")) == 0)
209 config
= config_get (RIP_NODE
, line
);
210 else if (strncmp (line
, "router ripng", strlen ("router ripng")) == 0)
211 config
= config_get (RIPNG_NODE
, line
);
212 else if (strncmp (line
, "router ospf", strlen ("router ospf")) == 0)
213 config
= config_get (OSPF_NODE
, line
);
214 else if (strncmp (line
, "router ospf6", strlen ("router ospf6")) == 0)
215 config
= config_get (OSPF6_NODE
, line
);
216 else if (strncmp (line
, "router babel", strlen ("router babel")) == 0)
217 config
= config_get (BABEL_NODE
, line
);
218 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
219 config
= config_get (BGP_NODE
, line
);
220 else if (strncmp (line
, "router isis", strlen ("router isis")) == 0)
221 config
= config_get (ISIS_NODE
, line
);
222 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
223 config
= config_get (BGP_NODE
, line
);
224 else if (strncmp (line
, "route-map", strlen ("route-map")) == 0)
225 config
= config_get (RMAP_NODE
, line
);
226 else if (strncmp (line
, "access-list", strlen ("access-list")) == 0)
227 config
= config_get (ACCESS_NODE
, line
);
228 else if (strncmp (line
, "ipv6 access-list",
229 strlen ("ipv6 access-list")) == 0)
230 config
= config_get (ACCESS_IPV6_NODE
, line
);
231 else if (strncmp (line
, "ip prefix-list",
232 strlen ("ip prefix-list")) == 0)
233 config
= config_get (PREFIX_NODE
, line
);
234 else if (strncmp (line
, "ipv6 prefix-list",
235 strlen ("ipv6 prefix-list")) == 0)
236 config
= config_get (PREFIX_IPV6_NODE
, line
);
237 else if (strncmp (line
, "ip as-path access-list",
238 strlen ("ip as-path access-list")) == 0)
239 config
= config_get (AS_LIST_NODE
, line
);
240 else if (strncmp (line
, "ip community-list",
241 strlen ("ip community-list")) == 0)
242 config
= config_get (COMMUNITY_LIST_NODE
, line
);
243 else if (strncmp (line
, "ip route", strlen ("ip route")) == 0)
244 config
= config_get (IP_NODE
, line
);
245 else if (strncmp (line
, "ipv6 route", strlen ("ipv6 route")) == 0)
246 config
= config_get (IP_NODE
, line
);
247 else if (strncmp (line
, "key", strlen ("key")) == 0)
248 config
= config_get (KEYCHAIN_NODE
, line
);
249 else if (strncmp (line
, "line", strlen ("line")) == 0)
250 config
= config_get (VTY_NODE
, line
);
251 else if ( (strncmp (line
, "ipv6 forwarding",
252 strlen ("ipv6 forwarding")) == 0)
253 || (strncmp (line
, "ip forwarding",
254 strlen ("ip forwarding")) == 0) )
255 config
= config_get (FORWARDING_NODE
, line
);
256 else if (strncmp (line
, "service", strlen ("service")) == 0)
257 config
= config_get (SERVICE_NODE
, line
);
258 else if (strncmp (line
, "debug", strlen ("debug")) == 0)
259 config
= config_get (DEBUG_NODE
, line
);
260 else if (strncmp (line
, "password", strlen ("password")) == 0
261 || strncmp (line
, "enable password",
262 strlen ("enable password")) == 0)
263 config
= config_get (AAA_NODE
, line
);
264 else if (strncmp (line
, "ip protocol", strlen ("ip protocol")) == 0)
265 config
= config_get (PROTOCOL_NODE
, line
);
268 if (strncmp (line
, "log", strlen ("log")) == 0
269 || strncmp (line
, "hostname", strlen ("hostname")) == 0
271 config_add_line_uniq (config_top
, line
);
273 config_add_line (config_top
, line
);
281 vtysh_config_parse (char *line
)
293 vtysh_config_parse_line (begin
);
303 /* Macro to check delimiter is needed between each configuration line
305 #define NO_DELIMITER(I) \
306 ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
307 || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
308 (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
309 || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
312 /* Display configuration to file pointer. */
314 vtysh_config_dump (FILE *fp
)
316 struct listnode
*node
, *nnode
;
317 struct listnode
*mnode
, *mnnode
;
318 struct config
*config
;
323 for (ALL_LIST_ELEMENTS (config_top
, node
, nnode
, line
))
325 fprintf (fp
, "%s\n", line
);
331 for (i
= 0; i
< vector_active (configvec
); i
++)
332 if ((master
= vector_slot (configvec
, i
)) != NULL
)
334 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config
))
336 fprintf (fp
, "%s\n", config
->name
);
339 for (ALL_LIST_ELEMENTS (config
->line
, mnode
, mnnode
, line
))
341 fprintf (fp
, "%s\n", line
);
344 if (! NO_DELIMITER (i
))
350 if (NO_DELIMITER (i
))
357 for (i
= 0; i
< vector_active (configvec
); i
++)
358 if ((master
= vector_slot (configvec
, i
)) != NULL
)
360 list_delete (master
);
361 vector_slot (configvec
, i
) = NULL
;
363 list_delete_all_node (config_top
);
366 /* Read up configuration file from file_name. */
368 vtysh_read_file (FILE *confp
)
374 vty
->fd
= 0; /* stdout */
375 vty
->type
= VTY_TERM
;
376 vty
->node
= CONFIG_NODE
;
378 vtysh_execute_no_pager ("enable");
379 vtysh_execute_no_pager ("configure terminal");
381 /* Execute configuration file. */
382 ret
= vtysh_config_from_file (vty
, confp
);
384 vtysh_execute_no_pager ("end");
385 vtysh_execute_no_pager ("disable");
389 if (ret
!= CMD_SUCCESS
)
393 case CMD_ERR_AMBIGUOUS
:
394 fprintf (stderr
, "Ambiguous command.\n");
396 case CMD_ERR_NO_MATCH
:
397 fprintf (stderr
, "There is no such command.\n");
400 fprintf (stderr
, "Error occured during reading below line.\n%s\n",
406 /* Read up configuration file from config_default_dir. */
408 vtysh_read_config (const char *config_default_dir
)
412 confp
= fopen (config_default_dir
, "r");
416 vtysh_read_file (confp
);
418 host_config_set (config_default_dir
);
423 /* We don't write vtysh specific into file from vtysh. vtysh.conf should
424 * be edited by hand. So, we handle only "write terminal" case here and
425 * integrate vtysh specific conf with conf from daemons.
428 vtysh_config_write ()
431 extern struct host host
;
435 sprintf (line
, "hostname %s", host
.name
);
436 vtysh_config_parse_line(line
);
438 if (vtysh_writeconfig_integrated
)
439 vtysh_config_parse_line ("service integrated-vtysh-config");
445 config_top
= list_new ();
446 config_top
->del
= (void (*) (void *))line_del
;
447 configvec
= vector_init (1);