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;
22 static const struct uci_parse_option if_opts
[__SIF_MAX
] = {
23 [SIF_TYPE
] = { "type", UCI_TYPE_STRING
},
24 [SIF_IFNAME
] = { "ifname", UCI_TYPE_STRING
},
28 config_parse_interface(struct uci_section
*s
)
30 struct uci_option
*opts
[__SIF_MAX
];
31 struct interface
*iface
;
35 DPRINTF("Create interface '%s'\n", s
->e
.name
);
37 iface
= alloc_interface(s
->e
.name
, s
);
41 uci_parse_section(s
, if_opts
, __SIF_MAX
, opts
);
44 type
= opts
[SIF_TYPE
]->v
.string
;
46 if (!strcmp(type
, "bridge")) {
47 interface_attach_bridge(iface
, s
);
52 if (opts
[SIF_IFNAME
]) {
53 dev
= get_device(opts
[SIF_IFNAME
]->v
.string
, true);
57 add_device_user(&iface
->main_dev
, dev
);
70 static const struct uci_parse_option dev_opts
[__SDEV_MAX
] = {
71 [SDEV_NAME
] = { "name", UCI_TYPE_STRING
},
72 [SDEV_TYPE
] = { "type", UCI_TYPE_STRING
},
73 [SDEV_MTU
] = { "mtu", UCI_TYPE_STRING
},
74 [SDEV_MACADDR
] = { "macaddr", UCI_TYPE_STRING
},
75 [SDEV_TXQUEUELEN
] = { "txqueuelen", UCI_TYPE_STRING
},
79 add_int_option(struct uci_option
*o
, unsigned int *dest
)
87 val
= strtoul(o
->v
.string
, &error
, 0);
96 config_init_device_settings(struct device
*dev
, struct uci_option
**opts
)
98 struct ether_addr
*ea
;
102 if (add_int_option(opts
[SDEV_MTU
], &dev
->mtu
))
103 dev
->flags
|= DEV_OPT_MTU
;
105 if (add_int_option(opts
[SDEV_TXQUEUELEN
], &dev
->txqueuelen
))
106 dev
->flags
|= DEV_OPT_TXQUEUELEN
;
108 if (opts
[SDEV_MACADDR
]) {
109 ea
= ether_aton(opts
[SDEV_MACADDR
]->v
.string
);
111 memcpy(dev
->macaddr
, ea
, sizeof(dev
->macaddr
));
112 dev
->flags
|= DEV_OPT_MACADDR
;
118 config_init_devices(void)
120 struct uci_element
*e
;
122 struct uci_option
*opts
[__SDEV_MAX
];
124 uci_foreach_element(&uci_network
->sections
, e
) {
125 struct uci_section
*s
= uci_to_section(e
);
127 if (strcmp(s
->type
, "device") != 0)
130 uci_parse_section(s
, dev_opts
, __SDEV_MAX
, opts
);
131 if (!opts
[SDEV_NAME
])
135 if (opts
[SDEV_TYPE
]) {
136 const char *type
= opts
[SDEV_TYPE
]->v
.string
;
138 if (!strcmp(type
, "bridge"))
139 dev
= bridge_create(opts
[SDEV_NAME
]->v
.string
, s
);
141 dev
= get_device(opts
[SDEV_NAME
]->v
.string
, true);
147 config_init_device_settings(dev
, opts
);
148 dev
->config_hash
= uci_hash_options(opts
, __SDEV_MAX
);
153 config_init_interfaces(const char *name
)
155 struct uci_context
*ctx
;
156 struct uci_package
*p
= NULL
;
157 struct uci_element
*e
;
159 ctx
= uci_alloc_context();
162 uci_set_confdir(ctx
, "./config");
164 if (uci_load(ctx
, "network", &p
)) {
165 fprintf(stderr
, "Failed to load network config\n");
172 config_init_devices();
174 uci_foreach_element(&p
->sections
, e
) {
175 struct uci_section
*s
= uci_to_section(e
);
177 if (name
&& strcmp(s
->e
.name
, name
) != 0)
180 if (!strcmp(s
->type
, "interface"))
181 config_parse_interface(s
);
186 start_pending_interfaces();