networkd: netdev - split NetDev struct into per-kind structs

Similarly to how unit types work.
This commit is contained in:
Tom Gundersen 2014-07-16 13:17:10 +02:00
parent 653912918f
commit aa9f114058
23 changed files with 693 additions and 930 deletions

View File

@ -1808,7 +1808,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bond->ifname,
NETDEV(link->network->bond),
NETDEVIF(link->network->bond),
NULL);
r = netdev_join(link->network->bond, link, &netdev_join_handler);
@ -1817,7 +1817,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bond->ifname, strerror(-r),
NETDEV(link->network->bond),
NETDEVIF(link->network->bond),
NULL);
link_enter_failed(link);
return r;
@ -1831,7 +1831,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname,
NETDEV(link->network->bridge),
NETDEVIF(link->network->bridge),
NULL);
r = netdev_join(link->network->bridge, link, &netdev_join_handler);
@ -1840,7 +1840,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname, strerror(-r),
NETDEV(link->network->bridge),
NETDEVIF(link->network->bridge),
NULL);
link_enter_failed(link);
return r;
@ -1854,7 +1854,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->tunnel->ifname,
NETDEV(link->network->tunnel),
NETDEVIF(link->network->tunnel),
NULL);
r = netdev_join(link->network->tunnel, link, &netdev_join_handler);
@ -1863,7 +1863,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->tunnel->ifname, strerror(-r),
NETDEV(link->network->tunnel),
NETDEVIF(link->network->tunnel),
NULL);
link_enter_failed(link);
return r;
@ -1876,7 +1876,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, vlan->ifname, NETDEV(vlan), NULL);
link->ifname, vlan->ifname, NETDEVIF(vlan), NULL);
r = netdev_join(vlan, link, &netdev_join_handler);
if (r < 0) {
@ -1884,7 +1884,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, vlan->ifname, strerror(-r),
NETDEV(vlan), NULL);
NETDEVIF(vlan), NULL);
link_enter_failed(link);
return r;
}
@ -1896,7 +1896,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
link->ifname, macvlan->ifname, NETDEVIF(macvlan), NULL);
r = netdev_join(macvlan, link, &netdev_join_handler);
if (r < 0) {
@ -1904,7 +1904,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, macvlan->ifname, strerror(-r),
NETDEV(macvlan), NULL);
NETDEVIF(macvlan), NULL);
link_enter_failed(link);
return r;
}
@ -1916,7 +1916,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
link->ifname, vxlan->ifname, NETDEVIF(vxlan), NULL);
r = netdev_join(vxlan, link, &netdev_join_handler);
if (r < 0) {
@ -1924,7 +1924,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, vxlan->ifname, strerror(-r),
NETDEV(vxlan), NULL);
NETDEVIF(vxlan), NULL);
link_enter_failed(link);
return r;
}

View File

@ -63,49 +63,18 @@ static uint8_t bond_mode_to_kernel(BondMode mode) {
}
}
static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Bond *b = BOND(netdev);
int r;
assert(netdev);
assert(!link);
assert(b);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
if (netdev->bond_mode != _NETDEV_BOND_MODE_INVALID) {
if (b->mode != _NETDEV_BOND_MODE_INVALID) {
r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE,
bond_mode_to_kernel(netdev->bond_mode));
bond_mode_to_kernel(b->mode));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_BOND_MODE attribute: %s",
@ -114,26 +83,22 @@ static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
}
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return 0;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
static void bond_init(NetDev *netdev) {
Bond *b = BOND(netdev);
return r;
assert(netdev);
assert(b);
b->mode = _NETDEV_BOND_MODE_INVALID;
}
const NetDevVTable bond_vtable = {
.object_size = sizeof(Bond),
.init = bond_init,
.sections = "Match\0NetDev\0Bond\0",
.fill_message_create = netdev_bond_fill_message_create,
.enslave = netdev_enslave,
.create_type = NETDEV_CREATE_MASTER,
};

View File

@ -21,9 +21,9 @@
#pragma once
#include "networkd-netdev.h"
typedef struct Bond Bond;
extern const NetDevVTable bond_vtable;
#include "networkd-netdev.h"
typedef enum BondMode {
NETDEV_BOND_MODE_BALANCE_RR,
@ -37,6 +37,14 @@ typedef enum BondMode {
_NETDEV_BOND_MODE_INVALID = -1
} BondMode;
struct Bond {
NetDev meta;
BondMode mode;
};
extern const NetDevVTable bond_vtable;
const char *bond_mode_to_string(BondMode d) _const_;
BondMode bond_mode_from_string(const char *d) _pure_;

View File

@ -28,67 +28,8 @@
#include "networkd-netdev-bridge.h"
#include "missing.h"
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);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
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",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
const NetDevVTable bridge_vtable = {
.fill_message_create = netdev_bridge_fill_message_create,
.enslave = netdev_enslave,
.object_size = sizeof(Bridge),
.sections = "Match\0NetDev\0",
.create_type = NETDEV_CREATE_MASTER,
};

View File

@ -21,6 +21,12 @@
#pragma once
typedef struct Bridge Bridge;
#include "networkd-netdev.h"
struct Bridge {
NetDev meta;
};
extern const NetDevVTable bridge_vtable;

View File

@ -28,58 +28,8 @@
#include "sd-rtnl.h"
#include "networkd-netdev-dummy.h"
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);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
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",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
const NetDevVTable dummy_vtable = {
.fill_message_create = netdev_dummy_fill_message_create,
.object_size = sizeof(Dummy),
.sections = "Match\0NetDev\0",
.create_type = NETDEV_CREATE_INDEPENDENT,
};

View File

@ -21,6 +21,12 @@
#pragma once
typedef struct Dummy Dummy;
#include "networkd-netdev.h"
struct Dummy {
NetDev meta;
};
extern const NetDevVTable dummy_vtable;

View File

@ -27,28 +27,28 @@ NetDev.Name, config_parse_ifname, 0,
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
VLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vlanid)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(NetDev, macvlan_mode)
Tunnel.Local, config_parse_tunnel_address, 0, offsetof(NetDev, local)
Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(NetDev, remote)
Tunnel.TOS, config_parse_unsigned, 0, offsetof(NetDev, tos)
Tunnel.TTL, config_parse_unsigned, 0, offsetof(NetDev, ttl)
Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(NetDev, tunnel_pmtudisc)
Peer.Name, config_parse_ifname, 0, offsetof(NetDev, ifname_peer)
Peer.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac_peer)
VXLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vxlanid)
VXLAN.Group, config_parse_tunnel_address, 0, offsetof(NetDev, group)
VXLAN.TOS, config_parse_unsigned, 0, offsetof(NetDev, tos)
VXLAN.TTL, config_parse_unsigned, 0, offsetof(NetDev, ttl)
VXLAN.MacLearning, config_parse_bool, 0, offsetof(NetDev, learning)
Tun.OneQueue, config_parse_bool, 0, offsetof(NetDev, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(NetDev, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(NetDev, packet_info)
Tun.User, config_parse_string, 0, offsetof(NetDev, user_name)
Tun.Group, config_parse_string, 0, offsetof(NetDev, group_name)
Tap.OneQueue, config_parse_bool, 0, offsetof(NetDev, one_queue)
Tap.MultiQueue, config_parse_bool, 0, offsetof(NetDev, multi_queue)
Tap.PacketInfo, config_parse_bool, 0, offsetof(NetDev, packet_info)
Tap.User, config_parse_string, 0, offsetof(NetDev, user_name)
Tap.Group, config_parse_string, 0, offsetof(NetDev, group_name)
Bond.Mode, config_parse_bond_mode, 0, offsetof(NetDev, bond_mode)
VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
VXLAN.Group, config_parse_tunnel_address, 0, offsetof(VxLan, group)
VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)

View File

@ -37,67 +37,16 @@ DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
MacVlan *m = MACVLAN(netdev);
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_MACVLAN);
assert(m);
assert(link);
assert(netdev->ifname);
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,
"Could not append IFLA_IFNAME attribute: %s",
strerror(-r));
return r;
}
if (netdev->mtu) {
r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not open IFLA_LINKINFO container: %s",
strerror(-r));
return r;
}
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",
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 (m->mode != _NETDEV_MACVLAN_MODE_INVALID) {
r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MACVLAN_MODE attribute: %s",
@ -106,25 +55,22 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtn
}
}
r = sd_rtnl_message_close_container(req);
if (r < 0) {
log_error_netdev(netdev,
"Could not close IFLA_INFO_DATA container %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(req);
if (r < 0) {
log_error_netdev(netdev,
"Could not close IFLA_LINKINFO container %s",
strerror(-r));
return r;
}
return 0;
}
static void macvlan_init(NetDev *n) {
MacVlan *m = MACVLAN(n);
assert(n);
assert(m);
m->mode = _NETDEV_MACVLAN_MODE_INVALID;
}
const NetDevVTable macvlan_vtable = {
.fill_message_create_on_link = netdev_macvlan_fill_message_create,
.object_size = sizeof(MacVlan),
.init = macvlan_init,
.sections = "Match\0NetDev\0MACVLAN\0",
.fill_message_create = netdev_macvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
};

View File

@ -21,9 +21,9 @@
#pragma once
#include "networkd-netdev.h"
typedef struct MacVlan MacVlan;
extern const NetDevVTable macvlan_vtable;
#include "networkd-netdev.h"
typedef enum MacVlanMode {
NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE,
@ -34,6 +34,14 @@ typedef enum MacVlanMode {
_NETDEV_MACVLAN_MODE_INVALID = -1
} MacVlanMode;
struct MacVlan {
NetDev meta;
MacVlanMode mode;
};
extern const NetDevVTable macvlan_vtable;
const char *macvlan_mode_to_string(MacVlanMode d) _const_;
MacVlanMode macvlan_mode_from_string(const char *d) _pure_;

View File

@ -33,61 +33,14 @@
#include "conf-parser.h"
static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Tunnel *t = IPIP(netdev);
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_IPIP);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(m);
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if(netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
assert(t);
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0) {
@ -97,7 +50,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@ -105,7 +58,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@ -113,7 +66,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_TTL attribute: %s",
@ -121,81 +74,18 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Tunnel *t = SIT(netdev);
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_SIT);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(m);
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if(netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
assert(t);
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0) {
@ -205,7 +95,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@ -213,7 +103,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@ -221,7 +111,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_TTL attribute: %s",
@ -229,81 +119,18 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Tunnel *t = GRE(netdev);
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_GRE);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(m);
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if(netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
assert(t);
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
if (r < 0) {
@ -313,7 +140,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_LOCAL attribute: %s",
@ -321,7 +148,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_REMOTE attribute: %s",
@ -329,7 +156,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_TTL attribute: %s",
@ -337,7 +164,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_TOS attribute: %s",
@ -345,81 +172,18 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Tunnel *t = VTI(netdev);
int r;
assert(netdev);
assert(netdev->kind == NETDEV_KIND_VTI);
assert(netdev->ifname);
assert(netdev->manager);
assert(netdev->manager->rtnl);
assert(link);
assert(m);
assert(netdev->family == AF_INET);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if(netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
assert(t);
assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
if (r < 0) {
@ -429,7 +193,7 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@ -437,7 +201,7 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@ -445,40 +209,45 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
Tunnel *t = NULL;
assert(netdev);
assert(filename);
if (netdev->local.in.s_addr == INADDR_ANY) {
switch (netdev->kind) {
case NETDEV_KIND_IPIP:
t = IPIP(netdev);
break;
case NETDEV_KIND_SIT:
t = SIT(netdev);
break;
case NETDEV_KIND_GRE:
t = GRE(netdev);
break;
case NETDEV_KIND_VTI:
t = VTI(netdev);
break;
default:
assert_not_reached("Invalid tunnel kind");
}
assert(t);
if (t->local.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without local address configured in %s. Ignoring", filename);
return -EINVAL;
}
if (netdev->remote.in.s_addr == INADDR_ANY) {
if (t->remote.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
return -EINVAL;
}
if (netdev->family != AF_INET) {
if (t->family != AF_INET) {
log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
return -EINVAL;
}
@ -496,7 +265,7 @@ int config_parse_tunnel_address(const char *unit,
const char *rvalue,
void *data,
void *userdata) {
NetDev *n = userdata;
Tunnel *t = userdata;
union in_addr_union *addr = data;
int r;
@ -505,7 +274,7 @@ int config_parse_tunnel_address(const char *unit,
assert(rvalue);
assert(data);
r = net_parse_inaddr(rvalue, &n->family, addr);
r = net_parse_inaddr(rvalue, &t->family, addr);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Tunnel address is invalid, ignoring assignment: %s", rvalue);
@ -515,22 +284,74 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
static void ipip_init(NetDev *n) {
Tunnel *t = IPIP(n);
assert(n);
assert(t);
t->pmtudisc = true;
}
static void sit_init(NetDev *n) {
Tunnel *t = SIT(n);
assert(n);
assert(t);
t->pmtudisc = true;
}
static void vti_init(NetDev *n) {
Tunnel *t = VTI(n);
assert(n);
assert(t);
t->pmtudisc = true;
}
static void gre_init(NetDev *n) {
Tunnel *t = GRE(n);
assert(n);
assert(t);
t->pmtudisc = true;
}
const NetDevVTable ipip_vtable = {
.fill_message_create_on_link = netdev_ipip_fill_message_create,
.object_size = sizeof(Tunnel),
.init = ipip_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_ipip_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable sit_vtable = {
.fill_message_create_on_link = netdev_sit_fill_message_create,
.object_size = sizeof(Tunnel),
.init = sit_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_sit_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable vti_vtable = {
.fill_message_create_on_link = netdev_vti_fill_message_create,
.object_size = sizeof(Tunnel),
.init = vti_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_vti_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable gre_vtable = {
.fill_message_create_on_link = netdev_gre_fill_message_create,
.object_size = sizeof(Tunnel),
.init = gre_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_gre_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};

View File

@ -21,8 +21,22 @@
#pragma once
typedef struct Tunnel Tunnel;
#include "networkd-netdev.h"
struct Tunnel {
NetDev meta;
int family;
unsigned ttl;
unsigned tos;
union in_addr_union local;
union in_addr_union remote;
bool pmtudisc;
};
extern const NetDevVTable ipip_vtable;
extern const NetDevVTable sit_vtable;
extern const NetDevVTable vti_vtable;

View File

@ -28,24 +28,27 @@
#define TUN_DEV "/dev/net/tun"
static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
TunTap *t;
assert(netdev);
assert(netdev->ifname);
assert(ifr);
memset(ifr, 0, sizeof(*ifr));
if (netdev->kind == NETDEV_KIND_TAP)
if (netdev->kind == NETDEV_KIND_TAP) {
t = TAP(netdev);
ifr->ifr_flags |= IFF_TAP;
else
} else {
t = TUN(netdev);
ifr->ifr_flags |= IFF_TUN;
}
if (!netdev->packet_info)
if (!t->packet_info)
ifr->ifr_flags |= IFF_NO_PI;
if (netdev->one_queue)
if (t->one_queue)
ifr->ifr_flags |= IFF_ONE_QUEUE;
if (netdev->multi_queue)
if (t->multi_queue)
ifr->ifr_flags |= IFF_MULTI_QUEUE;
strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
@ -55,12 +58,16 @@ static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
_cleanup_close_ int fd;
TunTap *t = NULL;
const char *user;
const char *group;
uid_t uid;
gid_t gid;
int r = 0;
assert(netdev);
assert(ifr);
fd = open(TUN_DEV, O_RDWR);
if (fd < 0) {
log_error_netdev(netdev,
@ -77,14 +84,21 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return r;
}
if(netdev->user_name) {
if (netdev->kind == NETDEV_KIND_TAP)
t = TAP(netdev);
else
t = TUN(netdev);
user = netdev->user_name;
assert(t);
if(t->user_name) {
user = t->user_name;
r = get_user_creds(&user, &uid, NULL, NULL, NULL);
if (r < 0) {
log_error("Cannot resolve user name %s: %s",
netdev->user_name, strerror(-r));
t->user_name, strerror(-r));
return 0;
}
@ -96,14 +110,14 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
}
if(netdev->group_name) {
if(t->group_name) {
group = netdev->group_name;
group = t->group_name;
r = get_group_creds(&group, &gid);
if (r < 0) {
log_error("Cannot resolve group name %s: %s",
netdev->group_name, strerror(-r));
t->group_name, strerror(-r));
return 0;
}
@ -129,34 +143,47 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
static int netdev_create_tuntap(NetDev *netdev) {
struct ifreq ifr;
struct ifreq ifr = {};
int r;
assert(netdev);
assert(netdev->ifname);
switch(netdev->kind) {
case NETDEV_KIND_TUN:
case NETDEV_KIND_TAP:
break;
default:
return -ENOTSUP;
}
r = netdev_fill_tuntap_message(netdev, &ifr);
if(r < 0)
return r;
log_debug_netdev(netdev, "Creating tuntap netdev: %s",
netdev_kind_to_string(netdev->kind));
return netdev_tuntap_add(netdev, &ifr);
}
static void tuntap_done(NetDev *netdev) {
TunTap *t = NULL;
assert(netdev);
if (netdev->kind == NETDEV_KIND_TUN)
t = TUN(netdev);
else
t = TAP(netdev);
assert(t);
free(t->user_name);
t->user_name = NULL;
free(t->group_name);
t->group_name = NULL;
}
const NetDevVTable tun_vtable = {
.object_size = sizeof(TunTap),
.sections = "Match\0NetDev\0Tun\0",
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
};
const NetDevVTable tap_vtable = {
.object_size = sizeof(TunTap),
.sections = "Match\0NetDev\0Tap\0",
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
};

View File

@ -21,7 +21,19 @@
#pragma once
typedef struct TunTap TunTap;
#include "networkd-netdev.h"
struct TunTap {
NetDev meta;
char *user_name;
char *group_name;
bool one_queue;
bool multi_queue;
bool packet_info;
};
extern const NetDevVTable tun_vtable;
extern const NetDevVTable tap_vtable;

View File

@ -27,47 +27,15 @@
#include "sd-rtnl.h"
#include "networkd-netdev-veth.h"
static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
Veth *v = VETH(netdev);
int r;
assert(netdev);
assert(netdev->ifname);
assert(!link);
assert(v);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
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",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container(m, VETH_INFO_PEER);
if (r < 0) {
log_error_netdev(netdev,
@ -76,16 +44,16 @@ static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
if (netdev->ifname_peer) {
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname_peer);
if (v->ifname_peer) {
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
if (r < 0) {
log_error("Failed to add netlink interface name: %s", strerror(-r));
return r;
}
}
if (netdev->mac_peer) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac_peer);
if (v->mac_peer) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
@ -102,34 +70,28 @@ static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_veth_verify(NetDev *netdev, const char *filename) {
Veth *v = VETH(netdev);
int r;
assert(netdev);
assert(v);
assert(filename);
if (!netdev->ifname_peer) {
if (!v->ifname_peer) {
log_warning("Veth NetDev without peer name configured in %s. Ignoring",
filename);
return -EINVAL;
}
if (!netdev->mac_peer) {
r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
if (!v->mac_peer) {
r = netdev_get_mac(v->ifname_peer, &v->mac_peer);
if (r < 0) {
log_warning("Failed to generate predictable MAC address for %s. Ignoring",
netdev->ifname_peer);
v->ifname_peer);
return -EINVAL;
}
}
@ -137,7 +99,21 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) {
return 0;
}
static void veth_done(NetDev *n) {
Veth *v = VETH(n);
assert(n);
assert(v);
free(v->ifname_peer);
free(v->mac_peer);
}
const NetDevVTable veth_vtable = {
.object_size = sizeof(Veth),
.sections = "Match\0NetDev\0Peer\0",
.done = veth_done,
.fill_message_create = netdev_veth_fill_message_create,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_veth_verify,
};

View File

@ -21,6 +21,15 @@
#pragma once
typedef struct Veth Veth;
#include "networkd-netdev.h"
struct Veth {
NetDev meta;
char *ifname_peer;
struct ether_addr *mac_peer;
};
extern const NetDevVTable veth_vtable;

View File

@ -26,68 +26,16 @@
#include "list.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
VLan *v = VLAN(netdev);
int r;
assert(netdev);
assert(netdev->ifname);
assert(netdev->kind == NETDEV_KIND_VLAN);
assert(v);
assert(link);
assert(req);
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,
"Could not append IFLA_IFNAME attribute: %s",
strerror(-r));
return r;
}
if (netdev->mtu) {
r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not open IFLA_LINKINFO container: %s",
strerror(-r));
return r;
}
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",
strerror(-r));
return r;
}
if (netdev->vlanid <= VLANID_MAX) {
r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
if (v->id <= VLANID_MAX) {
r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, v->id);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VLAN_ID attribute: %s",
@ -96,38 +44,38 @@ static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
}
}
r = sd_rtnl_message_close_container(req);
if (r < 0) {
log_error_netdev(netdev,
"Could not close IFLA_INFO_DATA container %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(req);
if (r < 0) {
log_error_netdev(netdev,
"Could not close IFLA_LINKINFO container %s",
strerror(-r));
return r;
}
return 0;
}
static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
VLan *v = VLAN(netdev);
assert(netdev);
assert(v);
assert(filename);
if (netdev->vlanid > VLANID_MAX) {
log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
if (v->id > VLANID_MAX) {
log_warning("VLAN without valid Id (%"PRIu64") configured in %s. Ignoring", v->id, filename);
return -EINVAL;
}
return 0;
}
static void vlan_init(NetDev *netdev) {
VLan *v = VLAN(netdev);
assert(netdev);
assert(v);
v->id = VLANID_MAX + 1;
}
const NetDevVTable vlan_vtable = {
.fill_message_create_on_link = netdev_vlan_fill_message_create,
.object_size = sizeof(VLan),
.init = vlan_init,
.sections = "Match\0NetDev\0VLAN\0",
.fill_message_create = netdev_vlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vlan_verify,
};

View File

@ -21,8 +21,16 @@
#pragma once
typedef struct VLan VLan;
#include "networkd-netdev.h"
#define VLANID_MAX 4094
struct VLan {
NetDev meta;
uint64_t id;
};
extern const NetDevVTable vlan_vtable;

View File

@ -28,39 +28,17 @@
#include "missing.h"
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
VxLan *v = VXLAN(netdev);
int r;
assert(netdev);
assert(v);
assert(link);
assert(link->ifname);
assert(m);
r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
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",
strerror(-r));
return r;
}
if (netdev->vlanid <= VXLAN_VID_MAX) {
r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, netdev->vxlanid);
if (v->id <= VXLAN_VID_MAX) {
r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_ID attribute: %s",
@ -69,7 +47,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &netdev->group.in);
r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_GROUP attribute: %s",
@ -85,8 +63,8 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
return r;
}
if(netdev->ttl) {
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, netdev->ttl);
if(v->ttl) {
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_TTL attribute: %s",
@ -95,8 +73,8 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
if(netdev->tos) {
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, netdev->tos);
if(v->tos) {
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_TOS attribute: %s",
@ -105,7 +83,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, netdev->learning);
r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_LEARNING attribute: %s",
@ -113,22 +91,17 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
return r;
}
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
VxLan *v = VXLAN(netdev);
assert(netdev);
assert(v);
assert(filename);
if (netdev->vxlanid > VXLAN_VID_MAX) {
if (v->id > VXLAN_VID_MAX) {
log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
return -EINVAL;
}
@ -136,7 +109,21 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
return 0;
}
static void vxlan_init(NetDev *netdev) {
VxLan *v = VXLAN(netdev);
assert(netdev);
assert(v);
v->id = VXLAN_VID_MAX + 1;
v->learning = true;
}
const NetDevVTable vxlan_vtable = {
.fill_message_create_on_link = netdev_vxlan_fill_message_create,
.object_size = sizeof(VxLan),
.init = vxlan_init,
.sections = "Match\0NetDev\0VXLAN\0",
.fill_message_create = netdev_vxlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vxlan_verify,
};

View File

@ -21,8 +21,22 @@
#pragma once
typedef struct VxLan VxLan;
#include "networkd-netdev.h"
#include "in-addr-util.h"
#define VXLAN_VID_MAX (1u << 24) - 1
struct VxLan {
NetDev meta;
uint64_t id;
union in_addr_union group;
unsigned tos;
unsigned ttl;
bool learning;
};
extern const NetDevVTable vxlan_vtable;

View File

@ -22,15 +22,6 @@
#include <net/if.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"
@ -111,17 +102,17 @@ static void netdev_free(NetDev *netdev) {
free(netdev->description);
free(netdev->ifname);
free(netdev->ifname_peer);
free(netdev->mac);
free(netdev->mac_peer);
free(netdev->user_name);
free(netdev->group_name);
condition_free_list(netdev->match_host);
condition_free_list(netdev->match_virt);
condition_free_list(netdev->match_kernel);
condition_free_list(netdev->match_arch);
if (NETDEV_VTABLE(netdev) &&
NETDEV_VTABLE(netdev)->done)
NETDEV_VTABLE(netdev)->done(netdev);
free(netdev);
}
@ -268,6 +259,8 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
return 1;
}
log_debug_netdev(netdev, "created");
return 1;
}
@ -294,50 +287,14 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac
link_ref(link);
LIST_PREPEND(callbacks, netdev->callbacks, cb);
log_debug_netdev(netdev, "will enslave '%s', when reday",
link->ifname);
}
return 0;
}
/* 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));
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;
}
int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
uint16_t type;
const char *kind;
@ -487,8 +444,156 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
return 0;
}
static int netdev_create(NetDev *netdev, Link *link) {
int r;
assert(netdev);
/* create netdev */
if (NETDEV_VTABLE(netdev)->create) {
r = NETDEV_VTABLE(netdev)->create(netdev);
if (r < 0)
return r;
log_debug_netdev(netdev, "created");
} else {
_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 = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IFNAME, attribute: %s",
strerror(-r));
return r;
}
if (netdev->mac) {
r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
strerror(-r));
return r;
}
}
if (netdev->mtu) {
r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MTU attribute: %s",
strerror(-r));
return r;
}
}
if (link) {
r = sd_rtnl_message_append_u32(m, IFLA_LINK, link->ifindex);
if (r < 0) {
log_error_netdev(netdev,
"Colud not append IFLA_LINK attribute: %s",
strerror(-r));
return r;
}
}
r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
netdev_kind_to_string(netdev->kind));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_INFO_DATA attribute: %s",
strerror(-r));
return r;
}
if (NETDEV_VTABLE(netdev)->fill_message_create) {
r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
if (r < 0)
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
return r;
}
r = sd_rtnl_message_close_container(m);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_LINKINFO attribute: %s",
strerror(-r));
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);
netdev->state = NETDEV_STATE_CREATING;
log_debug_netdev(netdev, "creating");
}
return 0;
}
/* 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_VTABLE(netdev)->create_type) {
case NETDEV_CREATE_MASTER:
r = netdev_enslave(netdev, link, callback);
if (r < 0)
return r;
break;
case NETDEV_CREATE_STACKED:
r = netdev_create(netdev, link);
if (r < 0)
return r;
break;
default:
assert_not_reached("Can not join independent netdev");
}
return 0;
}
static int netdev_load_one(Manager *manager, const char *filename) {
_cleanup_netdev_unref_ NetDev *netdev = NULL;
_cleanup_free_ NetDev *netdev_raw = NULL;
_cleanup_fclose_ FILE *file = NULL;
int r;
@ -508,40 +613,60 @@ static int netdev_load_one(Manager *manager, const char *filename) {
return 0;
}
netdev = new0(NetDev, 1);
netdev_raw = new0(NetDev, 1);
if (!netdev_raw)
return log_oom();
netdev_raw->kind = _NETDEV_KIND_INVALID;
r = config_parse(NULL, filename, file,
"Match\0NetDev\0",
config_item_perf_lookup, network_netdev_gperf_lookup,
true, false, true, netdev_raw);
if (r < 0)
return r;
r = fseek(file, 0, SEEK_SET);
if (r < 0)
return -errno;
/* skip out early if configuration does not match the environment */
if (net_match_config(NULL, NULL, NULL, NULL, NULL,
netdev_raw->match_host, netdev_raw->match_virt,
netdev_raw->match_kernel, netdev_raw->match_arch,
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
if (!NETDEV_VTABLE(netdev_raw)) {
log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
return 0;
}
if (!netdev_raw->ifname) {
log_warning("NetDev without Name configured in %s. Ignoring", filename);
return 0;
}
netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
if (!netdev)
return log_oom();
netdev->n_ref = 1;
netdev->manager = manager;
netdev->state = _NETDEV_STATE_INVALID;
netdev->kind = _NETDEV_KIND_INVALID;
netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
netdev->bond_mode = _NETDEV_BOND_MODE_INVALID;
netdev->vlanid = VLANID_MAX + 1;
netdev->vxlanid = VXLAN_VID_MAX + 1;
netdev->tunnel_pmtudisc = true;
netdev->learning = true;
netdev->kind = netdev_raw->kind;
netdev->ifname = netdev_raw->ifname;
if (NETDEV_VTABLE(netdev)->init)
NETDEV_VTABLE(netdev)->init(netdev);
r = config_parse(NULL, filename, file,
"Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0Bond\0",
NETDEV_VTABLE(netdev)->sections,
config_item_perf_lookup, network_netdev_gperf_lookup,
false, false, true, netdev);
false, false, false, netdev);
if (r < 0)
return r;
/* skip out early if configuration does not match the environment */
if (net_match_config(NULL, NULL, NULL, NULL, NULL,
netdev->match_host, netdev->match_virt,
netdev->match_kernel, netdev->match_arch,
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
if (!NETDEV_VTABLE(netdev)) {
log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
return 0;
}
/* verify configuration */
if (NETDEV_VTABLE(netdev)->config_verify) {
r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
@ -549,30 +674,6 @@ static int netdev_load_one(Manager *manager, const char *filename) {
return 0;
}
if (!netdev->ifname) {
log_warning("NetDev without Name configured in %s. Ignoring", filename);
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_VXLAN && netdev->vxlanid <= VXLAN_VID_MAX) {
log_warning("VXLAN 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);
if (!netdev->filename)
return log_oom();
@ -594,38 +695,16 @@ static int netdev_load_one(Manager *manager, const char *filename) {
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);
switch (NETDEV_VTABLE(netdev)->create_type) {
case NETDEV_CREATE_MASTER:
case NETDEV_CREATE_INDEPENDENT:
r = netdev_create(netdev, NULL);
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;
break;
default:
break;
}
netdev = NULL;

View File

@ -66,6 +66,14 @@ typedef enum NetDevState {
_NETDEV_STATE_INVALID = -1,
} NetDevState;
typedef enum NetDevCreateType {
NETDEV_CREATE_INDEPENDENT,
NETDEV_CREATE_MASTER,
NETDEV_CREATE_STACKED,
_NETDEV_CREATE_MAX,
_NETDEV_CREATE_INVALID = -1,
} NetDevCreateType;
struct NetDev {
Manager *manager;
@ -78,49 +86,50 @@ struct NetDev {
Condition *match_kernel;
Condition *match_arch;
NetDevState state;
NetDevKind kind;
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;
size_t mtu;
int ifindex;
NetDevState state;
bool tunnel_pmtudisc;
bool learning;
bool one_queue;
bool multi_queue;
bool packet_info;
unsigned ttl;
unsigned tos;
int family;
union in_addr_union local;
union in_addr_union remote;
union in_addr_union group;
LIST_HEAD(netdev_join_callback, callbacks);
};
#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-veth.h"
#include "networkd-netdev-tunnel.h"
#include "networkd-netdev-dummy.h"
#include "networkd-netdev-tuntap.h"
struct NetDevVTable {
/* How much memory does an object of this unit type need */
size_t object_size;
/* Config file sections this netdev kind understands, separated
* by NUL chars */
const char *sections;
/* This should reset all type-specific variables. This should
* not allocate memory, and is called with zero-initialized
* data. It should hence only initialize variables that need
* to be set != 0. */
void (*init)(NetDev *n);
/* This should free all kind-specific variables. It should be
* idempotent. */
void (*done)(NetDev *n);
/* fill in message to create netdev */
int (*fill_message_create)(NetDev *netdev, sd_rtnl_message *message);
int (*fill_message_create)(NetDev *netdev, Link *link, 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);
/* specifies if netdev is independent, or a master device or a stacked device */
NetDevCreateType create_type;
/* create netdev, if not done via rtnl */
int (*create)(NetDev *netdev);
@ -133,6 +142,32 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
/* For casting a netdev into the various netdev kinds */
#define DEFINE_CAST(UPPERCASE, MixedCase) \
static inline MixedCase* UPPERCASE(NetDev *n) { \
if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \
return NULL; \
\
return (MixedCase*) n; \
}
/* For casting the various netdev kinds into a netdev */
#define NETDEV(n) (&(n)->meta)
DEFINE_CAST(BRIDGE, Bridge);
DEFINE_CAST(BOND, Bond);
DEFINE_CAST(VLAN, VLan);
DEFINE_CAST(MACVLAN, MacVlan);
DEFINE_CAST(VXLAN, VxLan);
DEFINE_CAST(IPIP, Tunnel);
DEFINE_CAST(GRE, Tunnel);
DEFINE_CAST(SIT, Tunnel);
DEFINE_CAST(VTI, Tunnel);
DEFINE_CAST(VETH, Veth);
DEFINE_CAST(DUMMY, Dummy);
DEFINE_CAST(TUN, TunTap);
DEFINE_CAST(TAP, TunTap);
int netdev_load(Manager *manager);
void netdev_drop(NetDev *netdev);
@ -167,4 +202,4 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign
#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname
#define NETDEVIF(netdev) "INTERFACE=%s", netdev->ifname

View File

@ -66,11 +66,11 @@ static int network_load_one(Manager *manager, const char *filename) {
if (!network->vlans)
return log_oom();
network->macvlans = hashmap_new(uint64_hash_func, uint64_compare_func);
network->macvlans = hashmap_new(string_hash_func, string_compare_func);
if (!network->macvlans)
return log_oom();
network->vxlans = hashmap_new(uint64_hash_func, uint64_compare_func);
network->vxlans = hashmap_new(string_hash_func, string_compare_func);
if (!network->vxlans)
return log_oom();
@ -323,10 +323,11 @@ int config_parse_netdev(const char *unit,
break;
case NETDEV_KIND_VLAN:
r = hashmap_put(network->vlans, &netdev->vlanid, netdev);
r = hashmap_put(network->vlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Can not add VLAN to network: %s", rvalue);
"Can not add VLAN '%s' to network: %s",
rvalue, strerror(-r));
return 0;
}
@ -335,7 +336,8 @@ int config_parse_netdev(const char *unit,
r = hashmap_put(network->macvlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Can not add MACVLAN to network: %s", rvalue);
"Can not add MACVLAN '%s' to network: %s",
rvalue, strerror(-r));
return 0;
}
@ -344,7 +346,8 @@ int config_parse_netdev(const char *unit,
r = hashmap_put(network->vxlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Can not add VXLAN to network: %s", rvalue);
"Can not add VXLAN '%s' to network: %s",
rvalue, strerror(-r));
return 0;
}