Skip to content

Commit

Permalink
ipv6: Introduce ip6_flow_hdr() to fill version, tclass and flowlabel.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
YOSHIFUJI Hideaki / 吉藤英明 authored and David S. Miller committed Jan 14, 2013
1 parent 00494be commit 3e4e4c1
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 13 deletions.
9 changes: 9 additions & 0 deletions include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,15 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add

extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);

/*
* Header manipulation
*/
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
__be32 flowlabel)
{
*(__be32 *)hdr = ntohl(0x60000000 | (tclass << 20)) | flowlabel;
}

/*
* Prototypes exported by ipv6
*/
Expand Down
6 changes: 2 additions & 4 deletions net/ipv6/ip6_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,9 +772,7 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
* Push down and install the IP header.
*/
ipv6h = ipv6_hdr(skb);
*(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel);
ipv6h->hop_limit = tunnel->parms.hop_limit;
ipv6h->nexthdr = proto;
ipv6h->saddr = fl6->saddr;
Expand Down Expand Up @@ -1240,7 +1238,7 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
__be16 *p = (__be16 *)(ipv6h+1);

*(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000);
ip6_flow_hdr(ipv6h, 0, t->fl.u.ip6.flowlabel);
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = NEXTHDR_GRE;
ipv6h->saddr = t->parms.laddr;
Expand Down
8 changes: 3 additions & 5 deletions net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
if (hlimit < 0)
hlimit = ip6_dst_hoplimit(dst);

*(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
ip6_flow_hdr(hdr, tclass, fl6->flowlabel);

hdr->payload_len = htons(seg_len);
hdr->nexthdr = proto;
Expand Down Expand Up @@ -267,7 +267,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
skb_put(skb, sizeof(struct ipv6hdr));
hdr = ipv6_hdr(skb);

*(__be32*)hdr = htonl(0x60000000);
ip6_flow_hdr(hdr, 0, 0);

hdr->payload_len = htons(len);
hdr->nexthdr = proto;
Expand Down Expand Up @@ -1548,9 +1548,7 @@ int ip6_push_pending_frames(struct sock *sk)
skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);

*(__be32*)hdr = fl6->flowlabel |
htonl(0x60000000 | ((int)np->cork.tclass << 20));

ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel);
hdr->hop_limit = np->cork.hop_limit;
hdr->nexthdr = proto;
hdr->saddr = fl6->saddr;
Expand Down
4 changes: 1 addition & 3 deletions net/ipv6/ip6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,9 +1030,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ipv6h = ipv6_hdr(skb);
*(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
ip6_flow_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield), fl6->flowlabel);
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = proto;
ipv6h->saddr = fl6->saddr;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/netfilter/ip6t_REJECT.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
skb_put(nskb, sizeof(struct ipv6hdr));
skb_reset_network_header(nskb);
ip6h = ipv6_hdr(nskb);
*(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20));
ip6_flow_hdr(ip6h, tclass, 0);
ip6h->hop_limit = ip6_dst_hoplimit(dst);
ip6h->nexthdr = IPPROTO_TCP;
ip6h->saddr = oip6h->daddr;
Expand Down

0 comments on commit 3e4e4c1

Please sign in to comment.