1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "network-internal.h"
26 #include "path-util.h"
27 #include "conf-files.h"
28 #include "conf-parser.h"
30 #include "siphash24.h"
32 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
33 [NETDEV_KIND_BRIDGE] = "bridge",
34 [NETDEV_KIND_BOND] = "bond",
35 [NETDEV_KIND_VLAN] = "vlan",
36 [NETDEV_KIND_MACVLAN] = "macvlan",
37 [NETDEV_KIND_VXLAN] = "vxlan",
38 [NETDEV_KIND_IPIP] = "ipip",
39 [NETDEV_KIND_GRE] = "gre",
40 [NETDEV_KIND_SIT] = "sit",
41 [NETDEV_KIND_VETH] = "veth",
42 [NETDEV_KIND_VTI] = "vti",
43 [NETDEV_KIND_DUMMY] = "dummy",
44 [NETDEV_KIND_TUN] = "tun",
45 [NETDEV_KIND_TAP] = "tap",
48 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
49 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
52 static void netdev_cancel_callbacks(NetDev *netdev) {
53 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
54 netdev_enslave_callback *callback;
59 rtnl_message_new_synthetic_error(-ENODEV, 0, &m);
61 while ((callback = netdev->callbacks)) {
63 assert(callback->link);
64 assert(callback->callback);
65 assert(netdev->manager);
66 assert(netdev->manager->rtnl);
68 callback->callback(netdev->manager->rtnl, m, link);
71 LIST_REMOVE(callbacks, netdev->callbacks, callback);
76 static void netdev_free(NetDev *netdev) {
80 netdev_cancel_callbacks(netdev);
83 hashmap_remove(netdev->manager->netdevs, netdev->ifname);
85 free(netdev->filename);
87 free(netdev->description);
89 free(netdev->ifname_peer);
91 free(netdev->mac_peer);
92 free(netdev->user_name);
93 free(netdev->group_name);
95 condition_free_list(netdev->match_host);
96 condition_free_list(netdev->match_virt);
97 condition_free_list(netdev->match_kernel);
98 condition_free_list(netdev->match_arch);
103 NetDev *netdev_unref(NetDev *netdev) {
104 if (netdev && (-- netdev->n_ref <= 0))
110 NetDev *netdev_ref(NetDev *netdev) {
112 assert_se(++ netdev->n_ref >= 2);
117 void netdev_drop(NetDev *netdev) {
118 if (!netdev || netdev->state == NETDEV_STATE_LINGER)
121 netdev->state = NETDEV_STATE_LINGER;
123 log_debug_netdev(netdev, "netdev removed");
125 netdev_cancel_callbacks(netdev);
127 netdev_unref(netdev);
132 int netdev_get(Manager *manager, const char *name, NetDev **ret) {
139 netdev = hashmap_get(manager->netdevs, name);
150 static int netdev_enter_failed(NetDev *netdev) {
151 netdev->state = NETDEV_STATE_FAILED;
156 static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_handler_t callback) {
157 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
161 assert(netdev->state == NETDEV_STATE_READY);
162 assert(netdev->manager);
163 assert(netdev->manager->rtnl);
167 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req,
168 RTM_SETLINK, link->ifindex);
170 log_error_netdev(netdev,
171 "Could not allocate RTM_SETLINK message: %s",
176 r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->ifindex);
178 log_error_netdev(netdev,
179 "Could not append IFLA_MASTER attribute: %s",
184 r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
186 log_error_netdev(netdev,
187 "Could not send rtnetlink message: %s",
194 log_debug_netdev(netdev, "enslaving link '%s'", link->ifname);
199 static int netdev_enter_ready(NetDev *netdev) {
200 netdev_enslave_callback *callback, *callback_next;
204 assert(netdev->ifname);
206 if (netdev->state != NETDEV_STATE_CREATING)
209 netdev->state = NETDEV_STATE_READY;
211 log_info_netdev(netdev, "netdev ready");
213 LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
214 /* enslave the links that were attempted to be enslaved before the
216 r = netdev_enslave_ready(netdev, callback->link, callback->callback);
220 LIST_REMOVE(callbacks, netdev->callbacks, callback);
221 link_unref(callback->link);
228 /* callback for netdev's created without a backing Link */
229 static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
230 _cleanup_netdev_unref_ NetDev *netdev = userdata;
233 assert(netdev->state != _NETDEV_STATE_INVALID);
235 r = sd_rtnl_message_get_errno(m);
237 log_debug_netdev(netdev, "netdev exists, using existing");
239 log_warning_netdev(netdev, "netdev could not be created: %s", strerror(-r));
248 static int netdev_create(NetDev *netdev) {
249 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
254 assert(netdev->ifname);
255 assert(netdev->manager);
256 assert(netdev->manager->rtnl);
258 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
260 log_error_netdev(netdev,
261 "Could not allocate RTM_NEWLINK message: %s",
266 r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
268 log_error_netdev(netdev,
269 "Could not append IFLA_IFNAME attribute: %s",
275 r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
277 log_error_netdev(netdev,
278 "Could not append IFLA_MTU attribute: %s",
285 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
287 log_error_netdev(netdev,
288 "Colud not append IFLA_ADDRESS attribute: %s",
294 r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
296 log_error_netdev(netdev,
297 "Could not open IFLA_LINKINFO container: %s",
302 kind = netdev_kind_to_string(netdev->kind);
304 log_error_netdev(netdev, "Invalid kind");
308 r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
310 log_error_netdev(netdev,
311 "Could not open IFLA_INFO_DATA container: %s",
316 r = sd_rtnl_message_close_container(req);
318 log_error_netdev(netdev,
319 "Could not close IFLA_INFO_DATA container %s",
324 r = sd_rtnl_message_close_container(req);
326 log_error_netdev(netdev,
327 "Could not close IFLA_LINKINFO container %s",
332 r = sd_rtnl_call_async(netdev->manager->rtnl, req, &netdev_create_handler, netdev, 0, NULL);
334 log_error_netdev(netdev,
335 "Could not send rtnetlink message: %s", strerror(-r));
341 log_debug_netdev(netdev, "creating netdev");
343 netdev->state = NETDEV_STATE_CREATING;
348 /* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
349 int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
352 switch(netdev->kind) {
353 case NETDEV_KIND_VLAN:
354 return netdev_create_vlan(netdev, link, callback);
355 case NETDEV_KIND_MACVLAN:
356 return netdev_create_macvlan(netdev, link, callback);
357 case NETDEV_KIND_VXLAN:
358 return netdev_create_vxlan(netdev, link, callback);
359 case NETDEV_KIND_IPIP:
360 case NETDEV_KIND_GRE:
361 case NETDEV_KIND_SIT:
362 case NETDEV_KIND_VTI:
363 return netdev_create_tunnel(netdev, link, callback);
368 if (netdev->state == NETDEV_STATE_READY) {
369 r = netdev_enslave_ready(netdev, link, callback);
373 /* the netdev is not yet read, save this request for when it is*/
374 netdev_enslave_callback *cb;
376 cb = new0(netdev_enslave_callback, 1);
380 cb->callback = callback;
384 LIST_PREPEND(callbacks, netdev->callbacks, cb);
390 int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
400 r = sd_rtnl_message_get_type(message, &type);
402 log_error_netdev(netdev, "Could not get rtnl message type");
406 if (type != RTM_NEWLINK) {
407 log_error_netdev(netdev, "Can not set ifindex from unexpected rtnl message type");
411 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
413 log_error_netdev(netdev, "Could not get ifindex: %s", strerror(-r));
414 netdev_enter_failed(netdev);
416 } else if (ifindex <= 0) {
417 log_error_netdev(netdev, "Got invalid ifindex: %d", ifindex);
418 netdev_enter_failed(netdev);
422 if (netdev->ifindex > 0) {
423 if (netdev->ifindex != ifindex) {
424 log_error_netdev(netdev, "Could not set ifindex to %d, already set to %d",
425 ifindex, netdev->ifindex);
426 netdev_enter_failed(netdev);
429 /* ifindex already set to the same for this netdev */
433 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name);
435 log_error_netdev(netdev, "Could not get IFNAME");
439 if (!streq(netdev->ifname, received_name)) {
440 log_error_netdev(netdev, "Received newlink with wrong IFNAME %s",
442 netdev_enter_failed(netdev);
446 r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO);
448 log_error_netdev(netdev, "Could not get LINKINFO");
452 r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind);
454 log_error_netdev(netdev, "Could not get KIND");
458 r = sd_rtnl_message_exit_container(message);
460 log_error_netdev(netdev, "Could not exit container");
464 if (netdev->kind == NETDEV_KIND_TAP)
465 /* the kernel does not distinguish between tun and tap */
468 kind = netdev_kind_to_string(netdev->kind);
470 log_error_netdev(netdev, "Could not get kind");
471 netdev_enter_failed(netdev);
476 if (!streq(kind, received_kind)) {
477 log_error_netdev(netdev,
478 "Received newlink with wrong KIND %s, "
479 "expected %s", received_kind, kind);
480 netdev_enter_failed(netdev);
484 netdev->ifindex = ifindex;
486 log_debug_netdev(netdev, "netdev has index %d", netdev->ifindex);
488 netdev_enter_ready(netdev);
493 #define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
495 static int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
496 _cleanup_free_ struct ether_addr *mac = NULL;
505 mac = new0(struct ether_addr, 1);
510 sz = sizeof(sd_id128_t) + l;
513 /* fetch some persistent data unique to the machine */
514 r = sd_id128_get_machine((sd_id128_t*) v);
518 /* combine with some data unique (on this machine) to this
520 memcpy(v + sizeof(sd_id128_t), ifname, l);
522 /* Let's hash the host machine ID plus the container name. We
523 * use a fixed, but originally randomly created hash key here. */
524 siphash24(result, v, sz, HASH_KEY.bytes);
526 assert_cc(ETH_ALEN <= sizeof(result));
527 memcpy(mac->ether_addr_octet, result, ETH_ALEN);
529 /* see eth_random_addr in the kernel */
530 mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
531 mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
539 static int netdev_load_one(Manager *manager, const char *filename) {
540 _cleanup_netdev_unref_ NetDev *netdev = NULL;
541 _cleanup_fclose_ FILE *file = NULL;
547 if (null_or_empty_path(filename)) {
548 log_debug("skipping empty file: %s", filename);
552 file = fopen(filename, "re");
560 netdev = new0(NetDev, 1);
565 netdev->manager = manager;
566 netdev->state = _NETDEV_STATE_INVALID;
567 netdev->kind = _NETDEV_KIND_INVALID;
568 netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
569 netdev->bond_mode = _NETDEV_BOND_MODE_INVALID;
570 netdev->vlanid = VLANID_MAX + 1;
571 netdev->vxlanid = VXLAN_VID_MAX + 1;
572 netdev->tunnel_pmtudisc = true;
573 netdev->learning = true;
575 r = config_parse(NULL, filename, file,
576 "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0Bond\0",
577 config_item_perf_lookup, (void*) network_netdev_gperf_lookup,
578 false, false, netdev);
580 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
584 switch (netdev->kind) {
585 case _NETDEV_KIND_INVALID:
586 log_warning("NetDev without Kind configured in %s. Ignoring", filename);
588 case NETDEV_KIND_VLAN:
589 if (netdev->vlanid > VLANID_MAX) {
590 log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
594 case NETDEV_KIND_VXLAN:
595 if (netdev->vxlanid > VXLAN_VID_MAX) {
596 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
600 case NETDEV_KIND_IPIP:
601 case NETDEV_KIND_GRE:
602 case NETDEV_KIND_SIT:
603 case NETDEV_KIND_VTI:
604 if (netdev->local.in.s_addr == INADDR_ANY) {
605 log_warning("Tunnel without local address configured in %s. Ignoring", filename);
608 if (netdev->remote.in.s_addr == INADDR_ANY) {
609 log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
612 if (netdev->family != AF_INET) {
613 log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
621 if (!netdev->ifname) {
622 log_warning("NetDev without Name configured in %s. Ignoring", filename);
626 if (netdev->kind != NETDEV_KIND_VLAN && netdev->vlanid <= VLANID_MAX) {
627 log_warning("VLAN Id configured for a %s in %s. Ignoring",
628 netdev_kind_to_string(netdev->kind), filename);
632 if (netdev->kind != NETDEV_KIND_VXLAN && netdev->vxlanid <= VXLAN_VID_MAX) {
633 log_warning("VXLAN Id configured for a %s in %s. Ignoring",
634 netdev_kind_to_string(netdev->kind), filename);
638 if (netdev->kind != NETDEV_KIND_MACVLAN &&
639 netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
640 log_warning("MACVLAN Mode configured for a %s in %s. Ignoring",
641 netdev_kind_to_string(netdev->kind), filename);
645 netdev->filename = strdup(filename);
646 if (!netdev->filename)
649 if (net_match_config(NULL, NULL, NULL, NULL, NULL,
650 netdev->match_host, netdev->match_virt,
651 netdev->match_kernel, netdev->match_arch,
652 NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
656 r = netdev_get_mac(netdev->ifname, &netdev->mac);
658 log_error("Failed to generate predictable MAC address for %s",
664 r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
668 LIST_HEAD_INIT(netdev->callbacks);
670 switch (netdev->kind) {
671 case NETDEV_KIND_VETH:
672 if (!netdev->ifname_peer) {
673 log_warning("Veth NetDev without peer name configured "
674 "in %s. Ignoring", filename);
679 r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
681 log_error("Failed to generate predictable MAC address for %s",
682 netdev->ifname_peer);
687 r = netdev_create_veth(netdev, netdev_create_handler);
692 case NETDEV_KIND_DUMMY:
693 r = netdev_create_dummy(netdev, netdev_create_handler);
698 case NETDEV_KIND_BRIDGE:
699 r = netdev_create(netdev);
703 case NETDEV_KIND_BOND:
704 r = netdev_create_bond(netdev, netdev_create_handler);
712 log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
719 int netdev_load(Manager *manager) {
726 while ((netdev = hashmap_first(manager->netdevs)))
727 netdev_unref(netdev);
729 r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs);
731 log_error("Failed to enumerate netdev files: %s", strerror(-r));
735 STRV_FOREACH_BACKWARDS(f, files) {
736 r = netdev_load_one(manager, *f);