6 #include <sys/socket.h>
7 #include <net/ethernet.h>
10 #include "interface.h"
12 struct uci_context
*uci_ctx
;
13 static struct uci_package
*uci_network
;
14 bool config_init
= false;
16 static void uci_attr_to_blob(struct blob_buf
*b
, const char *str
,
17 const char *name
, enum blobmsg_type type
)
23 case BLOBMSG_TYPE_STRING
:
24 blobmsg_add_string(b
, name
, str
);
26 case BLOBMSG_TYPE_BOOL
:
27 if (!strcmp(str
, "true") || !strcmp(str
, "1"))
29 else if (!strcmp(str
, "false") || !strcmp(str
, "0"))
34 blobmsg_add_u8(b
, name
, intval
);
36 case BLOBMSG_TYPE_INT32
:
37 intval
= strtol(str
, &err
, 0);
41 blobmsg_add_u32(b
, name
, intval
);
48 static void uci_array_to_blob(struct blob_buf
*b
, struct uci_option
*o
,
49 enum blobmsg_type type
)
51 struct uci_element
*e
;
52 char *str
, *next
, *word
;
54 if (o
->type
== UCI_TYPE_LIST
) {
55 uci_foreach_element(&o
->v
.list
, e
) {
56 uci_attr_to_blob(b
, e
->name
, NULL
, type
);
61 str
= strdup(o
->v
.string
);
64 while ((word
= strsep(&next
, " \t")) != NULL
) {
68 uci_attr_to_blob(b
, word
, NULL
, type
);
74 static void uci_to_blob(struct blob_buf
*b
, struct uci_section
*s
,
75 const struct config_param_list
*p
)
77 const struct blobmsg_policy
*attr
;
78 struct uci_element
*e
;
83 uci_foreach_element(&s
->options
, e
) {
84 for (i
= 0; i
< p
->n_params
; i
++) {
86 if (!strcmp(attr
->name
, e
->name
))
95 if (attr
->type
== BLOBMSG_TYPE_ARRAY
) {
99 array
= blobmsg_open_array(b
, attr
->name
);
100 uci_array_to_blob(b
, o
, p
->info
[i
].type
);
101 blobmsg_close_array(b
, array
);
105 if (o
->type
== UCI_TYPE_LIST
)
108 uci_attr_to_blob(b
, o
->v
.string
, attr
->name
, attr
->type
);
113 config_parse_interface(struct uci_section
*s
)
115 struct blob_buf b
= {};
117 DPRINTF("Create interface '%s'\n", s
->e
.name
);
119 blob_buf_init(&b
, 0);
120 uci_to_blob(&b
, s
, &interface_attr_list
);
121 alloc_interface(s
->e
.name
, s
, b
.head
);
133 static const struct uci_parse_option dev_opts
[__SDEV_MAX
] = {
134 [SDEV_NAME
] = { "name", UCI_TYPE_STRING
},
135 [SDEV_TYPE
] = { "type", UCI_TYPE_STRING
},
136 [SDEV_MTU
] = { "mtu", UCI_TYPE_STRING
},
137 [SDEV_MACADDR
] = { "macaddr", UCI_TYPE_STRING
},
138 [SDEV_TXQUEUELEN
] = { "txqueuelen", UCI_TYPE_STRING
},
142 add_int_option(struct uci_option
*o
, unsigned int *dest
)
150 val
= strtoul(o
->v
.string
, &error
, 0);
159 config_init_device_settings(struct device
*dev
, struct uci_option
**opts
)
161 struct ether_addr
*ea
;
165 if (add_int_option(opts
[SDEV_MTU
], &dev
->mtu
))
166 dev
->flags
|= DEV_OPT_MTU
;
168 if (add_int_option(opts
[SDEV_TXQUEUELEN
], &dev
->txqueuelen
))
169 dev
->flags
|= DEV_OPT_TXQUEUELEN
;
171 if (opts
[SDEV_MACADDR
]) {
172 ea
= ether_aton(opts
[SDEV_MACADDR
]->v
.string
);
174 memcpy(dev
->macaddr
, ea
, sizeof(dev
->macaddr
));
175 dev
->flags
|= DEV_OPT_MACADDR
;
181 config_init_devices(void)
183 struct uci_element
*e
;
185 struct uci_option
*opts
[__SDEV_MAX
];
187 uci_foreach_element(&uci_network
->sections
, e
) {
188 struct uci_section
*s
= uci_to_section(e
);
190 if (strcmp(s
->type
, "device") != 0)
193 uci_parse_section(s
, dev_opts
, __SDEV_MAX
, opts
);
194 if (!opts
[SDEV_NAME
])
198 if (opts
[SDEV_TYPE
]) {
199 const char *type
= opts
[SDEV_TYPE
]->v
.string
;
201 if (!strcmp(type
, "bridge"))
202 dev
= bridge_create(opts
[SDEV_NAME
]->v
.string
, s
);
204 dev
= get_device(opts
[SDEV_NAME
]->v
.string
, true);
210 config_init_device_settings(dev
, opts
);
211 dev
->config_hash
= uci_hash_options(opts
, __SDEV_MAX
);
216 config_init_interfaces(const char *name
)
218 struct uci_context
*ctx
;
219 struct uci_package
*p
= NULL
;
220 struct uci_element
*e
;
222 ctx
= uci_alloc_context();
225 uci_set_confdir(ctx
, "./config");
227 if (uci_load(ctx
, "network", &p
)) {
228 fprintf(stderr
, "Failed to load network config\n");
235 config_init_devices();
237 uci_foreach_element(&p
->sections
, e
) {
238 struct uci_section
*s
= uci_to_section(e
);
240 if (name
&& strcmp(s
->e
.name
, name
) != 0)
243 if (!strcmp(s
->type
, "interface"))
244 config_parse_interface(s
);
249 start_pending_interfaces();