Update primary code license to Apache 2.0.
[cascardo/ovs.git] / lib / cfg.c
1 /* Copyright (c) 2008, 2009 Nicira Networks
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <config.h>
17 #include "cfg.h"
18 #include <arpa/inet.h>
19 #include <assert.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <fnmatch.h>
24 #include <inttypes.h>
25 #include <netinet/in.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include "coverage.h"
31 #include "dynamic-string.h"
32 #include "ofpbuf.h"
33 #include "packets.h"
34 #include "svec.h"
35 #include "timeval.h"
36 #include "util.h"
37
38 #define THIS_MODULE VLM_cfg
39 #include "vlog.h"
40
41 /* XXX This file really needs a unit test!  For a while, cfg_get_string(0,
42  * "bridge.a.controller") would return the value of
43  * "bridge.a.controller.in-band", if it existed, and I'm really not certain
44  * that the fix didn't break other things. */
45
46 /* Configuration file name. */
47 static char *cfg_name;
48
49 /* Put the temporary file in the same directory as cfg_name, so that
50  * they are guaranteed to be in the same file system and therefore we can
51  * rename() tmp_name over cfg_name. */
52 static char *tmp_name;
53
54 /* Lock information. */
55 static char *lock_name;
56 static int lock_fd = -1;
57
58 /* Flag to indicate whether local modifications have been made. */
59 static bool dirty;
60
61 static uint8_t cfg_cookie[CFG_COOKIE_LEN];
62
63 /* Current configuration.  Maintained in sorted order. */
64 static struct svec cfg = SVEC_EMPTY_INITIALIZER;
65
66 static bool has_double_dot(const char *key, size_t len);
67 static bool is_valid_key(const char *key, size_t len,
68                          const char *file_name, int line_number,
69                          const char *id);
70 static char *parse_section(const char *file_name, int line_number,
71                            const char *);
72 static void parse_setting(const char *file_name, int line_number,
73                           const char *section, const char *);
74 static int compare_key(const char *a, const char *b);
75 static char **find_key_le(const char *key);
76 static char **find_key_ge(const char *key);
77 static char *find_key(const char *);
78 static bool parse_mac(const char *, uint8_t mac[6]);
79 static bool parse_dpid(const char *, uint64_t *);
80 static bool is_key(const char *);
81 static bool is_int(const char *);
82 static bool is_bool(const char *);
83 static const char *extract_value(const char *key);
84 static const char *get_nth_value(int idx, const char *key);
85 static bool is_type(const char *s, enum cfg_flags);
86
87 #define CC_ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
88 #define CC_DIGIT "0123456789"
89 #define CC_ALNUM CC_ALPHA CC_DIGIT
90 #define CC_SPACE " \t\r\n\v"
91
92 #define CC_FILE_NAME CC_ALNUM "._-"
93 #define CC_KEY CC_ALNUM "._-@$:+"
94
95 /* Sets 'file_name' as the configuration file read by cfg_read().  Returns 0 on
96  * success, otherwise a positive errno value if 'file_name' cannot be opened.
97  *
98  * This function does not actually read the named file or directory.  Use
99  * cfg_read() to (re)read all the configuration files. */
100 int
101 cfg_set_file(const char *file_name)
102 {
103     const char *slash;
104     int fd;
105
106     if (cfg_name) {
107         assert(lock_fd < 0);
108         free(cfg_name);
109         free(lock_name);
110         free(tmp_name);
111         cfg_name = lock_name = tmp_name = NULL;
112     }
113
114     /* Make sure that we can open this file for reading. */
115     fd = open(file_name, O_RDONLY);
116     if (fd < 0) {
117         return errno;
118     }
119     close(fd);
120
121     cfg_name = xstrdup(file_name);
122
123     /* Put the temporary file in the same directory as cfg_name, so that they
124      * are guaranteed to be in the same file system, to guarantee that
125      * rename(tmp_name, cfg_name) will work. */
126     tmp_name = xasprintf("%s.~tmp~", file_name);
127
128     /* Put the lock file in the same directory as cfg_name, but prefixed by
129      * a dot so as not to garner administrator interest. */
130     slash = strrchr(file_name, '/');
131     if (slash) {
132         lock_name = xasprintf("%.*s/.%s.~lock~",
133                               slash - file_name, file_name, slash + 1);
134     } else {
135         lock_name = xasprintf(".%s.~lock~", file_name);
136     }
137
138     VLOG_INFO("using \"%s\" as configuration file, \"%s\" as lock file",
139               file_name, lock_name);
140     return 0;
141 }
142
143 static int
144 update_cookie(void)
145 {
146     int i;
147     SHA1Context context;
148
149     if (SHA1Reset(&context) != shaSuccess) {
150         return -1;
151     }
152     for (i = 0; i < cfg.n; i++) {
153         if (SHA1Input(&context, (uint8_t *)cfg.names[i], 
154                     strlen(cfg.names[i])) != shaSuccess) {
155             return -1;
156         }
157         SHA1Input(&context, (uint8_t *)"\n", 1);
158     }
159     if (SHA1Result(&context, cfg_cookie) != shaSuccess) {
160         return -1;
161     }
162
163     return 0;
164 }
165
166 /* Reads all of the configuration files or directories that have been added
167  * with cfg_add_file(), merges their content.  Any previous configuration is
168  * replaced.  Returns 0 if successful, otherwise a positive errno value. */
169 int
170 cfg_read(void)
171 {
172     struct svec old_cfg;
173     struct ds ds;
174     FILE *file;
175     char *section;
176     int line_number;
177
178
179     if (!cfg_name) {
180         return ENODEV;
181     }
182
183     /* Save old configuration data and clear the active configuration. */
184     svec_init(&old_cfg);
185     svec_swap(&old_cfg, &cfg);
186
187     /* Read new configuration. */
188     VLOG_DBG("reading configuration from %s", cfg_name);
189
190     file = fopen(cfg_name, "r");
191     if (!file) {
192         VLOG_ERR("failed to open \"%s\": %s", cfg_name, strerror(errno));
193         return errno;
194     }
195
196     ds_init(&ds);
197     section = NULL;
198     line_number = 0;
199     while (!ds_get_line(&ds, file)) {
200         const char *s = ds_cstr(&ds);
201         size_t indent = strspn(s, CC_SPACE);
202
203         line_number++;
204         s += indent;
205         if (*s == '#' || *s == '\0') {
206             /* Ignore comments and lines that contain only white space. */
207         } else if (*s == '[') {
208             if (!indent) {
209                 free(section);
210                 section = parse_section(cfg_name, line_number, s);
211             } else {
212                 VLOG_ERR("%s:%d: ignoring indented section header",
213                          cfg_name, line_number);
214             }
215         } else if (indent && !section) {
216             VLOG_ERR("%s:%d: ignoring indented line outside any section",
217                      cfg_name, line_number);
218         } else {
219             if (!indent) {
220                 free(section);
221                 section = NULL;
222             }
223             parse_setting(cfg_name, line_number, section, s);
224         }
225     }
226     ds_destroy(&ds);
227     free(section);
228
229     svec_sort(&cfg);
230     svec_terminate(&cfg);
231     update_cookie();
232
233     fclose(file);
234
235     if (VLOG_IS_DBG_ENABLED()) {
236         struct svec removed, added;
237         size_t i;
238
239         svec_diff(&old_cfg, &cfg, &removed, NULL, &added);
240         if (removed.n || added.n) {
241             VLOG_DBG("configuration changes:");
242             for (i = 0; i < removed.n; i++) {
243                 VLOG_DBG("-%s", removed.names[i]);
244             }
245             for (i = 0; i < added.n; i++) {
246                 VLOG_DBG("+%s", added.names[i]);
247             }
248         } else {
249             VLOG_DBG("configuration unchanged");
250         }
251         svec_destroy(&added);
252         svec_destroy(&removed);
253     }
254     svec_destroy(&old_cfg);
255
256     dirty = false;
257
258     return 0;
259 }
260
261 /* Fills 'svec' with the entire configuration file. */
262 void
263 cfg_get_all(struct svec *svec)
264 {
265     svec_clear(svec);
266     svec_append(svec, &cfg);
267 }
268
269 int
270 cfg_get_cookie(uint8_t *cookie)
271 {
272     if (dirty) {
273         update_cookie();
274     }
275
276     memcpy(cookie, cfg_cookie, sizeof(cfg_cookie));
277     return 0;
278 }
279
280 void
281 cfg_unlock(void)
282 {
283     if (lock_fd != -1) {
284         COVERAGE_INC(cfg_unlock);
285         close(lock_fd);
286         lock_fd = -1;
287     }
288 }
289
290 static int
291 open_lockfile(const char *name)
292 {
293     for (;;) {
294         /* Try to open an existing lock file. */
295         int fd = open(name, O_RDWR);
296         if (fd >= 0) {
297             return fd;
298         } else if (errno != ENOENT) {
299             VLOG_WARN("%s: failed to open lock file: %s",
300                       name, strerror(errno));
301             return -errno;
302         }
303
304         /* Try to create a new lock file. */
305         VLOG_INFO("%s: lock file does not exist, creating", name);
306         fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
307         if (fd >= 0) {
308             return fd;
309         } else if (errno != EEXIST) {
310             VLOG_WARN("%s: failed to create lock file: %s",
311                       name, strerror(errno));
312             return -errno;
313         }
314
315         /* Someone else created the lock file.  Try again. */
316     }
317 }
318
319 static int
320 try_lock(int fd, bool block)
321 {
322     struct flock l;
323     memset(&l, 0, sizeof l);
324     l.l_type = F_WRLCK;
325     l.l_whence = SEEK_SET;
326     l.l_start = 0;
327     l.l_len = 0;
328     return fcntl(fd, block ? F_SETLKW : F_SETLK, &l) == -1 ? errno : 0;
329 }
330
331 /* Locks the configuration file against modification by other processes and
332  * re-reads it from disk.
333  *
334  * The 'timeout' specifies the maximum number of milliseconds to wait for the
335  * config file to become free.  Use 0 to avoid waiting or INT_MAX to wait
336  * forever.
337  *
338  * Returns 0 on success, otherwise a positive errno value. */
339 int
340 cfg_lock(uint8_t *cookie, int timeout)
341 {
342     long long int start = time_msec();
343     long long int elapsed = 0;
344     int fd;
345     uint8_t curr_cookie[CFG_COOKIE_LEN];
346
347     assert(lock_fd < 0);
348     COVERAGE_INC(cfg_lock);
349     for (;;) {
350         int error;
351
352         /* Open lock file. */
353         fd = open_lockfile(lock_name);
354         if (fd < 0) {
355             return -fd;
356         }
357
358         /* Try to lock it.  This will block (if 'timeout' > 0). */
359         error = try_lock(fd, timeout > 0);
360         time_refresh();
361         elapsed = time_msec() - start;
362         if (!error) {
363             /* Success! */
364             break;
365         }
366
367         /* Lock failed.  Close the lock file and reopen it on the next
368          * iteration, just in case someone deletes it underneath us (even
369          * though that should not happen). */
370         close(fd);
371         if (error != EINTR) {
372             /* Hard error, give up. */
373             COVERAGE_INC(cfg_lock_error);
374             VLOG_WARN("%s: failed to lock file "
375                       "(after %lld ms, with %d-ms timeout): %s",
376                       lock_name, elapsed, timeout, strerror(error));
377             return error;
378         }
379
380         /* Probably, the periodic timer set up by time_init() woke up us.  Just
381          * check whether it's time to give up. */
382         if (timeout != INT_MAX && elapsed >= timeout) {
383             COVERAGE_INC(cfg_lock_timeout);
384             VLOG_WARN("%s: giving up on lock file after %lld ms",
385                       lock_name, elapsed);
386             return ETIMEDOUT;
387         }
388         COVERAGE_INC(cfg_lock_retry);
389     }
390     if (elapsed) {
391         VLOG_WARN("%s: waited %lld ms for lock file", lock_name, elapsed);
392     }
393     lock_fd = fd;
394
395     cfg_read();
396
397     if (cookie) {
398         cfg_get_cookie(curr_cookie);
399
400         if (memcmp(curr_cookie, cookie, sizeof *curr_cookie)) {
401             /* Configuration has changed, so reject. */
402             cfg_unlock();
403             return EINVAL;
404         }
405     }
406
407     return 0;
408 }
409
410 static int
411 do_write_config(const void *data, size_t len)
412 {
413     FILE *file;
414     int error;
415
416     file = fopen(tmp_name, "w");
417     if (file == NULL) {
418         VLOG_WARN("could not open %s for writing: %s",
419                   tmp_name, strerror(errno));
420         return errno;
421     }
422
423     fwrite(data, 1, len, file);
424
425     /* This is essentially equivalent to:
426      *       error = ferror(file) || fflush(file) || fclose(file);
427      * but it doesn't short-circuit, so that it always closes 'file'. */
428     error = ferror(file);
429     error = fflush(file) || error;
430     error = fclose(file) || error;
431     if (error) {
432         VLOG_WARN("problem writing to %s: %s", tmp_name, strerror(errno));
433         return errno;
434     }
435
436     if (rename(tmp_name, cfg_name) < 0) {
437         VLOG_WARN("could not rename %s to %s: %s",
438                   tmp_name, cfg_name, strerror(errno));
439         return errno;
440     }
441
442     dirty = false;
443
444     return 0;
445 }
446
447 /* Write the current configuration into the configuration file.  Returns 0 if
448  * successful, otherwise a negative errno value. */
449 int
450 cfg_write(void)
451 {
452     char *content;
453     int retval;
454
455     svec_sort(&cfg);
456     content = (cfg.n
457                ? svec_join(&cfg, "\n", "\n")
458                : xstrdup("# This file intentionally left blank.\n"));
459     retval = do_write_config(content, strlen(content));
460     free(content);
461
462     return retval;
463 }
464
465 int
466 cfg_write_data(uint8_t *data, size_t len)
467 {
468     int retval = do_write_config(data, len);
469     if (!retval) {
470         cfg_read();
471     }
472     return retval;
473 }
474
475 /* Returns true if the configuration has changed since the last time it was
476  * read or written. */
477 bool
478 cfg_is_dirty(void)
479 {
480     return dirty;
481 }
482
483 void
484 cfg_buf_put(struct ofpbuf *buffer)
485 {
486     int i;
487
488     for (i = 0; i < cfg.n; i++) {
489         ofpbuf_put(buffer, cfg.names[i], strlen(cfg.names[i]));
490         ofpbuf_put(buffer, "\n", 1);
491     }
492 }
493
494 /* Formats the printf()-style format string in the parameter 'format', which
495  * must be the function's last parameter, into string variable 'dst'.  The
496  * function is responsible for freeing 'dst'. */
497 #define FORMAT_KEY(FORMAT, DST)                 \
498     do {                                        \
499       va_list args__;                           \
500       va_start(args__, FORMAT);                 \
501       (DST) = xvasprintf(FORMAT, args__);       \
502       va_end(args__);                           \
503     } while (0)
504
505 /* Returns true if the configuration includes a key named 'key'. */
506 bool
507 cfg_has(const char *key_, ...)
508 {
509     char *key;
510     bool retval;
511
512     FORMAT_KEY(key_, key);
513     retval = find_key(key) != NULL;
514     free(key);
515     return retval;
516 }
517
518 bool
519 cfg_is_valid(enum cfg_flags flags, const char *key_, ...)
520 {
521     char *key, **first, **last, **p;
522     size_t n;
523     bool retval;
524
525     FORMAT_KEY(key_, key);
526     first = find_key_le(key);
527     last = find_key_ge(key);
528     n = last - first;
529     retval = ((!(flags & CFG_REQUIRED) || n)
530               && (!(flags & CFG_MULTIPLE) || n <= 1));
531     for (p = first; retval && p < last; p++) {
532         retval = is_type(strchr(*p, '=') + 1, flags);
533     }
534     free(key);
535     return retval;
536 }
537
538 /* Returns true if the configuration includes at least one key whose name
539  * begins with 'section' followed by a dot. */
540 bool
541 cfg_has_section(const char *section_, ...)
542 {
543     struct ds section;
544     bool retval = false;
545     va_list args;
546     char **p;
547
548     ds_init(&section);
549     va_start(args, section_);
550     ds_put_format_valist(&section, section_, args);
551     ds_put_char(&section, '.');
552     va_end(args);
553
554     for (p = cfg.names; *p; p++) { /* XXX this is inefficient */
555         if (!strncmp(section.string, *p, section.length)) {
556             retval = true;
557             break;
558         }
559     }
560
561     ds_destroy(&section);
562     return retval;
563 }
564
565 /* Returns the number of values for the given 'key'.  The return value is 0 if
566  * no values exist for 'key'. */
567 int
568 cfg_count(const char *key_, ...)
569 {
570     char *key;
571     int retval;
572
573     FORMAT_KEY(key_, key);
574     retval = find_key_ge(key) - find_key_le(key);
575     free(key);
576     return retval;
577 }
578
579 /* Fills 'svec' with all of the immediate subsections of 'section'.  For
580  * example, if 'section' is "bridge" and keys bridge.a, bridge.b, bridge.b.c,
581  * and bridge.c.x.y.z exist, then 'svec' would be initialized to a, b, and
582  * c.  The caller must first initialize 'svec'. */
583 void
584 cfg_get_subsections(struct svec *svec, const char *section_, ...)
585 {
586     struct ds section;
587     va_list args;
588     char **p;
589
590     ds_init(&section);
591     va_start(args, section_);
592     ds_put_format_valist(&section, section_, args);
593     ds_put_char(&section, '.');
594     va_end(args);
595
596     svec_clear(svec);
597     for (p = cfg.names; *p; p++) { /* XXX this is inefficient */
598         if (!strncmp(section.string, *p, section.length)) {
599             const char *ss = *p + section.length;
600             size_t ss_len = strcspn(ss, ".=");
601             svec_add_nocopy(svec, xmemdup0(ss, ss_len));
602         }
603     }
604     svec_unique(svec);
605     ds_destroy(&section);
606 }
607
608 void
609 cfg_add_entry(const char *entry_, ...)
610 {
611     char *entry;
612
613     FORMAT_KEY(entry_, entry);
614     svec_add_nocopy(&cfg, entry);
615     svec_sort(&cfg);
616     svec_terminate(&cfg);
617     dirty = true;
618 }
619
620 void
621 cfg_del_entry(const char *entry_, ...)
622 {
623     char *entry;
624
625     FORMAT_KEY(entry_, entry);
626     svec_del(&cfg, entry);
627     svec_terminate(&cfg);
628     free(entry);
629     dirty = true;
630 }
631
632 void
633 cfg_del_section(const char *section_, ...)
634 {
635     struct ds section;
636     va_list args;
637     char **p;
638
639     ds_init(&section);
640     va_start(args, section_);
641     ds_put_format_valist(&section, section_, args);
642     ds_put_char(&section, '.');
643     va_end(args);
644
645     for (p = cfg.names; *p; p++) {
646         if (!strncmp(section.string, *p, section.length)) {
647             free(*p);
648             *p = NULL;
649         }
650     }
651     svec_compact(&cfg);
652     svec_terminate(&cfg);
653
654     ds_destroy(&section);
655     dirty = true;
656 }
657
658 void
659 cfg_del_match(const char *pattern_, ...)
660 {
661     bool matched = false;
662     char *pattern;
663     char **p;
664
665     FORMAT_KEY(pattern_, pattern);
666
667     for (p = cfg.names; *p; p++) {
668         if (!fnmatch(pattern, *p, 0)) {
669             free(*p);
670             *p = NULL;
671             matched = true;
672         }
673     }
674     if (matched) {
675         svec_compact(&cfg);
676         svec_terminate(&cfg);
677         dirty = true;
678     }
679
680     free(pattern);
681 }
682
683 /* Fills 'svec' with all of the key-value pairs that have sections that
684  * begin with 'section'.  The caller must first initialize 'svec'. */
685 void
686 cfg_get_section(struct svec *svec, const char *section_, ...)
687 {
688     struct ds section;
689     va_list args;
690     char **p;
691
692     ds_init(&section);
693     va_start(args, section_);
694     ds_put_format_valist(&section, section_, args);
695     ds_put_char(&section, '.');
696     va_end(args);
697
698     for (p = cfg.names; *p; p++) { /* XXX this is inefficient */
699         if (!strncmp(section.string, *p, section.length)) {
700             svec_add(svec, *p);
701         }
702     }
703     ds_destroy(&section);
704 }
705
706 /* Returns the value numbered 'idx' of 'key'.  Returns a null pointer if 'idx'
707  * is greater than or equal to cfg_count(key).  The caller must not modify or
708  * free the returned string or retain its value beyond the next call to
709  * cfg_read(). */
710 const char *
711 cfg_get_string(int idx, const char *key_, ...)
712 {
713     const char *retval;
714     char *key;
715
716     FORMAT_KEY(key_, key);
717     retval = get_nth_value(idx, key);
718     free(key);
719     return retval;
720 }
721
722 /* Returns the value numbered 'idx' of 'key'.  Returns a null pointer if 'idx'
723  * is greater than or equal to cfg_count(key) or if the value 'idx' of 'key' is
724  * not a valid key.  The caller must not modify or free the returned string or
725  * retain its value beyond the next call to cfg_read(). */
726 const char *
727 cfg_get_key(int idx, const char *key_, ...)
728 {
729     const char *value, *retval;
730     char *key;
731
732     FORMAT_KEY(key_, key);
733     value = get_nth_value(idx, key);
734     retval = value && is_key(value) ? value : NULL;
735     free(key);
736     return retval;
737 }
738
739 /* Returns the value numbered 'idx' of 'key', converted to an integer.  Returns
740  * 0 if 'idx' is greater than or equal to cfg_count(key) or if the value 'idx'
741  * of 'key' is not a valid integer.  */
742 int
743 cfg_get_int(int idx, const char *key_, ...)
744 {
745     const char *value;
746     int retval;
747     char *key;
748
749     FORMAT_KEY(key_, key);
750     value = get_nth_value(idx, key);
751     retval = value && is_int(value) ? atoi(value) : 0;
752     free(key);
753     return retval;
754 }
755
756 /* Returns the value numbered 'idx' of 'key', converted to a boolean value.
757  * Returns false if 'idx' is greater than or equal to cfg_count(key) or if the
758  * value 'idx' of 'key' is not a valid boolean.  */
759 bool
760 cfg_get_bool(int idx, const char *key_, ...)
761 {
762     const char *value;
763     bool retval;
764     char *key;
765
766     FORMAT_KEY(key_, key);
767     value = get_nth_value(idx, key);
768     retval = value && is_bool(value) ? !strcmp(value, "true") : false;
769     free(key);
770     return retval;
771 }
772
773 /* Returns the value numbered 'idx' of 'key', converted to an IP address in
774  * network byte order.  Returns 0 if 'idx' is greater than or equal to
775  * cfg_count(key) or if the value 'idx' of 'key' is not a valid IP address (as
776  * determined by inet_aton()).  */
777 uint32_t
778 cfg_get_ip(int idx, const char *key_, ...)
779 {
780     struct in_addr addr;
781     const char *value;
782     char *key;
783
784     FORMAT_KEY(key_, key);
785     value = get_nth_value(idx, key);
786     if (!value || !inet_aton(value, &addr)) {
787         addr.s_addr = htonl(0);
788     }
789     free(key);
790     return addr.s_addr;
791 }
792
793 /* Returns the value numbered 'idx' of 'key', converted to an MAC address in
794  * host byte order.  Returns 0 if 'idx' is greater than or equal to
795  * cfg_count(key) or if the value 'idx' of 'key' is not a valid MAC address in
796  * the format "##:##:##:##:##:##".  */
797 uint64_t
798 cfg_get_mac(int idx, const char *key_, ...)
799 {
800     uint8_t mac[ETH_ADDR_LEN];
801     const char *value;
802     char *key;
803
804     FORMAT_KEY(key_, key);
805     value = get_nth_value(idx, key);
806     if (!value || !parse_mac(value, mac)) {
807         memset(mac, 0, sizeof mac);
808     }
809     free(key);
810     return eth_addr_to_uint64(mac);
811 }
812
813 /* Returns the value numbered 'idx' of 'key', parsed as an datapath ID.
814  * Returns 0 if 'idx' is greater than or equal to cfg_count(key) or if the
815  * value 'idx' of 'key' is not a valid datapath ID consisting of exactly 12
816  * hexadecimal digits.  */
817 uint64_t
818 cfg_get_dpid(int idx, const char *key_, ...)
819 {
820     uint64_t dpid;
821     const char *value;
822     char *key;
823
824     FORMAT_KEY(key_, key);
825     value = get_nth_value(idx, key);
826     if (!value || !parse_dpid(value, &dpid)) {
827         dpid = 0;
828     }
829     free(key);
830     return dpid;
831 }
832
833 /* Returns the value numbered 'idx' of 'key', converted to an integer.  Returns
834  * -1 if 'idx' is greater than or equal to cfg_count(key) or if the value 'idx'
835  * of 'key' is not a valid integer between 0 and 4095.  */
836 int
837 cfg_get_vlan(int idx, const char *key_, ...)
838 {
839     const char *value;
840     int retval;
841     char *key;
842
843     FORMAT_KEY(key_, key);
844     value = get_nth_value(idx, key);
845     if (value && is_int(value)) {
846         retval = atoi(value);
847         if (retval < 0 || retval > 4095) {
848             retval = -1;
849         }
850     } else {
851         retval = -1;
852     }
853     free(key);
854     return retval;
855 }
856
857 /* Fills 'svec' with all of the string values of 'key'.  The caller must
858  * first initialize 'svec'. */
859 void
860 cfg_get_all_strings(struct svec *svec, const char *key_, ...)
861 {
862     char **p, **q;
863     char *key;
864
865     FORMAT_KEY(key_, key);
866     svec_clear(svec);
867     for (p = find_key_le(key), q = find_key_ge(key); p < q; p++) {
868         svec_add(svec, extract_value(*p));
869     }
870     free(key);
871 }
872
873 /* Fills 'svec' with all of the values of 'key' that are valid keys.
874  * Values of 'key' that are not valid keys are omitted.   The caller 
875  * must first initialize 'svec'. */
876 void
877 cfg_get_all_keys(struct svec *svec, const char *key_, ...)
878 {
879     char **p, **q;
880     char *key;
881
882     FORMAT_KEY(key_, key);
883     svec_clear(svec);
884     for (p = find_key_le(key), q = find_key_ge(key); p < q; p++) {
885         const char *value = extract_value(*p);
886         if (is_key(value)) {
887             svec_add(svec, value);
888         }
889     }
890     free(key);
891 }
892 \f
893 static bool
894 has_double_dot(const char *key, size_t len)
895 {
896     if (len >= 2) {
897         size_t i;
898
899         for (i = 0; i < len - 1; i++) {
900             if (key[i] == '.' && key[i + 1] == '.') {
901                 return true;
902             }
903         }
904     }
905     return false;
906 }
907
908 static bool
909 is_valid_key(const char *key, size_t len,
910                  const char *file_name, int line_number, const char *id)
911 {
912     if (!len) {
913         VLOG_ERR("%s:%d: missing %s name", file_name, line_number, id);
914         return false;
915     } else if (key[0] == '.') {
916         VLOG_ERR("%s:%d: %s name \"%.*s\" begins with invalid character '.'",
917                  file_name, line_number, id, (int) len, key);
918         return false;
919     } else if (key[len - 1] == '.') {
920         VLOG_ERR("%s:%d: %s name \"%.*s\" ends with invalid character '.'",
921                  file_name, line_number, id, (int) len, key);
922         return false;
923     } else if (has_double_dot(key, len)) {
924         VLOG_ERR("%s:%d: %s name \"%.*s\" contains '..', which is not allowed",
925                  file_name, line_number, id, (int) len, key);
926         return false;
927     } else {
928         return true;
929     }
930 }
931
932 static char *
933 parse_section(const char *file_name, int line_number, const char *s)
934 {
935     struct ds section;
936     size_t len;
937
938     ds_init(&section);
939
940     /* Skip [ and any white space. */
941     s++;
942     s += strspn(s, CC_SPACE);
943
944     /* Obtain the section name. */
945     len = strspn(s, CC_KEY);
946     if (!is_valid_key(s, len, file_name, line_number, "section")) {
947         goto error;
948     }
949     ds_put_buffer(&section, s, len);
950     s += len;
951
952     /* Obtain the subsection name, if any. */
953     s += strspn(s, CC_SPACE);
954     if (*s == '"') {
955         s++;
956         len = strspn(s, CC_KEY);
957         if (!is_valid_key(s, len, file_name, line_number, "subsection")) {
958             goto error;
959         }
960         ds_put_char(&section, '.');
961         ds_put_buffer(&section, s, len);
962         s += len;
963         if (*s != '"') {
964             VLOG_ERR("%s:%d: missing '\"' following subsection name",
965                      file_name, line_number);
966             goto error;
967         }
968         s++;
969         s += strspn(s, CC_SPACE);
970     }
971
972     /* Check for ]. */
973     if (*s != ']') {
974         VLOG_ERR("%s:%d: missing ']' following section name",
975                  file_name, line_number);
976         goto error;
977     }
978     s++;
979     s += strspn(s, CC_SPACE);
980     if (*s != '\0') {
981         VLOG_ERR("%s:%d: trailing garbage following ']'",
982                  file_name, line_number);
983         goto error;
984     }
985
986     return ds_cstr(&section);
987
988 error:
989     ds_destroy(&section);
990     return NULL;
991 }
992
993 static void
994 parse_setting(const char *file_name, int line_number, const char *section,
995               const char *s)
996 {
997     struct ds key = DS_EMPTY_INITIALIZER;
998     struct ds value = DS_EMPTY_INITIALIZER;
999     size_t len;
1000
1001     if (section) {
1002         ds_put_format(&key, "%s.", section);
1003     }
1004
1005     /* Obtain the key. */
1006     len = strspn(s, CC_KEY);
1007     if (!len) {
1008         VLOG_ERR("%s:%d: missing key name", file_name, line_number);
1009         goto done;
1010     }
1011     if (!is_valid_key(s, len, file_name, line_number, "key")) {
1012         goto done;
1013     }
1014     ds_put_buffer(&key, s, len);
1015     s += len;
1016
1017     /* Skip the '='. */
1018     s += strspn(s, CC_SPACE);
1019     if (*s != '=') {
1020         VLOG_ERR("%s:%d: missing '=' following key", file_name, line_number);
1021         goto done;
1022     }
1023     s++;
1024     s += strspn(s, CC_SPACE);
1025
1026     /* Obtain the value. */
1027     ds_put_cstr(&value, s);
1028     while (value.length > 0 && strchr(CC_SPACE, ds_last(&value))) {
1029         value.length--;
1030     }
1031
1032     /* Add the setting. */
1033     svec_add_nocopy(&cfg, xasprintf("%s=%s", ds_cstr(&key), ds_cstr(&value)));
1034
1035 done:
1036     ds_destroy(&key);
1037     ds_destroy(&value);
1038 }
1039
1040 static int
1041 compare_key(const char *a, const char *b)
1042 {
1043     for (;;) {
1044         int ac = *a == '\0' || *a == '=' ? INT_MAX : *a;
1045         int bc = *b == '\0' || *b == '=' ? INT_MAX : *b;
1046         if (ac != bc) {
1047             return ac < bc ? -1 : 1;
1048         } else if (ac == INT_MAX) {
1049             return 0;
1050         }
1051         a++;
1052         b++;
1053     }
1054 }
1055
1056 /* Returns the address of the greatest configuration string with a key less
1057  * than or equal to 'key'.  Returns the address of the null terminator if all
1058  * configuration strings are greater than 'key'. */
1059 static char **
1060 find_key_le(const char *key)
1061 {
1062     int low = 0;
1063     int len = cfg.n;
1064     while (len > 0) {
1065         int half = len >> 1;
1066         int middle = low + half;
1067         if (compare_key(cfg.names[middle], key) < 0) {
1068             low = middle + 1;
1069             len -= half + 1;
1070         } else {
1071             len = half;
1072         }
1073     }
1074     return &cfg.names[low];
1075 }
1076
1077 /* Returns the address of the least configuration string with a key greater
1078  * than or equal to 'key'.  Returns the address of the null terminator if all
1079  * configuration strings are less than 'key'. */
1080 static char **
1081 find_key_ge(const char *key)
1082 {
1083     int low = 0;
1084     int len = cfg.n;
1085     while (len > 0) {
1086         int half = len >> 1;
1087         int middle = low + half;
1088         if (compare_key(cfg.names[middle], key) > 0) {
1089             len = half;
1090         } else {
1091             low = middle + 1;
1092             len -= half + 1;
1093         }
1094     }
1095     return &cfg.names[low];
1096 }
1097
1098 static char *
1099 find_key(const char *key)
1100 {
1101     char **p = find_key_le(key);
1102     return p < &cfg.names[cfg.n] && !compare_key(*p, key) ? *p : NULL;
1103 }
1104
1105 static bool
1106 parse_mac(const char *s, uint8_t mac[6])
1107 {
1108     return sscanf(s, "%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8,
1109                   &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6;
1110 }
1111
1112 static bool
1113 parse_dpid(const char *s, uint64_t *dpid)
1114 {
1115     if (strlen(s) == 12 && strspn(s, "0123456789abcdefABCDEF") == 12) {
1116         *dpid = strtoll(s, NULL, 16);
1117         return true;
1118     } else {
1119         return false;
1120     }
1121 }
1122
1123 static bool
1124 is_key(const char *s)
1125 {
1126     /* XXX needs to check the same things as is_valid_key() too. */
1127     return *s && s[strspn(s, CC_KEY)] == '\0';
1128 }
1129
1130 static bool
1131 is_int(const char *s)
1132 {
1133     return *s && s[strspn(s, CC_DIGIT)] == '\0';
1134 }
1135
1136 static bool
1137 is_bool(const char *s)
1138 {
1139     return !strcmp(s, "true") || !strcmp(s, "false");
1140 }
1141
1142 static const char *
1143 extract_value(const char *key)
1144 {
1145     const char *p = strchr(key, '=');
1146     return p ? p + 1 : NULL;
1147 }
1148
1149 static const char *
1150 get_nth_value(int idx, const char *key)
1151 {
1152     char **p = find_key_le(key);
1153     char **q = find_key_ge(key);
1154     return idx < q - p ? extract_value(p[idx]) : NULL;
1155 }
1156
1157 static bool
1158 is_type(const char *s, enum cfg_flags flags)
1159 {
1160     uint8_t mac[ETH_ADDR_LEN];
1161     struct in_addr addr;
1162     uint64_t dpid;
1163
1164     return (flags & CFG_STRING
1165             || (flags & CFG_KEY && is_key(s))
1166             || (flags & CFG_INT && is_int(s))
1167             || (flags & CFG_BOOL && is_bool(s))
1168             || (flags & CFG_IP && inet_aton(s, &addr))
1169             || (flags & CFG_MAC && parse_mac(s, mac))
1170             || (flags & CFG_DPID && parse_dpid(s, &dpid)));
1171 }