提交 9ce8ade0 编写于 作者: T Thomas Graf 提交者: David S. Miller

[IPv6] route: Fix prohibit and blackhole routing decision

Lookups resolving to ip6_blk_hole_entry must result in silently
discarding the packets whereas an ip6_pkt_prohibit_entry is
supposed to cause an ICMPV6_ADM_PROHIBITED message to be sent.

Thanks to Kim Nordlund <kim.nordlund@nokia.com> for noticing
this bug.
Signed-off-by: NThomas Graf <tgraf@suug.ch>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 3a31b9d2
...@@ -94,6 +94,9 @@ static int ip6_dst_gc(void); ...@@ -94,6 +94,9 @@ static int ip6_dst_gc(void);
static int ip6_pkt_discard(struct sk_buff *skb); static int ip6_pkt_discard(struct sk_buff *skb);
static int ip6_pkt_discard_out(struct sk_buff *skb); static int ip6_pkt_discard_out(struct sk_buff *skb);
static int ip6_pkt_prohibit(struct sk_buff *skb);
static int ip6_pkt_prohibit_out(struct sk_buff *skb);
static int ip6_pkt_blk_hole(struct sk_buff *skb);
static void ip6_link_failure(struct sk_buff *skb); static void ip6_link_failure(struct sk_buff *skb);
static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu); static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
...@@ -150,8 +153,8 @@ struct rt6_info ip6_prohibit_entry = { ...@@ -150,8 +153,8 @@ struct rt6_info ip6_prohibit_entry = {
.obsolete = -1, .obsolete = -1,
.error = -EACCES, .error = -EACCES,
.metrics = { [RTAX_HOPLIMIT - 1] = 255, }, .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_discard, .input = ip6_pkt_prohibit,
.output = ip6_pkt_discard_out, .output = ip6_pkt_prohibit_out,
.ops = &ip6_dst_ops, .ops = &ip6_dst_ops,
.path = (struct dst_entry*)&ip6_prohibit_entry, .path = (struct dst_entry*)&ip6_prohibit_entry,
} }
...@@ -170,8 +173,8 @@ struct rt6_info ip6_blk_hole_entry = { ...@@ -170,8 +173,8 @@ struct rt6_info ip6_blk_hole_entry = {
.obsolete = -1, .obsolete = -1,
.error = -EINVAL, .error = -EINVAL,
.metrics = { [RTAX_HOPLIMIT - 1] = 255, }, .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_discard, .input = ip6_pkt_blk_hole,
.output = ip6_pkt_discard_out, .output = ip6_pkt_blk_hole,
.ops = &ip6_dst_ops, .ops = &ip6_dst_ops,
.path = (struct dst_entry*)&ip6_blk_hole_entry, .path = (struct dst_entry*)&ip6_blk_hole_entry,
} }
...@@ -1742,24 +1745,46 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) ...@@ -1742,24 +1745,46 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
* Drop the packet on the floor * Drop the packet on the floor
*/ */
static int ip6_pkt_discard(struct sk_buff *skb) static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
{ {
int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS);
IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
} }
static int ip6_pkt_discard(struct sk_buff *skb)
{
return ip6_pkt_drop(skb, ICMPV6_NOROUTE);
}
static int ip6_pkt_discard_out(struct sk_buff *skb) static int ip6_pkt_discard_out(struct sk_buff *skb)
{ {
skb->dev = skb->dst->dev; skb->dev = skb->dst->dev;
return ip6_pkt_discard(skb); return ip6_pkt_discard(skb);
} }
static int ip6_pkt_prohibit(struct sk_buff *skb)
{
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED);
}
static int ip6_pkt_prohibit_out(struct sk_buff *skb)
{
skb->dev = skb->dst->dev;
return ip6_pkt_prohibit(skb);
}
static int ip6_pkt_blk_hole(struct sk_buff *skb)
{
kfree_skb(skb);
return 0;
}
/* /*
* Allocate a dst for local (unicast / anycast) address. * Allocate a dst for local (unicast / anycast) address.
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册