Blame view
net/ipv6/output_core.c
4.28 KB
3c73a0368 ipv6: Update ipv6... |
1 2 3 4 5 |
/* * IPv6 library code, needed by static components when full IPv6 support is * not configured or static. These functions are needed by GSO/GRO implementation. */ #include <linux/export.h> |
5188cd44c drivers/net, ipv6... |
6 |
#include <net/ip.h> |
3c73a0368 ipv6: Update ipv6... |
7 8 |
#include <net/ipv6.h> #include <net/ip6_fib.h> |
3ce9b35ff ipv6: move ip6_ds... |
9 |
#include <net/addrconf.h> |
6dfac5c33 ipv6: strengthen ... |
10 |
#include <net/secure_seq.h> |
a263653ed netfilter: don't ... |
11 |
#include <linux/netfilter.h> |
3c73a0368 ipv6: Update ipv6... |
12 |
|
5a352dd0a ipv6: hash net pt... |
13 |
static u32 __ipv6_select_ident(struct net *net, u32 hashrnd, |
fd0273d79 ipv6: Remove exte... |
14 15 |
const struct in6_addr *dst, const struct in6_addr *src) |
0508c07f5 ipv6: Select frag... |
16 17 18 19 20 |
{ u32 hash, id; hash = __ipv6_addr_jhash(dst, hashrnd); hash = __ipv6_addr_jhash(src, hash); |
5a352dd0a ipv6: hash net pt... |
21 |
hash ^= net_hash_mix(net); |
0508c07f5 ipv6: Select frag... |
22 23 24 25 26 27 28 29 30 31 32 |
/* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve, * set the hight order instead thus minimizing possible future * collisions. */ id = ip_idents_reserve(hash, 1); if (unlikely(!id)) id = 1 << 31; return id; } |
5188cd44c drivers/net, ipv6... |
33 34 35 36 37 38 39 40 |
/* This function exists only for tap drivers that must support broken * clients requesting UFO without specifying an IPv6 fragment ID. * * This is similar to ipv6_select_ident() but we use an independent hash * seed to limit information leakage. * * The network header must be set before calling this. */ |
60335608e net: accept UFO d... |
41 |
__be32 ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb) |
5188cd44c drivers/net, ipv6... |
42 43 44 45 |
{ static u32 ip6_proxy_idents_hashrnd __read_mostly; struct in6_addr buf[2]; struct in6_addr *addrs; |
0508c07f5 ipv6: Select frag... |
46 |
u32 id; |
5188cd44c drivers/net, ipv6... |
47 48 49 50 51 52 |
addrs = skb_header_pointer(skb, skb_network_offset(skb) + offsetof(struct ipv6hdr, saddr), sizeof(buf), buf); if (!addrs) |
60335608e net: accept UFO d... |
53 |
return 0; |
5188cd44c drivers/net, ipv6... |
54 55 56 |
net_get_random_once(&ip6_proxy_idents_hashrnd, sizeof(ip6_proxy_idents_hashrnd)); |
5a352dd0a ipv6: hash net pt... |
57 |
id = __ipv6_select_ident(net, ip6_proxy_idents_hashrnd, |
0508c07f5 ipv6: Select frag... |
58 |
&addrs[1], &addrs[0]); |
60335608e net: accept UFO d... |
59 |
return htonl(id); |
5188cd44c drivers/net, ipv6... |
60 61 |
} EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); |
7f1598678 ipv6: ipv6_select... |
62 63 64 |
__be32 ipv6_select_ident(struct net *net, const struct in6_addr *daddr, const struct in6_addr *saddr) |
0508c07f5 ipv6: Select frag... |
65 66 67 68 69 |
{ static u32 ip6_idents_hashrnd __read_mostly; u32 id; net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); |
fd0273d79 ipv6: Remove exte... |
70 |
id = __ipv6_select_ident(net, ip6_idents_hashrnd, daddr, saddr); |
286c2349f ipv6: Clean up ip... |
71 |
return htonl(id); |
0508c07f5 ipv6: Select frag... |
72 73 |
} EXPORT_SYMBOL(ipv6_select_ident); |
3c73a0368 ipv6: Update ipv6... |
74 75 |
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) { |
6399f1fae ipv6: avoid overf... |
76 |
unsigned int offset = sizeof(struct ipv6hdr); |
29a3cad5c ipv6: Correct com... |
77 78 |
unsigned int packet_len = skb_tail_pointer(skb) - skb_network_header(skb); |
3c73a0368 ipv6: Update ipv6... |
79 80 |
int found_rhdr = 0; *nexthdr = &ipv6_hdr(skb)->nexthdr; |
2423496af ipv6: Prevent ove... |
81 82 |
while (offset <= packet_len) { struct ipv6_opt_hdr *exthdr; |
3c73a0368 ipv6: Update ipv6... |
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
switch (**nexthdr) { case NEXTHDR_HOP: break; case NEXTHDR_ROUTING: found_rhdr = 1; break; case NEXTHDR_DEST: #if IS_ENABLED(CONFIG_IPV6_MIP6) if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) break; #endif if (found_rhdr) return offset; break; |
67ba4152e ipv6: White-space... |
99 |
default: |
3c73a0368 ipv6: Update ipv6... |
100 101 |
return offset; } |
2423496af ipv6: Prevent ove... |
102 103 |
if (offset + sizeof(struct ipv6_opt_hdr) > packet_len) return -EINVAL; |
3c73a0368 ipv6: Update ipv6... |
104 105 |
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + offset); |
3de33e1ba ipv6: accept 64k ... |
106 107 |
offset += ipv6_optlen(exthdr); if (offset > IPV6_MAXPLEN) |
6399f1fae ipv6: avoid overf... |
108 |
return -EINVAL; |
2423496af ipv6: Prevent ove... |
109 |
*nexthdr = &exthdr->nexthdr; |
3c73a0368 ipv6: Update ipv6... |
110 |
} |
2423496af ipv6: Prevent ove... |
111 |
return -EINVAL; |
3c73a0368 ipv6: Update ipv6... |
112 113 |
} EXPORT_SYMBOL(ip6_find_1stfragopt); |
3ce9b35ff ipv6: move ip6_ds... |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
#if IS_ENABLED(CONFIG_IPV6) int ip6_dst_hoplimit(struct dst_entry *dst) { int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); if (hoplimit == 0) { struct net_device *dev = dst->dev; struct inet6_dev *idev; rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) hoplimit = idev->cnf.hop_limit; else hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit; rcu_read_unlock(); } return hoplimit; } EXPORT_SYMBOL(ip6_dst_hoplimit); #endif |
788787b55 ipv6: move ip6_lo... |
135 |
|
cf91a99da ipv4, ipv6: Pass ... |
136 |
int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
788787b55 ipv6: move ip6_lo... |
137 138 139 140 141 142 143 |
{ int len; len = skb->len - sizeof(struct ipv6hdr); if (len > IPV6_MAXPLEN) len = 0; ipv6_hdr(skb)->payload_len = htons(len); |
f6c20c596 net: ipv6: Fixed ... |
144 |
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
788787b55 ipv6: move ip6_lo... |
145 |
|
a8e3e1a9f net: l3mdev: Add ... |
146 147 148 149 150 151 |
/* if egress device is enslaved to an L3 master device pass the * skb to its handler for processing */ skb = l3mdev_ip6_out(sk, skb); if (unlikely(!skb)) return 0; |
b4e479a96 ipv6: Set skb->pr... |
152 |
skb->protocol = htons(ETH_P_IPV6); |
29a26a568 netfilter: Pass s... |
153 154 |
return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, NULL, skb_dst(skb)->dev, |
13206b6bf net: Pass net int... |
155 |
dst_output); |
788787b55 ipv6: move ip6_lo... |
156 157 |
} EXPORT_SYMBOL_GPL(__ip6_local_out); |
33224b16f ipv4, ipv6: Pass ... |
158 |
int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
788787b55 ipv6: move ip6_lo... |
159 160 |
{ int err; |
cf91a99da ipv4, ipv6: Pass ... |
161 |
err = __ip6_local_out(net, sk, skb); |
788787b55 ipv6: move ip6_lo... |
162 |
if (likely(err == 1)) |
13206b6bf net: Pass net int... |
163 |
err = dst_output(net, sk, skb); |
788787b55 ipv6: move ip6_lo... |
164 165 166 167 |
return err; } EXPORT_SYMBOL_GPL(ip6_local_out); |