[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(usagi-users 00052) Sugesstion for Setting the IPv6 Traffic Class



Greetings from Finland.

This is  a suggestion for setting the TC-octet on socket level. All comments 
would appreciated.

The patch below introduces a new socket option IPV6_TCLASS for SOL_IPV6. 
The option causes the traffic -- sent from the socket it was applied to -- to 
be stamped with given 8-bit Traffic Class -value. I tested it with TCP and UDP 
sockets and according to tcpdump(8) the TC-field in the IPv6-header got the 
intended value. The patch is against the current USAGI/kernel linux24-release 
from CVS.

-- 
  Sampo Saaristo
  TUT/Telecom lab

--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__
Index: include/linux/in6.h
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/include/linux/in6.h,v
retrieving revision 1.10
diff -u -r1.10 in6.h
--- include/linux/in6.h	2000/12/02 08:30:46	1.10
+++ include/linux/in6.h	2000/12/07 09:57:38
@@ -138,6 +138,7 @@
 #define IPV6_NEXTHOP		9
 #define IPV6_AUTHHDR		10
 #define IPV6_FLOWINFO		11
+#define IPV6_TCLASS		12
 
 #define IPV6_UNICAST_HOPS	16
 #define IPV6_MULTICAST_IF	17
Index: include/net/sock.h
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/include/net/sock.h,v
retrieving revision 1.7
diff -u -r1.7 sock.h
--- include/net/sock.h	2000/11/21 08:25:59	1.7
+++ include/net/sock.h	2000/12/07 09:57:38
@@ -146,6 +146,7 @@
 	struct in6_addr		*daddr_cache;
 
 	__u32			flow_label;
+	__u8                    tclass;
 	__u32			frag_size;
 	int			hop_limit;
 	int			mcast_hops;
Index: net/ipv6/ip6_output.c
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/net/ipv6/ip6_output.c,v
retrieving revision 1.4
diff -u -r1.4 ip6_output.c
--- net/ipv6/ip6_output.c	2000/11/23 10:40:00	1.4
+++ net/ipv6/ip6_output.c	2000/12/07 09:57:38
@@ -24,6 +24,7 @@
  *				etc.
  *
  *      H. von Brand    :       Added missing #include <linux/string.h>
+ *      S. Saaristo     :       Support for setting of traffic class.     
  */
 
 #include <linux/config.h>
@@ -228,8 +229,11 @@
 
 	*(u32*)hdr = __constant_htonl(0x60000000) | fl->fl6_flowlabel;
 	hlimit = -1;
-	if (np)
-		hlimit = np->hop_limit;
+	if (np){
+	        hlimit = np->hop_limit;
+                hdr->tclass1 = np->tclass>>4;
+                hdr->tclass2_flow[0] |= np->tclass << 4;
+	}
 	if (hlimit < 0)
 		hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
 
@@ -282,15 +286,15 @@
 	hdr->payload_len = htons(len);
 	hdr->nexthdr = proto;
 	hdr->hop_limit = np->hop_limit;
-
 	ipv6_addr_copy(&hdr->saddr, saddr);
 	ipv6_addr_copy(&hdr->daddr, daddr);
 
 	return 0;
 }
 
-static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, 
struct flowi *fl,
-				  int hlimit, unsigned pktlength)
+static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, 
+				  struct flowi *fl, int hlimit, u8 tclass, 
+				  unsigned pktlength)
 {
 	struct ipv6hdr *hdr;
 	
@@ -301,6 +305,8 @@
 
 	hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr));
 	hdr->hop_limit = hlimit;
+	hdr->tclass1 = tclass>>4;
+	hdr->tclass2_flow[0] |= tclass << 4;
 	hdr->nexthdr = fl->proto;
 
 	ipv6_addr_copy(&hdr->saddr, fl->nl_u.ip6_u.saddr);
@@ -328,7 +334,8 @@
 			 const void *data, struct dst_entry *dst,
 			 struct flowi *fl, struct ipv6_txoptions *opt,
 			 struct in6_addr *final_dst,
-			 int hlimit, int flags, unsigned length, int mtu)
+			 int hlimit, u8 tclass, 
+			 int flags, unsigned length, int mtu)
 {
 	struct ipv6hdr *hdr;
 	struct sk_buff *last_skb;
@@ -435,7 +442,7 @@
 
 	skb_reserve(last_skb, (dst->dev->hard_header_len + 15) & ~15);
 
-	hdr = ip6_bld_1(sk, last_skb, fl, hlimit, frag_len+unfrag_len);
+	hdr = ip6_bld_1(sk, last_skb, fl, hlimit, tclass, frag_len+unfrag_len);
 	prev_hdr = &hdr->nexthdr;
 
 	if (opt && opt->opt_nflen)
@@ -533,6 +540,7 @@
 	int err = 0;
 	unsigned int pktlength, jumbolen, mtu;
 	struct in6_addr saddr;
+	u8 tclass;
 
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
@@ -672,9 +680,12 @@
 
 		hdr = (struct ipv6hdr *) skb->tail;
 		skb->nh.ipv6h = hdr;
-
+		
+		if(np)
+		        tclass = np->tclass;
+		
 		if (!sk->protinfo.af_inet.hdrincl) {
-			ip6_bld_1(sk, skb, fl, hlimit,
+		                  ip6_bld_1(sk, skb, fl, hlimit, tclass,
 				  jumbolen ? sizeof(struct ipv6hdr) : pktlength);
 
 			if (opt || jumbolen) {
@@ -705,8 +716,8 @@
 			goto out;
 		}
 
-		err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst, hlimit,
-				    flags, length, mtu);
+		err = ip6_frag_xmit(sk, getfrag, data, dst, fl, opt, final_dst,
+				    hlimit, tclass, flags, length, mtu);
 	}
 
 	/*
Index: net/ipv6/ipv6_sockglue.c
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/net/ipv6/ipv6_sockglue.c,v
retrieving revision 1.17
diff -u -r1.17 ipv6_sockglue.c
--- net/ipv6/ipv6_sockglue.c	2000/11/14 03:27:41	1.17
+++ net/ipv6/ipv6_sockglue.c	2000/12/07 09:57:38
@@ -257,6 +257,12 @@
 		np->rxopt.bits.rxflow = valbool;
 		retv = 0;
 		break;
+        case IPV6_TCLASS:
+                if (optlen != sizeof(int))
+                        goto e_inval;
+                np->tclass = (__u8 *)val; 
+                retv = 0;
+                break;
 
 	case IPV6_PKTOPTIONS:
 	{