aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/route.h3
-rw-r--r--net/ipv4/inet_connection_sock.c4
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/route.c48
-rw-r--r--net/ipv4/xfrm4_policy.c1
6 files changed, 34 insertions, 28 deletions
diff --git a/include/net/route.h b/include/net/route.h
index da22243d2760..bc40b633a5c4 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -48,7 +48,8 @@ struct rtable {
48 int rt_genid; 48 int rt_genid;
49 unsigned int rt_flags; 49 unsigned int rt_flags;
50 __u16 rt_type; 50 __u16 rt_type;
51 __u16 rt_is_input; 51 __u8 rt_is_input;
52 __u8 rt_uses_gateway;
52 53
53 int rt_iif; 54 int rt_iif;
54 55
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index f0c5b9c1a957..d34ce2972c8f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -406,7 +406,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
406 rt = ip_route_output_flow(net, fl4, sk); 406 rt = ip_route_output_flow(net, fl4, sk);
407 if (IS_ERR(rt)) 407 if (IS_ERR(rt))
408 goto no_route; 408 goto no_route;
409 if (opt && opt->opt.is_strictroute && rt->rt_gateway) 409 if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
410 goto route_err; 410 goto route_err;
411 return &rt->dst; 411 return &rt->dst;
412 412
@@ -442,7 +442,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
442 rt = ip_route_output_flow(net, fl4, sk); 442 rt = ip_route_output_flow(net, fl4, sk);
443 if (IS_ERR(rt)) 443 if (IS_ERR(rt))
444 goto no_route; 444 goto no_route;
445 if (opt && opt->opt.is_strictroute && rt->rt_gateway) 445 if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
446 goto route_err; 446 goto route_err;
447 rcu_read_unlock(); 447 rcu_read_unlock();
448 return &rt->dst; 448 return &rt->dst;
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 7f35ac26a71a..694de3b7aebf 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb)
85 85
86 rt = skb_rtable(skb); 86 rt = skb_rtable(skb);
87 87
88 if (opt->is_strictroute && rt->rt_gateway) 88 if (opt->is_strictroute && rt->rt_uses_gateway)
89 goto sr_failed; 89 goto sr_failed;
90 90
91 if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) && 91 if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 24a29a39e9a8..6537a408a4fb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -193,7 +193,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
193 } 193 }
194 194
195 rcu_read_lock_bh(); 195 rcu_read_lock_bh();
196 nexthop = rt->rt_gateway ? rt->rt_gateway : ip_hdr(skb)->daddr; 196 nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
197 neigh = __ipv4_neigh_lookup_noref(dev, nexthop); 197 neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
198 if (unlikely(!neigh)) 198 if (unlikely(!neigh))
199 neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); 199 neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
@@ -371,7 +371,7 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
371 skb_dst_set_noref(skb, &rt->dst); 371 skb_dst_set_noref(skb, &rt->dst);
372 372
373packet_routed: 373packet_routed:
374 if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_gateway) 374 if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway)
375 goto no_route; 375 goto no_route;
376 376
377 /* OK, we know where to send it, allocate and build IP header. */ 377 /* OK, we know where to send it, allocate and build IP header. */
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5b0180f11b20..3a116cb0991a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1126,7 +1126,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
1126 mtu = dst->dev->mtu; 1126 mtu = dst->dev->mtu;
1127 1127
1128 if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { 1128 if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
1129 if (rt->rt_gateway && mtu > 576) 1129 if (rt->rt_uses_gateway && mtu > 576)
1130 mtu = 576; 1130 mtu = 576;
1131 } 1131 }
1132 1132
@@ -1177,7 +1177,9 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
1177 if (fnhe->fnhe_gw) { 1177 if (fnhe->fnhe_gw) {
1178 rt->rt_flags |= RTCF_REDIRECTED; 1178 rt->rt_flags |= RTCF_REDIRECTED;
1179 rt->rt_gateway = fnhe->fnhe_gw; 1179 rt->rt_gateway = fnhe->fnhe_gw;
1180 } 1180 rt->rt_uses_gateway = 1;
1181 } else if (!rt->rt_gateway)
1182 rt->rt_gateway = daddr;
1181 1183
1182 orig = rcu_dereference(fnhe->fnhe_rth); 1184 orig = rcu_dereference(fnhe->fnhe_rth);
1183 rcu_assign_pointer(fnhe->fnhe_rth, rt); 1185 rcu_assign_pointer(fnhe->fnhe_rth, rt);
@@ -1186,13 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
1186 1188
1187 fnhe->fnhe_stamp = jiffies; 1189 fnhe->fnhe_stamp = jiffies;
1188 ret = true; 1190 ret = true;
1189 } else {
1190 /* Routes we intend to cache in nexthop exception have
1191 * the DST_NOCACHE bit clear. However, if we are
1192 * unsuccessful at storing this route into the cache
1193 * we really need to set it.
1194 */
1195 rt->dst.flags |= DST_NOCACHE;
1196 } 1191 }
1197 spin_unlock_bh(&fnhe_lock); 1192 spin_unlock_bh(&fnhe_lock);
1198 1193
@@ -1215,15 +1210,8 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
1215 if (prev == orig) { 1210 if (prev == orig) {
1216 if (orig) 1211 if (orig)
1217 rt_free(orig); 1212 rt_free(orig);
1218 } else { 1213 } else
1219 /* Routes we intend to cache in the FIB nexthop have
1220 * the DST_NOCACHE bit clear. However, if we are
1221 * unsuccessful at storing this route into the cache
1222 * we really need to set it.
1223 */
1224 rt->dst.flags |= DST_NOCACHE;
1225 ret = false; 1214 ret = false;
1226 }
1227 1215
1228 return ret; 1216 return ret;
1229} 1217}
@@ -1284,8 +1272,10 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
1284 if (fi) { 1272 if (fi) {
1285 struct fib_nh *nh = &FIB_RES_NH(*res); 1273 struct fib_nh *nh = &FIB_RES_NH(*res);
1286 1274
1287 if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) 1275 if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) {
1288 rt->rt_gateway = nh->nh_gw; 1276 rt->rt_gateway = nh->nh_gw;
1277 rt->rt_uses_gateway = 1;
1278 }
1289 dst_init_metrics(&rt->dst, fi->fib_metrics, true); 1279 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1290#ifdef CONFIG_IP_ROUTE_CLASSID 1280#ifdef CONFIG_IP_ROUTE_CLASSID
1291 rt->dst.tclassid = nh->nh_tclassid; 1281 rt->dst.tclassid = nh->nh_tclassid;
@@ -1294,8 +1284,18 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
1294 cached = rt_bind_exception(rt, fnhe, daddr); 1284 cached = rt_bind_exception(rt, fnhe, daddr);
1295 else if (!(rt->dst.flags & DST_NOCACHE)) 1285 else if (!(rt->dst.flags & DST_NOCACHE))
1296 cached = rt_cache_route(nh, rt); 1286 cached = rt_cache_route(nh, rt);
1297 } 1287 if (unlikely(!cached)) {
1298 if (unlikely(!cached)) 1288 /* Routes we intend to cache in nexthop exception or
1289 * FIB nexthop have the DST_NOCACHE bit clear.
1290 * However, if we are unsuccessful at storing this
1291 * route into the cache we really need to set it.
1292 */
1293 rt->dst.flags |= DST_NOCACHE;
1294 if (!rt->rt_gateway)
1295 rt->rt_gateway = daddr;
1296 rt_add_uncached_list(rt);
1297 }
1298 } else
1299 rt_add_uncached_list(rt); 1299 rt_add_uncached_list(rt);
1300 1300
1301#ifdef CONFIG_IP_ROUTE_CLASSID 1301#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -1363,6 +1363,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1363 rth->rt_iif = 0; 1363 rth->rt_iif = 0;
1364 rth->rt_pmtu = 0; 1364 rth->rt_pmtu = 0;
1365 rth->rt_gateway = 0; 1365 rth->rt_gateway = 0;
1366 rth->rt_uses_gateway = 0;
1366 INIT_LIST_HEAD(&rth->rt_uncached); 1367 INIT_LIST_HEAD(&rth->rt_uncached);
1367 if (our) { 1368 if (our) {
1368 rth->dst.input= ip_local_deliver; 1369 rth->dst.input= ip_local_deliver;
@@ -1432,7 +1433,6 @@ static int __mkroute_input(struct sk_buff *skb,
1432 return -EINVAL; 1433 return -EINVAL;
1433 } 1434 }
1434 1435
1435
1436 err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), 1436 err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
1437 in_dev->dev, in_dev, &itag); 1437 in_dev->dev, in_dev, &itag);
1438 if (err < 0) { 1438 if (err < 0) {
@@ -1488,6 +1488,7 @@ static int __mkroute_input(struct sk_buff *skb,
1488 rth->rt_iif = 0; 1488 rth->rt_iif = 0;
1489 rth->rt_pmtu = 0; 1489 rth->rt_pmtu = 0;
1490 rth->rt_gateway = 0; 1490 rth->rt_gateway = 0;
1491 rth->rt_uses_gateway = 0;
1491 INIT_LIST_HEAD(&rth->rt_uncached); 1492 INIT_LIST_HEAD(&rth->rt_uncached);
1492 1493
1493 rth->dst.input = ip_forward; 1494 rth->dst.input = ip_forward;
@@ -1658,6 +1659,7 @@ local_input:
1658 rth->rt_iif = 0; 1659 rth->rt_iif = 0;
1659 rth->rt_pmtu = 0; 1660 rth->rt_pmtu = 0;
1660 rth->rt_gateway = 0; 1661 rth->rt_gateway = 0;
1662 rth->rt_uses_gateway = 0;
1661 INIT_LIST_HEAD(&rth->rt_uncached); 1663 INIT_LIST_HEAD(&rth->rt_uncached);
1662 if (res.type == RTN_UNREACHABLE) { 1664 if (res.type == RTN_UNREACHABLE) {
1663 rth->dst.input= ip_error; 1665 rth->dst.input= ip_error;
@@ -1826,6 +1828,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
1826 rth->rt_iif = orig_oif ? : 0; 1828 rth->rt_iif = orig_oif ? : 0;
1827 rth->rt_pmtu = 0; 1829 rth->rt_pmtu = 0;
1828 rth->rt_gateway = 0; 1830 rth->rt_gateway = 0;
1831 rth->rt_uses_gateway = 0;
1829 INIT_LIST_HEAD(&rth->rt_uncached); 1832 INIT_LIST_HEAD(&rth->rt_uncached);
1830 1833
1831 RT_CACHE_STAT_INC(out_slow_tot); 1834 RT_CACHE_STAT_INC(out_slow_tot);
@@ -2104,6 +2107,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
2104 rt->rt_flags = ort->rt_flags; 2107 rt->rt_flags = ort->rt_flags;
2105 rt->rt_type = ort->rt_type; 2108 rt->rt_type = ort->rt_type;
2106 rt->rt_gateway = ort->rt_gateway; 2109 rt->rt_gateway = ort->rt_gateway;
2110 rt->rt_uses_gateway = ort->rt_uses_gateway;
2107 2111
2108 INIT_LIST_HEAD(&rt->rt_uncached); 2112 INIT_LIST_HEAD(&rt->rt_uncached);
2109 2113
@@ -2182,7 +2186,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
2182 if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr)) 2186 if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr))
2183 goto nla_put_failure; 2187 goto nla_put_failure;
2184 } 2188 }
2185 if (rt->rt_gateway && 2189 if (rt->rt_uses_gateway &&
2186 nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway)) 2190 nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway))
2187 goto nla_put_failure; 2191 goto nla_put_failure;
2188 2192
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 681ea2f413e2..05c5ab8d983c 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -91,6 +91,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
91 RTCF_LOCAL); 91 RTCF_LOCAL);
92 xdst->u.rt.rt_type = rt->rt_type; 92 xdst->u.rt.rt_type = rt->rt_type;
93 xdst->u.rt.rt_gateway = rt->rt_gateway; 93 xdst->u.rt.rt_gateway = rt->rt_gateway;
94 xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
94 xdst->u.rt.rt_pmtu = rt->rt_pmtu; 95 xdst->u.rt.rt_pmtu = rt->rt_pmtu;
95 INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); 96 INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
96 97