Commit 286c2349 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by David S. Miller

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: default avatarMartin 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: default avatarDavid S. Miller <davem@davemloft.net>
parent 01b69614
...@@ -671,8 +671,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add ...@@ -671,8 +671,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
} }
void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, u32 ipv6_select_ident(struct net *net, struct rt6_info *rt);
struct rt6_info *rt);
void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb); void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
int ip6_dst_hoplimit(struct dst_entry *dst); int ip6_dst_hoplimit(struct dst_entry *dst);
......
...@@ -551,7 +551,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb, ...@@ -551,7 +551,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
struct frag_hdr *fh; struct frag_hdr *fh;
unsigned int mtu, hlen, left, len; unsigned int mtu, hlen, left, len;
int hroom, troom; int hroom, troom;
__be32 frag_id = 0; __be32 frag_id;
int ptr, offset = 0, err = 0; int ptr, offset = 0, err = 0;
u8 *prevhdr, nexthdr = 0; u8 *prevhdr, nexthdr = 0;
struct net *net = dev_net(skb_dst(skb)->dev); struct net *net = dev_net(skb_dst(skb)->dev);
...@@ -584,6 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb, ...@@ -584,6 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
} }
mtu -= hlen + sizeof(struct frag_hdr); mtu -= hlen + sizeof(struct frag_hdr);
frag_id = ipv6_select_ident(net, rt);
if (skb_has_frag_list(skb)) { if (skb_has_frag_list(skb)) {
int first_len = skb_pagelen(skb); int first_len = skb_pagelen(skb);
struct sk_buff *frag2; struct sk_buff *frag2;
...@@ -632,11 +634,10 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb, ...@@ -632,11 +634,10 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
skb_reset_network_header(skb); skb_reset_network_header(skb);
memcpy(skb_network_header(skb), tmp_hdr, hlen); memcpy(skb_network_header(skb), tmp_hdr, hlen);
ipv6_select_ident(net, fh, rt);
fh->nexthdr = nexthdr; fh->nexthdr = nexthdr;
fh->reserved = 0; fh->reserved = 0;
fh->frag_off = htons(IP6_MF); fh->frag_off = htons(IP6_MF);
frag_id = fh->identification; fh->identification = frag_id;
first_len = skb_pagelen(skb); first_len = skb_pagelen(skb);
skb->data_len = first_len - skb_headlen(skb); skb->data_len = first_len - skb_headlen(skb);
...@@ -778,10 +779,6 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb, ...@@ -778,10 +779,6 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
*/ */
fh->nexthdr = nexthdr; fh->nexthdr = nexthdr;
fh->reserved = 0; fh->reserved = 0;
if (!frag_id) {
ipv6_select_ident(net, fh, rt);
frag_id = fh->identification;
} else
fh->identification = frag_id; fh->identification = frag_id;
/* /*
...@@ -1064,7 +1061,6 @@ static inline int ip6_ufo_append_data(struct sock *sk, ...@@ -1064,7 +1061,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct frag_hdr fhdr;
int err; int err;
/* There is support for UDP large send offload by network /* 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,8 +1102,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
sizeof(struct frag_hdr)) & ~7; sizeof(struct frag_hdr)) & ~7;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP; skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
ipv6_select_ident(sock_net(sk), &fhdr, rt); skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk), rt);
skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
append: append:
return skb_append_datato_frags(sk, skb, getfrag, from, return skb_append_datato_frags(sk, skb, getfrag, from,
......
...@@ -60,8 +60,7 @@ void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb) ...@@ -60,8 +60,7 @@ void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb)
} }
EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, u32 ipv6_select_ident(struct net *net, struct rt6_info *rt)
struct rt6_info *rt)
{ {
static u32 ip6_idents_hashrnd __read_mostly; static u32 ip6_idents_hashrnd __read_mostly;
u32 id; u32 id;
...@@ -70,7 +69,7 @@ void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr, ...@@ -70,7 +69,7 @@ void ipv6_select_ident(struct net *net, struct frag_hdr *fhdr,
id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr, id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr,
&rt->rt6i_src.addr); &rt->rt6i_src.addr);
fhdr->identification = htonl(id); return htonl(id);
} }
EXPORT_SYMBOL(ipv6_select_ident); EXPORT_SYMBOL(ipv6_select_ident);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment