1 /* Copyright (c) 2008, 2009 Nicira Networks
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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <arpa/inet.h>
25 #include <netinet/in.h>
29 #include "dynamic-string.h"
37 #define THIS_MODULE VLM_cfg
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. */
45 /* Configuration file name. */
46 static char *cfg_name;
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;
53 /* Lock information. */
54 static struct lockfile *lockfile;
56 /* Flag to indicate whether local modifications have been made. */
59 static uint8_t cfg_cookie[CFG_COOKIE_LEN];
61 /* Current configuration. Maintained in sorted order. */
62 static struct svec cfg = SVEC_EMPTY_INITIALIZER;
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,
68 static char *parse_section(const char *file_name, int line_number,
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);
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"
90 #define CC_FILE_NAME CC_ALNUM "._-"
91 #define CC_KEY CC_ALNUM "._-@$:+"
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.
102 * This function does not actually read the named file or directory. Use
103 * cfg_read() to (re)read all the configuration files. */
105 cfg_set_file(const char *file_name)
114 cfg_name = tmp_name = NULL;
117 /* Make sure that we can open this file for reading. */
118 fd = open(file_name, O_RDONLY);
124 cfg_name = xstrdup(file_name);
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);
131 lock_name = lockfile_name(file_name);
132 VLOG_INFO("using \"%s\" as configuration file, \"%s\" as lock file",
133 file_name, lock_name);
142 struct sha1_ctx 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);
150 sha1_final(&context, cfg_cookie);
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. */
172 /* Save old configuration data and clear the active configuration. */
174 svec_swap(&old_cfg, &cfg);
176 /* Read new configuration. */
177 VLOG_DBG("reading configuration from %s", cfg_name);
179 file = fopen(cfg_name, "r");
181 VLOG_ERR("failed to open \"%s\": %s", cfg_name, strerror(errno));
182 svec_terminate(&cfg);
189 while (!ds_get_line(&ds, file)) {
190 const char *s = ds_cstr(&ds);
191 size_t indent = strspn(s, CC_SPACE);
195 if (*s == '#' || *s == '\0') {
196 /* Ignore comments and lines that contain only white space. */
197 } else if (*s == '[') {
200 section = parse_section(cfg_name, line_number, s);
202 VLOG_ERR("%s:%d: ignoring indented section header",
203 cfg_name, line_number);
205 } else if (indent && !section) {
206 VLOG_ERR("%s:%d: ignoring indented line outside any section",
207 cfg_name, line_number);
213 parse_setting(cfg_name, line_number, section, s);
220 svec_terminate(&cfg);
225 if (VLOG_IS_DBG_ENABLED()) {
226 struct svec removed, added;
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]);
235 for (i = 0; i < added.n; i++) {
236 VLOG_DBG("+%s", added.names[i]);
239 VLOG_DBG("configuration unchanged");
241 svec_destroy(&added);
242 svec_destroy(&removed);
244 svec_destroy(&old_cfg);
251 /* Fills 'svec' with the entire configuration file. */
253 cfg_get_all(struct svec *svec)
256 svec_append(svec, &cfg);
260 cfg_get_cookie(uint8_t *cookie)
266 memcpy(cookie, cfg_cookie, sizeof(cfg_cookie));
274 lockfile_unlock(lockfile);
279 /* Locks the configuration file against modification by other processes and
280 * re-reads it from disk.
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
286 * Returns 0 on success, otherwise a positive errno value. */
288 cfg_lock(uint8_t *cookie, int timeout)
293 error = lockfile_lock(cfg_name, timeout, &lockfile);
301 uint8_t curr_cookie[CFG_COOKIE_LEN];
302 cfg_get_cookie(curr_cookie);
304 if (memcmp(curr_cookie, cookie, sizeof *curr_cookie)) {
305 /* Configuration has changed, so reject. */
315 do_write_config(const void *data, size_t len)
320 file = fopen(tmp_name, "w");
322 VLOG_WARN("could not open %s for writing: %s",
323 tmp_name, strerror(errno));
327 fwrite(data, 1, len, file);
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;
336 VLOG_WARN("problem writing to %s: %s", tmp_name, strerror(errno));
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));
351 /* Write the current configuration into the configuration file. Returns 0 if
352 * successful, otherwise a negative errno value. */
361 ? svec_join(&cfg, "\n", "\n")
362 : xstrdup("# This file intentionally left blank.\n"));
363 retval = do_write_config(content, strlen(content));
370 cfg_write_data(uint8_t *data, size_t len)
372 int retval = do_write_config(data, len);
379 /* Returns true if the configuration has changed since the last time it was
380 * read or written. */
388 cfg_buf_put(struct ofpbuf *buffer)
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);
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) \
404 va_start(args__, FORMAT); \
405 (DST) = xvasprintf(FORMAT, args__); \
409 /* Returns true if the configuration includes a key named 'key'. */
411 cfg_has(const char *key_, ...)
416 FORMAT_KEY(key_, key);
417 retval = find_key(key) != NULL;
423 cfg_is_valid(enum cfg_flags flags, const char *key_, ...)
425 char *key, **first, **last, **p;
429 FORMAT_KEY(key_, key);
430 first = find_key_le(key);
431 last = find_key_ge(key);
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);
442 /* Returns true if the configuration includes at least one key whose name
443 * begins with 'section' followed by a dot. */
445 cfg_has_section(const char *section_, ...)
453 va_start(args, section_);
454 ds_put_format_valist(§ion, section_, args);
455 ds_put_char(§ion, '.');
458 for (p = cfg.names; *p; p++) { /* XXX this is inefficient */
459 if (!strncmp(section.string, *p, section.length)) {
465 ds_destroy(§ion);
469 /* Returns the number of values for the given 'key'. The return value is 0 if
470 * no values exist for 'key'. */
472 cfg_count(const char *key_, ...)
477 FORMAT_KEY(key_, key);
478 retval = find_key_ge(key) - find_key_le(key);
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'. */
488 cfg_get_subsections(struct svec *svec, const char *section_, ...)
495 va_start(args, section_);
496 ds_put_format_valist(§ion, section_, args);
497 ds_put_char(§ion, '.');
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));
509 ds_destroy(§ion);
513 cfg_add_entry(const char *entry_, ...)
517 FORMAT_KEY(entry_, entry);
518 svec_add_nocopy(&cfg, entry);
520 svec_terminate(&cfg);
525 cfg_del_entry(const char *entry_, ...)
529 FORMAT_KEY(entry_, entry);
530 svec_del(&cfg, entry);
531 svec_terminate(&cfg);
537 cfg_del_section(const char *section_, ...)
544 va_start(args, section_);
545 ds_put_format_valist(§ion, section_, args);
546 ds_put_char(§ion, '.');
549 for (p = cfg.names; *p; p++) {
550 if (!strncmp(section.string, *p, section.length)) {
556 svec_terminate(&cfg);
558 ds_destroy(§ion);
563 cfg_del_match(const char *pattern_, ...)
565 bool matched = false;
569 FORMAT_KEY(pattern_, pattern);
571 for (p = cfg.names; *p; p++) {
572 if (!fnmatch(pattern, *p, 0)) {
580 svec_terminate(&cfg);
587 /* Fills 'svec' with all of the key-value pairs that match shell glob pattern
588 * 'pattern'. The caller must first initialize 'svec'. */
590 cfg_get_matches(struct svec *svec, const char *pattern_, ...)
595 FORMAT_KEY(pattern_, pattern);
597 for (p = cfg.names; *p; p++) {
598 if (!fnmatch(pattern, *p, 0)) {
606 /* Fills 'svec' with all of the key-value pairs that have sections that
607 * begin with 'section'. The caller must first initialize 'svec'. */
609 cfg_get_section(struct svec *svec, const char *section_, ...)
616 va_start(args, section_);
617 ds_put_format_valist(§ion, section_, args);
618 ds_put_char(§ion, '.');
621 for (p = cfg.names; *p; p++) { /* XXX this is inefficient */
622 if (!strncmp(section.string, *p, section.length)) {
626 ds_destroy(§ion);
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
634 cfg_get_string(int idx, const char *key_, ...)
639 FORMAT_KEY(key_, key);
640 retval = get_nth_value(idx, key);
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(). */
650 cfg_get_key(int idx, const char *key_, ...)
652 const char *value, *retval;
655 FORMAT_KEY(key_, key);
656 value = get_nth_value(idx, key);
657 retval = value && is_key(value) ? value : NULL;
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. */
666 cfg_get_int(int idx, const char *key_, ...)
672 FORMAT_KEY(key_, key);
673 value = get_nth_value(idx, key);
674 retval = value && is_int(value) ? atoi(value) : 0;
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. */
683 cfg_get_bool(int idx, const char *key_, ...)
689 FORMAT_KEY(key_, key);
690 value = get_nth_value(idx, key);
691 retval = value && is_bool(value) ? !strcmp(value, "true") : false;
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()). */
701 cfg_get_ip(int idx, const char *key_, ...)
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);
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 "##:##:##:##:##:##". */
721 cfg_get_mac(int idx, const char *key_, ...)
723 uint8_t mac[ETH_ADDR_LEN];
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);
733 return eth_addr_to_uint64(mac);
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. */
741 cfg_get_dpid(int idx, const char *key_, ...)
747 FORMAT_KEY(key_, key);
748 value = get_nth_value(idx, key);
749 if (!value || !parse_dpid(value, &dpid)) {
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. */
760 cfg_get_vlan(int idx, const char *key_, ...)
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) {
780 /* Fills 'svec' with all of the string values of 'key'. The caller must
781 * first initialize 'svec'. */
783 cfg_get_all_strings(struct svec *svec, const char *key_, ...)
788 FORMAT_KEY(key_, key);
790 for (p = find_key_le(key), q = find_key_ge(key); p < q; p++) {
791 svec_add(svec, extract_value(*p));
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'. */
800 cfg_get_all_keys(struct svec *svec, const char *key_, ...)
805 FORMAT_KEY(key_, key);
807 for (p = find_key_le(key), q = find_key_ge(key); p < q; p++) {
808 const char *value = extract_value(*p);
810 svec_add(svec, value);
817 has_double_dot(const char *key, size_t len)
822 for (i = 0; i < len - 1; i++) {
823 if (key[i] == '.' && key[i + 1] == '.') {
832 is_valid_key(const char *key, size_t len,
833 const char *file_name, int line_number, const char *id)
836 VLOG_ERR("%s:%d: missing %s name", file_name, line_number, id);
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);
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);
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);
856 parse_section(const char *file_name, int line_number, const char *s)
863 /* Skip [ and any white space. */
865 s += strspn(s, CC_SPACE);
867 /* Obtain the section name. */
868 len = strspn(s, CC_KEY);
869 if (!is_valid_key(s, len, file_name, line_number, "section")) {
872 ds_put_buffer(§ion, s, len);
875 /* Obtain the subsection name, if any. */
876 s += strspn(s, CC_SPACE);
879 len = strspn(s, CC_KEY);
880 if (!is_valid_key(s, len, file_name, line_number, "subsection")) {
883 ds_put_char(§ion, '.');
884 ds_put_buffer(§ion, s, len);
887 VLOG_ERR("%s:%d: missing '\"' following subsection name",
888 file_name, line_number);
892 s += strspn(s, CC_SPACE);
897 VLOG_ERR("%s:%d: missing ']' following section name",
898 file_name, line_number);
902 s += strspn(s, CC_SPACE);
904 VLOG_ERR("%s:%d: trailing garbage following ']'",
905 file_name, line_number);
909 return ds_cstr(§ion);
912 ds_destroy(§ion);
917 parse_setting(const char *file_name, int line_number, const char *section,
920 struct ds key = DS_EMPTY_INITIALIZER;
921 struct ds value = DS_EMPTY_INITIALIZER;
925 ds_put_format(&key, "%s.", section);
928 /* Obtain the key. */
929 len = strspn(s, CC_KEY);
931 VLOG_ERR("%s:%d: missing key name", file_name, line_number);
934 if (!is_valid_key(s, len, file_name, line_number, "key")) {
937 ds_put_buffer(&key, s, len);
941 s += strspn(s, CC_SPACE);
943 VLOG_ERR("%s:%d: missing '=' following key", file_name, line_number);
947 s += strspn(s, CC_SPACE);
949 /* Obtain the value. */
950 ds_put_cstr(&value, s);
951 while (value.length > 0 && strchr(CC_SPACE, ds_last(&value))) {
955 /* Add the setting. */
956 svec_add_nocopy(&cfg, xasprintf("%s=%s", ds_cstr(&key), ds_cstr(&value)));
964 compare_key(const char *a, const char *b)
967 int ac = *a == '\0' || *a == '=' ? INT_MAX : *a;
968 int bc = *b == '\0' || *b == '=' ? INT_MAX : *b;
970 return ac < bc ? -1 : 1;
971 } else if (ac == INT_MAX) {
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'. */
983 find_key_le(const char *key)
989 int middle = low + half;
990 if (compare_key(cfg.names[middle], key) < 0) {
997 return &cfg.names[low];
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'. */
1004 find_key_ge(const char *key)
1009 int half = len >> 1;
1010 int middle = low + half;
1011 if (compare_key(cfg.names[middle], key) > 0) {
1018 return &cfg.names[low];
1022 find_key(const char *key)
1024 char **p = find_key_le(key);
1025 return p < &cfg.names[cfg.n] && !compare_key(*p, key) ? *p : NULL;
1029 parse_mac(const char *s, uint8_t mac[6])
1031 return (sscanf(s, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))
1032 == ETH_ADDR_SCAN_COUNT);
1036 parse_dpid(const char *s, uint64_t *dpid)
1038 if (strlen(s) == 12 && strspn(s, "0123456789abcdefABCDEF") == 12) {
1039 *dpid = strtoll(s, NULL, 16);
1047 is_key(const char *s)
1049 /* XXX needs to check the same things as is_valid_key() too. */
1050 return *s && s[strspn(s, CC_KEY)] == '\0';
1054 is_int(const char *s)
1056 return *s && s[strspn(s, CC_DIGIT)] == '\0';
1060 is_bool(const char *s)
1062 return !strcmp(s, "true") || !strcmp(s, "false");
1066 extract_value(const char *key)
1068 const char *p = strchr(key, '=');
1069 return p ? p + 1 : NULL;
1073 get_nth_value(int idx, const char *key)
1075 char **p = find_key_le(key);
1076 char **q = find_key_ge(key);
1077 return idx < q - p ? extract_value(p[idx]) : NULL;
1081 is_type(const char *s, enum cfg_flags flags)
1083 uint8_t mac[ETH_ADDR_LEN];
1084 struct in_addr addr;
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)));