1 // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 2 /* Do not edit directly, auto-generated from: */ 3 /* Documentation/netlink/specs/netdev.yaml */ 4 /* YNL-GEN user source */ 5 6 #include <stdlib.h> 7 #include <string.h> 8 #include "netdev-user.h" 9 #include "ynl.h" 10 #include <linux/netdev.h> 11 12 #include <libmnl/libmnl.h> 13 #include <linux/genetlink.h> 14 15 /* Enums */ 16 static const char * const netdev_op_strmap[] = { 17 [NETDEV_CMD_DEV_GET] = "dev-get", 18 [NETDEV_CMD_DEV_ADD_NTF] = "dev-add-ntf", 19 [NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf", 20 [NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf", 21 }; 22 23 const char *netdev_op_str(int op) 24 { 25 if (op < 0 || op >= (int)MNL_ARRAY_SIZE(netdev_op_strmap)) 26 return NULL; 27 return netdev_op_strmap[op]; 28 } 29 30 static const char * const netdev_xdp_act_strmap[] = { 31 [0] = "basic", 32 [1] = "redirect", 33 [2] = "ndo-xmit", 34 [3] = "xsk-zerocopy", 35 [4] = "hw-offload", 36 [5] = "rx-sg", 37 [6] = "ndo-xmit-sg", 38 }; 39 40 const char *netdev_xdp_act_str(enum netdev_xdp_act value) 41 { 42 value = ffs(value) - 1; 43 if (value < 0 || value >= (int)MNL_ARRAY_SIZE(netdev_xdp_act_strmap)) 44 return NULL; 45 return netdev_xdp_act_strmap[value]; 46 } 47 48 /* Policies */ 49 struct ynl_policy_attr netdev_dev_policy[NETDEV_A_DEV_MAX + 1] = { 50 [NETDEV_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, 51 [NETDEV_A_DEV_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, 52 [NETDEV_A_DEV_XDP_FEATURES] = { .name = "xdp-features", .type = YNL_PT_U64, }, 53 }; 54 55 struct ynl_policy_nest netdev_dev_nest = { 56 .max_attr = NETDEV_A_DEV_MAX, 57 .table = netdev_dev_policy, 58 }; 59 60 /* Common nested types */ 61 /* ============== NETDEV_CMD_DEV_GET ============== */ 62 /* NETDEV_CMD_DEV_GET - do */ 63 void netdev_dev_get_req_free(struct netdev_dev_get_req *req) 64 { 65 free(req); 66 } 67 68 void netdev_dev_get_rsp_free(struct netdev_dev_get_rsp *rsp) 69 { 70 free(rsp); 71 } 72 73 int netdev_dev_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 74 { 75 struct ynl_parse_arg *yarg = data; 76 struct netdev_dev_get_rsp *dst; 77 const struct nlattr *attr; 78 79 dst = yarg->data; 80 81 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 82 unsigned int type = mnl_attr_get_type(attr); 83 84 if (type == NETDEV_A_DEV_IFINDEX) { 85 if (ynl_attr_validate(yarg, attr)) 86 return MNL_CB_ERROR; 87 dst->_present.ifindex = 1; 88 dst->ifindex = mnl_attr_get_u32(attr); 89 } else if (type == NETDEV_A_DEV_XDP_FEATURES) { 90 if (ynl_attr_validate(yarg, attr)) 91 return MNL_CB_ERROR; 92 dst->_present.xdp_features = 1; 93 dst->xdp_features = mnl_attr_get_u64(attr); 94 } 95 } 96 97 return MNL_CB_OK; 98 } 99 100 struct netdev_dev_get_rsp * 101 netdev_dev_get(struct ynl_sock *ys, struct netdev_dev_get_req *req) 102 { 103 struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 104 struct netdev_dev_get_rsp *rsp; 105 struct nlmsghdr *nlh; 106 int err; 107 108 nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); 109 ys->req_policy = &netdev_dev_nest; 110 yrs.yarg.rsp_policy = &netdev_dev_nest; 111 112 if (req->_present.ifindex) 113 mnl_attr_put_u32(nlh, NETDEV_A_DEV_IFINDEX, req->ifindex); 114 115 rsp = calloc(1, sizeof(*rsp)); 116 yrs.yarg.data = rsp; 117 yrs.cb = netdev_dev_get_rsp_parse; 118 yrs.rsp_cmd = NETDEV_CMD_DEV_GET; 119 120 err = ynl_exec(ys, nlh, &yrs); 121 if (err < 0) 122 goto err_free; 123 124 return rsp; 125 126 err_free: 127 netdev_dev_get_rsp_free(rsp); 128 return NULL; 129 } 130 131 /* NETDEV_CMD_DEV_GET - dump */ 132 void netdev_dev_get_list_free(struct netdev_dev_get_list *rsp) 133 { 134 struct netdev_dev_get_list *next = rsp; 135 136 while ((void *)next != YNL_LIST_END) { 137 rsp = next; 138 next = rsp->next; 139 140 free(rsp); 141 } 142 } 143 144 struct netdev_dev_get_list *netdev_dev_get_dump(struct ynl_sock *ys) 145 { 146 struct ynl_dump_state yds = {}; 147 struct nlmsghdr *nlh; 148 int err; 149 150 yds.ys = ys; 151 yds.alloc_sz = sizeof(struct netdev_dev_get_list); 152 yds.cb = netdev_dev_get_rsp_parse; 153 yds.rsp_cmd = NETDEV_CMD_DEV_GET; 154 yds.rsp_policy = &netdev_dev_nest; 155 156 nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); 157 158 err = ynl_exec_dump(ys, nlh, &yds); 159 if (err < 0) 160 goto free_list; 161 162 return yds.first; 163 164 free_list: 165 netdev_dev_get_list_free(yds.first); 166 return NULL; 167 } 168 169 /* NETDEV_CMD_DEV_GET - notify */ 170 void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp) 171 { 172 free(rsp); 173 } 174 175 static const struct ynl_ntf_info netdev_ntf_info[] = { 176 [NETDEV_CMD_DEV_ADD_NTF] = { 177 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 178 .cb = netdev_dev_get_rsp_parse, 179 .policy = &netdev_dev_nest, 180 .free = (void *)netdev_dev_get_ntf_free, 181 }, 182 [NETDEV_CMD_DEV_DEL_NTF] = { 183 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 184 .cb = netdev_dev_get_rsp_parse, 185 .policy = &netdev_dev_nest, 186 .free = (void *)netdev_dev_get_ntf_free, 187 }, 188 [NETDEV_CMD_DEV_CHANGE_NTF] = { 189 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 190 .cb = netdev_dev_get_rsp_parse, 191 .policy = &netdev_dev_nest, 192 .free = (void *)netdev_dev_get_ntf_free, 193 }, 194 }; 195 196 const struct ynl_family ynl_netdev_family = { 197 .name = "netdev", 198 .ntf_info = netdev_ntf_info, 199 .ntf_info_size = MNL_ARRAY_SIZE(netdev_ntf_info), 200 }; 201