diff options
Diffstat (limited to 'target/linux/generic/patches-3.8')
-rw-r--r-- | target/linux/generic/patches-3.8/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.8/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/patches-3.8/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch new file mode 100644 index 0000000000..f4d78533e6 --- /dev/null +++ b/target/linux/generic/patches-3.8/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch @@ -0,0 +1,263 @@ +Index: linux-3.8.13/include/net/netns/ipv6.h +=================================================================== +--- linux-3.8.13.orig/include/net/netns/ipv6.h 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/include/net/netns/ipv6.h 2013-06-10 14:14:20.898911309 +0200 +@@ -54,6 +54,7 @@ + unsigned long ip6_rt_last_gc; + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + struct rt6_info *ip6_prohibit_entry; ++ struct rt6_info *ip6_failed_policy_entry; + struct rt6_info *ip6_blk_hole_entry; + struct fib6_table *fib6_local_tbl; + struct fib_rules_ops *fib6_rules_ops; +Index: linux-3.8.13/include/uapi/linux/fib_rules.h +=================================================================== +--- linux-3.8.13.orig/include/uapi/linux/fib_rules.h 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/include/uapi/linux/fib_rules.h 2013-06-10 14:14:20.898911309 +0200 +@@ -64,6 +64,10 @@ + FR_ACT_BLACKHOLE, /* Drop without notification */ + FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ + FR_ACT_PROHIBIT, /* Drop with EACCES */ ++ FR_ACT_RES9, ++ FR_ACT_RES10, ++ FR_ACT_RES11, ++ FR_ACT_FAILED_POLICY, /* Drop with EPERM */ + __FR_ACT_MAX, + }; + +Index: linux-3.8.13/include/uapi/linux/icmpv6.h +=================================================================== +--- linux-3.8.13.orig/include/uapi/linux/icmpv6.h 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/include/uapi/linux/icmpv6.h 2013-06-10 14:14:20.898911309 +0200 +@@ -115,6 +115,7 @@ + #define ICMPV6_NOT_NEIGHBOUR 2 + #define ICMPV6_ADDR_UNREACH 3 + #define ICMPV6_PORT_UNREACH 4 ++#define ICMPV6_FAILED_POLICY 5 + + /* + * Codes for Time Exceeded +Index: linux-3.8.13/include/uapi/linux/rtnetlink.h +=================================================================== +--- linux-3.8.13.orig/include/uapi/linux/rtnetlink.h 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/include/uapi/linux/rtnetlink.h 2013-06-10 14:14:20.898911309 +0200 +@@ -203,6 +203,7 @@ + RTN_THROW, /* Not in this table */ + RTN_NAT, /* Translate this address */ + RTN_XRESOLVE, /* Use external resolver */ ++ RTN_FAILED_POLICY, /* Failed ingress/egress policy */ + __RTN_MAX + }; + +Index: linux-3.8.13/net/ipv4/fib_rules.c +=================================================================== +--- linux-3.8.13.orig/net/ipv4/fib_rules.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv4/fib_rules.c 2013-06-10 14:14:20.898911309 +0200 +@@ -84,6 +84,10 @@ + err = -EACCES; + goto errout; + ++ case FR_ACT_FAILED_POLICY: ++ err = -EPERM; ++ goto errout; ++ + case FR_ACT_BLACKHOLE: + default: + err = -EINVAL; +Index: linux-3.8.13/net/ipv4/fib_semantics.c +=================================================================== +--- linux-3.8.13.orig/net/ipv4/fib_semantics.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv4/fib_semantics.c 2013-06-10 14:14:20.898911309 +0200 +@@ -138,6 +138,10 @@ + .error = -EINVAL, + .scope = RT_SCOPE_NOWHERE, + }, ++ [RTN_FAILED_POLICY] = { ++ .error = -EPERM, ++ .scope = RT_SCOPE_UNIVERSE, ++ }, + }; + + static void rt_fibinfo_free(struct rtable __rcu **rtp) +Index: linux-3.8.13/net/ipv4/fib_trie.c +=================================================================== +--- linux-3.8.13.orig/net/ipv4/fib_trie.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv4/fib_trie.c 2013-06-10 14:14:20.902911309 +0200 +@@ -2350,6 +2350,7 @@ + [RTN_THROW] = "THROW", + [RTN_NAT] = "NAT", + [RTN_XRESOLVE] = "XRESOLVE", ++ [RTN_FAILED_POLICY] = "FAILED_POLICY", + }; + + static inline const char *rtn_type(char *buf, size_t len, unsigned int t) +Index: linux-3.8.13/net/ipv4/ipmr.c +=================================================================== +--- linux-3.8.13.orig/net/ipv4/ipmr.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv4/ipmr.c 2013-06-10 14:14:20.902911309 +0200 +@@ -181,6 +181,7 @@ + case FR_ACT_UNREACHABLE: + return -ENETUNREACH; + case FR_ACT_PROHIBIT: ++ case FR_ACT_FAILED_POLICY: + return -EACCES; + case FR_ACT_BLACKHOLE: + default: +Index: linux-3.8.13/net/ipv6/fib6_rules.c +=================================================================== +--- linux-3.8.13.orig/net/ipv6/fib6_rules.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv6/fib6_rules.c 2013-06-10 14:14:20.902911309 +0200 +@@ -69,6 +69,9 @@ + case FR_ACT_PROHIBIT: + rt = net->ipv6.ip6_prohibit_entry; + goto discard_pkt; ++ case FR_ACT_FAILED_POLICY: ++ rt = net->ipv6.ip6_failed_policy_entry; ++ goto discard_pkt; + } + + table = fib6_get_table(net, rule->table); +Index: linux-3.8.13/net/ipv6/ip6mr.c +=================================================================== +--- linux-3.8.13.orig/net/ipv6/ip6mr.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv6/ip6mr.c 2013-06-10 14:14:20.902911309 +0200 +@@ -166,6 +166,8 @@ + return -ENETUNREACH; + case FR_ACT_PROHIBIT: + return -EACCES; ++ case FR_ACT_FAILED_POLICY: ++ return -EPERM; + case FR_ACT_BLACKHOLE: + default: + return -EINVAL; +Index: linux-3.8.13/net/ipv6/route.c +=================================================================== +--- linux-3.8.13.orig/net/ipv6/route.c 2013-06-10 14:14:20.910911309 +0200 ++++ linux-3.8.13/net/ipv6/route.c 2013-06-10 14:14:20.906911309 +0200 +@@ -258,6 +258,24 @@ + .rt6i_ref = ATOMIC_INIT(1), + }; + ++static int ip6_pkt_failed_policy(struct sk_buff *skb); ++static int ip6_pkt_failed_policy_out(struct sk_buff *skb); ++ ++static const struct rt6_info ip6_failed_policy_entry_template = { ++ .dst = { ++ .__refcnt = ATOMIC_INIT(1), ++ .__use = 1, ++ .obsolete = DST_OBSOLETE_FORCE_CHK, ++ .error = -EPERM, ++ .input = ip6_pkt_failed_policy, ++ .output = ip6_pkt_failed_policy_out, ++ }, ++ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), ++ .rt6i_protocol = RTPROT_KERNEL, ++ .rt6i_metric = ~(u32) 0, ++ .rt6i_ref = ATOMIC_INIT(1), ++}; ++ + static const struct rt6_info ip6_blk_hole_entry_template = { + .dst = { + .__refcnt = ATOMIC_INIT(1), +@@ -1516,6 +1534,9 @@ + case RTN_THROW: + rt->dst.error = -EAGAIN; + break; ++ case RTN_FAILED_POLICY: ++ rt->dst.error = -EPERM; ++ break; + default: + rt->dst.error = -ENETUNREACH; + break; +@@ -2110,6 +2131,17 @@ + return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); + } + ++static int ip6_pkt_failed_policy(struct sk_buff *skb) ++{ ++ return ip6_pkt_drop(skb, ICMPV6_FAILED_POLICY, IPSTATS_MIB_INNOROUTES); ++} ++ ++static int ip6_pkt_failed_policy_out(struct sk_buff *skb) ++{ ++ skb->dev = skb_dst(skb)->dev; ++ return ip6_pkt_drop(skb, ICMPV6_FAILED_POLICY, IPSTATS_MIB_OUTNOROUTES); ++} ++ + #endif + + /* +@@ -2321,7 +2353,8 @@ + if (rtm->rtm_type == RTN_UNREACHABLE || + rtm->rtm_type == RTN_BLACKHOLE || + rtm->rtm_type == RTN_PROHIBIT || +- rtm->rtm_type == RTN_THROW) ++ rtm->rtm_type == RTN_THROW || ++ rtm->rtm_type == RTN_FAILED_POLICY) + cfg->fc_flags |= RTF_REJECT; + + if (rtm->rtm_type == RTN_LOCAL) +@@ -2524,6 +2557,9 @@ + case -EACCES: + rtm->rtm_type = RTN_PROHIBIT; + break; ++ case -EPERM: ++ rtm->rtm_type = RTN_FAILED_POLICY; ++ break; + case -EAGAIN: + rtm->rtm_type = RTN_THROW; + break; +@@ -2775,6 +2811,8 @@ + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + net->ipv6.ip6_prohibit_entry->dst.dev = dev; + net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); ++ net->ipv6.ip6_failed_policy_entry->dst.dev = dev; ++ net->ipv6.ip6_failed_policy_entry->rt6i_idev = in6_dev_get(dev); + net->ipv6.ip6_blk_hole_entry->dst.dev = dev; + net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); + #endif +@@ -3037,6 +3075,17 @@ + net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; + dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, + ip6_template_metrics, true); ++ ++ net->ipv6.ip6_failed_policy_entry = ++ kmemdup(&ip6_failed_policy_entry_template, ++ sizeof(*net->ipv6.ip6_failed_policy_entry), GFP_KERNEL); ++ if (!net->ipv6.ip6_failed_policy_entry) ++ goto out_ip6_blk_hole_entry; ++ net->ipv6.ip6_failed_policy_entry->dst.path = ++ (struct dst_entry *)net->ipv6.ip6_failed_policy_entry; ++ net->ipv6.ip6_failed_policy_entry->dst.ops = &net->ipv6.ip6_dst_ops; ++ dst_init_metrics(&net->ipv6.ip6_failed_policy_entry->dst, ++ ip6_template_metrics, true); + #endif + + net->ipv6.sysctl.flush_delay = 0; +@@ -3055,6 +3104,8 @@ + return ret; + + #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++out_ip6_blk_hole_entry: ++ kfree(net->ipv6.ip6_blk_hole_entry); + out_ip6_prohibit_entry: + kfree(net->ipv6.ip6_prohibit_entry); + out_ip6_null_entry: +@@ -3072,6 +3123,7 @@ + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(net->ipv6.ip6_prohibit_entry); + kfree(net->ipv6.ip6_blk_hole_entry); ++ kfree(net->ipv6.ip6_failed_policy_entry); + #endif + dst_entries_destroy(&net->ipv6.ip6_dst_ops); + } +@@ -3168,6 +3220,9 @@ + init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); + init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; + init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); ++ init_net.ipv6.ip6_failed_policy_entry->dst.dev = init_net.loopback_dev; ++ init_net.ipv6.ip6_failed_policy_entry->rt6i_idev = ++ in6_dev_get(init_net.loopback_dev); + #endif + ret = fib6_init(); + if (ret) |