aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-04-10 05:02:28 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-10 05:02:28 -0400
commit4738c1db1593687713869fa69e733eebc7b0d6d8 (patch)
tree4da848f5944f89cc5393f173d95227c3e76423f2 /include/linux
parent3cccd6078413e9707f0ef3652b4e6e9cb84e9fa0 (diff)
[SKFILTER]: Add SKF_ADF_NLATTR instruction
SKF_ADF_NLATTR searches for a netlink attribute, which avoids manually parsing and walking attributes. It takes the offset at which to start searching in the 'A' register and the attribute type in the 'X' register and returns the offset in the 'A' register. When the attribute is not found it returns zero. A top-level attribute can be located using a filter like this (example for nfnetlink, using struct nfgenmsg): ... { /* A = offset of first attribute */ .code = BPF_LD | BPF_IMM, .k = sizeof(struct nlmsghdr) + sizeof(struct nfgenmsg) }, { /* X = CTA_PROTOINFO */ .code = BPF_LDX | BPF_IMM, .k = CTA_PROTOINFO, }, { /* A = netlink attribute offset */ .code = BPF_LD | BPF_B | BPF_ABS, .k = SKF_AD_OFF + SKF_AD_NLATTR }, { /* Exit if not found */ .code = BPF_JMP | BPF_JEQ | BPF_K, .k = 0, .jt = <error> }, ... A nested attribute below the CTA_PROTOINFO attribute would then be parsed like this: ... { /* A += sizeof(struct nlattr) */ .code = BPF_ALU | BPF_ADD | BPF_K, .k = sizeof(struct nlattr), }, { /* X = CTA_PROTOINFO_TCP */ .code = BPF_LDX | BPF_IMM, .k = CTA_PROTOINFO_TCP, }, { /* A = netlink attribute offset */ .code = BPF_LD | BPF_B | BPF_ABS, .k = SKF_AD_OFF + SKF_AD_NLATTR }, ... The data of an attribute can be loaded into 'A' like this: ... { /* X = A (attribute offset) */ .code = BPF_MISC | BPF_TAX, }, { /* A = skb->data[X + k] */ .code = BPF_LD | BPF_B | BPF_IND, .k = sizeof(struct nlattr), }, ... Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 673e5677ebcc..b6ea9aa9e853 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -121,7 +121,8 @@ struct sock_fprog /* Required for SO_ATTACH_FILTER. */
121#define SKF_AD_PROTOCOL 0 121#define SKF_AD_PROTOCOL 0
122#define SKF_AD_PKTTYPE 4 122#define SKF_AD_PKTTYPE 4
123#define SKF_AD_IFINDEX 8 123#define SKF_AD_IFINDEX 8
124#define SKF_AD_MAX 12 124#define SKF_AD_NLATTR 12
125#define SKF_AD_MAX 16
125#define SKF_NET_OFF (-0x100000) 126#define SKF_NET_OFF (-0x100000)
126#define SKF_LL_OFF (-0x200000) 127#define SKF_LL_OFF (-0x200000)
127 128