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"
31 * Compiler is warning about prototypes not being declared.
32 * The DEFUNSH and DEFUN macro's are messing with the
33 * compiler I believe. This is just to make it happy.
35 int line_cmp(char *, char*);
36 void line_del(char *);
37 struct config
*config_new(void);
38 int config_cmp(struct config
*, struct config
*);
39 void config_del(struct config
*);
40 struct config
*config_get(int, const char *);
41 void config_add_line(struct list
*, const char *);
42 void config_add_line_uniq(struct list
*, const char *);
43 void vtysh_config_parse_line(const char *);
47 extern int vtysh_writeconfig_integrated
;
51 /* Configuration node name. */
54 /* Configuration string line. */
57 /* Configuration can be nest. */
58 struct config
*config
;
60 /* Index of this config. */
64 struct list
*config_top
;
67 line_cmp (char *c1
, char *c2
)
69 return strcmp (c1
, c2
);
75 XFREE (MTYPE_VTYSH_CONFIG_LINE
, line
);
81 struct config
*config
;
82 config
= XCALLOC (MTYPE_VTYSH_CONFIG
, sizeof (struct config
));
87 config_cmp (struct config
*c1
, struct config
*c2
)
89 return strcmp (c1
->name
, c2
->name
);
93 config_del (struct config
* config
)
95 list_delete (config
->line
);
97 XFREE (MTYPE_VTYSH_CONFIG_LINE
, config
->name
);
98 XFREE (MTYPE_VTYSH_CONFIG
, config
);
102 config_get (int index
, const char *line
)
104 struct config
*config
;
105 struct config
*config_loop
;
107 struct listnode
*node
, *nnode
;
109 config
= config_loop
= NULL
;
111 master
= vector_lookup_ensure (configvec
, index
);
115 master
= list_new ();
116 master
->del
= (void (*) (void *))config_del
;
117 master
->cmp
= (int (*)(void *, void *)) config_cmp
;
118 vector_set_index (configvec
, index
, master
);
121 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config_loop
))
123 if (strcmp (config_loop
->name
, line
) == 0)
124 config
= config_loop
;
129 config
= config_new ();
130 config
->line
= list_new ();
131 config
->line
->del
= (void (*) (void *))line_del
;
132 config
->line
->cmp
= (int (*)(void *, void *)) line_cmp
;
133 config
->name
= XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
);
134 config
->index
= index
;
135 listnode_add (master
, config
);
141 config_add_line (struct list
*config
, const char *line
)
143 listnode_add (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
147 config_add_line_uniq (struct list
*config
, const char *line
)
149 struct listnode
*node
, *nnode
;
152 for (ALL_LIST_ELEMENTS (config
, node
, nnode
, pnt
))
154 if (strcmp (pnt
, line
) == 0)
157 listnode_add_sort (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
161 vtysh_config_parse_line (const char *line
)
164 static struct config
*config
= NULL
;
174 /* printf ("[%s]\n", line); */
178 /* Suppress exclamation points ! and commented lines. The !s are generated
179 * dynamically in vtysh_config_dump() */
184 /* Store line to current configuration. */
187 if (strncmp (line
, " address-family vpnv4",
188 strlen (" address-family vpnv4")) == 0)
189 config
= config_get (BGP_VPNV4_NODE
, line
);
190 else if (strncmp (line
, " address-family ipv4 multicast",
191 strlen (" address-family ipv4 multicast")) == 0)
192 config
= config_get (BGP_IPV4M_NODE
, line
);
193 else if (strncmp (line
, " address-family ipv4", strlen (" address-family ipv4")) == 0 ||
194 strncmp (line
, " address-family ipv4 unicast", strlen (" address-family ipv4 unicast")) == 0)
195 config
= config_get (BGP_IPV4_NODE
, line
);
196 else if (strncmp (line
, " address-family ipv6", strlen (" address-family ipv6")) == 0 ||
197 strncmp (line
, " address-family ipv6 unicast", strlen (" address-family ipv6 unicast")) == 0)
198 config
= config_get (BGP_IPV6_NODE
, line
);
199 else if (config
->index
== RMAP_NODE
||
200 config
->index
== INTERFACE_NODE
||
201 config
->index
== VTY_NODE
)
202 config_add_line_uniq (config
->line
, line
);
204 config_add_line (config
->line
, line
);
207 config_add_line (config_top
, line
);
210 if (strncmp (line
, "interface", strlen ("interface")) == 0)
211 config
= config_get (INTERFACE_NODE
, line
);
212 else if (strncmp (line
, "router-id", strlen ("router-id")) == 0)
213 config
= config_get (ZEBRA_NODE
, line
);
214 else if (strncmp (line
, "router rip", strlen ("router rip")) == 0)
215 config
= config_get (RIP_NODE
, line
);
216 else if (strncmp (line
, "router ripng", strlen ("router ripng")) == 0)
217 config
= config_get (RIPNG_NODE
, line
);
218 else if (strncmp (line
, "router ospf", strlen ("router ospf")) == 0)
219 config
= config_get (OSPF_NODE
, line
);
220 else if (strncmp (line
, "router ospf6", strlen ("router ospf6")) == 0)
221 config
= config_get (OSPF6_NODE
, line
);
222 else if (strncmp (line
, "router babel", strlen ("router babel")) == 0)
223 config
= config_get (BABEL_NODE
, line
);
224 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
225 config
= config_get (BGP_NODE
, line
);
226 else if (strncmp (line
, "router isis", strlen ("router isis")) == 0)
227 config
= config_get (ISIS_NODE
, line
);
228 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
229 config
= config_get (BGP_NODE
, line
);
230 else if (strncmp (line
, "route-map", strlen ("route-map")) == 0)
231 config
= config_get (RMAP_NODE
, line
);
232 else if (strncmp (line
, "access-list", strlen ("access-list")) == 0)
233 config
= config_get (ACCESS_NODE
, line
);
234 else if (strncmp (line
, "ipv6 access-list",
235 strlen ("ipv6 access-list")) == 0)
236 config
= config_get (ACCESS_IPV6_NODE
, line
);
237 else if (strncmp (line
, "ip prefix-list",
238 strlen ("ip prefix-list")) == 0)
239 config
= config_get (PREFIX_NODE
, line
);
240 else if (strncmp (line
, "ipv6 prefix-list",
241 strlen ("ipv6 prefix-list")) == 0)
242 config
= config_get (PREFIX_IPV6_NODE
, line
);
243 else if (strncmp (line
, "ip as-path access-list",
244 strlen ("ip as-path access-list")) == 0)
245 config
= config_get (AS_LIST_NODE
, line
);
246 else if (strncmp (line
, "ip community-list",
247 strlen ("ip community-list")) == 0)
248 config
= config_get (COMMUNITY_LIST_NODE
, line
);
249 else if (strncmp (line
, "ip route", strlen ("ip route")) == 0)
250 config
= config_get (IP_NODE
, line
);
251 else if (strncmp (line
, "ipv6 route", strlen ("ipv6 route")) == 0)
252 config
= config_get (IP_NODE
, line
);
253 else if (strncmp (line
, "key", strlen ("key")) == 0)
254 config
= config_get (KEYCHAIN_NODE
, line
);
255 else if (strncmp (line
, "line", strlen ("line")) == 0)
256 config
= config_get (VTY_NODE
, line
);
257 else if ( (strncmp (line
, "ipv6 forwarding",
258 strlen ("ipv6 forwarding")) == 0)
259 || (strncmp (line
, "ip forwarding",
260 strlen ("ip forwarding")) == 0) )
261 config
= config_get (FORWARDING_NODE
, line
);
262 else if (strncmp (line
, "service", strlen ("service")) == 0)
263 config
= config_get (SERVICE_NODE
, line
);
264 else if (strncmp (line
, "debug", strlen ("debug")) == 0)
265 config
= config_get (DEBUG_NODE
, line
);
266 else if (strncmp (line
, "password", strlen ("password")) == 0
267 || strncmp (line
, "enable password",
268 strlen ("enable password")) == 0)
269 config
= config_get (AAA_NODE
, line
);
270 else if (strncmp (line
, "ip protocol", strlen ("ip protocol")) == 0)
271 config
= config_get (PROTOCOL_NODE
, line
);
274 if (strncmp (line
, "log", strlen ("log")) == 0
275 || strncmp (line
, "hostname", strlen ("hostname")) == 0
277 config_add_line_uniq (config_top
, line
);
279 config_add_line (config_top
, line
);
287 vtysh_config_parse (char *line
)
299 vtysh_config_parse_line (begin
);
309 /* Macro to check delimiter is needed between each configuration line
311 #define NO_DELIMITER(I) \
312 ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
313 || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
314 (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
315 || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
318 /* Display configuration to file pointer. */
320 vtysh_config_dump (FILE *fp
)
322 struct listnode
*node
, *nnode
;
323 struct listnode
*mnode
, *mnnode
;
324 struct config
*config
;
329 for (ALL_LIST_ELEMENTS (config_top
, node
, nnode
, line
))
331 fprintf (fp
, "%s\n", line
);
337 for (i
= 0; i
< vector_active (configvec
); i
++)
338 if ((master
= vector_slot (configvec
, i
)) != NULL
)
340 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config
))
342 fprintf (fp
, "%s\n", config
->name
);
345 for (ALL_LIST_ELEMENTS (config
->line
, mnode
, mnnode
, line
))
347 fprintf (fp
, "%s\n", line
);
350 if (! NO_DELIMITER (i
))
356 if (NO_DELIMITER (i
))
363 for (i
= 0; i
< vector_active (configvec
); i
++)
364 if ((master
= vector_slot (configvec
, i
)) != NULL
)
366 list_delete (master
);
367 vector_slot (configvec
, i
) = NULL
;
369 list_delete_all_node (config_top
);
372 /* Read up configuration file from file_name. */
374 vtysh_read_file (FILE *confp
)
379 vty
->fd
= 0; /* stdout */
380 vty
->type
= VTY_TERM
;
381 vty
->node
= CONFIG_NODE
;
383 vtysh_execute_no_pager ("enable");
384 vtysh_execute_no_pager ("configure terminal");
386 /* Execute configuration file. */
387 vtysh_config_from_file (vty
, confp
);
389 vtysh_execute_no_pager ("end");
390 vtysh_execute_no_pager ("disable");
395 /* Read up configuration file from config_default_dir. */
397 vtysh_read_config (const char *config_default_dir
)
401 host_config_set (config_default_dir
);
402 confp
= fopen (config_default_dir
, "r");
406 vtysh_read_file (confp
);
412 /* We don't write vtysh specific into file from vtysh. vtysh.conf should
413 * be edited by hand. So, we handle only "write terminal" case here and
414 * integrate vtysh specific conf with conf from daemons.
417 vtysh_config_write ()
420 extern struct host host
;
424 sprintf (line
, "hostname %s", host
.name
);
425 vtysh_config_parse_line(line
);
427 if (vtysh_writeconfig_integrated
)
428 vtysh_config_parse_line ("service integrated-vtysh-config");
430 user_config_write ();
436 config_top
= list_new ();
437 config_top
->del
= (void (*) (void *))line_del
;
438 configvec
= vector_init (1);