aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2015-05-22 23:55:56 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-25 13:25:32 -0400
commit286c2349f6665c3e67f464a5faa14a0e28be4842 (patch)
treea6ece8bde9655f0c39edb9d10a8867be7229fb69 /net/ipv6
parent01b6961410b76af228eb993220024ff6db6ba80c (diff)
ipv6: Clean up ipv6_select_ident() and ip6_fragment()
This patch changes the ipv6_select_ident() signature to return a fragment id instead of taking a whole frag_hdr as a param to only set the frag_hdr->identification. It also cleans up ip6_fragment() to obtain the fragment id at the beginning instead of using multiple "if" later to check fragment id has been generated or not. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Cc: Hannes Frederic Sowa <hannes@stressinduktion.org> Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_output.c17
-rw-r--r--net/ipv6/output_core.c5
2 files changed, 8 insertions, 14 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index bc09cb97b840..05e2cdf938bd 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -551,7 +551,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
551 struct frag_hdr *fh; 551 struct frag_hdr *fh;
552 unsigned int mtu, hlen, left, len; 552 unsigned int mtu, hlen, left, len;
553 int hroom, troom; 553 int hroom, troom;
554 __be32 frag_id = 0; 554 __be32 frag_id;
555 int ptr, offset = 0, err = 0; 555 int ptr, offset = 0, err = 0;
556 u8 *prevhdr, nexthdr = 0; 556 u8 *prevhdr, nexthdr = 0;
557 struct net *net = dev_net(skb_dst(skb)->dev); 557 struct net *net = dev_net(skb_dst(skb)->dev);
@@ -584,6 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
584 } 584 }
585 mtu -= hlen + sizeof(struct frag_hdr); 585 mtu -= hlen + sizeof(struct frag_hdr);
586 586
587 frag_id = ipv6_select_ident(net, rt);
588
587 if (skb_has_frag_list(skb)) { 589 if (skb_has_frag_list(skb)) {
588 int first_len = skb_pagelen(skb); 590 int first_len = skb_pagelen(skb);
589 struct sk_buff *frag2; 591 struct sk_buff *frag2;
@@ -632,11 +634,10 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
632 skb_reset_network_header(skb); 634 skb_reset_network_header(skb);
633 memcpy(skb_network_header(skb), tmp_hdr, hlen); 635 memcpy(skb_network_header(skb), tmp_hdr, hlen);
634 636
635 ipv6_select_ident(net, fh, rt);
636 fh->nexthdr = nexthdr; 637 fh->nexthdr = nexthdr;
637 fh->reserved = 0; 638 fh->reserved = 0;
638 fh->frag_off = htons(IP6_MF); 639 fh->frag_off = htons(IP6_MF);
639 frag_id = fh->identification; 640 fh->identification = frag_id;
640 641
641 first_len = skb_pagelen(skb); 642 first_len = skb_pagelen(skb);
642 skb->data_len = first_len - skb_headlen(skb); 643 skb->data_len = first_len - skb_headlen(skb);
@@ -778,11 +779,7 @@ slow_path:
778 */ 779 */
779 fh->nexthdr = nexthdr; 780 fh->nexthdr = nexthdr;
780 fh->reserved = 0; 781 fh->reserved = 0;
781 if (!frag_id) { 782 fh->identification = frag_id;
782 ipv6_select_ident(net, fh, rt);
783 frag_id = fh->identification;
784 } else
785 fh->identification = frag_id;
786 783
787 /* 784 /*
788 * Copy a block of the IP datagram. 785 * Copy a block of the IP datagram.
@@ -1064,7 +1061,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1064 1061
1065{ 1062{
1066 struct sk_buff *skb; 1063 struct sk_buff *skb;
1067 struct frag_hdr fhdr;
1068 int err; 1064 int err;
1069 1065
1070 /* There is support for UDP large send offload by network 1066 /* There is support for UDP large send offload by network
@@ -1106,8 +1102,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1106 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - 1102 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
1107 sizeof(struct frag_hdr)) & ~7; 1103 sizeof(struct frag_hdr)) & ~7;
1108 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1104 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1109 ipv6_select_ident(sock_net(sk), &fhdr, rt); 1105 skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk), rt);
1110 skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
1111 1106
1112append: 1107append:
1113 return skb_append_datato_frags(sk, skb, getfrag, from, 1108 return skb_append_datato_frags(sk, skb, getfrag, from,
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 85892af57364..ef0e2326496b 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -60,8 +60,7 @@ void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb)
60} 60}
61EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); 61EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
62 62
63void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, 63u32 ipv6_select_ident(struct net *net, struct rt6_info *rt)
64 struct rt6_info *rt)
65{ 64{
66 static u32 ip6_idents_hashrnd __read_mostly; 65 static u32 ip6_idents_hashrnd __read_mostly;
67 u32 id; 66 u32 id;
@@ -70,7 +69,7 @@ void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr,
70 69
71 id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr, 70 id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr,
72 &rt->rt6i_src.addr); 71 &rt->rt6i_src.addr);
73 fhdr->identification = htonl(id); 72 return htonl(id);
74} 73}
75EXPORT_SYMBOL(ipv6_select_ident); 74EXPORT_SYMBOL(ipv6_select_ident);
76 75