X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv6%2Fip6_input.c;h=17eb48b8e329af87498a1482dd0cfc64dad83789;hb=3b23e665b68387f5ee7b21f7b75ceea4d9acae4a;hp=09a3201e408aa9fd32d78d15d525db49968462d4;hpb=8eefca4888c986d993b2571eb31f0397a5d0a178;p=linux-2.6 diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 09a3201e40..17eb48b8e3 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -102,6 +102,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (hdr->version != 6) goto err; + /* + * RFC4291 2.5.3 + * A packet received on an interface with a destination address + * of loopback must be dropped. + */ + if (!(dev->flags & IFF_LOOPBACK) && + ipv6_addr_loopback(&hdr->daddr)) + goto err; + skb->transport_header = skb->network_header + sizeof(*hdr); IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); @@ -262,21 +271,23 @@ int ip6_mc_input(struct sk_buff *skb) * is for MLD (0x0000). */ if ((ptr[2] | ptr[3]) == 0) { + deliver = 0; + if (!ipv6_ext_hdr(nexthdr)) { /* BUG */ - goto discard; + goto out; } offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr); if (offset < 0) - goto discard; + goto out; if (nexthdr != IPPROTO_ICMPV6) - goto discard; + goto out; if (!pskb_may_pull(skb, (skb_network_header(skb) + offset + 1 - skb->data))) - goto discard; + goto out; icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset); @@ -285,12 +296,9 @@ int ip6_mc_input(struct sk_buff *skb) case ICMPV6_MGM_REPORT: case ICMPV6_MGM_REDUCTION: case ICMPV6_MLD2_REPORT: + deliver = 1; break; - default: - /* Bogus */ - goto discard; } - deliver = 1; goto out; } /* unknown RA - process it normally */ @@ -308,15 +316,14 @@ int ip6_mc_input(struct sk_buff *skb) ip6_mr_input(skb2); } } -#endif out: - if (likely(deliver)) { +#endif + if (likely(deliver)) ip6_input(skb); - return 0; + else { + /* discard */ + kfree_skb(skb); } -discard: - /* discard */ - kfree_skb(skb); return 0; }