struct nfattr
{
u_int16_t nfa_len;
- u_int16_t nfa_type;
+ u_int16_t nfa_type; /* we use 15 bits for the type, and the highest
+ * bit to indicate whether the payload is nested */
} __attribute__ ((packed));
-/* FIXME: Shamelessly copy and pasted from rtnetlink.h, it's time
- * to put this in a generic file */
+/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from
+ * rtnetlink.h, it's time to put this in a generic file */
+
+#define NFNL_NFA_NEST 0x8000
+#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
#define NFA_ALIGNTO 4
#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
#define NFA_NEST(skb, type) \
({ struct nfattr *__start = (struct nfattr *) (skb)->tail; \
- NFA_PUT(skb, type, 0, NULL); \
+ NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \
__start; })
#define NFA_NEST_END(skb, start) \
({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \
memset(tb, 0, sizeof(struct nfattr *) * maxattr);
while (NFA_OK(nfa, len)) {
- unsigned flavor = nfa->nfa_type;
+ unsigned flavor = NFA_TYPE(nfa);
if (flavor && flavor <= maxattr)
tb[flavor-1] = nfa;
nfa = NFA_NEXT(nfa, len);
int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
while (NFA_OK(attr, attrlen)) {
- unsigned flavor = attr->nfa_type;
+ unsigned flavor = NFA_TYPE(attr);
if (flavor) {
if (flavor > attr_count)
return -EINVAL;