aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7faa9d5e1503..4b4944c3e4c4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops *ops);
84 84
85static int ip6_pkt_discard(struct sk_buff *skb); 85static int ip6_pkt_discard(struct sk_buff *skb);
86static int ip6_pkt_discard_out(struct sk_buff *skb); 86static int ip6_pkt_discard_out(struct sk_buff *skb);
87static int ip6_pkt_prohibit(struct sk_buff *skb);
88static int ip6_pkt_prohibit_out(struct sk_buff *skb);
87static void ip6_link_failure(struct sk_buff *skb); 89static void ip6_link_failure(struct sk_buff *skb);
88static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, 90static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
89 struct sk_buff *skb, u32 mtu); 91 struct sk_buff *skb, u32 mtu);
@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = {
234 236
235#ifdef CONFIG_IPV6_MULTIPLE_TABLES 237#ifdef CONFIG_IPV6_MULTIPLE_TABLES
236 238
237static int ip6_pkt_prohibit(struct sk_buff *skb);
238static int ip6_pkt_prohibit_out(struct sk_buff *skb);
239
240static const struct rt6_info ip6_prohibit_entry_template = { 239static const struct rt6_info ip6_prohibit_entry_template = {
241 .dst = { 240 .dst = {
242 .__refcnt = ATOMIC_INIT(1), 241 .__refcnt = ATOMIC_INIT(1),
@@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg)
1565 goto out; 1564 goto out;
1566 } 1565 }
1567 } 1566 }
1568 rt->dst.output = ip6_pkt_discard_out;
1569 rt->dst.input = ip6_pkt_discard;
1570 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; 1567 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
1571 switch (cfg->fc_type) { 1568 switch (cfg->fc_type) {
1572 case RTN_BLACKHOLE: 1569 case RTN_BLACKHOLE:
1573 rt->dst.error = -EINVAL; 1570 rt->dst.error = -EINVAL;
1571 rt->dst.output = dst_discard;
1572 rt->dst.input = dst_discard;
1574 break; 1573 break;
1575 case RTN_PROHIBIT: 1574 case RTN_PROHIBIT:
1576 rt->dst.error = -EACCES; 1575 rt->dst.error = -EACCES;
1576 rt->dst.output = ip6_pkt_prohibit_out;
1577 rt->dst.input = ip6_pkt_prohibit;
1577 break; 1578 break;
1578 case RTN_THROW: 1579 case RTN_THROW:
1579 rt->dst.error = -EAGAIN;
1580 break;
1581 default: 1580 default:
1582 rt->dst.error = -ENETUNREACH; 1581 rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
1582 : -ENETUNREACH;
1583 rt->dst.output = ip6_pkt_discard_out;
1584 rt->dst.input = ip6_pkt_discard;
1583 break; 1585 break;
1584 } 1586 }
1585 goto install_route; 1587 goto install_route;
@@ -1903,9 +1905,7 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
1903 else 1905 else
1904 rt->rt6i_gateway = *dest; 1906 rt->rt6i_gateway = *dest;
1905 rt->rt6i_flags = ort->rt6i_flags; 1907 rt->rt6i_flags = ort->rt6i_flags;
1906 if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == 1908 rt6_set_from(rt, ort);
1907 (RTF_DEFAULT | RTF_ADDRCONF))
1908 rt6_set_from(rt, ort);
1909 rt->rt6i_metric = 0; 1909 rt->rt6i_metric = 0;
1910 1910
1911#ifdef CONFIG_IPV6_SUBTREES 1911#ifdef CONFIG_IPV6_SUBTREES
@@ -2144,8 +2144,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb)
2144 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); 2144 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
2145} 2145}
2146 2146
2147#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2148
2149static int ip6_pkt_prohibit(struct sk_buff *skb) 2147static int ip6_pkt_prohibit(struct sk_buff *skb)
2150{ 2148{
2151 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); 2149 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
@@ -2157,8 +2155,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
2157 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); 2155 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
2158} 2156}
2159 2157
2160#endif
2161
2162/* 2158/*
2163 * Allocate a dst for local (unicast / anycast) address. 2159 * Allocate a dst for local (unicast / anycast) address.
2164 */ 2160 */
@@ -2168,12 +2164,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2168 bool anycast) 2164 bool anycast)
2169{ 2165{
2170 struct net *net = dev_net(idev->dev); 2166 struct net *net = dev_net(idev->dev);
2171 struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); 2167 struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
2172 2168 DST_NOCOUNT, NULL);
2173 if (!rt) { 2169 if (!rt)
2174 net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n");
2175 return ERR_PTR(-ENOMEM); 2170 return ERR_PTR(-ENOMEM);
2176 }
2177 2171
2178 in6_dev_hold(idev); 2172 in6_dev_hold(idev);
2179 2173