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