int *hlimit) 
int *hlimit, int *tclass) 
int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,		      struct ipv6_txoptions *opt,		      int *hlimit){	struct in6_pktinfo *src_info;	struct cmsghdr *cmsg;	struct ipv6_rt_hdr *rthdr;	struct ipv6_opt_hdr *hdr;	int len;	int err = 0;	for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {		int addr_type;		struct net_device *dev = NULL;		if (!CMSG_OK(msg, cmsg)) {			err = -EINVAL;			goto exit_f;		}		if (cmsg->cmsg_level != SOL_IPV6)			continue;		switch (cmsg->cmsg_type) { 		case IPV6_PKTINFO: 		case IPV6_2292PKTINFO: 			if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {				err = -EINVAL;				goto exit_f;			}			src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);						if (src_info->ipi6_ifindex) {				if (fl->oif && src_info->ipi6_ifindex != fl->oif)					return -EINVAL;				fl->oif = src_info->ipi6_ifindex;			}			addr_type = ipv6_addr_type(&src_info->ipi6_addr);			if (addr_type == IPV6_ADDR_ANY)				break;						if (addr_type & IPV6_ADDR_LINKLOCAL) {				if (!src_info->ipi6_ifindex)					return -EINVAL;				else {					dev = dev_get_by_index(src_info->ipi6_ifindex);					if (!dev)						return -ENODEV;				}			}			if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) {				if (dev)					dev_put(dev);				err = -EINVAL;				goto exit_f;			}			if (dev)				dev_put(dev);			ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr);			break;		case IPV6_FLOWINFO:                        if (cmsg->cmsg_len < CMSG_LEN(4)) {				err = -EINVAL;				goto exit_f;			}			if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) {				if ((fl->fl6_flowlabel^*(u32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {					err = -EINVAL;					goto exit_f;				}			}			fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);			break;		case IPV6_2292HOPOPTS:		case IPV6_HOPOPTS:                        if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {				err = -EINVAL;				goto exit_f;			}			hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);			len = ((hdr->hdrlen + 1) << 3);			if (cmsg->cmsg_len < CMSG_LEN(len)) {				err = -EINVAL;				goto exit_f;			}			if (!capable(CAP_NET_RAW)) {				err = -EPERM;				goto exit_f;			}			opt->opt_nflen += len;			opt->hopopt = hdr;			break;		case IPV6_2292DSTOPTS:                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {				err = -EINVAL;				goto exit_f;			}			hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);			len = ((hdr->hdrlen + 1) << 3);			if (cmsg->cmsg_len < CMSG_LEN(len)) {				err = -EINVAL;				goto exit_f;			}			if (!capable(CAP_NET_RAW)) {				err = -EPERM;				goto exit_f;			}			if (opt->dst1opt) {				err = -EINVAL;				goto exit_f;			}			opt->opt_flen += len;			opt->dst1opt = hdr;			break;		case IPV6_DSTOPTS:		case IPV6_RTHDRDSTOPTS:			if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {				err = -EINVAL;				goto exit_f;			}			hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);			len = ((hdr->hdrlen + 1) << 3);			if (cmsg->cmsg_len < CMSG_LEN(len)) {				err = -EINVAL;				goto exit_f;			}			if (!capable(CAP_NET_RAW)) {				err = -EPERM;				goto exit_f;			}			if (cmsg->cmsg_type == IPV6_DSTOPTS) {				opt->opt_flen += len;				opt->dst1opt = hdr;			} else {				opt->opt_nflen += len;				opt->dst0opt = hdr;			}			break;		case IPV6_2292RTHDR:		case IPV6_RTHDR:                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {				err = -EINVAL;				goto exit_f;			}			rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);			/*			 *	TYPE 0			 */			if (rthdr->type) {				err = -EINVAL;				goto exit_f;			}			len = ((rthdr->hdrlen + 1) << 3);                        if (cmsg->cmsg_len < CMSG_LEN(len)) {				err = -EINVAL;				goto exit_f;			}			/* segments left must also match */			if ((rthdr->hdrlen >> 1) != rthdr->segments_left) {				err = -EINVAL;				goto exit_f;			}			opt->opt_nflen += len;			opt->srcrt = rthdr;			if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {				int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);				opt->opt_nflen += dsthdrlen;				opt->dst0opt = opt->dst1opt;				opt->dst1opt = NULL;				opt->opt_flen -= dsthdrlen;			}			break;		case IPV6_2292HOPLIMIT:		case IPV6_HOPLIMIT:			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {				err = -EINVAL;				goto exit_f;			}			*hlimit = *(int *)CMSG_DATA(cmsg);			break;		default:			LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",			               cmsg->cmsg_type);			err = -EINVAL;			break;		};	}exit_f:	return err;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/41a1f8ea4fbfcdc4232f023732584aae2220de31/datagram.c/clean/net/ipv6/datagram.c