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 "netdev-user.h" 8 #include "ynl.h" 9 #include <linux/netdev.h> 10 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <libmnl/libmnl.h> 15 #include <linux/genetlink.h> 16 17 /* Enums */ 18 static const char * const netdev_op_strmap[] = { 19 [NETDEV_CMD_DEV_GET] = "dev-get", 20 [NETDEV_CMD_DEV_ADD_NTF] = "dev-add-ntf", 21 [NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf", 22 [NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf", 23 }; 24 25 const char *netdev_op_str(int op) 26 { 27 if (op < 0 || op >= (int)MNL_ARRAY_SIZE(netdev_op_strmap)) 28 return NULL; 29 return netdev_op_strmap[op]; 30 } 31 32 static const char * const netdev_xdp_act_strmap[] = { 33 [0] = "basic", 34 [1] = "redirect", 35 [2] = "ndo-xmit", 36 [3] = "xsk-zerocopy", 37 [4] = "hw-offload", 38 [5] = "rx-sg", 39 [6] = "ndo-xmit-sg", 40 }; 41 42 const char *netdev_xdp_act_str(enum netdev_xdp_act value) 43 { 44 value = ffs(value) - 1; 45 if (value < 0 || value >= (int)MNL_ARRAY_SIZE(netdev_xdp_act_strmap)) 46 return NULL; 47 return netdev_xdp_act_strmap[value]; 48 } 49 50 /* Policies */ 51 struct ynl_policy_attr netdev_dev_policy[NETDEV_A_DEV_MAX + 1] = { 52 [NETDEV_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, 53 [NETDEV_A_DEV_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, 54 [NETDEV_A_DEV_XDP_FEATURES] = { .name = "xdp-features", .type = YNL_PT_U64, }, 55 }; 56 57 struct ynl_policy_nest netdev_dev_nest = { 58 .max_attr = NETDEV_A_DEV_MAX, 59 .table = netdev_dev_policy, 60 }; 61 62 /* Common nested types */ 63 /* ============== NETDEV_CMD_DEV_GET ============== */ 64 /* NETDEV_CMD_DEV_GET - do */ 65 void netdev_dev_get_req_free(struct netdev_dev_get_req *req) 66 { 67 free(req); 68 } 69 70 void netdev_dev_get_rsp_free(struct netdev_dev_get_rsp *rsp) 71 { 72 free(rsp); 73 } 74 75 int netdev_dev_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 76 { 77 struct ynl_parse_arg *yarg = data; 78 struct netdev_dev_get_rsp *dst; 79 const struct nlattr *attr; 80 81 dst = yarg->data; 82 83 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 84 if (mnl_attr_get_type(attr) == 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 } 90 else if (mnl_attr_get_type(attr) == NETDEV_A_DEV_XDP_FEATURES) { 91 if (ynl_attr_validate(yarg, attr)) 92 return MNL_CB_ERROR; 93 dst->_present.xdp_features = 1; 94 dst->xdp_features = mnl_attr_get_u64(attr); 95 } 96 } 97 98 return MNL_CB_OK; 99 } 100 101 struct netdev_dev_get_rsp * 102 netdev_dev_get(struct ynl_sock *ys, struct netdev_dev_get_req *req) 103 { 104 struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 105 struct netdev_dev_get_rsp *rsp; 106 struct nlmsghdr *nlh; 107 int err; 108 109 nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); 110 ys->req_policy = &netdev_dev_nest; 111 yrs.yarg.rsp_policy = &netdev_dev_nest; 112 113 if (req->_present.ifindex) 114 mnl_attr_put_u32(nlh, NETDEV_A_DEV_IFINDEX, req->ifindex); 115 116 rsp = calloc(1, sizeof(*rsp)); 117 yrs.yarg.data = rsp; 118 yrs.cb = netdev_dev_get_rsp_parse; 119 yrs.rsp_cmd = NETDEV_CMD_DEV_GET; 120 121 err = ynl_exec(ys, nlh, &yrs); 122 if (err < 0) 123 goto err_free; 124 125 return rsp; 126 127 err_free: 128 netdev_dev_get_rsp_free(rsp); 129 return NULL; 130 } 131 132 /* NETDEV_CMD_DEV_GET - dump */ 133 void netdev_dev_get_list_free(struct netdev_dev_get_list *rsp) 134 { 135 struct netdev_dev_get_list *next = rsp; 136 137 while ((void *)next != YNL_LIST_END) { 138 rsp = next; 139 next = rsp->next; 140 141 free(rsp); 142 } 143 } 144 145 struct netdev_dev_get_list *netdev_dev_get_dump(struct ynl_sock *ys) 146 { 147 struct ynl_dump_state yds = {}; 148 struct nlmsghdr *nlh; 149 int err; 150 151 yds.ys = ys; 152 yds.alloc_sz = sizeof(struct netdev_dev_get_list); 153 yds.cb = netdev_dev_get_rsp_parse; 154 yds.rsp_cmd = NETDEV_CMD_DEV_GET; 155 yds.rsp_policy = &netdev_dev_nest; 156 157 nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); 158 159 err = ynl_exec_dump(ys, nlh, &yds); 160 if (err < 0) 161 goto free_list; 162 163 return yds.first; 164 165 free_list: 166 netdev_dev_get_list_free(yds.first); 167 return NULL; 168 } 169 170 /* NETDEV_CMD_DEV_GET - notify */ 171 void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp) 172 { 173 free(rsp); 174 } 175 176 /* --------------- Common notification parsing --------------- */ 177 struct ynl_ntf_base_type *netdev_ntf_parse(struct ynl_sock *ys) 178 { 179 struct ynl_parse_arg yarg = { .ys = ys, }; 180 struct ynl_ntf_base_type *rsp; 181 struct genlmsghdr *genlh; 182 struct nlmsghdr *nlh; 183 mnl_cb_t parse; 184 int len, err; 185 186 len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE); 187 if (len < (ssize_t)(sizeof(*nlh) + sizeof(*genlh))) 188 return NULL; 189 190 nlh = (struct nlmsghdr *)ys->rx_buf; 191 genlh = mnl_nlmsg_get_payload(nlh); 192 193 switch (genlh->cmd) { 194 case NETDEV_CMD_DEV_ADD_NTF: 195 case NETDEV_CMD_DEV_DEL_NTF: 196 case NETDEV_CMD_DEV_CHANGE_NTF: 197 rsp = calloc(1, sizeof(struct netdev_dev_get_ntf)); 198 parse = netdev_dev_get_rsp_parse; 199 yarg.rsp_policy = &netdev_dev_nest; 200 rsp->free = (void *)netdev_dev_get_ntf_free; 201 break; 202 default: 203 ynl_error_unknown_notification(ys, genlh->cmd); 204 return NULL; 205 } 206 207 yarg.data = rsp->data; 208 209 err = mnl_cb_run2(ys->rx_buf, len, 0, 0, parse, &yarg, 210 ynl_cb_array, NLMSG_MIN_TYPE); 211 if (err < 0) 212 goto err_free; 213 214 rsp->family = nlh->nlmsg_type; 215 rsp->cmd = genlh->cmd; 216 return rsp; 217 218 err_free: 219 free(rsp); 220 return NULL; 221 } 222 223 static const struct ynl_ntf_info netdev_ntf_info[] = { 224 [NETDEV_CMD_DEV_ADD_NTF] = { 225 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 226 .cb = netdev_dev_get_rsp_parse, 227 .policy = &netdev_dev_nest, 228 .free = (void *)netdev_dev_get_ntf_free, 229 }, 230 [NETDEV_CMD_DEV_DEL_NTF] = { 231 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 232 .cb = netdev_dev_get_rsp_parse, 233 .policy = &netdev_dev_nest, 234 .free = (void *)netdev_dev_get_ntf_free, 235 }, 236 [NETDEV_CMD_DEV_CHANGE_NTF] = { 237 .alloc_sz = sizeof(struct netdev_dev_get_ntf), 238 .cb = netdev_dev_get_rsp_parse, 239 .policy = &netdev_dev_nest, 240 .free = (void *)netdev_dev_get_ntf_free, 241 }, 242 }; 243 244 const struct ynl_family ynl_netdev_family = { 245 .name = "netdev", 246 .ntf_info = netdev_ntf_info, 247 .ntf_info_size = MNL_ARRAY_SIZE(netdev_ntf_info), 248 }; 249