Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv6: Introduce ip6_flow_hdr() to fill version, tclass and flowlabel.

This is not only for readability but also for optimization.
What we do here is to build the 32bit word at the beginning of the ipv6
header (the "ip6_flow" virtual member of struct ip6_hdr in RFC3542) and
we do not need to read the tclass portion of the target buffer.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

YOSHIFUJI Hideaki / 吉藤英明 and committed by
David S. Miller
3e4e4c1f 00494be4

+16 -13
+9
include/net/ipv6.h
··· 547 547 extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); 548 548 549 549 /* 550 + * Header manipulation 551 + */ 552 + static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass, 553 + __be32 flowlabel) 554 + { 555 + *(__be32 *)hdr = ntohl(0x60000000 | (tclass << 20)) | flowlabel; 556 + } 557 + 558 + /* 550 559 * Prototypes exported by ipv6 551 560 */ 552 561
+2 -4
net/ipv6/ip6_gre.c
··· 772 772 * Push down and install the IP header. 773 773 */ 774 774 ipv6h = ipv6_hdr(skb); 775 - *(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000); 776 - dsfield = INET_ECN_encapsulate(0, dsfield); 777 - ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); 775 + ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel); 778 776 ipv6h->hop_limit = tunnel->parms.hop_limit; 779 777 ipv6h->nexthdr = proto; 780 778 ipv6h->saddr = fl6->saddr; ··· 1238 1240 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen); 1239 1241 __be16 *p = (__be16 *)(ipv6h+1); 1240 1242 1241 - *(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000); 1243 + ip6_flow_hdr(ipv6h, 0, t->fl.u.ip6.flowlabel); 1242 1244 ipv6h->hop_limit = t->parms.hop_limit; 1243 1245 ipv6h->nexthdr = NEXTHDR_GRE; 1244 1246 ipv6h->saddr = t->parms.laddr;
+3 -5
net/ipv6/ip6_output.c
··· 216 216 if (hlimit < 0) 217 217 hlimit = ip6_dst_hoplimit(dst); 218 218 219 - *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel; 219 + ip6_flow_hdr(hdr, tclass, fl6->flowlabel); 220 220 221 221 hdr->payload_len = htons(seg_len); 222 222 hdr->nexthdr = proto; ··· 267 267 skb_put(skb, sizeof(struct ipv6hdr)); 268 268 hdr = ipv6_hdr(skb); 269 269 270 - *(__be32*)hdr = htonl(0x60000000); 270 + ip6_flow_hdr(hdr, 0, 0); 271 271 272 272 hdr->payload_len = htons(len); 273 273 hdr->nexthdr = proto; ··· 1548 1548 skb_reset_network_header(skb); 1549 1549 hdr = ipv6_hdr(skb); 1550 1550 1551 - *(__be32*)hdr = fl6->flowlabel | 1552 - htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1553 - 1551 + ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel); 1554 1552 hdr->hop_limit = np->cork.hop_limit; 1555 1553 hdr->nexthdr = proto; 1556 1554 hdr->saddr = fl6->saddr;
+1 -3
net/ipv6/ip6_tunnel.c
··· 1030 1030 skb_push(skb, sizeof(struct ipv6hdr)); 1031 1031 skb_reset_network_header(skb); 1032 1032 ipv6h = ipv6_hdr(skb); 1033 - *(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000); 1034 - dsfield = INET_ECN_encapsulate(0, dsfield); 1035 - ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); 1033 + ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel); 1036 1034 ipv6h->hop_limit = t->parms.hop_limit; 1037 1035 ipv6h->nexthdr = proto; 1038 1036 ipv6h->saddr = fl6->saddr;
+1 -1
net/ipv6/netfilter/ip6t_REJECT.c
··· 126 126 skb_put(nskb, sizeof(struct ipv6hdr)); 127 127 skb_reset_network_header(nskb); 128 128 ip6h = ipv6_hdr(nskb); 129 - *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); 129 + ip6_flow_hdr(ip6h, tclass, 0); 130 130 ip6h->hop_limit = ip6_dst_hoplimit(dst); 131 131 ip6h->nexthdr = IPPROTO_TCP; 132 132 ip6h->saddr = oip6h->daddr;