[NETDEV_KIND_VETH] = "veth",
[NETDEV_KIND_VTI] = "vti",
[NETDEV_KIND_DUMMY] = "dummy",
+ [NETDEV_KIND_TUN] = "tun",
+ [NETDEV_KIND_TAP] = "tap",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
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);
return r;
}
+ link_ref(link);
+
log_debug_netdev(netdev, "enslaving link '%s'", link->ifname);
return 0;
}
static int netdev_enter_ready(NetDev *netdev) {
- netdev_enslave_callback *callback;
+ netdev_enslave_callback *callback, *callback_next;
+ int r;
assert(netdev);
assert(netdev->ifname);
log_info_netdev(netdev, "netdev ready");
- LIST_FOREACH(callbacks, callback, netdev->callbacks) {
+ LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
/* enslave the links that were attempted to be enslaved before the
* link was ready */
- netdev_enslave_ready(netdev, callback->link, callback->callback);
+ r = netdev_enslave_ready(netdev, callback->link, callback->callback);
+ if (r < 0)
+ return r;
+
+ LIST_REMOVE(callbacks, netdev->callbacks, callback);
+ link_unref(callback->link);
+ free(callback);
}
return 0;
return 1;
}
-int config_parse_tunnel_address(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
- NetDev *n = data;
- unsigned char family = AF_INET;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = net_parse_inaddr(rvalue, &family, n);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Tunnel address is invalid, ignoring assignment: %s", rvalue);
- return 0;
- }
- return 0;
-}
-
static int netdev_create(NetDev *netdev) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
const char *kind;
cb->callback = callback;
cb->link = link;
+ link_ref(link);
LIST_PREPEND(callbacks, netdev->callbacks, cb);
}
return r;
}
- kind = netdev_kind_to_string(netdev->kind);
- if (!kind) {
- log_error_netdev(netdev, "Could not get kind");
- netdev_enter_failed(netdev);
- return -EINVAL;
+ if (netdev->kind == NETDEV_KIND_TAP)
+ /* the kernel does not distinguish between tun and tap */
+ kind = "tun";
+ else {
+ kind = netdev_kind_to_string(netdev->kind);
+ if (!kind) {
+ log_error_netdev(netdev, "Could not get kind");
+ netdev_enter_failed(netdev);
+ return -EINVAL;
+ }
}
if (!streq(kind, received_kind)) {
- log_error_netdev(netdev, "Received newlink with wrong KIND %s, "
+ log_error_netdev(netdev,
+ "Received newlink with wrong KIND %s, "
"expected %s", received_kind, kind);
netdev_enter_failed(netdev);
return r;
netdev->learning = true;
r = config_parse(NULL, filename, file,
- "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0",
+ "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0",
config_item_perf_lookup, (void*) network_netdev_gperf_lookup,
false, false, netdev);
if (r < 0) {
return r;
}
- if (netdev->kind == _NETDEV_KIND_INVALID) {
+ switch (netdev->kind) {
+ case _NETDEV_KIND_INVALID:
log_warning("NetDev without Kind configured in %s. Ignoring", filename);
return 0;
+ case NETDEV_KIND_VLAN:
+ if (netdev->vlanid > VLANID_MAX) {
+ log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
+ return 0;
+ }
+ break;
+ case NETDEV_KIND_VXLAN:
+ if (netdev->vxlanid > VXLAN_VID_MAX) {
+ log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
+ return 0;
+ }
+ break;
+ case NETDEV_KIND_IPIP:
+ case NETDEV_KIND_GRE:
+ case NETDEV_KIND_SIT:
+ case NETDEV_KIND_VTI:
+ if (netdev->local.in.s_addr == INADDR_ANY) {
+ log_warning("Tunnel without local address configured in %s. Ignoring", filename);
+ return 0;
+ }
+ if (netdev->remote.in.s_addr == INADDR_ANY) {
+ log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
+ return 0;
+ }
+ if (netdev->family != AF_INET) {
+ log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
+ return 0;
+ }
+ break;
+ default:
+ break;
}
if (!netdev->ifname) {
return 0;
}
- if (netdev->kind == NETDEV_KIND_VLAN && netdev->vlanid > VLANID_MAX) {
- log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
- return 0;
- }
-
- if (netdev->kind == NETDEV_KIND_VXLAN && netdev->vxlanid > VXLAN_VID_MAX) {
- log_warning("VXLAN without valid Id 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);
if (r < 0)
return r;
- netdev_ref(netdev);
-
break;
case NETDEV_KIND_BRIDGE:
case NETDEV_KIND_BOND:
if (r < 0)
return r;
break;
+
+ case NETDEV_KIND_TUN:
+ case NETDEV_KIND_TAP:
+ r = netdev_create_tuntap(netdev);
+ if (r < 0)
+ return r;
+ break;
+
default:
break;
}