ipv6: fix handling of blackhole and prohibit routes
Subsystems (3)
RFC PATCH 1/1 ipv6: fix handling of blackhole and prohibit routes
Hi,
enclosed is a patch to fix addition of blackhole and prohibit routes.
Comments are welcome.
Regards,
Nicolas
Quoted 1 line
From
0131261ac3947631b96036ffafb30ee2e95604f2Mon Sep 17 00:00:00 2001
From: Nicolas Dichtel <[email protected]>
Date: Thu, 30 Aug 2012 07:07:30 -0400
Subject: [PATCH] ipv6: fix handling of blackhole and prohibit routes
When adding a blackhole or a prohibit route, they were handling like classic routes. Moreover, it was only possible to add this kind of routes by specifying an interface.
Bug already reported here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498
Before the patch:
$ ip route add blackhole 2001::1/128 RTNETLINK answers: No such device $ ip route add blackhole 2001::1/128 dev eth0 $ ip -6 route | grep 2001 2001::1 dev eth0 metric 1024
After:
$ ip route add blackhole 2001::1/128 $ ip -6 route | grep 2001 blackhole 2001::1 dev lo metric 1024 error -22
--- include/linux/route.h | 2 ++ net/ipv6/route.c | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-)
include/linux/route.h +2 -0
@@ -58,6 +58,8 @@ struct rtentry {#define RTF_WINDOW 0x0080/* per route window clamping */ #define RTF_IRTT 0x0100/* Initial round trip time */ #define RTF_REJECT 0x0200/* Reject route */ +#define RTF_BLACKHOLE 0x0400/* Blackhole route */ +#define RTF_PROHIBIT 0x0800/* Prohibit route */ /* * <linux/ipv6_route.h> uses RTF values >= 64k
net/ipv6/route.c +22 -5
@@ -251,7 +251,7 @@ static struct rt6_info ip6_prohibit_entry_template = { .input = ip6_pkt_prohibit, .output = ip6_pkt_prohibit_out, }, - .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), + .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP | RTF_PROHIBIT), .rt6i_protocol = RTPROT_KERNEL, .rt6i_metric = ~(u32) 0, .rt6i_ref = ATOMIC_INIT(1),
@@ -266,7 +266,7 @@ static struct rt6_info ip6_blk_hole_entry_template = { .input = dst_discard, .output = dst_discard, }, - .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), + .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP | RTF_BLACKHOLE), .rt6i_protocol = RTPROT_KERNEL, .rt6i_metric = ~(u32) 0, .rt6i_ref = ATOMIC_INIT(1),
@@ -1463,8 +1463,15 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.output = ip6_pkt_discard_out; rt->dst.input = ip6_pkt_discard; - rt->dst.error = -ENETUNREACH ; rt->rt6i_flags =RTF_REJECT |RTF_NONEXTHOP ; +if (cfg->fc_flags &RTF_BLACKHOLE ) { + rt->dst.error = -EINVAL ; + rt->rt6i_flags |=RTF_BLACKHOLE ; + }else if (cfg->fc_flags &RTF_PROHIBIT ) { + rt->dst.error = -EACCES ; + rt->rt6i_flags |=RTF_PROHIBIT ; + }else + rt->dst.error = -ENETUNREACH ; goto install_route; }
@@ -2264,6 +2271,10 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,if (rtm->rtm_type ==RTN_UNREACHABLE ) cfg->fc_flags |=RTF_REJECT ; +if (rtm->rtm_type ==RTN_BLACKHOLE ) + cfg->fc_flags |=RTF_REJECT |RTF_BLACKHOLE ; +if (rtm->rtm_type ==RTN_PROHIBIT ) + cfg->fc_flags |=RTF_REJECT |RTF_PROHIBIT ;if (rtm->rtm_type ==RTN_LOCAL ) cfg->fc_flags |=RTF_LOCAL ;
@@ -2391,8 +2402,14 @@ static int rt6_fill_node(struct net *net, rtm->rtm_table = table;if (nla_put_u32 (skb,RTA_TABLE , table)) goto nla_put_failure; -if (rt->rt6i_flags &RTF_REJECT ) - rtm->rtm_type =RTN_UNREACHABLE ; +if (rt->rt6i_flags &RTF_REJECT ) { +if (rt->rt6i_flags &RTF_BLACKHOLE ) + rtm->rtm_type =RTN_BLACKHOLE ; +else if (rt->rt6i_flags &RTF_PROHIBIT ) + rtm->rtm_type =RTN_PROHIBIT ; +else + rtm->rtm_type =RTN_UNREACHABLE ; + }else if (rt->rt6i_flags &RTF_LOCAL ) rtm->rtm_type =RTN_LOCAL ;else if (rt->dst.dev && (rt->dst.dev->flags &IFF_LOOPBACK ))
Signature · 1 line
1.7.10.4
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Thu, 30 Aug 2012 16:29:28 +0200
Quoted 1 line
Comments are welcome.
I don't see why we have to create new flags for this.
Handle it like ipv4, where the RTN_* type dictates whether the route is blackhole, prohibit, or other type of route.
RFC PATCH v2 1/1 ipv6: fix handling of blackhole and prohibit routes
When adding a blackhole or a prohibit route, they were handling like classic routes. Moreover, it was only possible to add this kind of routes by specifying an interface.
Bug already reported here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498
Before the patch:
$ ip route add blackhole 2001::1/128 RTNETLINK answers: No such device $ ip route add blackhole 2001::1/128 dev eth0 $ ip -6 route | grep 2001 2001::1 dev eth0 metric 1024
After:
$ ip route add blackhole 2001::1/128 $ ip -6 route | grep 2001 blackhole 2001::1 dev lo metric 1024 error -22
--- include/net/ip6_fib.h | 1 + net/ipv6/route.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-)
include/net/ip6_fib.h +1 -0
@@ -37,6 +37,7 @@ struct fib6_config {int fc_ifindex;u32 fc_flags;u32 fc_protocol; +u32 fc_type;/* only 8 bits are used */ struct in6_addr fc_dst;struct in6_addr fc_src;
net/ipv6/route.c +28 -4
@@ -1463,8 +1463,18 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.output = ip6_pkt_discard_out; rt->dst.input = ip6_pkt_discard; - rt->dst.error = -ENETUNREACH ; rt->rt6i_flags =RTF_REJECT |RTF_NONEXTHOP ; +switch (cfg->fc_type) { +case RTM_BLACKHOLE : + rt->dst.error = -EINVAL ; +break ; +case RTM_PROHIBIT : + rt->dst.error = -EACCES ; +break ; +default : + rt->dst.error = -ENETUNREACH ; +break ; + } goto install_route; }
@@ -2261,8 +2271,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_flags =RTF_UP ; cfg->fc_protocol = rtm->rtm_protocol; + cfg->type = rtm->rtm_type; -if (rtm->rtm_type ==RTN_UNREACHABLE ) +if (rtm->rtm_type ==RTN_UNREACHABLE || + rtm->rtm_type ==RTN_BLACKHOLE || + rtm->rtm_type ==RTN_PROHIBIT ) cfg->fc_flags |=RTF_REJECT ;if (rtm->rtm_type ==RTN_LOCAL )
@@ -2391,8 +2404,19 @@ static int rt6_fill_node(struct net *net, rtm->rtm_table = table;if (nla_put_u32 (skb,RTA_TABLE , table)) goto nla_put_failure; -if (rt->rt6i_flags &RTF_REJECT ) - rtm->rtm_type =RTN_UNREACHABLE ; +if (rt->rt6i_flags &RTF_REJECT ) { +switch (rt->dst.error) { +case -EINVAL : + rtm->rtm_type =RTN_BLACKHOLE ; +break ; +case -EACCES : + rtm->rtm_type =RTN_PROHIBIT ; +break ; +default : + rtm->rtm_type =RTN_UNREACHABLE ; +break ; + } + }else if (rt->rt6i_flags &RTF_LOCAL ) rtm->rtm_type =RTN_LOCAL ;else if (rt->dst.dev && (rt->dst.dev->flags &IFF_LOOPBACK ))
Signature · 1 line
1.7.12
Please, forget this patch, it's a wrong version.
Sorry for that.
Regards,
Nicolas
Quoted 97 lines · Nicolas Dichtel
When adding a blackhole or a prohibit route, they were handling like classic routes. Moreover, it was only possible to add this kind of routes by specifying an interface.
Bug already reported here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498Before the patch:
$ ip route add blackhole 2001::1/128 RTNETLINK answers: No such device $ ip route add blackhole 2001::1/128 dev eth0 $ ip -6 route | grep 2001 2001::1 dev eth0 metric 1024After:
$ ip route add blackhole 2001::1/128 $ ip -6 route | grep 2001 blackhole 2001::1 dev lo metric 1024 error -22Signed-off-by Nicolas Dichtel <[email protected]>--- include/net/ip6_fib.h | 1 + net/ipv6/route.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-)include/net/ip6_fib.h +1
-0@@ -37,6 +37,7 @@ struct fib6_config {int fc_ifindex;u32 fc_flags;u32 fc_protocol; +u32 fc_type;/* only 8 bits are used */ struct in6_addr fc_dst;struct in6_addr fc_src;net/ipv6/route.c +28
-4@@ -1463,8 +1463,18 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.output = ip6_pkt_discard_out; rt->dst.input = ip6_pkt_discard; - rt->dst.error = -ENETUNREACH ; rt->rt6i_flags =RTF_REJECT |RTF_NONEXTHOP ; +switch (cfg->fc_type) { +case RTM_BLACKHOLE : + rt->dst.error = -EINVAL ; +break ; +case RTM_PROHIBIT : + rt->dst.error = -EACCES ; +break ; +default : + rt->dst.error = -ENETUNREACH ; +break ; + } goto install_route; }@@ -2261,8 +2271,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_flags =RTF_UP ; cfg->fc_protocol = rtm->rtm_protocol; + cfg->type = rtm->rtm_type; -if (rtm->rtm_type ==RTN_UNREACHABLE ) +if (rtm->rtm_type ==RTN_UNREACHABLE || + rtm->rtm_type ==RTN_BLACKHOLE || + rtm->rtm_type ==RTN_PROHIBIT ) cfg->fc_flags |=RTF_REJECT ;if (rtm->rtm_type ==RTN_LOCAL )@@ -2391,8 +2404,19 @@ static int rt6_fill_node(struct net *net, rtm->rtm_table = table;if (nla_put_u32 (skb,RTA_TABLE , table)) goto nla_put_failure; -if (rt->rt6i_flags &RTF_REJECT ) - rtm->rtm_type =RTN_UNREACHABLE ; +if (rt->rt6i_flags &RTF_REJECT ) { +switch (rt->dst.error) { +case -EINVAL : + rtm->rtm_type =RTN_BLACKHOLE ; +break ; +case -EACCES : + rtm->rtm_type =RTN_PROHIBIT ; +break ; +default : + rtm->rtm_type =RTN_UNREACHABLE ; +break ; + } + }else if (rt->rt6i_flags &RTF_LOCAL ) rtm->rtm_type =RTN_LOCAL ;else if (rt->dst.dev && (rt->dst.dev->flags &IFF_LOOPBACK ))
Signature · 14 lines
Nicolas DICHTEL 6WIND R&D Engineer Tel: +33 1 39 30 92 10 Fax: +33 1 39 30 92 11 [email protected] www.6wind.com Twitter: http://twitter.com/6windsoftware Join the Multicore Packet Processing Forum: www.multicorepacketprocessing.com Ce courriel ainsi que toutes les pièces jointes, est uniquement destiné à son ou ses destinataires. Il contient des informations confidentielles qui sont la propriété de 6WIND. Toute révélation, distribution ou copie des informations qu'il contient est strictement interdite. Si vous avez reçu ce message par erreur, veuillez immédiatement le signaler à l'émetteur et détruire toutes les données reçues. This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to 6WIND. All unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message.
RFC PATCH v3 1/1 ipv6: fix handling of blackhole and prohibit routes
When adding a blackhole or a prohibit route, they were handling like classic routes. Moreover, it was only possible to add this kind of routes by specifying an interface.
Bug already reported here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498
Before the patch:
$ ip route add blackhole 2001::1/128 RTNETLINK answers: No such device $ ip route add blackhole 2001::1/128 dev eth0 $ ip -6 route | grep 2001 2001::1 dev eth0 metric 1024
After:
$ ip route add blackhole 2001::1/128 $ ip -6 route | grep 2001 blackhole 2001::1 dev lo metric 1024 error -22
v2: wrong patch
v3: add a field fc_type in struct fib6_config to store RTN_* type
--- include/net/ip6_fib.h | 1 + net/ipv6/route.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-)
include/net/ip6_fib.h +1 -0
@@ -37,6 +37,7 @@ struct fib6_config {int fc_ifindex;u32 fc_flags;u32 fc_protocol; +u32 fc_type;/* only 8 bits are used */ struct in6_addr fc_dst;struct in6_addr fc_src;
net/ipv6/route.c +28 -4
@@ -1463,8 +1463,18 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.output = ip6_pkt_discard_out; rt->dst.input = ip6_pkt_discard; - rt->dst.error = -ENETUNREACH ; rt->rt6i_flags =RTF_REJECT |RTF_NONEXTHOP ; +switch (cfg->fc_type) { +case RTN_BLACKHOLE : + rt->dst.error = -EINVAL ; +break ; +case RTN_PROHIBIT : + rt->dst.error = -EACCES ; +break ; +default : + rt->dst.error = -ENETUNREACH ; +break ; + } goto install_route; }
@@ -2261,8 +2271,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_flags =RTF_UP ; cfg->fc_protocol = rtm->rtm_protocol; + cfg->fc_type = rtm->rtm_type; -if (rtm->rtm_type ==RTN_UNREACHABLE ) +if (rtm->rtm_type ==RTN_UNREACHABLE || + rtm->rtm_type ==RTN_BLACKHOLE || + rtm->rtm_type ==RTN_PROHIBIT ) cfg->fc_flags |=RTF_REJECT ;if (rtm->rtm_type ==RTN_LOCAL )
@@ -2391,8 +2404,19 @@ static int rt6_fill_node(struct net *net, rtm->rtm_table = table;if (nla_put_u32 (skb,RTA_TABLE , table)) goto nla_put_failure; -if (rt->rt6i_flags &RTF_REJECT ) - rtm->rtm_type =RTN_UNREACHABLE ; +if (rt->rt6i_flags &RTF_REJECT ) { +switch (rt->dst.error) { +case -EINVAL : + rtm->rtm_type =RTN_BLACKHOLE ; +break ; +case -EACCES : + rtm->rtm_type =RTN_PROHIBIT ; +break ; +default : + rtm->rtm_type =RTN_UNREACHABLE ; +break ; + } + }else if (rt->rt6i_flags &RTF_LOCAL ) rtm->rtm_type =RTN_LOCAL ;else if (rt->dst.dev && (rt->dst.dev->flags &IFF_LOOPBACK ))
Signature · 1 line
1.7.12
David Miller
maintainerFrom: Nicolas Dichtel <[email protected]>
Date: Wed, 5 Sep 2012 08:12:42 -0400
Quoted 15 lines
When adding a blackhole or a prohibit route, they were handling like classic routes. Moreover, it was only possible to add this kind of routes by specifying an interface.
Bug already reported here:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=498498Before the patch:
$ ip route add blackhole 2001::1/128 RTNETLINK answers: No such device $ ip route add blackhole 2001::1/128 dev eth0 $ ip -6 route | grep 2001 2001::1 dev eth0 metric 1024After:
Quoted 8 lines
$ ip route add blackhole 2001::1/128 $ ip -6 route | grep 2001 blackhole 2001::1 dev lo metric 1024 error -22v2: wrong patch
v3: add a fieldfc_typein structfib6_configto store RTN_* typeSigned-off-by Nicolas Dichtel <[email protected]>
I like this a lot more than your original patch, applied to net-next, thanks.