 if (!rta) { memset(tree, 0, sizeof(*tree)); return 0; } 
int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,			 struct tcf_ematch_tree *tree){	int idx, list_len, matches_len, err = -EINVAL;	struct rtattr *tb[TCA_EMATCH_TREE_MAX];	struct rtattr *rt_match, *rt_hdr, *rt_list;	struct tcf_ematch_tree_hdr *tree_hdr;	struct tcf_ematch *em;	if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)		goto errout;	rt_hdr = tb[TCA_EMATCH_TREE_HDR-1];	rt_list = tb[TCA_EMATCH_TREE_LIST-1];	if (rt_hdr == NULL || rt_list == NULL)		goto errout;	if (RTA_PAYLOAD(rt_hdr) < sizeof(*tree_hdr) ||	    RTA_PAYLOAD(rt_list) < sizeof(*rt_match))		goto errout;	tree_hdr = RTA_DATA(rt_hdr);	memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr));	rt_match = RTA_DATA(rt_list);	list_len = RTA_PAYLOAD(rt_list);	matches_len = tree_hdr->nmatches * sizeof(*em);	tree->matches = kmalloc(matches_len, GFP_KERNEL);	if (tree->matches == NULL)		goto errout;	memset(tree->matches, 0, matches_len);	/* We do not use rtattr_parse_nested here because the maximum	 * number of attributes is unknown. This saves us the allocation	 * for a tb buffer which would serve no purpose at all.	 * 	 * The array of rt attributes is parsed in the order as they are	 * provided, their type must be incremental from 1 to n. Even	 * if it does not serve any real purpose, a failure of sticking	 * to this policy will result in parsing failure. */	for (idx = 0; RTA_OK(rt_match, list_len); idx++) {		err = -EINVAL;		if (rt_match->rta_type != (idx + 1))			goto errout_abort;		if (idx >= tree_hdr->nmatches)			goto errout_abort;		if (RTA_PAYLOAD(rt_match) < sizeof(struct tcf_ematch_hdr))			goto errout_abort;		em = tcf_em_get_match(tree, idx);		err = tcf_em_validate(tp, tree_hdr, em, rt_match, idx);		if (err < 0)			goto errout_abort;		rt_match = RTA_NEXT(rt_match, list_len);	}	/* Check if the number of matches provided by userspace actually	 * complies with the array of matches. The number was used for	 * the validation of references and a mismatch could lead to	 * undefined references during the matching process. */	if (idx != tree_hdr->nmatches) {		err = -EINVAL;		goto errout_abort;	}	err = 0;errout:	return err;errout_abort:	tcf_em_tree_destroy(tp, tree);	return err;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b541ca2c5a3f3f399d6f2ec9da33c1be5a8d8c19/ematch.c/clean/net/sched/ematch.c