static int set_config_network_nic(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- char *copy = strdup(key), *p;
- int ret = -1;
+ char *copy, *idx_start, *idx_end;
+ unsigned int idx;
struct lxc_config_t *config;
+ size_t numstrlen;
+ int ret = -1;
+ struct lxc_netdev *netdev = NULL;
+ copy = strdup(key);
if (!copy) {
SYSERROR("failed to allocate memory");
return -1;
}
+
/*
* Ok we know that to get here we've got "lxc.network."
* and it isn't any of the other network entries. So
* nic) followed by a valid entry.
*/
if (*(key + 12) < '0' || *(key + 12) > '9')
- goto out;
+ goto on_error;
- p = strchr(key + 12, '.');
- if (!p)
- goto out;
+ /* beginning index string */
+ idx_start = (copy + 11);
+ /* temporarily \o-terminate */
+ *idx_start = '\0';
+
+ idx_end = strchr((copy + 12), '.');
+ if (!idx_end)
+ goto on_error;
+
+ /* temporarily \o-terminate */
+ *idx_end = '\0';
- strcpy(copy + 12, p + 1);
+ /* parse current index */
+ if (lxc_safe_uint((idx_start + 1), &idx) < 0)
+ goto on_error;
+
+ numstrlen = strlen((idx_start + 1));
+
+ /* repair configuration key */
+ *idx_start = '.';
+ *idx_end = '.';
+
+ /* lookup network key in jump table */
+ memmove(copy + 12, idx_end + 1, strlen(idx_end + 1));
+ copy[strlen(key) - numstrlen + 1] = '\0';
config = lxc_getconfig(copy);
if (!config) {
ERROR("unknown key %s", key);
- goto out;
+ goto on_error;
}
- ret = config->set(key, value, lxc_conf, data);
-out:
+ /* This, of course is utterly nonsensical on so many levels, but better
+ * safe than sorry.
+ */
+ if (idx == UINT_MAX) {
+ SYSERROR("number of configured networks would overflow the "
+ "counter... what are you doing?");
+ goto on_error;
+ }
+
+ /* get netdev */
+ netdev = lxc_get_netdev_by_idx(lxc_conf, idx);
+ if (!netdev)
+ goto on_error;
+
+ /* set config item */
+ ret = config->set(key, value, lxc_conf, netdev);
+
+on_error:
free(copy);
return ret;
}
static int set_config_network_type(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- struct lxc_list *network = &lxc_conf->network;
struct lxc_netdev *netdev;
- struct lxc_list *list;
+ /* If value is empty e.g. "lxc.network.type=", then clear the network
+ * from the config.
+ */
if (lxc_config_value_empty(value))
return lxc_clear_config_network(lxc_conf);
- netdev = malloc(sizeof(*netdev));
- if (!netdev) {
- SYSERROR("failed to allocate memory");
- return -1;
- }
-
- memset(netdev, 0, sizeof(*netdev));
- lxc_list_init(&netdev->ipv4);
- lxc_list_init(&netdev->ipv6);
-
- list = malloc(sizeof(*list));
- if (!list) {
- SYSERROR("failed to allocate memory");
- free(netdev);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
+ if (!netdev)
return -1;
- }
-
- lxc_list_init(list);
- list->elem = netdev;
- lxc_list_add_tail(network, list);
-
- if (!strcmp(value, "veth"))
+ if (!strcmp(value, "veth")) {
netdev->type = LXC_NET_VETH;
- else if (!strcmp(value, "macvlan")) {
+ } else if (!strcmp(value, "macvlan")) {
netdev->type = LXC_NET_MACVLAN;
macvlan_mode(&netdev->priv.macvlan_attr.mode, "private");
- } else if (!strcmp(value, "vlan"))
+ } else if (!strcmp(value, "vlan")) {
netdev->type = LXC_NET_VLAN;
- else if (!strcmp(value, "phys"))
+ } else if (!strcmp(value, "phys")) {
netdev->type = LXC_NET_PHYS;
- else if (!strcmp(value, "empty"))
+ } else if (!strcmp(value, "empty")) {
netdev->type = LXC_NET_EMPTY;
- else if (!strcmp(value, "none"))
+ } else if (!strcmp(value, "none")) {
netdev->type = LXC_NET_NONE;
- else {
+ } else {
ERROR("invalid network type %s", value);
return -1;
}
+
return 0;
}
return fulllen;
}
-static struct lxc_netdev *network_netdev(const char *key, const char *value,
- struct lxc_list *network)
-{
- struct lxc_netdev *netdev = NULL;
-
- if (lxc_list_empty(network)) {
- ERROR("network is not created for '%s' = '%s' option", key,
- value);
- return NULL;
- }
-
- if (get_network_netdev_idx(key + 12) == -1)
- netdev = lxc_list_last_elem(network);
- else
- netdev = get_netdev_from_key(key + 12, network);
-
- if (!netdev) {
- ERROR("no network device defined for '%s' = '%s' option", key,
- value);
- return NULL;
- }
-
- return netdev;
-}
-
static int network_ifname(char **valuep, const char *value)
{
return set_config_string_item_max(valuep, value, IFNAMSIZ);
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
struct lxc_list *it;
int ret = 0;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
- if (netdev->type != LXC_NET_VETH) {
- ERROR("Invalid veth pair for a non-veth netdev");
- return -1;
- }
-
return network_ifname(&netdev->priv.veth_attr.pair, value);
}
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
- if (netdev->type != LXC_NET_MACVLAN) {
- ERROR("Invalid macvlan.mode for a non-macvlan netdev");
- return -1;
- }
-
return macvlan_mode(&netdev->priv.macvlan_attr.mode, value);
}
}
rand_complete_hwaddr(new_value);
- netdev = network_netdev(key, new_value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev) {
free(new_value);
return -1;
- };
+ }
if (lxc_config_value_empty(new_value)) {
free(new_value);
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
- if (netdev->type != LXC_NET_VLAN) {
- ERROR("Invalid vlan.id for a non-macvlan netdev");
- return -1;
- }
-
if (get_u16(&netdev->priv.vlan_attr.vid, value, 0))
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
if (lxc_config_value_empty(value))
return clr_config_network_item(key, lxc_conf);
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
struct lxc_list *list;
char *slash, *valdup, *netmask;
- if (lxc_config_value_empty(value))
- return clr_config_network_item(key, lxc_conf);
-
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
{
struct lxc_netdev *netdev;
- netdev = network_netdev(key, value, &lxc_conf->network);
+ /* lxc.network.* without an index */
+ if (!data)
+ netdev = lxc_get_netdev_by_idx(lxc_conf, 0);
+ else
+ netdev = data;
if (!netdev)
return -1;
goto out;
}
- ret = config->set(key, value, plc->conf, data);
+ ret = config->set(key, value, plc->conf, NULL);
out:
free(linep);