[NETFILTER] nfnetlink: use highest bit of nfa_type to indicate nested TLV

As Henrik Nordstrom pointed out, all our efforts with "split endian" (i.e.
host byte order tags, net byte order values) are useless, unless a parser
can determine whether an attribute is nested or not.

This patch steals the highest bit of nfattr.nfa_type to indicate whether
the data payload contains a nested nfattr (1) or not (0).

This will break userspace compatibility, but luckily no kernel with
nfnetlink was released so far.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Harald Welte
2005-10-10 20:52:19 -07:00
committed by David S. Miller
parent f40863cec8
commit ebe0bbf06c
2 changed files with 10 additions and 6 deletions

View File

@ -41,11 +41,15 @@ enum nfnetlink_groups {
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))
@ -59,7 +63,7 @@ struct nfattr
#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)); \