[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: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3a31b9d2f2
commit
9ce8ade015
|
@ -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 = {
|
||||||
.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 = {
|
||||||
.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)
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue