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