1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 3 /* 4 * NETLINK Netlink attributes 5 * 6 * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch> 7 */ 8 9 #include <errno.h> 10 #include "nlattr.h" 11 #include <linux/rtnetlink.h> 12 #include <string.h> 13 #include <stdio.h> 14 15 static uint16_t nla_attr_minlen[LIBBPF_NLA_TYPE_MAX+1] = { 16 [LIBBPF_NLA_U8] = sizeof(uint8_t), 17 [LIBBPF_NLA_U16] = sizeof(uint16_t), 18 [LIBBPF_NLA_U32] = sizeof(uint32_t), 19 [LIBBPF_NLA_U64] = sizeof(uint64_t), 20 [LIBBPF_NLA_STRING] = 1, 21 [LIBBPF_NLA_FLAG] = 0, 22 }; 23 24 static struct nlattr *nla_next(const struct nlattr *nla, int *remaining) 25 { 26 int totlen = NLA_ALIGN(nla->nla_len); 27 28 *remaining -= totlen; 29 return (struct nlattr *) ((char *) nla + totlen); 30 } 31 32 static int nla_ok(const struct nlattr *nla, int remaining) 33 { 34 return remaining >= sizeof(*nla) && 35 nla->nla_len >= sizeof(*nla) && 36 nla->nla_len <= remaining; 37 } 38 39 static int nla_type(const struct nlattr *nla) 40 { 41 return nla->nla_type & NLA_TYPE_MASK; 42 } 43 44 static int validate_nla(struct nlattr *nla, int maxtype, 45 struct libbpf_nla_policy *policy) 46 { 47 struct libbpf_nla_policy *pt; 48 unsigned int minlen = 0; 49 int type = nla_type(nla); 50 51 if (type < 0 || type > maxtype) 52 return 0; 53 54 pt = &policy[type]; 55 56 if (pt->type > LIBBPF_NLA_TYPE_MAX) 57 return 0; 58 59 if (pt->minlen) 60 minlen = pt->minlen; 61 else if (pt->type != LIBBPF_NLA_UNSPEC) 62 minlen = nla_attr_minlen[pt->type]; 63 64 if (libbpf_nla_len(nla) < minlen) 65 return -1; 66 67 if (pt->maxlen && libbpf_nla_len(nla) > pt->maxlen) 68 return -1; 69 70 if (pt->type == LIBBPF_NLA_STRING) { 71 char *data = libbpf_nla_data(nla); 72 73 if (data[libbpf_nla_len(nla) - 1] != '\0') 74 return -1; 75 } 76 77 return 0; 78 } 79 80 static inline int nlmsg_len(const struct nlmsghdr *nlh) 81 { 82 return nlh->nlmsg_len - NLMSG_HDRLEN; 83 } 84 85 /** 86 * Create attribute index based on a stream of attributes. 87 * @arg tb Index array to be filled (maxtype+1 elements). 88 * @arg maxtype Maximum attribute type expected and accepted. 89 * @arg head Head of attribute stream. 90 * @arg len Length of attribute stream. 91 * @arg policy Attribute validation policy. 92 * 93 * Iterates over the stream of attributes and stores a pointer to each 94 * attribute in the index array using the attribute type as index to 95 * the array. Attribute with a type greater than the maximum type 96 * specified will be silently ignored in order to maintain backwards 97 * compatibility. If \a policy is not NULL, the attribute will be 98 * validated using the specified policy. 99 * 100 * @see nla_validate 101 * @return 0 on success or a negative error code. 102 */ 103 int libbpf_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, 104 int len, struct libbpf_nla_policy *policy) 105 { 106 struct nlattr *nla; 107 int rem, err; 108 109 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); 110 111 libbpf_nla_for_each_attr(nla, head, len, rem) { 112 int type = nla_type(nla); 113 114 if (type > maxtype) 115 continue; 116 117 if (policy) { 118 err = validate_nla(nla, maxtype, policy); 119 if (err < 0) 120 goto errout; 121 } 122 123 if (tb[type]) 124 fprintf(stderr, "Attribute of type %#x found multiple times in message, " 125 "previous attribute is being ignored.\n", type); 126 127 tb[type] = nla; 128 } 129 130 err = 0; 131 errout: 132 return err; 133 } 134 135 /** 136 * Create attribute index based on nested attribute 137 * @arg tb Index array to be filled (maxtype+1 elements). 138 * @arg maxtype Maximum attribute type expected and accepted. 139 * @arg nla Nested Attribute. 140 * @arg policy Attribute validation policy. 141 * 142 * Feeds the stream of attributes nested into the specified attribute 143 * to libbpf_nla_parse(). 144 * 145 * @see libbpf_nla_parse 146 * @return 0 on success or a negative error code. 147 */ 148 int libbpf_nla_parse_nested(struct nlattr *tb[], int maxtype, 149 struct nlattr *nla, 150 struct libbpf_nla_policy *policy) 151 { 152 return libbpf_nla_parse(tb, maxtype, libbpf_nla_data(nla), 153 libbpf_nla_len(nla), policy); 154 } 155 156 /* dump netlink extended ack error message */ 157 int libbpf_nla_dump_errormsg(struct nlmsghdr *nlh) 158 { 159 struct libbpf_nla_policy extack_policy[NLMSGERR_ATTR_MAX + 1] = { 160 [NLMSGERR_ATTR_MSG] = { .type = LIBBPF_NLA_STRING }, 161 [NLMSGERR_ATTR_OFFS] = { .type = LIBBPF_NLA_U32 }, 162 }; 163 struct nlattr *tb[NLMSGERR_ATTR_MAX + 1], *attr; 164 struct nlmsgerr *err; 165 char *errmsg = NULL; 166 int hlen, alen; 167 168 /* no TLVs, nothing to do here */ 169 if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS)) 170 return 0; 171 172 err = (struct nlmsgerr *)NLMSG_DATA(nlh); 173 hlen = sizeof(*err); 174 175 /* if NLM_F_CAPPED is set then the inner err msg was capped */ 176 if (!(nlh->nlmsg_flags & NLM_F_CAPPED)) 177 hlen += nlmsg_len(&err->msg); 178 179 attr = (struct nlattr *) ((void *) err + hlen); 180 alen = nlh->nlmsg_len - hlen; 181 182 if (libbpf_nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen, 183 extack_policy) != 0) { 184 fprintf(stderr, 185 "Failed to parse extended error attributes\n"); 186 return 0; 187 } 188 189 if (tb[NLMSGERR_ATTR_MSG]) 190 errmsg = (char *) libbpf_nla_data(tb[NLMSGERR_ATTR_MSG]); 191 192 fprintf(stderr, "Kernel error message: %s\n", errmsg); 193 194 return 0; 195 } 196