LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - netlink-slot.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 100 108 92.6 %
Date: 2019-08-22 15:41:25 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <errno.h>
       4             : 
       5             : #include "sd-netlink.h"
       6             : 
       7             : #include "alloc-util.h"
       8             : #include "netlink-internal.h"
       9             : #include "netlink-slot.h"
      10             : #include "string-util.h"
      11             : 
      12          30 : int netlink_slot_allocate(
      13             :                 sd_netlink *nl,
      14             :                 bool floating,
      15             :                 NetlinkSlotType type,
      16             :                 size_t extra,
      17             :                 void *userdata,
      18             :                 const char *description,
      19             :                 sd_netlink_slot **ret) {
      20             : 
      21          30 :         _cleanup_free_ sd_netlink_slot *slot = NULL;
      22             : 
      23          30 :         assert(nl);
      24          30 :         assert(ret);
      25             : 
      26          30 :         slot = malloc0(offsetof(sd_netlink_slot, reply_callback) + extra);
      27          30 :         if (!slot)
      28           0 :                 return -ENOMEM;
      29             : 
      30          30 :         slot->n_ref = 1;
      31          30 :         slot->netlink = nl;
      32          30 :         slot->userdata = userdata;
      33          30 :         slot->type = type;
      34          30 :         slot->floating = floating;
      35             : 
      36          30 :         if (description) {
      37          20 :                 slot->description = strdup(description);
      38          20 :                 if (!slot->description)
      39           0 :                         return -ENOMEM;
      40             :         }
      41             : 
      42          30 :         if (!floating)
      43           5 :                 sd_netlink_ref(nl);
      44             : 
      45          30 :         LIST_PREPEND(slots, nl->slots, slot);
      46             : 
      47          30 :         *ret = TAKE_PTR(slot);
      48             : 
      49          30 :         return 0;
      50             : }
      51             : 
      52          56 : void netlink_slot_disconnect(sd_netlink_slot *slot, bool unref) {
      53             :         sd_netlink *nl;
      54             : 
      55          56 :         assert(slot);
      56             : 
      57          56 :         nl = slot->netlink;
      58          56 :         if (!nl)
      59          26 :                 return;
      60             : 
      61          30 :         switch (slot->type) {
      62             : 
      63          17 :         case NETLINK_REPLY_CALLBACK:
      64          17 :                 (void) hashmap_remove(nl->reply_callbacks, &slot->reply_callback.serial);
      65             : 
      66          17 :                 if (slot->reply_callback.timeout != 0)
      67           8 :                         prioq_remove(nl->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
      68             : 
      69          17 :                 break;
      70          13 :         case NETLINK_MATCH_CALLBACK:
      71          13 :                 LIST_REMOVE(match_callbacks, nl->match_callbacks, &slot->match_callback);
      72             : 
      73          13 :                 switch (slot->match_callback.type) {
      74           5 :                 case RTM_NEWLINK:
      75             :                 case RTM_DELLINK:
      76           5 :                         (void) socket_broadcast_group_unref(nl, RTNLGRP_LINK);
      77             : 
      78           5 :                         break;
      79           2 :                 case RTM_NEWADDR:
      80             :                 case RTM_DELADDR:
      81           2 :                         (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_IFADDR);
      82           2 :                         (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_IFADDR);
      83             : 
      84           2 :                         break;
      85           2 :                 case RTM_NEWROUTE:
      86             :                 case RTM_DELROUTE:
      87           2 :                         (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_ROUTE);
      88           2 :                         (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_ROUTE);
      89             : 
      90           2 :                         break;
      91             :                 }
      92             : 
      93          13 :                 break;
      94           0 :         default:
      95           0 :                 assert_not_reached("Wut? Unknown slot type?");
      96             :         }
      97             : 
      98          30 :         slot->type = _NETLINK_SLOT_INVALID;
      99          30 :         slot->netlink = NULL;
     100          30 :         LIST_REMOVE(slots, nl->slots, slot);
     101             : 
     102          30 :         if (!slot->floating)
     103           4 :                 sd_netlink_unref(nl);
     104          26 :         else if (unref)
     105          26 :                 sd_netlink_slot_unref(slot);
     106             : }
     107             : 
     108          30 : static sd_netlink_slot* netlink_slot_free(sd_netlink_slot *slot) {
     109          30 :         assert(slot);
     110             : 
     111          30 :         netlink_slot_disconnect(slot, false);
     112             : 
     113          30 :         if (slot->destroy_callback)
     114          11 :                 slot->destroy_callback(slot->userdata);
     115             : 
     116          30 :         free(slot->description);
     117          30 :         return mfree(slot);
     118             : }
     119             : 
     120          32 : DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_netlink_slot, sd_netlink_slot, netlink_slot_free);
     121             : 
     122           2 : sd_netlink *sd_netlink_slot_get_netlink(sd_netlink_slot *slot) {
     123           2 :         assert_return(slot, NULL);
     124             : 
     125           2 :         return slot->netlink;
     126             : }
     127             : 
     128           3 : void *sd_netlink_slot_get_userdata(sd_netlink_slot *slot) {
     129           3 :         assert_return(slot, NULL);
     130             : 
     131           3 :         return slot->userdata;
     132             : }
     133             : 
     134           1 : void *sd_netlink_slot_set_userdata(sd_netlink_slot *slot, void *userdata) {
     135             :         void *ret;
     136             : 
     137           1 :         assert_return(slot, NULL);
     138             : 
     139           1 :         ret = slot->userdata;
     140           1 :         slot->userdata = userdata;
     141             : 
     142           1 :         return ret;
     143             : }
     144             : 
     145           3 : int sd_netlink_slot_get_destroy_callback(sd_netlink_slot *slot, sd_netlink_destroy_t *callback) {
     146           3 :         assert_return(slot, -EINVAL);
     147             : 
     148           3 :         if (callback)
     149           2 :                 *callback = slot->destroy_callback;
     150             : 
     151           3 :         return !!slot->destroy_callback;
     152             : }
     153             : 
     154           1 : int sd_netlink_slot_set_destroy_callback(sd_netlink_slot *slot, sd_netlink_destroy_t callback) {
     155           1 :         assert_return(slot, -EINVAL);
     156             : 
     157           1 :         slot->destroy_callback = callback;
     158           1 :         return 0;
     159             : }
     160             : 
     161           3 : int sd_netlink_slot_get_floating(sd_netlink_slot *slot) {
     162           3 :         assert_return(slot, -EINVAL);
     163             : 
     164           3 :         return slot->floating;
     165             : }
     166             : 
     167           1 : int sd_netlink_slot_set_floating(sd_netlink_slot *slot, int b) {
     168           1 :         assert_return(slot, -EINVAL);
     169             : 
     170           1 :         if (slot->floating == !!b)
     171           0 :                 return 0;
     172             : 
     173           1 :         if (!slot->netlink) /* Already disconnected */
     174           0 :                 return -ESTALE;
     175             : 
     176           1 :         slot->floating = b;
     177             : 
     178           1 :         if (b) {
     179           1 :                 sd_netlink_slot_ref(slot);
     180           1 :                 sd_netlink_unref(slot->netlink);
     181             :         } else {
     182           0 :                 sd_netlink_ref(slot->netlink);
     183           0 :                 sd_netlink_slot_unref(slot);
     184             :         }
     185             : 
     186           1 :         return 1;
     187             : }
     188             : 
     189           3 : int sd_netlink_slot_get_description(sd_netlink_slot *slot, const char **description) {
     190           3 :         assert_return(slot, -EINVAL);
     191             : 
     192           3 :         if (description)
     193           2 :                 *description = slot->description;
     194             : 
     195           3 :         return !!slot->description;
     196             : }
     197             : 
     198           1 : int sd_netlink_slot_set_description(sd_netlink_slot *slot, const char *description) {
     199           1 :         assert_return(slot, -EINVAL);
     200             : 
     201           1 :         return free_and_strdup(&slot->description, description);
     202             : }

Generated by: LCOV version 1.14