LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - generic-netlink.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 28 47 59.6 %
Date: 2019-08-22 15:41:25 Functions: 3 4 75.0 %

          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           2 : int sd_genl_socket_open(sd_netlink **ret) {
      21           2 :         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           1 : 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           1 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
      32             : 
      33           1 :         assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
      34             : 
      35           1 :         r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family);
      36           1 :         if (r < 0)
      37           0 :                 return r;
      38             : 
      39           1 :         r = message_new_empty(nl, &m);
      40           1 :         if (r < 0)
      41           0 :                 return r;
      42             : 
      43           1 :         size = NLMSG_SPACE(sizeof(struct genlmsghdr));
      44           1 :         m->hdr = malloc0(size);
      45           1 :         if (!m->hdr)
      46           0 :                 return -ENOMEM;
      47             : 
      48           1 :         m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
      49             : 
      50           1 :         type_get_type_system(genl_cmd_type, &type_system);
      51             : 
      52           1 :         r = type_system_get_type(type_system, &nl_type, cmd);
      53           1 :         if (r < 0)
      54           0 :                 return r;
      55             : 
      56           1 :         m->hdr->nlmsg_len = size;
      57           1 :         m->hdr->nlmsg_type = nlmsg_type;
      58             : 
      59           1 :         type_get_type_system(nl_type, &m->containers[0].type_system);
      60           1 :         genl = NLMSG_DATA(m->hdr);
      61           1 :         genl->cmd = cmd;
      62           1 :         genl->version = genl_families[family].version;
      63             : 
      64           1 :         *ret = TAKE_PTR(m);
      65             : 
      66           1 :         return 0;
      67             : }
      68             : 
      69           1 : int sd_genl_message_new(sd_netlink *nl, sd_genl_family family, uint8_t cmd, sd_netlink_message **ret) {
      70             :         int r;
      71           1 :         uint16_t id = GENL_ID_CTRL;
      72             : 
      73           1 :         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           1 :         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