.. | .. |
---|
22 | 22 | #include <net/ipv6.h> |
---|
23 | 23 | #include <net/ip6_route.h> |
---|
24 | 24 | #include <net/l3mdev.h> |
---|
25 | | -#if IS_ENABLED(CONFIG_IPV6_MIP6) |
---|
26 | | -#include <net/mip6.h> |
---|
27 | | -#endif |
---|
28 | 25 | |
---|
29 | 26 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, |
---|
30 | 27 | const xfrm_address_t *saddr, |
---|
.. | .. |
---|
71 | 68 | return 0; |
---|
72 | 69 | } |
---|
73 | 70 | |
---|
74 | | -static int xfrm6_get_tos(const struct flowi *fl) |
---|
75 | | -{ |
---|
76 | | - return 0; |
---|
77 | | -} |
---|
78 | | - |
---|
79 | | -static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
---|
80 | | - int nfheader_len) |
---|
81 | | -{ |
---|
82 | | - if (dst->ops->family == AF_INET6) { |
---|
83 | | - struct rt6_info *rt = (struct rt6_info *)dst; |
---|
84 | | - path->path_cookie = rt6_get_cookie(rt); |
---|
85 | | - } |
---|
86 | | - |
---|
87 | | - path->u.rt6.rt6i_nfheader_len = nfheader_len; |
---|
88 | | - |
---|
89 | | - return 0; |
---|
90 | | -} |
---|
91 | | - |
---|
92 | 71 | static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
---|
93 | 72 | const struct flowi *fl) |
---|
94 | 73 | { |
---|
.. | .. |
---|
116 | 95 | atomic_inc(&dev_net(dev)->ipv6.rt6_stats->fib_rt_uncache); |
---|
117 | 96 | |
---|
118 | 97 | return 0; |
---|
119 | | -} |
---|
120 | | - |
---|
121 | | -static inline void |
---|
122 | | -_decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) |
---|
123 | | -{ |
---|
124 | | - struct flowi6 *fl6 = &fl->u.ip6; |
---|
125 | | - int onlyproto = 0; |
---|
126 | | - const struct ipv6hdr *hdr = ipv6_hdr(skb); |
---|
127 | | - u32 offset = sizeof(*hdr); |
---|
128 | | - struct ipv6_opt_hdr *exthdr; |
---|
129 | | - const unsigned char *nh = skb_network_header(skb); |
---|
130 | | - u16 nhoff = IP6CB(skb)->nhoff; |
---|
131 | | - int oif = 0; |
---|
132 | | - u8 nexthdr; |
---|
133 | | - |
---|
134 | | - if (!nhoff) |
---|
135 | | - nhoff = offsetof(struct ipv6hdr, nexthdr); |
---|
136 | | - |
---|
137 | | - nexthdr = nh[nhoff]; |
---|
138 | | - |
---|
139 | | - if (skb_dst(skb)) |
---|
140 | | - oif = skb_dst(skb)->dev->ifindex; |
---|
141 | | - |
---|
142 | | - memset(fl6, 0, sizeof(struct flowi6)); |
---|
143 | | - fl6->flowi6_mark = skb->mark; |
---|
144 | | - fl6->flowi6_oif = reverse ? skb->skb_iif : oif; |
---|
145 | | - |
---|
146 | | - fl6->daddr = reverse ? hdr->saddr : hdr->daddr; |
---|
147 | | - fl6->saddr = reverse ? hdr->daddr : hdr->saddr; |
---|
148 | | - |
---|
149 | | - while (nh + offset + sizeof(*exthdr) < skb->data || |
---|
150 | | - pskb_may_pull(skb, nh + offset + sizeof(*exthdr) - skb->data)) { |
---|
151 | | - nh = skb_network_header(skb); |
---|
152 | | - exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
---|
153 | | - |
---|
154 | | - switch (nexthdr) { |
---|
155 | | - case NEXTHDR_FRAGMENT: |
---|
156 | | - onlyproto = 1; |
---|
157 | | - /* fall through */ |
---|
158 | | - case NEXTHDR_ROUTING: |
---|
159 | | - case NEXTHDR_HOP: |
---|
160 | | - case NEXTHDR_DEST: |
---|
161 | | - offset += ipv6_optlen(exthdr); |
---|
162 | | - nexthdr = exthdr->nexthdr; |
---|
163 | | - exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
---|
164 | | - break; |
---|
165 | | - |
---|
166 | | - case IPPROTO_UDP: |
---|
167 | | - case IPPROTO_UDPLITE: |
---|
168 | | - case IPPROTO_TCP: |
---|
169 | | - case IPPROTO_SCTP: |
---|
170 | | - case IPPROTO_DCCP: |
---|
171 | | - if (!onlyproto && (nh + offset + 4 < skb->data || |
---|
172 | | - pskb_may_pull(skb, nh + offset + 4 - skb->data))) { |
---|
173 | | - __be16 *ports; |
---|
174 | | - |
---|
175 | | - nh = skb_network_header(skb); |
---|
176 | | - ports = (__be16 *)(nh + offset); |
---|
177 | | - fl6->fl6_sport = ports[!!reverse]; |
---|
178 | | - fl6->fl6_dport = ports[!reverse]; |
---|
179 | | - } |
---|
180 | | - fl6->flowi6_proto = nexthdr; |
---|
181 | | - return; |
---|
182 | | - |
---|
183 | | - case IPPROTO_ICMPV6: |
---|
184 | | - if (!onlyproto && (nh + offset + 2 < skb->data || |
---|
185 | | - pskb_may_pull(skb, nh + offset + 2 - skb->data))) { |
---|
186 | | - u8 *icmp; |
---|
187 | | - |
---|
188 | | - nh = skb_network_header(skb); |
---|
189 | | - icmp = (u8 *)(nh + offset); |
---|
190 | | - fl6->fl6_icmp_type = icmp[0]; |
---|
191 | | - fl6->fl6_icmp_code = icmp[1]; |
---|
192 | | - } |
---|
193 | | - fl6->flowi6_proto = nexthdr; |
---|
194 | | - return; |
---|
195 | | - |
---|
196 | | -#if IS_ENABLED(CONFIG_IPV6_MIP6) |
---|
197 | | - case IPPROTO_MH: |
---|
198 | | - offset += ipv6_optlen(exthdr); |
---|
199 | | - if (!onlyproto && (nh + offset + 3 < skb->data || |
---|
200 | | - pskb_may_pull(skb, nh + offset + 3 - skb->data))) { |
---|
201 | | - struct ip6_mh *mh; |
---|
202 | | - |
---|
203 | | - nh = skb_network_header(skb); |
---|
204 | | - mh = (struct ip6_mh *)(nh + offset); |
---|
205 | | - fl6->fl6_mh_type = mh->ip6mh_type; |
---|
206 | | - } |
---|
207 | | - fl6->flowi6_proto = nexthdr; |
---|
208 | | - return; |
---|
209 | | -#endif |
---|
210 | | - |
---|
211 | | - /* XXX Why are there these headers? */ |
---|
212 | | - case IPPROTO_AH: |
---|
213 | | - case IPPROTO_ESP: |
---|
214 | | - case IPPROTO_COMP: |
---|
215 | | - default: |
---|
216 | | - fl6->fl6_ipsec_spi = 0; |
---|
217 | | - fl6->flowi6_proto = nexthdr; |
---|
218 | | - return; |
---|
219 | | - } |
---|
220 | | - } |
---|
221 | 98 | } |
---|
222 | 99 | |
---|
223 | 100 | static void xfrm6_update_pmtu(struct dst_entry *dst, struct sock *sk, |
---|
.. | .. |
---|
263 | 140 | if (xdst->u.rt6.rt6i_idev->dev == dev) { |
---|
264 | 141 | struct inet6_dev *loopback_idev = |
---|
265 | 142 | in6_dev_get(dev_net(dev)->loopback_dev); |
---|
266 | | - BUG_ON(!loopback_idev); |
---|
267 | 143 | |
---|
268 | 144 | do { |
---|
269 | 145 | in6_dev_put(xdst->u.rt6.rt6i_idev); |
---|
.. | .. |
---|
293 | 169 | .dst_ops = &xfrm6_dst_ops_template, |
---|
294 | 170 | .dst_lookup = xfrm6_dst_lookup, |
---|
295 | 171 | .get_saddr = xfrm6_get_saddr, |
---|
296 | | - .decode_session = _decode_session6, |
---|
297 | | - .get_tos = xfrm6_get_tos, |
---|
298 | | - .init_path = xfrm6_init_path, |
---|
299 | 172 | .fill_dst = xfrm6_fill_dst, |
---|
300 | 173 | .blackhole_route = ip6_blackhole_route, |
---|
301 | 174 | }; |
---|
.. | .. |
---|
416 | 289 | if (ret) |
---|
417 | 290 | goto out_state; |
---|
418 | 291 | |
---|
419 | | - register_pernet_subsys(&xfrm6_net_ops); |
---|
| 292 | + ret = register_pernet_subsys(&xfrm6_net_ops); |
---|
| 293 | + if (ret) |
---|
| 294 | + goto out_protocol; |
---|
420 | 295 | out: |
---|
421 | 296 | return ret; |
---|
| 297 | +out_protocol: |
---|
| 298 | + xfrm6_protocol_fini(); |
---|
422 | 299 | out_state: |
---|
423 | 300 | xfrm6_state_fini(); |
---|
424 | 301 | out_policy: |
---|