mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
networkd: add basic support for MACVLANs
This commit is contained in:
parent
e3ab0c0e19
commit
fe6b2d55bc
@ -142,8 +142,9 @@
|
|||||||
<term><varname>Kind=</varname></term>
|
<term><varname>Kind=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The netdev kind. Currently, <literal>bridge</literal>,
|
<para>The netdev kind. Currently, <literal>bridge</literal>,
|
||||||
<literal>bond</literal> and <literal>vlan</literal>
|
<literal>bond</literal>, <literal>vlan</literal> and
|
||||||
are supported. This option is compulsory.</para>
|
<literal>macvlan</literal> are supported. This option
|
||||||
|
is compulsory.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
@ -161,6 +162,21 @@
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
<para>The <literal>[MACVLAN]</literal> section only applies for netdevs of kind
|
||||||
|
<literal>macvlan</literal>, and accepts the following key:</para>
|
||||||
|
|
||||||
|
<variablelist class='network-directives'>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>Mode=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The MACVLAN mode to use. The supported options are
|
||||||
|
<literal>private</literal>, <literal>vepa</literal>,
|
||||||
|
<literal>bridge</literal> and <literal>passthru</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -235,6 +235,13 @@
|
|||||||
may be specified more than once.</para>
|
may be specified more than once.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>MACVLAN=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The name of a MACVLAN to create on the link. This option
|
||||||
|
may be specified more than once.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
<para>An <literal>[Address]</literal> section accepts the following keys.
|
<para>An <literal>[Address]</literal> section accepts the following keys.
|
||||||
|
@ -890,7 +890,7 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int link_enter_enslave(Link *link) {
|
static int link_enter_enslave(Link *link) {
|
||||||
NetDev *vlan;
|
NetDev *vlan, *macvlan;
|
||||||
Iterator i;
|
Iterator i;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -901,7 +901,8 @@ static int link_enter_enslave(Link *link) {
|
|||||||
link->state = LINK_STATE_ENSLAVING;
|
link->state = LINK_STATE_ENSLAVING;
|
||||||
|
|
||||||
if (!link->network->bridge && !link->network->bond &&
|
if (!link->network->bridge && !link->network->bond &&
|
||||||
hashmap_isempty(link->network->vlans))
|
hashmap_isempty(link->network->vlans) &&
|
||||||
|
hashmap_isempty(link->network->macvlans))
|
||||||
return link_enslaved(link);
|
return link_enslaved(link);
|
||||||
|
|
||||||
if (link->network->bridge) {
|
if (link->network->bridge) {
|
||||||
@ -943,6 +944,24 @@ static int link_enter_enslave(Link *link) {
|
|||||||
link->enslaving ++;
|
link->enslaving ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
|
||||||
|
log_struct_link(LOG_DEBUG, link,
|
||||||
|
"MESSAGE=%s: enslaving by '%s'",
|
||||||
|
link->ifname, macvlan->name, NETDEV(macvlan), NULL);
|
||||||
|
|
||||||
|
r = netdev_enslave(macvlan, link, &enslave_handler);
|
||||||
|
if (r < 0) {
|
||||||
|
log_struct_link(LOG_WARNING, link,
|
||||||
|
"MESSAGE=%s: could not enslave by '%s': %s",
|
||||||
|
link->ifname, macvlan->name, strerror(-r),
|
||||||
|
NETDEV(macvlan), NULL);
|
||||||
|
link_enter_failed(link);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
link->enslaving ++;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,3 +23,4 @@ NetDev.Description, config_parse_string, 0,
|
|||||||
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, name)
|
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, name)
|
||||||
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
|
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
|
||||||
VLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vlanid)
|
VLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vlanid)
|
||||||
|
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(NetDev, macvlan_mode)
|
||||||
|
@ -32,11 +32,22 @@ static const char* const netdev_kind_table[] = {
|
|||||||
[NETDEV_KIND_BRIDGE] = "bridge",
|
[NETDEV_KIND_BRIDGE] = "bridge",
|
||||||
[NETDEV_KIND_BOND] = "bond",
|
[NETDEV_KIND_BOND] = "bond",
|
||||||
[NETDEV_KIND_VLAN] = "vlan",
|
[NETDEV_KIND_VLAN] = "vlan",
|
||||||
|
[NETDEV_KIND_MACVLAN] = "macvlan",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
|
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
|
||||||
|
|
||||||
|
static const char* const macvlan_mode_table[] = {
|
||||||
|
[NETDEV_MACVLAN_MODE_PRIVATE] = "private",
|
||||||
|
[NETDEV_MACVLAN_MODE_VEPA] = "vepa",
|
||||||
|
[NETDEV_MACVLAN_MODE_BRIDGE] = "bridge",
|
||||||
|
[NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
|
||||||
|
|
||||||
void netdev_free(NetDev *netdev) {
|
void netdev_free(NetDev *netdev) {
|
||||||
netdev_enslave_callback *callback;
|
netdev_enslave_callback *callback;
|
||||||
|
|
||||||
@ -166,8 +177,8 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(netdev);
|
assert(netdev);
|
||||||
assert(!(netdev->kind == NETDEV_KIND_VLAN) ||
|
assert(!(netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN) ||
|
||||||
(link && callback && netdev->vlanid <= VLANID_MAX));
|
(link && callback));
|
||||||
assert(netdev->name);
|
assert(netdev->name);
|
||||||
assert(netdev->manager);
|
assert(netdev->manager);
|
||||||
assert(netdev->manager->rtnl);
|
assert(netdev->manager->rtnl);
|
||||||
@ -220,7 +231,7 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->vlanid <= VLANID_MAX) {
|
if (netdev->vlanid <= VLANID_MAX || netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
|
||||||
r = sd_rtnl_message_open_container(req, IFLA_INFO_DATA);
|
r = sd_rtnl_message_open_container(req, IFLA_INFO_DATA);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error_netdev(netdev,
|
log_error_netdev(netdev,
|
||||||
@ -229,12 +240,24 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
|
if (netdev->vlanid <= VLANID_MAX) {
|
||||||
if (r < 0) {
|
r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
|
||||||
log_error_netdev(netdev,
|
if (r < 0) {
|
||||||
"Could not append IFLA_VLAN_ID attribute: %s",
|
log_error_netdev(netdev,
|
||||||
strerror(-r));
|
"Could not append IFLA_VLAN_ID attribute: %s",
|
||||||
return r;
|
strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
|
||||||
|
r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, netdev->macvlan_mode);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_netdev(netdev,
|
||||||
|
"Could not append IFLA_MACVLAN_MODE attribute: %s",
|
||||||
|
strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_rtnl_message_close_container(req);
|
r = sd_rtnl_message_close_container(req);
|
||||||
@ -272,7 +295,7 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
|
|||||||
}
|
}
|
||||||
|
|
||||||
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
|
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
|
||||||
if (netdev->kind == NETDEV_KIND_VLAN)
|
if (netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN)
|
||||||
return netdev_create(netdev, link, callback);
|
return netdev_create(netdev, link, callback);
|
||||||
|
|
||||||
if (netdev->state == NETDEV_STATE_READY) {
|
if (netdev->state == NETDEV_STATE_READY) {
|
||||||
@ -335,10 +358,12 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
|||||||
netdev->manager = manager;
|
netdev->manager = manager;
|
||||||
netdev->state = _NETDEV_STATE_INVALID;
|
netdev->state = _NETDEV_STATE_INVALID;
|
||||||
netdev->kind = _NETDEV_KIND_INVALID;
|
netdev->kind = _NETDEV_KIND_INVALID;
|
||||||
|
netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
|
||||||
netdev->vlanid = VLANID_MAX + 1;
|
netdev->vlanid = VLANID_MAX + 1;
|
||||||
|
|
||||||
r = config_parse(NULL, filename, file, "Match\0NetDev\0VLAN\0", config_item_perf_lookup,
|
r = config_parse(NULL, filename, file, "Match\0NetDev\0VLAN\0MACVLAN\0",
|
||||||
(void*) network_netdev_gperf_lookup, false, false, netdev);
|
config_item_perf_lookup, (void*) network_netdev_gperf_lookup,
|
||||||
|
false, false, netdev);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_warning("Could not parse config file %s: %s", filename, strerror(-r));
|
log_warning("Could not parse config file %s: %s", filename, strerror(-r));
|
||||||
return r;
|
return r;
|
||||||
@ -359,6 +384,19 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (netdev->kind != NETDEV_KIND_VLAN && netdev->vlanid <= VLANID_MAX) {
|
||||||
|
log_warning("VLAN Id configured for a %s in %s. Ignoring",
|
||||||
|
netdev_kind_to_string(netdev->kind), filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev->kind != NETDEV_KIND_MACVLAN &&
|
||||||
|
netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
|
||||||
|
log_warning("MACVLAN Mode configured for a %s in %s. Ignoring",
|
||||||
|
netdev_kind_to_string(netdev->kind), filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
netdev->filename = strdup(filename);
|
netdev->filename = strdup(filename);
|
||||||
if (!netdev->filename)
|
if (!netdev->filename)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
@ -375,7 +413,8 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
|||||||
|
|
||||||
LIST_HEAD_INIT(netdev->callbacks);
|
LIST_HEAD_INIT(netdev->callbacks);
|
||||||
|
|
||||||
if (netdev->kind != NETDEV_KIND_VLAN) {
|
if (netdev->kind != NETDEV_KIND_VLAN &&
|
||||||
|
netdev->kind != NETDEV_KIND_MACVLAN) {
|
||||||
r = netdev_create(netdev, NULL, NULL);
|
r = netdev_create(netdev, NULL, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -28,6 +28,7 @@ Network.Description, config_parse_string, 0,
|
|||||||
Network.Bridge, config_parse_bridge, 0, offsetof(Network, bridge)
|
Network.Bridge, config_parse_bridge, 0, offsetof(Network, bridge)
|
||||||
Network.Bond, config_parse_bond, 0, offsetof(Network, bond)
|
Network.Bond, config_parse_bond, 0, offsetof(Network, bond)
|
||||||
Network.VLAN, config_parse_vlan, 0, offsetof(Network, vlans)
|
Network.VLAN, config_parse_vlan, 0, offsetof(Network, vlans)
|
||||||
|
Network.MACVLAN, config_parse_macvlan, 0, offsetof(Network, macvlans)
|
||||||
Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
|
Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
|
||||||
Network.Address, config_parse_address, 0, 0
|
Network.Address, config_parse_address, 0, 0
|
||||||
Network.Gateway, config_parse_gateway, 0, 0
|
Network.Gateway, config_parse_gateway, 0, 0
|
||||||
|
@ -53,10 +53,14 @@ static int network_load_one(Manager *manager, const char *filename) {
|
|||||||
LIST_HEAD_INIT(network->static_addresses);
|
LIST_HEAD_INIT(network->static_addresses);
|
||||||
LIST_HEAD_INIT(network->static_routes);
|
LIST_HEAD_INIT(network->static_routes);
|
||||||
|
|
||||||
network->vlans = hashmap_new(uint64_hash_func, uint64_compare_func);
|
network->vlans = hashmap_new(string_hash_func, string_compare_func);
|
||||||
if (!network->vlans)
|
if (!network->vlans)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
network->macvlans = hashmap_new(uint64_hash_func, uint64_compare_func);
|
||||||
|
if (!network->macvlans)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
|
network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
|
||||||
if (!network->addresses_by_section)
|
if (!network->addresses_by_section)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
@ -150,6 +154,8 @@ void network_free(Network *network) {
|
|||||||
|
|
||||||
hashmap_free(network->vlans);
|
hashmap_free(network->vlans);
|
||||||
|
|
||||||
|
hashmap_free(network->macvlans);
|
||||||
|
|
||||||
while ((route = network->static_routes))
|
while ((route = network->static_routes))
|
||||||
route_free(route);
|
route_free(route);
|
||||||
|
|
||||||
@ -330,3 +336,45 @@ int config_parse_vlan(const char *unit,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_macvlan(const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
Network *network = userdata;
|
||||||
|
NetDev *netdev;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
r = netdev_get(network->manager, rvalue, &netdev);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
|
||||||
|
"MACVLAN is invalid, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev->kind != NETDEV_KIND_MACVLAN) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
|
||||||
|
"NetDev is not a MACVLAN, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = hashmap_put(network->macvlans, netdev->name, netdev);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
|
||||||
|
"Can not add MACVLAN to network: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -50,10 +50,20 @@ struct netdev_enslave_callback {
|
|||||||
LIST_FIELDS(netdev_enslave_callback, callbacks);
|
LIST_FIELDS(netdev_enslave_callback, callbacks);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum MacVlanMode {
|
||||||
|
NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE,
|
||||||
|
NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA,
|
||||||
|
NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE,
|
||||||
|
NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU,
|
||||||
|
_NETDEV_MACVLAN_MODE_MAX,
|
||||||
|
_NETDEV_MACVLAN_MODE_INVALID = -1
|
||||||
|
} MacVlanMode;
|
||||||
|
|
||||||
typedef enum NetDevKind {
|
typedef enum NetDevKind {
|
||||||
NETDEV_KIND_BRIDGE,
|
NETDEV_KIND_BRIDGE,
|
||||||
NETDEV_KIND_BOND,
|
NETDEV_KIND_BOND,
|
||||||
NETDEV_KIND_VLAN,
|
NETDEV_KIND_VLAN,
|
||||||
|
NETDEV_KIND_MACVLAN,
|
||||||
_NETDEV_KIND_MAX,
|
_NETDEV_KIND_MAX,
|
||||||
_NETDEV_KIND_INVALID = -1
|
_NETDEV_KIND_INVALID = -1
|
||||||
} NetDevKind;
|
} NetDevKind;
|
||||||
@ -81,6 +91,7 @@ struct NetDev {
|
|||||||
NetDevKind kind;
|
NetDevKind kind;
|
||||||
|
|
||||||
uint64_t vlanid;
|
uint64_t vlanid;
|
||||||
|
int32_t macvlan_mode;
|
||||||
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
NetDevState state;
|
NetDevState state;
|
||||||
@ -107,6 +118,7 @@ struct Network {
|
|||||||
NetDev *bridge;
|
NetDev *bridge;
|
||||||
NetDev *bond;
|
NetDev *bond;
|
||||||
Hashmap *vlans;
|
Hashmap *vlans;
|
||||||
|
Hashmap *macvlans;
|
||||||
bool dhcp;
|
bool dhcp;
|
||||||
bool dhcp_dns;
|
bool dhcp_dns;
|
||||||
bool dhcp_mtu;
|
bool dhcp_mtu;
|
||||||
@ -248,8 +260,13 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb);
|
|||||||
const char *netdev_kind_to_string(NetDevKind d) _const_;
|
const char *netdev_kind_to_string(NetDevKind d) _const_;
|
||||||
NetDevKind netdev_kind_from_string(const char *d) _pure_;
|
NetDevKind netdev_kind_from_string(const char *d) _pure_;
|
||||||
|
|
||||||
|
const char *macvlan_mode_to_string(MacVlanMode d) _const_;
|
||||||
|
MacVlanMode macvlan_mode_from_string(const char *d) _pure_;
|
||||||
|
|
||||||
int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
|
||||||
|
int config_parse_macvlan_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
|
||||||
/* gperf */
|
/* gperf */
|
||||||
const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
|
const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
|
||||||
|
|
||||||
@ -277,6 +294,10 @@ int config_parse_vlan(const char *unit, const char *filename, unsigned line,
|
|||||||
const char *section, unsigned section_line, const char *lvalue,
|
const char *section, unsigned section_line, const char *lvalue,
|
||||||
int ltype, const char *rvalue, void *data, void *userdata);
|
int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
|
||||||
|
int config_parse_macvlan(const char *unit, const char *filename, unsigned line,
|
||||||
|
const char *section, unsigned section_line, const char *lvalue,
|
||||||
|
int ltype, const char *rvalue, void *data, void *userdata);
|
||||||
|
|
||||||
/* gperf */
|
/* gperf */
|
||||||
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
|
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user