networkd: netdev - split NetDev struct into per-kind structs
Similarly to how unit types work.
This commit is contained in:
parent
653912918f
commit
aa9f114058
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef struct Bridge Bridge;
|
||||
|
||||
#include "networkd-netdev.h"
|
||||
|
||||
struct Bridge {
|
||||
NetDev meta;
|
||||
};
|
||||
|
||||
extern const NetDevVTable bridge_vtable;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef struct Dummy Dummy;
|
||||
|
||||
#include "networkd-netdev.h"
|
||||
|
||||
struct Dummy {
|
||||
NetDev meta;
|
||||
};
|
||||
|
||||
extern const NetDevVTable dummy_vtable;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue