Commit 41a1f8ea authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki
Browse files

[IPV6]: Support IPV6_{RECV,}TCLASS socket options / ancillary data.



Based on patch from David L Stevens <dlstevens@us.ibm.com>

Signed-off-by: default avatarDavid L Stevens <dlstevens@us.ibm.com>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
parent 333fad53
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -219,9 +219,7 @@ struct in6_flowlabel_req
#define IPV6_DSTOPTS		63
#define IPV6_RECVHOPLIMIT	64
#define IPV6_HOPLIMIT		65
#if 0
#define IPV6_RECVTCLASS		66
#define IPV6_TCLASS		67
#endif

#endif
+4 −1
Original line number Diff line number Diff line
@@ -245,7 +245,8 @@ struct ipv6_pinfo {
				ohopopts:1,
				dstopts:1,
				odstopts:1,
                                rxflow:1;
                                rxflow:1,
				rxtclass:1;
		} bits;
		__u16		all;
	} rxopt;
@@ -256,6 +257,7 @@ struct ipv6_pinfo {
	                        sndflow:1,
				pmtudisc:2,
				ipv6only:1;
	__u8			tclass;

	__u32			dst_cookie;

@@ -269,6 +271,7 @@ struct ipv6_pinfo {
		struct ipv6_txoptions *opt;
		struct rt6_info	*rt;
		int hop_limit;
		int tclass;
	} cork;
};

+1 −0
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ extern int ip6_append_data(struct sock *sk,
						int length,
						int transhdrlen,
		      				int hlimit,
		      				int tclass,
						struct ipv6_txoptions *opt,
						struct flowi *fl,
						struct rt6_info *rt,
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ extern int datagram_recv_ctl(struct sock *sk,
extern int			datagram_send_ctl(struct msghdr *msg,
						  struct flowi *fl,
						  struct ipv6_txoptions *opt,
						  int *hlimit);
						  int *hlimit, int *tclass);

#define		LOOPBACK4_IPV6		__constant_htonl(0x7f000006)

+24 −1
Original line number Diff line number Diff line
@@ -390,6 +390,11 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
		put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
	}

	if (np->rxopt.bits.rxtclass) {
		int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
		put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
	}

	if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
		u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
		put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
@@ -479,7 +484,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)

int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
		      struct ipv6_txoptions *opt,
		      int *hlimit)
		      int *hlimit, int *tclass)
{
	struct in6_pktinfo *src_info;
	struct cmsghdr *cmsg;
@@ -682,6 +687,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
			*hlimit = *(int *)CMSG_DATA(cmsg);
			break;

		case IPV6_TCLASS:
		    {
			int tc;

			err = -EINVAL;
			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
				goto exit_f;
			}

			tc = *(int *)CMSG_DATA(cmsg);
			if (tc < 0 || tc > 0xff)
				goto exit_f;

			err = 0;
			*tclass = tc;

			break;
		    }
		default:
			LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
			               cmsg->cmsg_type);
Loading