Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * IPv6 input
4 : : * Linux INET6 implementation
5 : : *
6 : : * Authors:
7 : : * Pedro Roque <roque@di.fc.ul.pt>
8 : : * Ian P. Morris <I.P.Morris@soton.ac.uk>
9 : : *
10 : : * Based in linux/net/ipv4/ip_input.c
11 : : */
12 : : /* Changes
13 : : *
14 : : * Mitsuru KANDA @USAGI and
15 : : * YOSHIFUJI Hideaki @USAGI: Remove ipv6_parse_exthdrs().
16 : : */
17 : :
18 : : #include <linux/errno.h>
19 : : #include <linux/types.h>
20 : : #include <linux/socket.h>
21 : : #include <linux/sockios.h>
22 : : #include <linux/net.h>
23 : : #include <linux/netdevice.h>
24 : : #include <linux/in6.h>
25 : : #include <linux/icmpv6.h>
26 : : #include <linux/mroute6.h>
27 : : #include <linux/slab.h>
28 : : #include <linux/indirect_call_wrapper.h>
29 : :
30 : : #include <linux/netfilter.h>
31 : : #include <linux/netfilter_ipv6.h>
32 : :
33 : : #include <net/sock.h>
34 : : #include <net/snmp.h>
35 : :
36 : : #include <net/ipv6.h>
37 : : #include <net/protocol.h>
38 : : #include <net/transp_v6.h>
39 : : #include <net/rawv6.h>
40 : : #include <net/ndisc.h>
41 : : #include <net/ip6_route.h>
42 : : #include <net/addrconf.h>
43 : : #include <net/xfrm.h>
44 : : #include <net/inet_ecn.h>
45 : : #include <net/dst_metadata.h>
46 : :
47 : : INDIRECT_CALLABLE_DECLARE(void udp_v6_early_demux(struct sk_buff *));
48 : : INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *));
49 : 950 : static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
50 : : struct sk_buff *skb)
51 : : {
52 : : void (*edemux)(struct sk_buff *skb);
53 : :
54 [ + - + + : 1900 : if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
+ - ]
55 : : const struct inet6_protocol *ipprot;
56 : :
57 : 1124 : ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
58 [ + - + - ]: 1124 : if (ipprot && (edemux = READ_ONCE(ipprot->early_demux)))
59 : 562 : INDIRECT_CALL_2(edemux, tcp_v6_early_demux,
60 : : udp_v6_early_demux, skb);
61 : : }
62 [ + + ]: 950 : if (!skb_valid_dst(skb))
63 : 562 : ip6_route_input(skb);
64 : 950 : }
65 : :
66 : 950 : int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
67 : : {
68 : : /* if ingress device is enslaved to an L3 master device pass the
69 : : * skb to its handler for processing
70 : : */
71 : : skb = l3mdev_ip6_rcv(skb);
72 [ + - ]: 950 : if (!skb)
73 : : return NET_RX_SUCCESS;
74 : 950 : ip6_rcv_finish_core(net, sk, skb);
75 : :
76 : 950 : return dst_input(skb);
77 : : }
78 : :
79 : 0 : static void ip6_sublist_rcv_finish(struct list_head *head)
80 : : {
81 : : struct sk_buff *skb, *next;
82 : :
83 [ # # ]: 0 : list_for_each_entry_safe(skb, next, head, list) {
84 : : skb_list_del_init(skb);
85 : : dst_input(skb);
86 : : }
87 : 0 : }
88 : :
89 : 0 : static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
90 : : struct list_head *head)
91 : : {
92 : : struct dst_entry *curr_dst = NULL;
93 : : struct sk_buff *skb, *next;
94 : : struct list_head sublist;
95 : :
96 : : INIT_LIST_HEAD(&sublist);
97 [ # # ]: 0 : list_for_each_entry_safe(skb, next, head, list) {
98 : : struct dst_entry *dst;
99 : :
100 : : skb_list_del_init(skb);
101 : : /* if ingress device is enslaved to an L3 master device pass the
102 : : * skb to its handler for processing
103 : : */
104 : : skb = l3mdev_ip6_rcv(skb);
105 [ # # ]: 0 : if (!skb)
106 : 0 : continue;
107 : 0 : ip6_rcv_finish_core(net, sk, skb);
108 : : dst = skb_dst(skb);
109 [ # # ]: 0 : if (curr_dst != dst) {
110 : : /* dispatch old sublist */
111 [ # # ]: 0 : if (!list_empty(&sublist))
112 : 0 : ip6_sublist_rcv_finish(&sublist);
113 : : /* start new sublist */
114 : : INIT_LIST_HEAD(&sublist);
115 : : curr_dst = dst;
116 : : }
117 : 0 : list_add_tail(&skb->list, &sublist);
118 : : }
119 : : /* dispatch final sublist */
120 : 0 : ip6_sublist_rcv_finish(&sublist);
121 : 0 : }
122 : :
123 : 950 : static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev,
124 : : struct net *net)
125 : : {
126 : : const struct ipv6hdr *hdr;
127 : : u32 pkt_len;
128 : : struct inet6_dev *idev;
129 : :
130 [ - + ]: 950 : if (skb->pkt_type == PACKET_OTHERHOST) {
131 : 0 : kfree_skb(skb);
132 : 0 : return NULL;
133 : : }
134 : :
135 : : rcu_read_lock();
136 : :
137 : 950 : idev = __in6_dev_get(skb->dev);
138 : :
139 [ + - ]: 4750 : __IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_IN, skb->len);
140 : :
141 [ + - + - ]: 950 : if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
142 [ - + ]: 950 : !idev || unlikely(idev->cnf.disable_ipv6)) {
143 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
144 : : goto drop;
145 : : }
146 : :
147 : 950 : memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
148 : :
149 : : /*
150 : : * Store incoming device index. When the packet will
151 : : * be queued, we cannot refer to skb->dev anymore.
152 : : *
153 : : * BTW, when we send a packet for our own local address on a
154 : : * non-loopback interface (e.g. ethX), it is being delivered
155 : : * via the loopback interface (lo) here; skb->dev = loopback_dev.
156 : : * It, however, should be considered as if it is being
157 : : * arrived via the sending interface (ethX), because of the
158 : : * nature of scoping architecture. --yoshfuji
159 : : */
160 [ + + ]: 1338 : IP6CB(skb)->iif = skb_valid_dst(skb) ? ip6_dst_idev(skb_dst(skb))->dev->ifindex : dev->ifindex;
161 : :
162 [ + - ]: 950 : if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
163 : : goto err;
164 : :
165 : : hdr = ipv6_hdr(skb);
166 : :
167 [ + - ]: 950 : if (hdr->version != 6)
168 : : goto err;
169 : :
170 [ + - - + : 6650 : __IP6_ADD_STATS(net, idev,
- + ]
171 : : IPSTATS_MIB_NOECTPKTS +
172 : : (ipv6_get_dsfield(hdr) & INET_ECN_MASK),
173 : : max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
174 : : /*
175 : : * RFC4291 2.5.3
176 : : * The loopback address must not be used as the source address in IPv6
177 : : * packets that are sent outside of a single node. [..]
178 : : * A packet received on an interface with a destination address
179 : : * of loopback must be dropped.
180 : : */
181 [ + - - + ]: 1900 : if ((ipv6_addr_loopback(&hdr->saddr) ||
182 [ # # ]: 0 : ipv6_addr_loopback(&hdr->daddr)) &&
183 [ # # ]: 0 : !(dev->flags & IFF_LOOPBACK) &&
184 : : !netif_is_l3_master(dev))
185 : : goto err;
186 : :
187 : : /* RFC4291 Errata ID: 3480
188 : : * Interface-Local scope spans only a single interface on a
189 : : * node and is useful only for loopback transmission of
190 : : * multicast. Packets with interface-local scope received
191 : : * from another node must be discarded.
192 : : */
193 [ + + + - ]: 1512 : if (!(skb->pkt_type == PACKET_LOOPBACK ||
194 [ + - ]: 1124 : dev->flags & IFF_LOOPBACK) &&
195 [ + - ]: 562 : ipv6_addr_is_multicast(&hdr->daddr) &&
196 : 562 : IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
197 : : goto err;
198 : :
199 : : /* If enabled, drop unicast packets that were encapsulated in link-layer
200 : : * multicast or broadcast to protected against the so-called "hole-196"
201 : : * attack in 802.11 wireless.
202 : : */
203 [ - + # # ]: 950 : if (!ipv6_addr_is_multicast(&hdr->daddr) &&
204 : 0 : (skb->pkt_type == PACKET_BROADCAST ||
205 [ # # ]: 0 : skb->pkt_type == PACKET_MULTICAST) &&
206 : 0 : idev->cnf.drop_unicast_in_l2_multicast)
207 : : goto err;
208 : :
209 : : /* RFC4291 2.7
210 : : * Nodes must not originate a packet to a multicast address whose scope
211 : : * field contains the reserved value 0; if such a packet is received, it
212 : : * must be silently dropped.
213 : : */
214 [ + - + - ]: 1900 : if (ipv6_addr_is_multicast(&hdr->daddr) &&
215 : 950 : IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0)
216 : : goto err;
217 : :
218 : : /*
219 : : * RFC4291 2.7
220 : : * Multicast addresses must not be used as source addresses in IPv6
221 : : * packets or appear in any Routing header.
222 : : */
223 [ + - ]: 950 : if (ipv6_addr_is_multicast(&hdr->saddr))
224 : : goto err;
225 : :
226 : : /* While RFC4291 is not explicit about v4mapped addresses
227 : : * in IPv6 headers, it seems clear linux dual-stack
228 : : * model can not deal properly with these.
229 : : * Security models could be fooled by ::ffff:127.0.0.1 for example.
230 : : *
231 : : * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02
232 : : */
233 [ + - ]: 950 : if (ipv6_addr_v4mapped(&hdr->saddr))
234 : : goto err;
235 : :
236 : 950 : skb->transport_header = skb->network_header + sizeof(*hdr);
237 : 950 : IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
238 : :
239 : 950 : pkt_len = ntohs(hdr->payload_len);
240 : :
241 : : /* pkt_len may be zero if Jumbo payload option is present */
242 [ - + # # ]: 950 : if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
243 [ - + ]: 950 : if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
244 [ # # ]: 0 : __IP6_INC_STATS(net,
245 : : idev, IPSTATS_MIB_INTRUNCATEDPKTS);
246 : : goto drop;
247 : : }
248 [ - + ]: 950 : if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
249 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
250 : : goto drop;
251 : : }
252 : : hdr = ipv6_hdr(skb);
253 : : }
254 : :
255 [ - + ]: 950 : if (hdr->nexthdr == NEXTHDR_HOP) {
256 [ # # ]: 0 : if (ipv6_parse_hopopts(skb) < 0) {
257 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
258 : : rcu_read_unlock();
259 : 0 : return NULL;
260 : : }
261 : : }
262 : :
263 : : rcu_read_unlock();
264 : :
265 : : /* Must drop socket now because of tproxy. */
266 : 950 : skb_orphan(skb);
267 : :
268 : 950 : return skb;
269 : : err:
270 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
271 : : drop:
272 : : rcu_read_unlock();
273 : 0 : kfree_skb(skb);
274 : 0 : return NULL;
275 : : }
276 : :
277 : 950 : int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
278 : : {
279 : 950 : struct net *net = dev_net(skb->dev);
280 : :
281 : 950 : skb = ip6_rcv_core(skb, dev, net);
282 [ + - ]: 950 : if (skb == NULL)
283 : : return NET_RX_DROP;
284 : 950 : return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
285 : : net, NULL, skb, dev, NULL,
286 : : ip6_rcv_finish);
287 : : }
288 : :
289 : 0 : static void ip6_sublist_rcv(struct list_head *head, struct net_device *dev,
290 : : struct net *net)
291 : : {
292 : 0 : NF_HOOK_LIST(NFPROTO_IPV6, NF_INET_PRE_ROUTING, net, NULL,
293 : : head, dev, NULL, ip6_rcv_finish);
294 : 0 : ip6_list_rcv_finish(net, NULL, head);
295 : 0 : }
296 : :
297 : : /* Receive a list of IPv6 packets */
298 : 0 : void ipv6_list_rcv(struct list_head *head, struct packet_type *pt,
299 : : struct net_device *orig_dev)
300 : : {
301 : : struct net_device *curr_dev = NULL;
302 : : struct net *curr_net = NULL;
303 : : struct sk_buff *skb, *next;
304 : : struct list_head sublist;
305 : :
306 : : INIT_LIST_HEAD(&sublist);
307 [ # # ]: 0 : list_for_each_entry_safe(skb, next, head, list) {
308 : 0 : struct net_device *dev = skb->dev;
309 : : struct net *net = dev_net(dev);
310 : :
311 : : skb_list_del_init(skb);
312 : 0 : skb = ip6_rcv_core(skb, dev, net);
313 [ # # ]: 0 : if (skb == NULL)
314 : 0 : continue;
315 : :
316 [ # # ]: 0 : if (curr_dev != dev || curr_net != net) {
317 : : /* dispatch old sublist */
318 [ # # ]: 0 : if (!list_empty(&sublist))
319 : 0 : ip6_sublist_rcv(&sublist, curr_dev, curr_net);
320 : : /* start new sublist */
321 : : INIT_LIST_HEAD(&sublist);
322 : : curr_dev = dev;
323 : : curr_net = net;
324 : : }
325 : 0 : list_add_tail(&skb->list, &sublist);
326 : : }
327 : : /* dispatch final sublist */
328 : 0 : ip6_sublist_rcv(&sublist, curr_dev, curr_net);
329 : 0 : }
330 : :
331 : : INDIRECT_CALLABLE_DECLARE(int udpv6_rcv(struct sk_buff *));
332 : : INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *));
333 : :
334 : : /*
335 : : * Deliver the packet to the host
336 : : */
337 : 950 : void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
338 : : bool have_final)
339 : : {
340 : : const struct inet6_protocol *ipprot;
341 : : struct inet6_dev *idev;
342 : : unsigned int nhoff;
343 : : bool raw;
344 : :
345 : : /*
346 : : * Parse extension headers
347 : : */
348 : :
349 : : resubmit:
350 : : idev = ip6_dst_idev(skb_dst(skb));
351 : 950 : nhoff = IP6CB(skb)->nhoff;
352 [ + - ]: 950 : if (!have_final) {
353 [ + - ]: 1900 : if (!pskb_pull(skb, skb_transport_offset(skb)))
354 : : goto discard;
355 : 950 : nexthdr = skb_network_header(skb)[nhoff];
356 : : }
357 : :
358 : : resubmit_final:
359 : 950 : raw = raw6_local_deliver(skb, nexthdr);
360 : 1900 : ipprot = rcu_dereference(inet6_protos[nexthdr]);
361 [ + - ]: 950 : if (ipprot) {
362 : : int ret;
363 : :
364 [ - + ]: 950 : if (have_final) {
365 [ # # ]: 0 : if (!(ipprot->flags & INET6_PROTO_FINAL)) {
366 : : /* Once we've seen a final protocol don't
367 : : * allow encapsulation on any non-final
368 : : * ones. This allows foo in UDP encapsulation
369 : : * to work.
370 : : */
371 : : goto discard;
372 : : }
373 [ + - ]: 950 : } else if (ipprot->flags & INET6_PROTO_FINAL) {
374 : : const struct ipv6hdr *hdr;
375 : : int sdif = inet6_sdif(skb);
376 : : struct net_device *dev;
377 : :
378 : : /* Only do this once for first final protocol */
379 : : have_final = true;
380 : :
381 : : /* Free reference early: we don't need it any more,
382 : : and it may hold ip_conntrack module loaded
383 : : indefinitely. */
384 : : nf_reset_ct(skb);
385 : :
386 : 950 : skb_postpull_rcsum(skb, skb_network_header(skb),
387 : : skb_network_header_len(skb));
388 : : hdr = ipv6_hdr(skb);
389 : :
390 : : /* skb->dev passed may be master dev for vrfs. */
391 [ - + ]: 950 : if (sdif) {
392 : 0 : dev = dev_get_by_index_rcu(net, sdif);
393 [ # # ]: 0 : if (!dev)
394 : : goto discard;
395 : : } else {
396 : 950 : dev = skb->dev;
397 : : }
398 : :
399 [ + - - + ]: 1900 : if (ipv6_addr_is_multicast(&hdr->daddr) &&
400 : 950 : !ipv6_chk_mcast_addr(dev, &hdr->daddr,
401 [ # # ]: 0 : &hdr->saddr) &&
402 : 0 : !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
403 : : goto discard;
404 : : }
405 [ - + # # ]: 950 : if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
406 : : !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
407 : : goto discard;
408 : :
409 : 950 : ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
410 : : skb);
411 [ - + ]: 950 : if (ret > 0) {
412 [ # # ]: 0 : if (ipprot->flags & INET6_PROTO_FINAL) {
413 : : /* Not an extension header, most likely UDP
414 : : * encapsulation. Use return value as nexthdr
415 : : * protocol not nhoff (which presumably is
416 : : * not set by handler).
417 : : */
418 : : nexthdr = ret;
419 : : goto resubmit_final;
420 : : } else {
421 : : goto resubmit;
422 : : }
423 [ + - ]: 950 : } else if (ret == 0) {
424 [ + - ]: 6650 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
425 : : }
426 : : } else {
427 [ # # ]: 0 : if (!raw) {
428 [ # # ]: 0 : if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
429 [ # # ]: 0 : __IP6_INC_STATS(net, idev,
430 : : IPSTATS_MIB_INUNKNOWNPROTOS);
431 : 0 : icmpv6_send(skb, ICMPV6_PARAMPROB,
432 : : ICMPV6_UNK_NEXTHDR, nhoff);
433 : : }
434 : 0 : kfree_skb(skb);
435 : : } else {
436 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDELIVERS);
437 : 0 : consume_skb(skb);
438 : : }
439 : : }
440 : 950 : return;
441 : :
442 : : discard:
443 [ # # ]: 0 : __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
444 : 0 : kfree_skb(skb);
445 : : }
446 : :
447 : 950 : static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
448 : : {
449 : : rcu_read_lock();
450 : 950 : ip6_protocol_deliver_rcu(net, skb, 0, false);
451 : : rcu_read_unlock();
452 : :
453 : 950 : return 0;
454 : : }
455 : :
456 : :
457 : 950 : int ip6_input(struct sk_buff *skb)
458 : : {
459 : 950 : return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN,
460 : 950 : dev_net(skb->dev), NULL, skb, skb->dev, NULL,
461 : : ip6_input_finish);
462 : : }
463 : : EXPORT_SYMBOL_GPL(ip6_input);
464 : :
465 : 950 : int ip6_mc_input(struct sk_buff *skb)
466 : : {
467 : : int sdif = inet6_sdif(skb);
468 : : const struct ipv6hdr *hdr;
469 : : struct net_device *dev;
470 : : bool deliver;
471 : :
472 [ + - ]: 7600 : __IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
473 : : __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
474 : : skb->len);
475 : :
476 : : /* skb->dev passed may be master dev for vrfs. */
477 [ - + ]: 950 : if (sdif) {
478 : : rcu_read_lock();
479 : 0 : dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif);
480 [ # # ]: 0 : if (!dev) {
481 : : rcu_read_unlock();
482 : 0 : kfree_skb(skb);
483 : 0 : return -ENODEV;
484 : : }
485 : : } else {
486 : 950 : dev = skb->dev;
487 : : }
488 : :
489 : : hdr = ipv6_hdr(skb);
490 : 950 : deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL);
491 [ - + ]: 950 : if (sdif)
492 : : rcu_read_unlock();
493 : :
494 : : #ifdef CONFIG_IPV6_MROUTE
495 : : /*
496 : : * IPv6 multicast router mode is now supported ;)
497 : : */
498 [ - + # # ]: 1900 : if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
499 : 0 : !(ipv6_addr_type(&hdr->daddr) &
500 [ # # ]: 0 : (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
501 : 0 : likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
502 : : /*
503 : : * Okay, we try to forward - split and duplicate
504 : : * packets.
505 : : */
506 : : struct sk_buff *skb2;
507 : : struct inet6_skb_parm *opt = IP6CB(skb);
508 : :
509 : : /* Check for MLD */
510 [ # # ]: 0 : if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
511 : : /* Check if this is a mld message */
512 : 0 : u8 nexthdr = hdr->nexthdr;
513 : : __be16 frag_off;
514 : : int offset;
515 : :
516 : : /* Check if the value of Router Alert
517 : : * is for MLD (0x0000).
518 : : */
519 [ # # ]: 0 : if (opt->ra == htons(IPV6_OPT_ROUTERALERT_MLD)) {
520 : : deliver = false;
521 : :
522 [ # # ]: 0 : if (!ipv6_ext_hdr(nexthdr)) {
523 : : /* BUG */
524 : : goto out;
525 : : }
526 : 0 : offset = ipv6_skip_exthdr(skb, sizeof(*hdr),
527 : : &nexthdr, &frag_off);
528 [ # # ]: 0 : if (offset < 0)
529 : : goto out;
530 : :
531 [ # # ]: 0 : if (ipv6_is_mld(skb, nexthdr, offset))
532 : : deliver = true;
533 : :
534 : : goto out;
535 : : }
536 : : /* unknown RA - process it normally */
537 : : }
538 : :
539 [ # # ]: 0 : if (deliver)
540 : 0 : skb2 = skb_clone(skb, GFP_ATOMIC);
541 : : else {
542 : : skb2 = skb;
543 : : skb = NULL;
544 : : }
545 : :
546 [ # # ]: 0 : if (skb2) {
547 : 0 : ip6_mr_input(skb2);
548 : : }
549 : : }
550 : : out:
551 : : #endif
552 [ + - ]: 950 : if (likely(deliver))
553 : 950 : ip6_input(skb);
554 : : else {
555 : : /* discard */
556 : 0 : kfree_skb(skb);
557 : : }
558 : :
559 : : return 0;
560 : : }
|