/* SPDX-License-Identifier: LGPL-2.1+ */
#include <net/if.h>
+#include <netinet/in.h>
#include "alloc-util.h"
#include "conf-files.h"
#include "netdev/geneve.h"
#include "netdev/ipvlan.h"
#include "netdev/l2tp-tunnel.h"
+#include "netdev/macsec.h"
#include "netdev/macvlan.h"
#include "netdev/netdev.h"
#include "netdev/netdevsim.h"
+#include "netdev/nlmon.h"
#include "netdev/tunnel.h"
#include "netdev/tuntap.h"
#include "netdev/vcan.h"
[NETDEV_KIND_MACVLAN] = &macvlan_vtable,
[NETDEV_KIND_MACVTAP] = &macvtap_vtable,
[NETDEV_KIND_IPVLAN] = &ipvlan_vtable,
+ [NETDEV_KIND_IPVTAP] = &ipvtap_vtable,
[NETDEV_KIND_VXLAN] = &vxlan_vtable,
[NETDEV_KIND_IPIP] = &ipip_vtable,
[NETDEV_KIND_GRE] = &gre_vtable,
[NETDEV_KIND_FOU] = &foutnl_vtable,
[NETDEV_KIND_ERSPAN] = &erspan_vtable,
[NETDEV_KIND_L2TP] = &l2tptnl_vtable,
+ [NETDEV_KIND_MACSEC] = &macsec_vtable,
+ [NETDEV_KIND_NLMON] = &nlmon_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_MACVLAN] = "macvlan",
[NETDEV_KIND_MACVTAP] = "macvtap",
[NETDEV_KIND_IPVLAN] = "ipvlan",
+ [NETDEV_KIND_IPVTAP] = "ipvtap",
[NETDEV_KIND_VXLAN] = "vxlan",
[NETDEV_KIND_IPIP] = "ipip",
[NETDEV_KIND_GRE] = "gre",
[NETDEV_KIND_FOU] = "fou",
[NETDEV_KIND_ERSPAN] = "erspan",
[NETDEV_KIND_L2TP] = "l2tp",
+ [NETDEV_KIND_MACSEC] = "macsec",
+ [NETDEV_KIND_NLMON] = "nlmon",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
if (link->flags & IFF_UP && netdev->kind == NETDEV_KIND_BOND) {
log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname);
- r = link_down(link);
+ r = link_down(link, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not bring link down: %m");
}
}
if (netdev_raw->kind == _NETDEV_KIND_INVALID) {
- log_warning("NetDev has no Kind configured in %s. Ignoring", filename);
+ log_warning("NetDev has no Kind= configured in %s. Ignoring", filename);
return 0;
}
if (!netdev_raw->ifname) {
- log_warning("NetDev without Name configured in %s. Ignoring", filename);
+ log_warning("NetDev without Name= configured in %s. Ignoring", filename);
return 0;
}
netdev->n_ref = 1;
netdev->manager = manager;
netdev->kind = netdev_raw->kind;
- netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time, so that done() will be called on destruction */
+ netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time,
+ so that done() will be called on destruction */
if (NETDEV_VTABLE(netdev)->init)
NETDEV_VTABLE(netdev)->init(netdev);
if (!netdev->filename)
return log_oom();
- if (!netdev->mac && netdev->kind != NETDEV_KIND_VLAN) {
+ if (!netdev->mac && NETDEV_VTABLE(netdev)->generate_mac) {
r = netdev_get_mac(netdev->ifname, &netdev->mac);
if (r < 0)
- return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname);
+ return log_netdev_error_errno(netdev, r,
+ "Failed to generate predictable MAC address for %s: %m",
+ netdev->ifname);
}
r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops);
return r;
r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
+ if (r == -EEXIST) {
+ NetDev *n = hashmap_get(netdev->manager->netdevs, netdev->ifname);
+
+ assert(n);
+ log_netdev_warning_errno(netdev, r,
+ "The setting Name=%s in %s conflicts with the one in %s, ignoring",
+ netdev->ifname, netdev->filename, n->filename);
+
+ /* Clear ifname before netdev_free() is called. Otherwise, the NetDev object 'n' is
+ * removed from the hashmap 'manager->netdevs'. */
+ netdev->ifname = mfree(netdev->ifname);
+ return 0;
+ }
if (r < 0)
return r;
case NETDEV_KIND_IP6TNL:
independent = IP6TNL(netdev)->independent;
break;
+ case NETDEV_KIND_ERSPAN:
+ independent = ERSPAN(netdev)->independent;
+ break;
default:
break;
}
if (r < 0)
return log_error_errno(r, "Failed to enumerate netdev files: %m");
- STRV_FOREACH_BACKWARDS(f, files) {
+ STRV_FOREACH(f, files) {
r = netdev_load_one(manager, *f);
if (r < 0)
return r;