networkd: netdev - introduce vtable for netdev kinds

Split each netdev kind into its own .h/.c.
This commit is contained in:
Tom Gundersen 2014-07-06 14:07:34 +02:00
parent 2023dc8a9a
commit 3be1d7e0c5
26 changed files with 727 additions and 642 deletions

View file

@ -4590,17 +4590,27 @@ libsystemd_networkd_core_la_CFLAGS = \
libsystemd_networkd_core_la_SOURCES = \
src/libsystemd-network/network-internal.h \
src/network/networkd.h \
src/network/networkd-link.c \
src/network/networkd-netdev.h \
src/network/networkd-netdev-tunnel.h \
src/network/networkd-netdev-veth.h \
src/network/networkd-netdev-vxlan.h \
src/network/networkd-netdev-vlan.h \
src/network/networkd-netdev-macvlan.h \
src/network/networkd-netdev-dummy.h \
src/network/networkd-netdev-tuntap.h \
src/network/networkd-netdev-bond.h \
src/network/networkd-netdev-bridge.h \
src/network/networkd-netdev.c \
src/network/networkd-tunnel.c \
src/network/networkd-veth.c \
src/network/networkd-vxlan.c \
src/network/networkd-vlan.c \
src/network/networkd-macvlan.c \
src/network/networkd-dummy.c \
src/network/networkd-tuntap.c \
src/network/networkd-bond.c \
src/network/networkd-bridge.c \
src/network/networkd-netdev-tunnel.c \
src/network/networkd-netdev-veth.c \
src/network/networkd-netdev-vxlan.c \
src/network/networkd-netdev-vlan.c \
src/network/networkd-netdev-macvlan.c \
src/network/networkd-netdev-dummy.c \
src/network/networkd-netdev-tuntap.c \
src/network/networkd-netdev-bond.c \
src/network/networkd-netdev-bridge.c \
src/network/networkd-link.c \
src/network/networkd-network.c \
src/network/networkd-address.c \
src/network/networkd-route.c \

View file

@ -24,6 +24,7 @@
#include <unistd.h>
#include "networkd.h"
#include "networkd-netdev.h"
#include "libudev-private.h"
#include "udev-util.h"
#include "util.h"

View file

@ -25,6 +25,7 @@
#include "conf-parser.h"
#include "path-util.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "network-internal.h"
#include "libudev-private.h"
#include "udev-util.h"

View file

@ -26,7 +26,7 @@
#include "conf-parser.h"
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-bond.h"
#include "missing.h"
static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
@ -63,7 +63,7 @@ static uint8_t bond_mode_to_kernel(BondMode mode) {
}
}
static int netdev_fill_bond_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
int r;
assert(m);
@ -123,41 +123,7 @@ static int netdev_fill_bond_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
int netdev_create_bond(NetDev *netdev, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_BOND);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
}
r = netdev_fill_bond_rtnl_message(netdev, m);
if(r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
netdev_ref(netdev);
log_debug_netdev(netdev, "Creating bond netdev: %s",
netdev_kind_to_string(netdev->kind));
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable bond_vtable = {
.fill_message_create = netdev_bond_fill_message_create,
.enslave = netdev_enslave,
};

View file

@ -0,0 +1,43 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable bond_vtable;
typedef enum BondMode {
NETDEV_BOND_MODE_BALANCE_RR,
NETDEV_BOND_MODE_ACTIVE_BACKUP,
NETDEV_BOND_MODE_BALANCE_XOR,
NETDEV_BOND_MODE_BROADCAST,
NETDEV_BOND_MODE_802_3AD,
NETDEV_BOND_MODE_BALANCE_TLB,
NETDEV_BOND_MODE_BALANCE_ALB,
_NETDEV_BOND_MODE_MAX,
_NETDEV_BOND_MODE_INVALID = -1
} BondMode;
const char *bond_mode_to_string(BondMode d) _const_;
BondMode bond_mode_from_string(const char *d) _pure_;
int config_parse_bond_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);

View file

@ -25,12 +25,14 @@
#include <net/if.h>
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-bridge.h"
#include "missing.h"
static int netdev_fill_bridge_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_bridge_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->ifname);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -49,8 +51,7 @@ static int netdev_fill_bridge_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "bridge");
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
@ -77,40 +78,7 @@ static int netdev_fill_bridge_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
int netdev_create_bridge(NetDev *netdev, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_BRIDGE);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
}
r = netdev_fill_bridge_rtnl_message(netdev, m);
if(r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
netdev_ref(netdev);
log_debug_netdev(netdev, "Creating bridge netdev.");
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable bridge_vtable = {
.fill_message_create = netdev_bridge_fill_message_create,
.enslave = netdev_enslave,
};

View file

@ -0,0 +1,26 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable bridge_vtable;

View file

@ -26,13 +26,13 @@
#include <linux/veth.h>
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-dummy.h"
static int netdev_fill_dummy_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_dummy_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->ifname);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -61,8 +61,7 @@ static int netdev_fill_dummy_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "dummy");
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
@ -81,42 +80,6 @@ static int netdev_fill_dummy_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
int netdev_create_dummy(NetDev *netdev, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
assert(netdev);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
}
if(netdev->kind != NETDEV_KIND_DUMMY)
return -ENOTSUP;
r = netdev_fill_dummy_rtnl_message(netdev, m);
if(r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
netdev_ref(netdev);
log_debug_netdev(netdev, "Creating dummy netdev.");
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable dummy_vtable = {
.fill_message_create = netdev_dummy_fill_message_create,
};

View file

@ -0,0 +1,26 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable dummy_vtable;

View file

@ -1,7 +1,10 @@
%{
#include <stddef.h>
#include "conf-parser.h"
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-netdev-tunnel.h"
#include "networkd-netdev-bond.h"
#include "networkd-netdev-macvlan.h"
#include "network-internal.h"
%}
struct ConfigPerfItem;

View file

@ -21,7 +21,7 @@
#include <net/if.h>
#include "networkd.h"
#include "networkd-netdev-macvlan.h"
#include "network-internal.h"
#include "conf-parser.h"
#include "list.h"
@ -36,37 +36,22 @@ static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
const char *kind;
static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_MACVLAN);
assert(link);
assert(callback);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
"Could not append IFLA_LINK attribute: %s",
strerror(-r));
return r;
}
if (link) {
r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINK attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
@ -103,13 +88,7 @@ int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t
return r;
}
kind = netdev_kind_to_string(netdev->kind);
if (!kind) {
log_error_netdev(netdev, "Invalid kind");
return -EINVAL;
}
r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "macvlan");
if (r < 0) {
log_error_netdev(netdev,
"Could not open IFLA_INFO_DATA container: %s",
@ -143,18 +122,9 @@ int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t
return r;
}
r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
link_ref(link);
log_debug_netdev(netdev, "creating netdev");
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable macvlan_vtable = {
.fill_message_create_on_link = netdev_macvlan_fill_message_create,
};

View file

@ -0,0 +1,40 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable macvlan_vtable;
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;
const char *macvlan_mode_to_string(MacVlanMode d) _const_;
MacVlanMode macvlan_mode_from_string(const char *d) _pure_;
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);

View file

@ -26,24 +26,22 @@
#include <linux/if_tunnel.h>
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-tunnel.h"
#include "network-internal.h"
#include "util.h"
#include "missing.h"
#include "conf-parser.h"
static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
NetDev *netdev;
static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_IPIP);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(link->network);
assert(link->network->tunnel);
assert(m);
netdev = link->network->tunnel;
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -142,17 +140,16 @@ static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
return r;
}
static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
NetDev *netdev;
static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_SIT);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(link->network);
assert(link->network->tunnel);
assert(m);
netdev = link->network->tunnel;
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -224,18 +221,10 @@ static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos);
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_TOS attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_PMTUDISC attribute: %s",
"Could not append IFLA_IPTUN_TTL attribute: %s",
strerror(-r));
return r;
}
@ -259,17 +248,16 @@ static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
return r;
}
static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
NetDev *netdev;
static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_GRE);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(link->network);
assert(link->network->tunnel);
assert(m);
netdev = link->network->tunnel;
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -376,17 +364,16 @@ static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
return r;
}
static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
NetDev *netdev;
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_VTI);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(link->network);
assert(link->network->tunnel);
assert(m);
netdev = link->network->tunnel;
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -477,65 +464,25 @@ static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
return r;
}
int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
assert(netdev);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(link->network);
assert(link->network->tunnel == netdev);
assert(filename);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
if (netdev->local.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without local address configured in %s. Ignoring", filename);
return -EINVAL;
}
switch(netdev->kind) {
case NETDEV_KIND_IPIP:
r = netdev_fill_ipip_rtnl_message(link, m);
if(r < 0)
return r;
break;
case NETDEV_KIND_SIT:
r = netdev_fill_sit_rtnl_message(link, m);
if(r < 0)
return r;
break;
case NETDEV_KIND_VTI:
netdev_fill_vti_rtnl_message(link, m);
if(r < 0)
return r;
break;
case NETDEV_KIND_GRE:
r = netdev_fill_ipgre_rtnl_message(link, m);
if(r < 0)
return r;
break;
default:
return -ENOTSUP;
if (netdev->remote.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
return -EINVAL;
}
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
if (netdev->family != AF_INET) {
log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
return -EINVAL;
}
link_ref(link);
log_debug_netdev(netdev, "Creating tunnel netdev: %s",
netdev_kind_to_string(netdev->kind));
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
@ -567,3 +514,23 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
const NetDevVTable ipip_vtable = {
.fill_message_create_on_link = netdev_ipip_fill_message_create,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable sit_vtable = {
.fill_message_create_on_link = netdev_sit_fill_message_create,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable vti_vtable = {
.fill_message_create_on_link = netdev_vti_fill_message_create,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable gre_vtable = {
.fill_message_create_on_link = netdev_gre_fill_message_create,
.config_verify = netdev_tunnel_verify,
};

View file

@ -0,0 +1,29 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable ipip_vtable;
extern const NetDevVTable sit_vtable;
extern const NetDevVTable vti_vtable;
extern const NetDevVTable gre_vtable;

View file

@ -23,11 +23,10 @@
#include <net/if.h>
#include <linux/if_tun.h>
#include "networkd.h"
#include "networkd-netdev-tuntap.h"
#define TUN_DEV "/dev/net/tun"
static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
assert(netdev);
@ -129,7 +128,7 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return r;
}
int netdev_create_tuntap(NetDev *netdev) {
static int netdev_create_tuntap(NetDev *netdev) {
struct ifreq ifr;
int r;
@ -153,3 +152,11 @@ int netdev_create_tuntap(NetDev *netdev) {
return netdev_tuntap_add(netdev, &ifr);
}
const NetDevVTable tun_vtable = {
.create = netdev_create_tuntap,
};
const NetDevVTable tap_vtable = {
.create = netdev_create_tuntap,
};

View file

@ -0,0 +1,27 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable tun_vtable;
extern const NetDevVTable tap_vtable;

View file

@ -25,13 +25,13 @@
#include <linux/veth.h>
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-veth.h"
static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(netdev->ifname);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -60,8 +60,7 @@ static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth");
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
@ -114,41 +113,31 @@ static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
int netdev_create_veth(NetDev *netdev, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
static int netdev_veth_verify(NetDev *netdev, const char *filename) {
int r;
assert(netdev);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(netdev->kind == NETDEV_KIND_VETH);
assert(filename);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
if (!netdev->ifname_peer) {
log_warning("Veth NetDev without peer name configured in %s. Ignoring",
filename);
return -EINVAL;
}
r = netdev_fill_veth_rtnl_message(netdev, m);
if(r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
if (!netdev->mac_peer) {
r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
if (r < 0) {
log_warning("Failed to generate predictable MAC address for %s. Ignoring",
netdev->ifname_peer);
return -EINVAL;
}
}
netdev_ref(netdev);
log_debug_netdev(netdev, "Creating veth netdev: %s",
netdev_kind_to_string(netdev->kind));
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable veth_vtable = {
.fill_message_create = netdev_veth_fill_message_create,
.config_verify = netdev_veth_verify,
};

View file

@ -0,0 +1,26 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
extern const NetDevVTable veth_vtable;

View file

@ -21,41 +21,27 @@
#include <net/if.h>
#include "networkd.h"
#include "networkd-netdev-vlan.h"
#include "network-internal.h"
#include "list.h"
int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
const char *kind;
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
int r;
assert(netdev);
assert(netdev->ifname);
assert(netdev->kind == NETDEV_KIND_VLAN);
assert(link);
assert(callback);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(req);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
"Could not append IFLA_LINK attribute: %s",
strerror(-r));
return r;
}
if (link) {
r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINK attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
@ -92,13 +78,7 @@ int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cal
return r;
}
kind = netdev_kind_to_string(netdev->kind);
if (!kind) {
log_error_netdev(netdev, "Invalid kind");
return -EINVAL;
}
r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "vlan");
if (r < 0) {
log_error_netdev(netdev,
"Could not open IFLA_INFO_DATA container: %s",
@ -132,18 +112,22 @@ int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cal
return r;
}
r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
return 0;
}
static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
assert(netdev);
assert(filename);
if (netdev->vlanid > VLANID_MAX) {
log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
return -EINVAL;
}
link_ref(link);
log_debug_netdev(netdev, "creating netdev");
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable vlan_vtable = {
.fill_message_create_on_link = netdev_vlan_fill_message_create,
.config_verify = netdev_vlan_verify,
};

View file

@ -0,0 +1,28 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
#define VLANID_MAX 4094
extern const NetDevVTable vlan_vtable;

View file

@ -24,15 +24,15 @@
#include <net/if.h>
#include "sd-rtnl.h"
#include "networkd.h"
#include "networkd-netdev-vxlan.h"
#include "missing.h"
static int netdev_fill_vxlan_rtnl_message(NetDev *netdev, Link *link, sd_rtnl_message *m) {
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
int r;
assert(netdev);
assert(link);
assert(link->network);
assert(link->ifname);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
@ -51,8 +51,7 @@ static int netdev_fill_vxlan_rtnl_message(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "vxlan");
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
@ -125,41 +124,19 @@ static int netdev_fill_vxlan_rtnl_message(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
int netdev_create_vxlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
assert(netdev);
assert(!(netdev->kind == NETDEV_KIND_VXLAN) || (link && callback));
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(filename);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
if (netdev->vxlanid > VXLAN_VID_MAX) {
log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
return -EINVAL;
}
r = netdev_fill_vxlan_rtnl_message(netdev, link, m);
if(r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
link_ref(link);
log_debug_netdev(netdev, "Creating vxlan netdev: %s",
netdev_kind_to_string(netdev->kind));
netdev->state = NETDEV_STATE_CREATING;
return 0;
}
const NetDevVTable vxlan_vtable = {
.fill_message_create_on_link = netdev_vxlan_fill_message_create,
.config_verify = netdev_vxlan_verify,
};

View file

@ -0,0 +1,28 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd-netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
extern const NetDevVTable vxlan_vtable;

View file

@ -21,7 +21,16 @@
#include <net/if.h>
#include "networkd.h"
#include "networkd-netdev.h"
#include "networkd-netdev-bridge.h"
#include "networkd-netdev-bond.h"
#include "networkd-netdev-vlan.h"
#include "networkd-netdev-macvlan.h"
#include "networkd-netdev-vxlan.h"
#include "networkd-netdev-tunnel.h"
#include "networkd-netdev-veth.h"
#include "networkd-netdev-dummy.h"
#include "networkd-netdev-tuntap.h"
#include "network-internal.h"
#include "path-util.h"
#include "conf-files.h"
@ -29,6 +38,22 @@
#include "list.h"
#include "siphash24.h"
const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_BRIDGE] = &bridge_vtable,
[NETDEV_KIND_BOND] = &bond_vtable,
[NETDEV_KIND_VLAN] = &vlan_vtable,
[NETDEV_KIND_MACVLAN] = &macvlan_vtable,
[NETDEV_KIND_VXLAN] = &vxlan_vtable,
[NETDEV_KIND_IPIP] = &ipip_vtable,
[NETDEV_KIND_GRE] = &gre_vtable,
[NETDEV_KIND_SIT] = &sit_vtable,
[NETDEV_KIND_VTI] = &vti_vtable,
[NETDEV_KIND_VETH] = &veth_vtable,
[NETDEV_KIND_DUMMY] = &dummy_vtable,
[NETDEV_KIND_TUN] = &tun_vtable,
[NETDEV_KIND_TAP] = &tap_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_BRIDGE] = "bridge",
[NETDEV_KIND_BOND] = "bond",
@ -246,7 +271,7 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
return 1;
}
static 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) {
int r;
assert(netdev);
@ -276,27 +301,39 @@ static int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t
/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
int r;
assert(netdev);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(NETDEV_VTABLE(netdev));
switch(netdev->kind) {
case NETDEV_KIND_VLAN:
return netdev_create_vlan(netdev, link, callback);
case NETDEV_KIND_MACVLAN:
return netdev_create_macvlan(netdev, link, callback);
case NETDEV_KIND_VXLAN:
return netdev_create_vxlan(netdev, link, callback);
case NETDEV_KIND_IPIP:
case NETDEV_KIND_GRE:
case NETDEV_KIND_SIT:
case NETDEV_KIND_VTI:
return netdev_create_tunnel(netdev, link, callback);
case NETDEV_KIND_BRIDGE:
case NETDEV_KIND_BOND:
return netdev_enslave(netdev, link, callback);
default:
assert_not_reached("Enslaving by invalid netdev kind");
}
if (NETDEV_VTABLE(netdev)->fill_message_create_on_link) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req,
RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_SETLINK message: %s",
strerror(-r));
return r;
}
NETDEV_VTABLE(netdev)->fill_message_create_on_link(netdev, link, req);
r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
link_ref(link);
} else if (NETDEV_VTABLE(netdev)->enslave) {
return NETDEV_VTABLE(netdev)->enslave(netdev, link, callback);
} else
assert_not_reached("Joining link to netdev of invalid kind");
return 0;
}
@ -406,7 +443,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
static int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
_cleanup_free_ struct ether_addr *mac = NULL;
uint8_t result[8];
size_t l, sz;
@ -502,63 +539,16 @@ static int netdev_load_one(Manager *manager, const char *filename) {
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
/* verify configuration */
switch (netdev->kind) {
case _NETDEV_KIND_INVALID:
log_warning("NetDev without Kind configured in %s. Ignoring", filename);
if (!NETDEV_VTABLE(netdev)) {
log_warning("NetDev with invalid Kind configured in %s. Igonring", filename);
return 0;
}
case NETDEV_KIND_VLAN:
if (netdev->vlanid > VLANID_MAX) {
log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
/* verify configuration */
if (NETDEV_VTABLE(netdev)->config_verify) {
r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
if (r < 0)
return 0;
}
break;
case NETDEV_KIND_VXLAN:
if (netdev->vxlanid > VXLAN_VID_MAX) {
log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
return 0;
}
break;
case NETDEV_KIND_IPIP:
case NETDEV_KIND_GRE:
case NETDEV_KIND_SIT:
case NETDEV_KIND_VTI:
if (netdev->local.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without local address configured in %s. Ignoring", filename);
return 0;
}
if (netdev->remote.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
return 0;
}
if (netdev->family != AF_INET) {
log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
return 0;
}
break;
case NETDEV_KIND_VETH:
if (!netdev->ifname_peer) {
log_warning("Veth NetDev without peer name configured "
"in %s. Ignoring", filename);
return 0;
}
if (!netdev->mac_peer) {
r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
if (r < 0) {
log_error("Failed to generate predictable MAC address for %s",
netdev->ifname_peer);
return r;
}
}
break;
default:
break;
}
if (!netdev->ifname) {
@ -604,36 +594,42 @@ static int netdev_load_one(Manager *manager, const char *filename) {
LIST_HEAD_INIT(netdev->callbacks);
/* create netdev */
switch (netdev->kind) {
case NETDEV_KIND_VETH:
r = netdev_create_veth(netdev, netdev_create_handler);
if (r < 0)
return r;
break;
case NETDEV_KIND_DUMMY:
r = netdev_create_dummy(netdev, netdev_create_handler);
if (r < 0)
return r;
break;
case NETDEV_KIND_BRIDGE:
r = netdev_create_bridge(netdev, netdev_create_handler);
if (r < 0)
return r;
break;
case NETDEV_KIND_BOND:
r = netdev_create_bond(netdev, netdev_create_handler);
if (r < 0)
return r;
break;
default:
break;
}
log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
/* create netdev */
if (NETDEV_VTABLE(netdev)->fill_message_create) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
strerror(-r));
return r;
}
r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, m);
if (r < 0)
return r;
r = sd_rtnl_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
if (r < 0) {
log_error_netdev(netdev,
"Could not send rtnetlink message: %s", strerror(-r));
return r;
}
netdev_ref(netdev);
log_debug_netdev(netdev, "creating");
netdev->state = NETDEV_STATE_CREATING;
} else if (NETDEV_VTABLE(netdev)->create) {
r = NETDEV_VTABLE(netdev)->create(netdev);
if (r < 0)
return r;
}
netdev = NULL;
return 0;

View file

@ -0,0 +1,170 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2013 Tom Gundersen <teg@jklm.no>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#pragma once
#include "networkd.h"
#include "hashmap.h"
#include "list.h"
#include "set.h"
#include "condition-util.h"
#include "in-addr-util.h"
typedef struct NetDevVTable NetDevVTable;
typedef struct netdev_join_callback netdev_join_callback;
struct netdev_join_callback {
sd_rtnl_message_handler_t callback;
Link *link;
LIST_FIELDS(netdev_join_callback, callbacks);
};
typedef enum NetDevKind {
NETDEV_KIND_BRIDGE,
NETDEV_KIND_BOND,
NETDEV_KIND_VLAN,
NETDEV_KIND_MACVLAN,
NETDEV_KIND_VXLAN,
NETDEV_KIND_IPIP,
NETDEV_KIND_GRE,
NETDEV_KIND_SIT,
NETDEV_KIND_VETH,
NETDEV_KIND_VTI,
NETDEV_KIND_DUMMY,
NETDEV_KIND_TUN,
NETDEV_KIND_TAP,
_NETDEV_KIND_MAX,
_NETDEV_KIND_INVALID = -1
} NetDevKind;
typedef enum NetDevState {
NETDEV_STATE_FAILED,
NETDEV_STATE_CREATING,
NETDEV_STATE_READY,
NETDEV_STATE_LINGER,
_NETDEV_STATE_MAX,
_NETDEV_STATE_INVALID = -1,
} NetDevState;
struct NetDev {
Manager *manager;
int n_ref;
char *filename;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_arch;
char *description;
char *ifname;
char *ifname_peer;
char *user_name;
char *group_name;
size_t mtu;
struct ether_addr *mac;
struct ether_addr *mac_peer;
NetDevKind kind;
uint64_t vlanid;
uint64_t vxlanid;
int32_t macvlan_mode;
int32_t bond_mode;
int ifindex;
NetDevState state;
bool tunnel_pmtudisc;
bool learning;
bool one_queue;
bool multi_queue;
bool packet_info;
unsigned ttl;
unsigned tos;
unsigned char family;
union in_addr_union local;
union in_addr_union remote;
union in_addr_union group;
LIST_HEAD(netdev_join_callback, callbacks);
};
struct NetDevVTable {
/* fill in message to create netdev */
int (*fill_message_create)(NetDev *netdev, sd_rtnl_message *message);
/* fill in message to create netdev on top of a given link */
int (*fill_message_create_on_link)(NetDev *netdev, Link *link, sd_rtnl_message *message);
/* fill in message to enslave link by netdev */
int (*enslave)(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
/* create netdev, if not done via rtnl */
int (*create)(NetDev *netdev);
/* verify that compulsory configuration options were specified */
int (*config_verify)(NetDev *netdev, const char *filename);
};
extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
int netdev_load(Manager *manager);
void netdev_drop(NetDev *netdev);
NetDev *netdev_unref(NetDev *netdev);
NetDev *netdev_ref(NetDev *netdev);
DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp)
int netdev_get(Manager *manager, const char *name, NetDev **ret);
int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink);
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
int netdev_get_mac(const char *ifname, struct ether_addr **ret);
int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb);
const char *netdev_kind_to_string(NetDevKind d) _const_;
NetDevKind netdev_kind_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);
/* gperf */
const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
/* Macros which append INTERFACE= to the message */
#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
#define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
#define log_error_netdev(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname

View file

@ -23,6 +23,7 @@
#include <net/if.h>
#include "networkd.h"
#include "networkd-netdev.h"
#include "network-internal.h"
#include "path-util.h"
#include "conf-files.h"

View file

@ -41,7 +41,6 @@
#include "in-addr-util.h"
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
#define VXLAN_VID_MAX (1u << 24) - 1
#define DHCP_ROUTE_METRIC 1024
#define IPV4LL_ROUTE_METRIC 2048
@ -53,109 +52,6 @@ typedef struct Route Route;
typedef struct Manager Manager;
typedef struct AddressPool AddressPool;
typedef struct netdev_join_callback netdev_join_callback;
struct netdev_join_callback {
sd_rtnl_message_handler_t callback;
Link *link;
LIST_FIELDS(netdev_join_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 BondMode {
NETDEV_BOND_MODE_BALANCE_RR,
NETDEV_BOND_MODE_ACTIVE_BACKUP,
NETDEV_BOND_MODE_BALANCE_XOR,
NETDEV_BOND_MODE_BROADCAST,
NETDEV_BOND_MODE_802_3AD,
NETDEV_BOND_MODE_BALANCE_TLB,
NETDEV_BOND_MODE_BALANCE_ALB,
_NETDEV_BOND_MODE_MAX,
_NETDEV_BOND_MODE_INVALID = -1
} BondMode;
typedef enum NetDevKind {
NETDEV_KIND_BRIDGE,
NETDEV_KIND_BOND,
NETDEV_KIND_VLAN,
NETDEV_KIND_MACVLAN,
NETDEV_KIND_VXLAN,
NETDEV_KIND_IPIP,
NETDEV_KIND_GRE,
NETDEV_KIND_SIT,
NETDEV_KIND_VETH,
NETDEV_KIND_VTI,
NETDEV_KIND_DUMMY,
NETDEV_KIND_TUN,
NETDEV_KIND_TAP,
_NETDEV_KIND_MAX,
_NETDEV_KIND_INVALID = -1
} NetDevKind;
typedef enum NetDevState {
NETDEV_STATE_FAILED,
NETDEV_STATE_CREATING,
NETDEV_STATE_READY,
NETDEV_STATE_LINGER,
_NETDEV_STATE_MAX,
_NETDEV_STATE_INVALID = -1,
} NetDevState;
struct NetDev {
Manager *manager;
int n_ref;
char *filename;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_arch;
char *description;
char *ifname;
char *ifname_peer;
char *user_name;
char *group_name;
size_t mtu;
struct ether_addr *mac;
struct ether_addr *mac_peer;
NetDevKind kind;
uint64_t vlanid;
uint64_t vxlanid;
int32_t macvlan_mode;
int32_t bond_mode;
int ifindex;
NetDevState state;
bool tunnel_pmtudisc;
bool learning;
bool one_queue;
bool multi_queue;
bool packet_info;
unsigned ttl;
unsigned tos;
unsigned char family;
union in_addr_union local;
union in_addr_union remote;
union in_addr_union group;
LIST_HEAD(netdev_join_callback, callbacks);
};
typedef enum DHCPSupport {
DHCP_SUPPORT_NONE,
DHCP_SUPPORT_BOTH,
@ -363,51 +259,6 @@ int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
#define _cleanup_manager_free_ _cleanup_(manager_freep)
/* NetDev */
#define VLANID_MAX 4094
int netdev_load(Manager *manager);
void netdev_drop(NetDev *netdev);
NetDev *netdev_unref(NetDev *netdev);
NetDev *netdev_ref(NetDev *netdev);
DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp)
int netdev_get(Manager *manager, const char *name, NetDev **ret);
int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink);
int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb);
int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
int netdev_create_veth(NetDev *netdev, sd_rtnl_message_handler_t callback);
int netdev_create_vxlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
int netdev_create_dummy(NetDev *netdev, sd_rtnl_message_handler_t callback);
int netdev_create_tuntap(NetDev *netdev);
int netdev_create_bond(NetDev *netdev, sd_rtnl_message_handler_t callback);
int netdev_create_bridge(NetDev *netdev, sd_rtnl_message_handler_t callback);
const char *netdev_kind_to_string(NetDevKind d) _const_;
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_;
const char *bond_mode_to_string(BondMode d) _const_;
BondMode bond_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_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);
int config_parse_bond_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 */
const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
/* Network */
int network_load(Manager *manager);
@ -555,18 +406,6 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union
#define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__)
/* More macros which append INTERFACE= to the message */
#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
#define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
#define log_error_netdev(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname
#define ADDRESS_FMT_VAL(address) \
(address).s_addr & 0xFF, \
((address).s_addr >> 8) & 0xFF, \