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