diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/exthdrs.c | 47 |
1 files changed, 16 insertions, 31 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 173a4bb52255..fc3a961fc5ba 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -372,22 +372,13 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) | |||
372 | struct rt0_hdr *rthdr; | 372 | struct rt0_hdr *rthdr; |
373 | int accept_source_route = ipv6_devconf.accept_source_route; | 373 | int accept_source_route = ipv6_devconf.accept_source_route; |
374 | 374 | ||
375 | if (accept_source_route < 0 || | 375 | idev = in6_dev_get(skb->dev); |
376 | ((idev = in6_dev_get(skb->dev)) == NULL)) { | 376 | if (idev) { |
377 | kfree_skb(skb); | 377 | if (accept_source_route > idev->cnf.accept_source_route) |
378 | return -1; | 378 | accept_source_route = idev->cnf.accept_source_route; |
379 | } | ||
380 | if (idev->cnf.accept_source_route < 0) { | ||
381 | in6_dev_put(idev); | 379 | in6_dev_put(idev); |
382 | kfree_skb(skb); | ||
383 | return -1; | ||
384 | } | 380 | } |
385 | 381 | ||
386 | if (accept_source_route > idev->cnf.accept_source_route) | ||
387 | accept_source_route = idev->cnf.accept_source_route; | ||
388 | |||
389 | in6_dev_put(idev); | ||
390 | |||
391 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 382 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
392 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 383 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
393 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | 384 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
@@ -399,24 +390,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) | |||
399 | 390 | ||
400 | hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb); | 391 | hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb); |
401 | 392 | ||
402 | switch (hdr->type) { | ||
403 | #ifdef CONFIG_IPV6_MIP6 | ||
404 | case IPV6_SRCRT_TYPE_2: | ||
405 | break; | ||
406 | #endif | ||
407 | case IPV6_SRCRT_TYPE_0: | ||
408 | if (accept_source_route > 0) | ||
409 | break; | ||
410 | kfree_skb(skb); | ||
411 | return -1; | ||
412 | default: | ||
413 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | ||
414 | IPSTATS_MIB_INHDRERRORS); | ||
415 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | ||
416 | (&hdr->type) - skb_network_header(skb)); | ||
417 | return -1; | ||
418 | } | ||
419 | |||
420 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || | 393 | if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || |
421 | skb->pkt_type != PACKET_HOST) { | 394 | skb->pkt_type != PACKET_HOST) { |
422 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 395 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
@@ -455,6 +428,8 @@ looped_back: | |||
455 | 428 | ||
456 | switch (hdr->type) { | 429 | switch (hdr->type) { |
457 | case IPV6_SRCRT_TYPE_0: | 430 | case IPV6_SRCRT_TYPE_0: |
431 | if (accept_source_route <= 0) | ||
432 | goto unknown_rh; | ||
458 | if (hdr->hdrlen & 0x01) { | 433 | if (hdr->hdrlen & 0x01) { |
459 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 434 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
460 | IPSTATS_MIB_INHDRERRORS); | 435 | IPSTATS_MIB_INHDRERRORS); |
@@ -466,6 +441,8 @@ looped_back: | |||
466 | break; | 441 | break; |
467 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 442 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
468 | case IPV6_SRCRT_TYPE_2: | 443 | case IPV6_SRCRT_TYPE_2: |
444 | if (accept_source_route < 0) | ||
445 | goto unknown_rh; | ||
469 | /* Silently discard invalid RTH type 2 */ | 446 | /* Silently discard invalid RTH type 2 */ |
470 | if (hdr->hdrlen != 2 || hdr->segments_left != 1) { | 447 | if (hdr->hdrlen != 2 || hdr->segments_left != 1) { |
471 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 448 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
@@ -475,6 +452,8 @@ looped_back: | |||
475 | } | 452 | } |
476 | break; | 453 | break; |
477 | #endif | 454 | #endif |
455 | default: | ||
456 | goto unknown_rh; | ||
478 | } | 457 | } |
479 | 458 | ||
480 | /* | 459 | /* |
@@ -578,6 +557,12 @@ looped_back: | |||
578 | skb_push(skb, skb->data - skb_network_header(skb)); | 557 | skb_push(skb, skb->data - skb_network_header(skb)); |
579 | dst_input(skb); | 558 | dst_input(skb); |
580 | return -1; | 559 | return -1; |
560 | |||
561 | unknown_rh: | ||
562 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); | ||
563 | icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, | ||
564 | (&hdr->type) - skb_network_header(skb)); | ||
565 | return -1; | ||
581 | } | 566 | } |
582 | 567 | ||
583 | static struct inet6_protocol rthdr_protocol = { | 568 | static struct inet6_protocol rthdr_protocol = { |