diff options
| -rw-r--r-- | net/ipv6/output_core.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index d1b35d377e62..6313abd53c9d 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c | |||
| @@ -6,24 +6,24 @@ | |||
| 6 | #include <net/ipv6.h> | 6 | #include <net/ipv6.h> |
| 7 | #include <net/ip6_fib.h> | 7 | #include <net/ip6_fib.h> |
| 8 | #include <net/addrconf.h> | 8 | #include <net/addrconf.h> |
| 9 | #include <net/secure_seq.h> | ||
| 9 | 10 | ||
| 10 | void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) | 11 | void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) |
| 11 | { | 12 | { |
| 12 | static atomic_t ipv6_fragmentation_id; | 13 | static atomic_t ipv6_fragmentation_id; |
| 14 | struct in6_addr addr; | ||
| 13 | int old, new; | 15 | int old, new; |
| 14 | 16 | ||
| 15 | #if IS_ENABLED(CONFIG_IPV6) | 17 | #if IS_ENABLED(CONFIG_IPV6) |
| 16 | if (rt) { | 18 | struct inet_peer *peer; |
| 17 | struct inet_peer *peer; | 19 | struct net *net; |
| 18 | struct net *net; | 20 | |
| 19 | 21 | net = dev_net(rt->dst.dev); | |
| 20 | net = dev_net(rt->dst.dev); | 22 | peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); |
| 21 | peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); | 23 | if (peer) { |
| 22 | if (peer) { | 24 | fhdr->identification = htonl(inet_getid(peer, 0)); |
| 23 | fhdr->identification = htonl(inet_getid(peer, 0)); | 25 | inet_putpeer(peer); |
| 24 | inet_putpeer(peer); | 26 | return; |
| 25 | return; | ||
| 26 | } | ||
| 27 | } | 27 | } |
| 28 | #endif | 28 | #endif |
| 29 | do { | 29 | do { |
| @@ -32,7 +32,10 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) | |||
| 32 | if (!new) | 32 | if (!new) |
| 33 | new = 1; | 33 | new = 1; |
| 34 | } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); | 34 | } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); |
| 35 | fhdr->identification = htonl(new); | 35 | |
| 36 | addr = rt->rt6i_dst.addr; | ||
| 37 | addr.s6_addr32[0] ^= (__force __be32)new; | ||
| 38 | fhdr->identification = htonl(secure_ipv6_id(addr.s6_addr32)); | ||
| 36 | } | 39 | } |
| 37 | EXPORT_SYMBOL(ipv6_select_ident); | 40 | EXPORT_SYMBOL(ipv6_select_ident); |
| 38 | 41 | ||
