LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - generic-netlink.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 28 47 59.6 %
Date: 2019-08-23 13:36:53 Functions: 3 4 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7 22 31.8 %

           Branch data     Line data    Source code
       1                 :            : #include <linux/genetlink.h>
       2                 :            : 
       3                 :            : #include "sd-netlink.h"
       4                 :            : #include "netlink-internal.h"
       5                 :            : #include "alloc-util.h"
       6                 :            : 
       7                 :            : typedef struct {
       8                 :            :         const char* name;
       9                 :            :         uint8_t version;
      10                 :            : } genl_family;
      11                 :            : 
      12                 :            : static const genl_family genl_families[] = {
      13                 :            :         [SD_GENL_ID_CTRL]   = { .name = "",          .version = 1 },
      14                 :            :         [SD_GENL_WIREGUARD] = { .name = "wireguard", .version = 1 },
      15                 :            :         [SD_GENL_FOU]       = { .name = "fou",       .version = 1 },
      16                 :            :         [SD_GENL_L2TP]      = { .name = "l2tp",      .version = 1 },
      17                 :            :         [SD_GENL_MACSEC]    = { .name = "macsec",    .version = 1 },
      18                 :            : };
      19                 :            : 
      20                 :          8 : int sd_genl_socket_open(sd_netlink **ret) {
      21                 :          8 :         return netlink_open_family(ret, NETLINK_GENERIC);
      22                 :            : }
      23                 :            : static int lookup_id(sd_netlink *nl, sd_genl_family family, uint16_t *id);
      24                 :            : 
      25                 :          4 : static int genl_message_new(sd_netlink *nl, sd_genl_family family, uint16_t nlmsg_type, uint8_t cmd, sd_netlink_message **ret) {
      26                 :            :         int r;
      27                 :            :         struct genlmsghdr *genl;
      28                 :            :         const NLType *genl_cmd_type, *nl_type;
      29                 :            :         const NLTypeSystem *type_system;
      30                 :            :         size_t size;
      31                 :          4 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
      32                 :            : 
      33   [ -  +  -  + ]:          4 :         assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
      34                 :            : 
      35                 :          4 :         r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family);
      36         [ -  + ]:          4 :         if (r < 0)
      37                 :          0 :                 return r;
      38                 :            : 
      39                 :          4 :         r = message_new_empty(nl, &m);
      40         [ -  + ]:          4 :         if (r < 0)
      41                 :          0 :                 return r;
      42                 :            : 
      43                 :          4 :         size = NLMSG_SPACE(sizeof(struct genlmsghdr));
      44                 :          4 :         m->hdr = malloc0(size);
      45         [ -  + ]:          4 :         if (!m->hdr)
      46                 :          0 :                 return -ENOMEM;
      47                 :            : 
      48                 :          4 :         m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
      49                 :            : 
      50                 :          4 :         type_get_type_system(genl_cmd_type, &type_system);
      51                 :            : 
      52                 :          4 :         r = type_system_get_type(type_system, &nl_type, cmd);
      53         [ -  + ]:          4 :         if (r < 0)
      54                 :          0 :                 return r;
      55                 :            : 
      56                 :          4 :         m->hdr->nlmsg_len = size;
      57                 :          4 :         m->hdr->nlmsg_type = nlmsg_type;
      58                 :            : 
      59                 :          4 :         type_get_type_system(nl_type, &m->containers[0].type_system);
      60                 :          4 :         genl = NLMSG_DATA(m->hdr);
      61                 :          4 :         genl->cmd = cmd;
      62                 :          4 :         genl->version = genl_families[family].version;
      63                 :            : 
      64                 :          4 :         *ret = TAKE_PTR(m);
      65                 :            : 
      66                 :          4 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :          4 : int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **ret) {
      70                 :            :         int r;
      71                 :          4 :         uint16_t id = GENL_ID_CTRL;
      72                 :            : 
      73         [ -  + ]:          4 :         if (family != SD_GENL_ID_CTRL) {
      74                 :          0 :                 r = lookup_id(nl, family, &id);
      75         [ #  # ]:          0 :                 if (r < 0)
      76                 :          0 :                         return r;
      77                 :            :         }
      78                 :            : 
      79                 :          4 :         return genl_message_new(nl, family, id, cmd, ret);
      80                 :            : }
      81                 :            : 
      82                 :          0 : static int lookup_id(sd_netlink *nl, sd_genl_family family, uint16_t *id) {
      83                 :            :         int r;
      84                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
      85                 :            : 
      86                 :          0 :         r = sd_genl_message_new(nl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req);
      87         [ #  # ]:          0 :         if (r < 0)
      88                 :          0 :                 return r;
      89                 :            : 
      90                 :          0 :         r = sd_netlink_message_append_string(req, CTRL_ATTR_FAMILY_NAME, genl_families[family].name);
      91         [ #  # ]:          0 :         if (r < 0)
      92                 :          0 :                 return r;
      93                 :            : 
      94                 :          0 :         r = sd_netlink_call(nl, req, 0, &reply);
      95         [ #  # ]:          0 :         if (r < 0)
      96                 :          0 :                 return r;
      97                 :            : 
      98                 :          0 :         return sd_netlink_message_read_u16(reply, CTRL_ATTR_FAMILY_ID, id);
      99                 :            : }

Generated by: LCOV version 1.14