LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - netlink-slot.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 100 108 92.6 %
Date: 2019-08-23 13:36:53 Functions: 14 14 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 69 105 65.7 %

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

Generated by: LCOV version 1.14