Lines Matching defs:netdev
29 #include "networkd-netdev.h"
84 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
86 static void netdev_cancel_callbacks(NetDev *netdev) {
90 if (!netdev)
95 while ((callback = netdev->callbacks)) {
99 assert(netdev->manager);
100 assert(netdev->manager->rtnl);
102 callback->callback(netdev->manager->rtnl, m, callback->link);
105 LIST_REMOVE(callbacks, netdev->callbacks, callback);
111 static void netdev_free(NetDev *netdev) {
112 if (!netdev)
115 netdev_cancel_callbacks(netdev);
117 if (netdev->ifname)
118 hashmap_remove(netdev->manager->netdevs, netdev->ifname);
120 free(netdev->filename);
122 free(netdev->description);
123 free(netdev->ifname);
124 free(netdev->mac);
126 condition_free_list(netdev->match_host);
127 condition_free_list(netdev->match_virt);
128 condition_free_list(netdev->match_kernel);
129 condition_free_list(netdev->match_arch);
131 if (NETDEV_VTABLE(netdev) &&
132 NETDEV_VTABLE(netdev)->done)
133 NETDEV_VTABLE(netdev)->done(netdev);
135 free(netdev);
138 NetDev *netdev_unref(NetDev *netdev) {
139 if (netdev && (-- netdev->n_ref <= 0))
140 netdev_free(netdev);
145 NetDev *netdev_ref(NetDev *netdev) {
146 if (netdev)
147 assert_se(++ netdev->n_ref >= 2);
149 return netdev;
152 void netdev_drop(NetDev *netdev) {
153 if (!netdev || netdev->state == NETDEV_STATE_LINGER)
156 netdev->state = NETDEV_STATE_LINGER;
158 log_netdev_debug(netdev, "netdev removed");
160 netdev_cancel_callbacks(netdev);
162 netdev_unref(netdev);
168 NetDev *netdev;
174 netdev = hashmap_get(manager->netdevs, name);
175 if (!netdev) {
180 *ret = netdev;
185 static int netdev_enter_failed(NetDev *netdev) {
186 netdev->state = NETDEV_STATE_FAILED;
188 netdev_cancel_callbacks(netdev);
193 static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_handler_t callback) {
197 assert(netdev);
198 assert(netdev->state == NETDEV_STATE_READY);
199 assert(netdev->manager);
200 assert(netdev->manager->rtnl);
201 assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
205 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
207 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
209 r = sd_netlink_message_append_u32(req, IFLA_MASTER, netdev->ifindex);
211 return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
213 r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
215 return log_netdev_error(netdev, "Could not send rtnetlink message: %m");
219 log_netdev_debug(netdev, "Enslaving link '%s'", link->ifname);
224 static int netdev_enter_ready(NetDev *netdev) {
228 assert(netdev);
229 assert(netdev->ifname);
231 if (netdev->state != NETDEV_STATE_CREATING)
234 netdev->state = NETDEV_STATE_READY;
236 log_netdev_info(netdev, "netdev ready");
238 LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
241 r = netdev_enslave_ready(netdev, callback->link, callback->callback);
245 LIST_REMOVE(callbacks, netdev->callbacks, callback);
250 if (NETDEV_VTABLE(netdev)->post_create)
251 NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL);
256 /* callback for netdev's created without a backing Link */
258 _cleanup_netdev_unref_ NetDev *netdev = userdata;
261 assert(netdev->state != _NETDEV_STATE_INVALID);
265 log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
267 log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
268 netdev_drop(netdev);
273 log_netdev_debug(netdev, "Created");
278 int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) {
281 assert(netdev);
282 assert(netdev->manager);
283 assert(netdev->manager->rtnl);
284 assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
286 if (netdev->state == NETDEV_STATE_READY) {
287 r = netdev_enslave_ready(netdev, link, callback);
290 } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) {
295 callback(netdev->manager->rtnl, m, link);
297 /* the netdev is not yet read, save this request for when it is */
308 LIST_PREPEND(callbacks, netdev->callbacks, cb);
310 log_netdev_debug(netdev, "Will enslave '%s', when ready", link->ifname);
316 int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
323 assert(netdev);
328 return log_netdev_error_errno(netdev, r, "Could not get rtnl message type: %m");
331 log_netdev_error(netdev, "Cannot set ifindex from unexpected rtnl message type.");
337 log_netdev_error_errno(netdev, r, "Could not get ifindex: %m");
338 netdev_enter_failed(netdev);
341 log_netdev_error(netdev, "Got invalid ifindex: %d", ifindex);
342 netdev_enter_failed(netdev);
346 if (netdev->ifindex > 0) {
347 if (netdev->ifindex != ifindex) {
348 log_netdev_error(netdev, "Could not set ifindex to %d, already set to %d",
349 ifindex, netdev->ifindex);
350 netdev_enter_failed(netdev);
353 /* ifindex already set to the same for this netdev */
359 return log_netdev_error_errno(netdev, r, "Could not get IFNAME: %m");
361 if (!streq(netdev->ifname, received_name)) {
362 log_netdev_error(netdev, "Received newlink with wrong IFNAME %s", received_name);
363 netdev_enter_failed(netdev);
369 return log_netdev_error_errno(netdev, r, "Could not get LINKINFO: %m");
373 return log_netdev_error_errno(netdev, r, "Could not get KIND: %m");
377 return log_netdev_error_errno(netdev, r, "Could not exit container: %m");
379 if (netdev->kind == NETDEV_KIND_TAP)
383 kind = netdev_kind_to_string(netdev->kind);
385 log_netdev_error(netdev, "Could not get kind");
386 netdev_enter_failed(netdev);
392 log_netdev_error(netdev,
395 netdev_enter_failed(netdev);
399 netdev->ifindex = ifindex;
401 log_netdev_debug(netdev, "netdev has index %d", netdev->ifindex);
403 netdev_enter_ready(netdev);
434 * netdev */
454 static int netdev_create(NetDev *netdev, Link *link,
458 assert(netdev);
461 /* create netdev */
462 if (NETDEV_VTABLE(netdev)->create) {
465 r = NETDEV_VTABLE(netdev)->create(netdev);
469 log_netdev_debug(netdev, "Created");
473 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
475 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m");
477 r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
479 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
481 if (netdev->mac) {
482 r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
484 return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
487 if (netdev->mtu) {
488 r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu);
490 return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m");
496 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINK attribute: %m");
501 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
503 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
505 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
507 if (NETDEV_VTABLE(netdev)->fill_message_create) {
508 r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
515 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
519 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
522 r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL);
524 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
528 r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
530 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
532 netdev_ref(netdev);
535 netdev->state = NETDEV_STATE_CREATING;
537 log_netdev_debug(netdev, "Creating");
544 int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) {
547 assert(netdev);
548 assert(netdev->manager);
549 assert(netdev->manager->rtnl);
550 assert(NETDEV_VTABLE(netdev));
552 switch (NETDEV_VTABLE(netdev)->create_type) {
554 r = netdev_enslave(netdev, link, callback);
560 r = netdev_create(netdev, link, callback);
566 assert_not_reached("Can not join independent netdev");
573 _cleanup_netdev_unref_ NetDev *netdev = NULL;
628 netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
629 if (!netdev)
632 netdev->n_ref = 1;
633 netdev->manager = manager;
634 netdev->state = _NETDEV_STATE_INVALID;
635 netdev->kind = netdev_raw->kind;
636 netdev->ifname = netdev_raw->ifname;
638 if (NETDEV_VTABLE(netdev)->init)
639 NETDEV_VTABLE(netdev)->init(netdev);
642 NETDEV_VTABLE(netdev)->sections,
644 false, false, false, netdev);
649 if (NETDEV_VTABLE(netdev)->config_verify) {
650 r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
655 netdev->filename = strdup(filename);
656 if (!netdev->filename)
659 if (!netdev->mac) {
660 r = netdev_get_mac(netdev->ifname, &netdev->mac);
662 return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname);
665 r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
669 LIST_HEAD_INIT(netdev->callbacks);
671 log_netdev_debug(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
673 switch (NETDEV_VTABLE(netdev)->create_type) {
676 r = netdev_create(netdev, NULL, NULL);
685 netdev = NULL;
692 NetDev *netdev;
698 while ((netdev = hashmap_first(manager->netdevs)))
699 netdev_unref(netdev);
701 r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs);
703 return log_error_errno(r, "Failed to enumerate netdev files: %m");