Also limit the range of vlan ids. Other implementations and
documentation use the ranges {0,1}-{4094,4095}, but we use
the one accepted by the kernel: 0-4094.
Reported-by: Oleksii Shevchuk <alxchk@gmail.com>
<varlistentry>
<term><varname>Id</varname></term>
<listitem>
<varlistentry>
<term><varname>Id</varname></term>
<listitem>
- <para>The VLAN ID to use. This option is compulsory.</para>
+ <para>The VLAN ID to use. An integer in the range 0-4094.
+ This option is compulsory.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
</variablelist>
<varlistentry>
<term><varname>Bridge</varname></term>
<listitem>
<varlistentry>
<term><varname>Bridge</varname></term>
<listitem>
- <para>The name of the bridge to add the configured link to.</para>
+ <para>The name of the bridge to add the link to.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Bond</varname></term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Bond</varname></term>
<listitem>
- <para>The name of the bond to add the configured link to.</para>
+ <para>The name of the bond to add the link to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>VLAN</varname></term>
+ <listitem>
+ <para>The name of a VLAN to create on the link. This option
+ may be specified more than once.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
</variablelist>
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_bridge, 0, offsetof(Network, bridge)
Network.Bond, config_parse_bond, 0, offsetof(Network, bond)
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_bridge, 0, offsetof(Network, bridge)
Network.Bond, config_parse_bond, 0, offsetof(Network, bond)
-Network.VLAN, config_parse_vlan, 0, offsetof(Network, vlan)
+Network.VLAN, config_parse_vlan, 0, offsetof(Network, vlans)
Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, name)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, name)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
-VLAN.Id, config_parse_int, 0, offsetof(NetDev, vlanid)
+VLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vlanid)
}
static int link_enter_enslave(Link *link) {
}
static int link_enter_enslave(Link *link) {
+ NetDev *vlan;
+ Iterator i;
link->state = LINK_STATE_ENSLAVING;
link->state = LINK_STATE_ENSLAVING;
- if (!link->network->bridge && !link->network->bond && !link->network->vlan)
+ if (!link->network->bridge && !link->network->bond && !link->network->vlans)
return link_enslaved(link);
if (link->network->bridge) {
return link_enslaved(link);
if (link->network->bridge) {
- if (link->network->vlan) {
+ HASHMAP_FOREACH(vlan, link->network->vlans, i) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%s: enslaving by '%s'",
- link->ifname, link->network->vlan->name,
- NETDEV(link->network->vlan),
- NULL);
+ link->ifname, vlan->name, NETDEV(vlan), NULL);
- r = netdev_enslave(link->network->vlan, link, &enslave_handler);
+ r = netdev_enslave(vlan, link, &enslave_handler);
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
if (r < 0) {
log_struct_link(LOG_WARNING, link,
"MESSAGE=%s: could not enslave by '%s': %s",
- link->ifname, link->network->vlan->name,
- strerror(-r), NETDEV(link->network->vlan),
- NULL);
+ link->ifname, vlan->name, strerror(-r),
+ NETDEV(vlan), NULL);
link_enter_failed(link);
return r;
}
link_enter_failed(link);
return r;
}
#include "conf-parser.h"
#include "list.h"
#include "conf-parser.h"
#include "list.h"
+#define VLANID_MAX 4094
+
static const char* const netdev_kind_table[] = {
[NETDEV_KIND_BRIDGE] = "bridge",
[NETDEV_KIND_BOND] = "bond",
static const char* const netdev_kind_table[] = {
[NETDEV_KIND_BRIDGE] = "bridge",
[NETDEV_KIND_BOND] = "bond",
- assert(!(netdev->kind == NETDEV_KIND_VLAN) || (link && callback && netdev->vlanid >= 0));
+ assert(!(netdev->kind == NETDEV_KIND_VLAN) || (link && callback && netdev->vlanid <= VLANID_MAX));
assert(netdev->name);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(netdev->name);
assert(netdev->manager);
assert(netdev->manager->rtnl);
- if (netdev->vlanid >= 0) {
+ if (netdev->vlanid <= VLANID_MAX) {
r = sd_rtnl_message_open_container(req, IFLA_INFO_DATA);
if (r < 0) {
log_error_netdev(netdev,
r = sd_rtnl_message_open_container(req, IFLA_INFO_DATA);
if (r < 0) {
log_error_netdev(netdev,
netdev->manager = manager;
netdev->state = _NETDEV_STATE_INVALID;
netdev->kind = _NETDEV_KIND_INVALID;
netdev->manager = manager;
netdev->state = _NETDEV_STATE_INVALID;
netdev->kind = _NETDEV_KIND_INVALID;
+ netdev->vlanid = VLANID_MAX + 1;
r = config_parse(NULL, filename, file, "NetDev\0VLAN\0", config_item_perf_lookup,
(void*) network_gperf_lookup, false, false, netdev);
r = config_parse(NULL, filename, file, "NetDev\0VLAN\0", config_item_perf_lookup,
(void*) network_gperf_lookup, false, false, netdev);
- if (netdev->kind == NETDEV_KIND_VLAN && netdev->vlanid < 0) {
- log_warning("VLAN without Id configured in %s. Ignoring", filename);
+ if (netdev->kind == NETDEV_KIND_VLAN && netdev->vlanid > VLANID_MAX) {
+ log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
LIST_HEAD_INIT(network->static_addresses);
LIST_HEAD_INIT(network->static_routes);
LIST_HEAD_INIT(network->static_addresses);
LIST_HEAD_INIT(network->static_routes);
+ network->vlans = hashmap_new(uint64_hash_func, uint64_compare_func);
+ if (!network->vlans)
+ return log_oom();
+
network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
if (!network->addresses_by_section)
return log_oom();
network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
if (!network->addresses_by_section)
return log_oom();
address_free(network->dns);
address_free(network->dns);
+ hashmap_free(network->vlans);
+
while ((route = network->static_routes))
route_free(route);
while ((route = network->static_routes))
route_free(route);
- network->vlan = netdev;
+ r = hashmap_put(network->vlans, &netdev->vlanid, netdev);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+ "Can not add VLAN to network: %s", rvalue);
+ return 0;
+ }
char *name;
NetDevKind kind;
char *name;
NetDevKind kind;
int ifindex;
NetDevState state;
int ifindex;
NetDevState state;
char *description;
NetDev *bridge;
NetDev *bond;
char *description;
NetDev *bridge;
NetDev *bond;
bool dhcp;
bool dhcp_dns;
bool dhcp_mtu;
bool dhcp;
bool dhcp_dns;
bool dhcp_mtu;