diff options
author | Martin KaFai Lau <kafai@fb.com> | 2015-05-22 23:55:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-25 13:25:32 -0400 |
commit | 286c2349f6665c3e67f464a5faa14a0e28be4842 (patch) | |
tree | a6ece8bde9655f0c39edb9d10a8867be7229fb69 /net/ipv6 | |
parent | 01b6961410b76af228eb993220024ff6db6ba80c (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.c | 17 | ||||
-rw-r--r-- | net/ipv6/output_core.c | 5 |
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 | ||
1112 | append: | 1107 | append: |
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 | } |
61 | EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); | 61 | EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); |
62 | 62 | ||
63 | void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, | 63 | u32 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 | } |
75 | EXPORT_SYMBOL(ipv6_select_ident); | 74 | EXPORT_SYMBOL(ipv6_select_ident); |
76 | 75 | ||