aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-11-20 03:49:27 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-20 03:49:27 -0500
commitd214c7537bbf2f247991fb65b3420b0b3d712c67 (patch)
tree11c26aa8c7c93d0bc15f206d65b3ddac3a6a8c33 /net
parent68fd991020fdf51bc94327d288ae4ae5d0b8dced (diff)
filter: add SKF_AD_NLATTR_NEST to look for nested attributes
SKF_AD_NLATTR allows us to find the first matching attribute in a stream of netlink attributes from one offset to the end of the netlink message. This is not suitable to look for a specific matching inside a set of nested attributes. For example, in ctnetlink messages, if we look for the CTA_V6_SRC attribute in a message that talks about an IPv4 connection, SKF_AD_NLATTR returns the offset of CTA_STATUS which has the same value of CTA_V6_SRC but outside the nest. To differenciate CTA_STATUS and CTA_V6_SRC, we would have to make assumptions on the size of the attribute and the usual offset, resulting in horrible BSF code. This patch adds SKF_AD_NLATTR_NEST, which is a variant of SKF_AD_NLATTR, that looks for an attribute inside the limits of a nested attributes, but not further. This patch validates that we have enough room to look for the nested attributes - based on a suggestion from Patrick McHardy. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/filter.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index df3744355839..d1d779ca096d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -319,6 +319,25 @@ load_b:
319 A = 0; 319 A = 0;
320 continue; 320 continue;
321 } 321 }
322 case SKF_AD_NLATTR_NEST: {
323 struct nlattr *nla;
324
325 if (skb_is_nonlinear(skb))
326 return 0;
327 if (A > skb->len - sizeof(struct nlattr))
328 return 0;
329
330 nla = (struct nlattr *)&skb->data[A];
331 if (nla->nla_len > A - skb->len)
332 return 0;
333
334 nla = nla_find_nested(nla, X);
335 if (nla)
336 A = (void *)nla - (void *)skb->data;
337 else
338 A = 0;
339 continue;
340 }
322 default: 341 default:
323 return 0; 342 return 0;
324 } 343 }