diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-02 17:31:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-02 17:31:35 -0500 |
commit | b23dd4fe42b455af5c6e20966b7d6959fa8352ea (patch) | |
tree | bf97323eae9a8d084170e573ff2c0c40bc72c3cd /net/ipv4 | |
parent | 452edd598f60522c11f7f88fdbab27eb36509d1a (diff) |
ipv4: Make output route lookup return rtable directly.
Instead of on the stack.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/af_inet.c | 30 | ||||
-rw-r--r-- | net/ipv4/arp.c | 19 | ||||
-rw-r--r-- | net/ipv4/datagram.c | 11 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 19 | ||||
-rw-r--r-- | net/ipv4/igmp.c | 16 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 11 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 6 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 7 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter.c | 12 | ||||
-rw-r--r-- | net/ipv4/raw.c | 8 | ||||
-rw-r--r-- | net/ipv4/route.c | 100 | ||||
-rw-r--r-- | net/ipv4/syncookies.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 28 | ||||
-rw-r--r-- | net/ipv4/udp.c | 5 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 12 |
17 files changed, 160 insertions, 138 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 44513bb8ac2e..35a502055018 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1101,23 +1101,20 @@ int sysctl_ip_dynaddr __read_mostly; | |||
1101 | static int inet_sk_reselect_saddr(struct sock *sk) | 1101 | static int inet_sk_reselect_saddr(struct sock *sk) |
1102 | { | 1102 | { |
1103 | struct inet_sock *inet = inet_sk(sk); | 1103 | struct inet_sock *inet = inet_sk(sk); |
1104 | int err; | ||
1105 | struct rtable *rt; | ||
1106 | __be32 old_saddr = inet->inet_saddr; | 1104 | __be32 old_saddr = inet->inet_saddr; |
1107 | __be32 new_saddr; | ||
1108 | __be32 daddr = inet->inet_daddr; | 1105 | __be32 daddr = inet->inet_daddr; |
1106 | struct rtable *rt; | ||
1107 | __be32 new_saddr; | ||
1109 | 1108 | ||
1110 | if (inet->opt && inet->opt->srr) | 1109 | if (inet->opt && inet->opt->srr) |
1111 | daddr = inet->opt->faddr; | 1110 | daddr = inet->opt->faddr; |
1112 | 1111 | ||
1113 | /* Query new route. */ | 1112 | /* Query new route. */ |
1114 | err = ip_route_connect(&rt, daddr, 0, | 1113 | rt = ip_route_connect(daddr, 0, RT_CONN_FLAGS(sk), |
1115 | RT_CONN_FLAGS(sk), | 1114 | sk->sk_bound_dev_if, sk->sk_protocol, |
1116 | sk->sk_bound_dev_if, | 1115 | inet->inet_sport, inet->inet_dport, sk, false); |
1117 | sk->sk_protocol, | 1116 | if (IS_ERR(rt)) |
1118 | inet->inet_sport, inet->inet_dport, sk, false); | 1117 | return PTR_ERR(rt); |
1119 | if (err) | ||
1120 | return err; | ||
1121 | 1118 | ||
1122 | sk_setup_caps(sk, &rt->dst); | 1119 | sk_setup_caps(sk, &rt->dst); |
1123 | 1120 | ||
@@ -1160,7 +1157,7 @@ int inet_sk_rebuild_header(struct sock *sk) | |||
1160 | daddr = inet->inet_daddr; | 1157 | daddr = inet->inet_daddr; |
1161 | if (inet->opt && inet->opt->srr) | 1158 | if (inet->opt && inet->opt->srr) |
1162 | daddr = inet->opt->faddr; | 1159 | daddr = inet->opt->faddr; |
1163 | { | 1160 | { |
1164 | struct flowi fl = { | 1161 | struct flowi fl = { |
1165 | .oif = sk->sk_bound_dev_if, | 1162 | .oif = sk->sk_bound_dev_if, |
1166 | .mark = sk->sk_mark, | 1163 | .mark = sk->sk_mark, |
@@ -1174,11 +1171,14 @@ int inet_sk_rebuild_header(struct sock *sk) | |||
1174 | }; | 1171 | }; |
1175 | 1172 | ||
1176 | security_sk_classify_flow(sk, &fl); | 1173 | security_sk_classify_flow(sk, &fl); |
1177 | err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); | 1174 | rt = ip_route_output_flow(sock_net(sk), &fl, sk); |
1178 | } | 1175 | } |
1179 | if (!err) | 1176 | if (!IS_ERR(rt)) { |
1177 | err = 0; | ||
1180 | sk_setup_caps(sk, &rt->dst); | 1178 | sk_setup_caps(sk, &rt->dst); |
1181 | else { | 1179 | } else { |
1180 | err = PTR_ERR(rt); | ||
1181 | |||
1182 | /* Routing failed... */ | 1182 | /* Routing failed... */ |
1183 | sk->sk_route_caps = 0; | 1183 | sk->sk_route_caps = 0; |
1184 | /* | 1184 | /* |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7927589813b5..fa9988da1da4 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -440,7 +440,8 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) | |||
440 | /*unsigned long now; */ | 440 | /*unsigned long now; */ |
441 | struct net *net = dev_net(dev); | 441 | struct net *net = dev_net(dev); |
442 | 442 | ||
443 | if (ip_route_output_key(net, &rt, &fl) < 0) | 443 | rt = ip_route_output_key(net, &fl); |
444 | if (IS_ERR(rt)) | ||
444 | return 1; | 445 | return 1; |
445 | if (rt->dst.dev != dev) { | 446 | if (rt->dst.dev != dev) { |
446 | NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); | 447 | NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); |
@@ -1063,10 +1064,10 @@ static int arp_req_set(struct net *net, struct arpreq *r, | |||
1063 | if (dev == NULL) { | 1064 | if (dev == NULL) { |
1064 | struct flowi fl = { .fl4_dst = ip, | 1065 | struct flowi fl = { .fl4_dst = ip, |
1065 | .fl4_tos = RTO_ONLINK }; | 1066 | .fl4_tos = RTO_ONLINK }; |
1066 | struct rtable *rt; | 1067 | struct rtable *rt = ip_route_output_key(net, &fl); |
1067 | err = ip_route_output_key(net, &rt, &fl); | 1068 | |
1068 | if (err != 0) | 1069 | if (IS_ERR(rt)) |
1069 | return err; | 1070 | return PTR_ERR(rt); |
1070 | dev = rt->dst.dev; | 1071 | dev = rt->dst.dev; |
1071 | ip_rt_put(rt); | 1072 | ip_rt_put(rt); |
1072 | if (!dev) | 1073 | if (!dev) |
@@ -1177,7 +1178,6 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r, | |||
1177 | static int arp_req_delete(struct net *net, struct arpreq *r, | 1178 | static int arp_req_delete(struct net *net, struct arpreq *r, |
1178 | struct net_device *dev) | 1179 | struct net_device *dev) |
1179 | { | 1180 | { |
1180 | int err; | ||
1181 | __be32 ip; | 1181 | __be32 ip; |
1182 | 1182 | ||
1183 | if (r->arp_flags & ATF_PUBL) | 1183 | if (r->arp_flags & ATF_PUBL) |
@@ -1187,10 +1187,9 @@ static int arp_req_delete(struct net *net, struct arpreq *r, | |||
1187 | if (dev == NULL) { | 1187 | if (dev == NULL) { |
1188 | struct flowi fl = { .fl4_dst = ip, | 1188 | struct flowi fl = { .fl4_dst = ip, |
1189 | .fl4_tos = RTO_ONLINK }; | 1189 | .fl4_tos = RTO_ONLINK }; |
1190 | struct rtable *rt; | 1190 | struct rtable *rt = ip_route_output_key(net, &fl); |
1191 | err = ip_route_output_key(net, &rt, &fl); | 1191 | if (IS_ERR(rt)) |
1192 | if (err != 0) | 1192 | return PTR_ERR(rt); |
1193 | return err; | ||
1194 | dev = rt->dst.dev; | 1193 | dev = rt->dst.dev; |
1195 | ip_rt_put(rt); | 1194 | ip_rt_put(rt); |
1196 | if (!dev) | 1195 | if (!dev) |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index eaee1edd2dd7..85bd24ca4f6d 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -46,11 +46,12 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
46 | if (!saddr) | 46 | if (!saddr) |
47 | saddr = inet->mc_addr; | 47 | saddr = inet->mc_addr; |
48 | } | 48 | } |
49 | err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, | 49 | rt = ip_route_connect(usin->sin_addr.s_addr, saddr, |
50 | RT_CONN_FLAGS(sk), oif, | 50 | RT_CONN_FLAGS(sk), oif, |
51 | sk->sk_protocol, | 51 | sk->sk_protocol, |
52 | inet->inet_sport, usin->sin_port, sk, true); | 52 | inet->inet_sport, usin->sin_port, sk, true); |
53 | if (err) { | 53 | if (IS_ERR(rt)) { |
54 | err = PTR_ERR(rt); | ||
54 | if (err == -ENETUNREACH) | 55 | if (err == -ENETUNREACH) |
55 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 56 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
56 | return err; | 57 | return err; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c23bd8cdeee0..994a785d98f9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -358,7 +358,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
358 | .fl4_tos = RT_TOS(ip_hdr(skb)->tos), | 358 | .fl4_tos = RT_TOS(ip_hdr(skb)->tos), |
359 | .proto = IPPROTO_ICMP }; | 359 | .proto = IPPROTO_ICMP }; |
360 | security_skb_classify_flow(skb, &fl); | 360 | security_skb_classify_flow(skb, &fl); |
361 | if (ip_route_output_key(net, &rt, &fl)) | 361 | rt = ip_route_output_key(net, &fl); |
362 | if (IS_ERR(rt)) | ||
362 | goto out_unlock; | 363 | goto out_unlock; |
363 | } | 364 | } |
364 | if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type, | 365 | if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type, |
@@ -388,9 +389,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, | |||
388 | int err; | 389 | int err; |
389 | 390 | ||
390 | security_skb_classify_flow(skb_in, &fl); | 391 | security_skb_classify_flow(skb_in, &fl); |
391 | err = __ip_route_output_key(net, &rt, &fl); | 392 | rt = __ip_route_output_key(net, &fl); |
392 | if (err) | 393 | if (IS_ERR(rt)) |
393 | return ERR_PTR(err); | 394 | return rt; |
394 | 395 | ||
395 | /* No need to clone since we're just using its address. */ | 396 | /* No need to clone since we're just using its address. */ |
396 | rt2 = rt; | 397 | rt2 = rt; |
@@ -412,15 +413,19 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, | |||
412 | goto relookup_failed; | 413 | goto relookup_failed; |
413 | 414 | ||
414 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { | 415 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { |
415 | err = __ip_route_output_key(net, &rt2, &fl); | 416 | rt2 = __ip_route_output_key(net, &fl); |
417 | if (IS_ERR(rt2)) | ||
418 | err = PTR_ERR(rt2); | ||
416 | } else { | 419 | } else { |
417 | struct flowi fl2 = {}; | 420 | struct flowi fl2 = {}; |
418 | unsigned long orefdst; | 421 | unsigned long orefdst; |
419 | 422 | ||
420 | fl2.fl4_dst = fl.fl4_src; | 423 | fl2.fl4_dst = fl.fl4_src; |
421 | err = ip_route_output_key(net, &rt2, &fl2); | 424 | rt2 = ip_route_output_key(net, &fl2); |
422 | if (err) | 425 | if (IS_ERR(rt2)) { |
426 | err = PTR_ERR(rt2); | ||
423 | goto relookup_failed; | 427 | goto relookup_failed; |
428 | } | ||
424 | /* Ugh! */ | 429 | /* Ugh! */ |
425 | orefdst = skb_in->_skb_refdst; /* save old refdst */ | 430 | orefdst = skb_in->_skb_refdst; /* save old refdst */ |
426 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, | 431 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index e0e77e297de3..44ba9068b72f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -325,7 +325,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
325 | struct flowi fl = { .oif = dev->ifindex, | 325 | struct flowi fl = { .oif = dev->ifindex, |
326 | .fl4_dst = IGMPV3_ALL_MCR, | 326 | .fl4_dst = IGMPV3_ALL_MCR, |
327 | .proto = IPPROTO_IGMP }; | 327 | .proto = IPPROTO_IGMP }; |
328 | if (ip_route_output_key(net, &rt, &fl)) { | 328 | rt = ip_route_output_key(net, &fl); |
329 | if (IS_ERR(rt)) { | ||
329 | kfree_skb(skb); | 330 | kfree_skb(skb); |
330 | return NULL; | 331 | return NULL; |
331 | } | 332 | } |
@@ -670,7 +671,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
670 | struct flowi fl = { .oif = dev->ifindex, | 671 | struct flowi fl = { .oif = dev->ifindex, |
671 | .fl4_dst = dst, | 672 | .fl4_dst = dst, |
672 | .proto = IPPROTO_IGMP }; | 673 | .proto = IPPROTO_IGMP }; |
673 | if (ip_route_output_key(net, &rt, &fl)) | 674 | rt = ip_route_output_key(net, &fl); |
675 | if (IS_ERR(rt)) | ||
674 | return -1; | 676 | return -1; |
675 | } | 677 | } |
676 | if (rt->rt_src == 0) { | 678 | if (rt->rt_src == 0) { |
@@ -1440,7 +1442,6 @@ void ip_mc_destroy_dev(struct in_device *in_dev) | |||
1440 | static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) | 1442 | static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) |
1441 | { | 1443 | { |
1442 | struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; | 1444 | struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; |
1443 | struct rtable *rt; | ||
1444 | struct net_device *dev = NULL; | 1445 | struct net_device *dev = NULL; |
1445 | struct in_device *idev = NULL; | 1446 | struct in_device *idev = NULL; |
1446 | 1447 | ||
@@ -1454,9 +1455,12 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) | |||
1454 | return NULL; | 1455 | return NULL; |
1455 | } | 1456 | } |
1456 | 1457 | ||
1457 | if (!dev && !ip_route_output_key(net, &rt, &fl)) { | 1458 | if (!dev) { |
1458 | dev = rt->dst.dev; | 1459 | struct rtable *rt = ip_route_output_key(net, &fl); |
1459 | ip_rt_put(rt); | 1460 | if (!IS_ERR(rt)) { |
1461 | dev = rt->dst.dev; | ||
1462 | ip_rt_put(rt); | ||
1463 | } | ||
1460 | } | 1464 | } |
1461 | if (dev) { | 1465 | if (dev) { |
1462 | imr->imr_ifindex = dev->ifindex; | 1466 | imr->imr_ifindex = dev->ifindex; |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 7f85d4aec26a..e4e301a61c5b 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -369,7 +369,8 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, | |||
369 | struct net *net = sock_net(sk); | 369 | struct net *net = sock_net(sk); |
370 | 370 | ||
371 | security_req_classify_flow(req, &fl); | 371 | security_req_classify_flow(req, &fl); |
372 | if (ip_route_output_flow(net, &rt, &fl, sk)) | 372 | rt = ip_route_output_flow(net, &fl, sk); |
373 | if (IS_ERR(rt)) | ||
373 | goto no_route; | 374 | goto no_route; |
374 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) | 375 | if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) |
375 | goto route_err; | 376 | goto route_err; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6613edfac28c..f9af98dd7561 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -778,7 +778,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
778 | .proto = IPPROTO_GRE, | 778 | .proto = IPPROTO_GRE, |
779 | .fl_gre_key = tunnel->parms.o_key | 779 | .fl_gre_key = tunnel->parms.o_key |
780 | }; | 780 | }; |
781 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | 781 | rt = ip_route_output_key(dev_net(dev), &fl); |
782 | if (IS_ERR(rt)) { | ||
782 | dev->stats.tx_carrier_errors++; | 783 | dev->stats.tx_carrier_errors++; |
783 | goto tx_error; | 784 | goto tx_error; |
784 | } | 785 | } |
@@ -953,9 +954,9 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) | |||
953 | .proto = IPPROTO_GRE, | 954 | .proto = IPPROTO_GRE, |
954 | .fl_gre_key = tunnel->parms.o_key | 955 | .fl_gre_key = tunnel->parms.o_key |
955 | }; | 956 | }; |
956 | struct rtable *rt; | 957 | struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); |
957 | 958 | ||
958 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { | 959 | if (!IS_ERR(rt)) { |
959 | tdev = rt->dst.dev; | 960 | tdev = rt->dst.dev; |
960 | ip_rt_put(rt); | 961 | ip_rt_put(rt); |
961 | } | 962 | } |
@@ -1215,9 +1216,9 @@ static int ipgre_open(struct net_device *dev) | |||
1215 | .proto = IPPROTO_GRE, | 1216 | .proto = IPPROTO_GRE, |
1216 | .fl_gre_key = t->parms.o_key | 1217 | .fl_gre_key = t->parms.o_key |
1217 | }; | 1218 | }; |
1218 | struct rtable *rt; | 1219 | struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); |
1219 | 1220 | ||
1220 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) | 1221 | if (IS_ERR(rt)) |
1221 | return -EADDRNOTAVAIL; | 1222 | return -EADDRNOTAVAIL; |
1222 | dev = rt->dst.dev; | 1223 | dev = rt->dst.dev; |
1223 | ip_rt_put(rt); | 1224 | ip_rt_put(rt); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 33316b3534ca..171f483b21d5 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -355,7 +355,8 @@ int ip_queue_xmit(struct sk_buff *skb) | |||
355 | * itself out. | 355 | * itself out. |
356 | */ | 356 | */ |
357 | security_sk_classify_flow(sk, &fl); | 357 | security_sk_classify_flow(sk, &fl); |
358 | if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk)) | 358 | rt = ip_route_output_flow(sock_net(sk), &fl, sk); |
359 | if (IS_ERR(rt)) | ||
359 | goto no_route; | 360 | goto no_route; |
360 | } | 361 | } |
361 | sk_setup_caps(sk, &rt->dst); | 362 | sk_setup_caps(sk, &rt->dst); |
@@ -1489,7 +1490,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1489 | .proto = sk->sk_protocol, | 1490 | .proto = sk->sk_protocol, |
1490 | .flags = ip_reply_arg_flowi_flags(arg) }; | 1491 | .flags = ip_reply_arg_flowi_flags(arg) }; |
1491 | security_skb_classify_flow(skb, &fl); | 1492 | security_skb_classify_flow(skb, &fl); |
1492 | if (ip_route_output_key(sock_net(sk), &rt, &fl)) | 1493 | rt = ip_route_output_key(sock_net(sk), &fl); |
1494 | if (IS_ERR(rt)) | ||
1493 | return; | 1495 | return; |
1494 | } | 1496 | } |
1495 | 1497 | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 988f52fba54a..e1e17576baa6 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -469,7 +469,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
469 | .proto = IPPROTO_IPIP | 469 | .proto = IPPROTO_IPIP |
470 | }; | 470 | }; |
471 | 471 | ||
472 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | 472 | rt = ip_route_output_key(dev_net(dev), &fl); |
473 | if (IS_ERR(rt)) { | ||
473 | dev->stats.tx_carrier_errors++; | 474 | dev->stats.tx_carrier_errors++; |
474 | goto tx_error_icmp; | 475 | goto tx_error_icmp; |
475 | } | 476 | } |
@@ -590,9 +591,9 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) | |||
590 | .fl4_tos = RT_TOS(iph->tos), | 591 | .fl4_tos = RT_TOS(iph->tos), |
591 | .proto = IPPROTO_IPIP | 592 | .proto = IPPROTO_IPIP |
592 | }; | 593 | }; |
593 | struct rtable *rt; | 594 | struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); |
594 | 595 | ||
595 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { | 596 | if (!IS_ERR(rt)) { |
596 | tdev = rt->dst.dev; | 597 | tdev = rt->dst.dev; |
597 | ip_rt_put(rt); | 598 | ip_rt_put(rt); |
598 | } | 599 | } |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8b65a12654e7..26ca2f2d37ce 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1618,8 +1618,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, | |||
1618 | .fl4_tos = RT_TOS(iph->tos), | 1618 | .fl4_tos = RT_TOS(iph->tos), |
1619 | .proto = IPPROTO_IPIP | 1619 | .proto = IPPROTO_IPIP |
1620 | }; | 1620 | }; |
1621 | 1621 | rt = ip_route_output_key(net, &fl); | |
1622 | if (ip_route_output_key(net, &rt, &fl)) | 1622 | if (IS_ERR(rt)) |
1623 | goto out_free; | 1623 | goto out_free; |
1624 | encap = sizeof(struct iphdr); | 1624 | encap = sizeof(struct iphdr); |
1625 | } else { | 1625 | } else { |
@@ -1629,8 +1629,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, | |||
1629 | .fl4_tos = RT_TOS(iph->tos), | 1629 | .fl4_tos = RT_TOS(iph->tos), |
1630 | .proto = IPPROTO_IPIP | 1630 | .proto = IPPROTO_IPIP |
1631 | }; | 1631 | }; |
1632 | 1632 | rt = ip_route_output_key(net, &fl); | |
1633 | if (ip_route_output_key(net, &rt, &fl)) | 1633 | if (IS_ERR(rt)) |
1634 | goto out_free; | 1634 | goto out_free; |
1635 | } | 1635 | } |
1636 | 1636 | ||
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 9770bb427952..67bf709180de 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -38,7 +38,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
38 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 38 | fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
39 | fl.mark = skb->mark; | 39 | fl.mark = skb->mark; |
40 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; | 40 | fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
41 | if (ip_route_output_key(net, &rt, &fl) != 0) | 41 | rt = ip_route_output_key(net, &fl); |
42 | if (IS_ERR(rt)) | ||
42 | return -1; | 43 | return -1; |
43 | 44 | ||
44 | /* Drop old route. */ | 45 | /* Drop old route. */ |
@@ -48,7 +49,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
48 | /* non-local src, find valid iif to satisfy | 49 | /* non-local src, find valid iif to satisfy |
49 | * rp-filter when calling ip_route_input. */ | 50 | * rp-filter when calling ip_route_input. */ |
50 | fl.fl4_dst = iph->saddr; | 51 | fl.fl4_dst = iph->saddr; |
51 | if (ip_route_output_key(net, &rt, &fl) != 0) | 52 | rt = ip_route_output_key(net, &fl); |
53 | if (IS_ERR(rt)) | ||
52 | return -1; | 54 | return -1; |
53 | 55 | ||
54 | orefdst = skb->_skb_refdst; | 56 | orefdst = skb->_skb_refdst; |
@@ -221,7 +223,11 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, | |||
221 | 223 | ||
222 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) | 224 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) |
223 | { | 225 | { |
224 | return ip_route_output_key(&init_net, (struct rtable **)dst, fl); | 226 | struct rtable *rt = ip_route_output_key(&init_net, fl); |
227 | if (IS_ERR(rt)) | ||
228 | return PTR_ERR(rt); | ||
229 | *dst = &rt->dst; | ||
230 | return 0; | ||
225 | } | 231 | } |
226 | 232 | ||
227 | static const struct nf_afinfo nf_ip_afinfo = { | 233 | static const struct nf_afinfo nf_ip_afinfo = { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d7a2d1eaec09..467d570d087a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -564,10 +564,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
564 | } | 564 | } |
565 | 565 | ||
566 | security_sk_classify_flow(sk, &fl); | 566 | security_sk_classify_flow(sk, &fl); |
567 | err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); | 567 | rt = ip_route_output_flow(sock_net(sk), &fl, sk); |
568 | if (IS_ERR(rt)) { | ||
569 | err = PTR_ERR(rt); | ||
570 | goto done; | ||
571 | } | ||
568 | } | 572 | } |
569 | if (err) | ||
570 | goto done; | ||
571 | 573 | ||
572 | err = -EACCES; | 574 | err = -EACCES; |
573 | if (rt->rt_flags & RTCF_BROADCAST && !sock_flag(sk, SOCK_BROADCAST)) | 575 | if (rt->rt_flags & RTCF_BROADCAST && !sock_flag(sk, SOCK_BROADCAST)) |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 63d37004ee66..5090e956f6b8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1014,8 +1014,8 @@ static int slow_chain_length(const struct rtable *head) | |||
1014 | return length >> FRACT_BITS; | 1014 | return length >> FRACT_BITS; |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | static int rt_intern_hash(unsigned hash, struct rtable *rt, | 1017 | static struct rtable *rt_intern_hash(unsigned hash, struct rtable *rt, |
1018 | struct rtable **rp, struct sk_buff *skb, int ifindex) | 1018 | struct sk_buff *skb, int ifindex) |
1019 | { | 1019 | { |
1020 | struct rtable *rth, *cand; | 1020 | struct rtable *rth, *cand; |
1021 | struct rtable __rcu **rthp, **candp; | 1021 | struct rtable __rcu **rthp, **candp; |
@@ -1056,7 +1056,7 @@ restart: | |||
1056 | printk(KERN_WARNING | 1056 | printk(KERN_WARNING |
1057 | "Neighbour table failure & not caching routes.\n"); | 1057 | "Neighbour table failure & not caching routes.\n"); |
1058 | ip_rt_put(rt); | 1058 | ip_rt_put(rt); |
1059 | return err; | 1059 | return ERR_PTR(err); |
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | 1062 | ||
@@ -1093,11 +1093,9 @@ restart: | |||
1093 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1093 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1094 | 1094 | ||
1095 | rt_drop(rt); | 1095 | rt_drop(rt); |
1096 | if (rp) | 1096 | if (skb) |
1097 | *rp = rth; | ||
1098 | else | ||
1099 | skb_dst_set(skb, &rth->dst); | 1097 | skb_dst_set(skb, &rth->dst); |
1100 | return 0; | 1098 | return rth; |
1101 | } | 1099 | } |
1102 | 1100 | ||
1103 | if (!atomic_read(&rth->dst.__refcnt)) { | 1101 | if (!atomic_read(&rth->dst.__refcnt)) { |
@@ -1154,7 +1152,7 @@ restart: | |||
1154 | 1152 | ||
1155 | if (err != -ENOBUFS) { | 1153 | if (err != -ENOBUFS) { |
1156 | rt_drop(rt); | 1154 | rt_drop(rt); |
1157 | return err; | 1155 | return ERR_PTR(err); |
1158 | } | 1156 | } |
1159 | 1157 | ||
1160 | /* Neighbour tables are full and nothing | 1158 | /* Neighbour tables are full and nothing |
@@ -1175,7 +1173,7 @@ restart: | |||
1175 | if (net_ratelimit()) | 1173 | if (net_ratelimit()) |
1176 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); | 1174 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); |
1177 | rt_drop(rt); | 1175 | rt_drop(rt); |
1178 | return -ENOBUFS; | 1176 | return ERR_PTR(-ENOBUFS); |
1179 | } | 1177 | } |
1180 | } | 1178 | } |
1181 | 1179 | ||
@@ -1201,11 +1199,9 @@ restart: | |||
1201 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1199 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1202 | 1200 | ||
1203 | skip_hashing: | 1201 | skip_hashing: |
1204 | if (rp) | 1202 | if (skb) |
1205 | *rp = rt; | ||
1206 | else | ||
1207 | skb_dst_set(skb, &rt->dst); | 1203 | skb_dst_set(skb, &rt->dst); |
1208 | return 0; | 1204 | return rt; |
1209 | } | 1205 | } |
1210 | 1206 | ||
1211 | static atomic_t __rt_peer_genid = ATOMIC_INIT(0); | 1207 | static atomic_t __rt_peer_genid = ATOMIC_INIT(0); |
@@ -1896,7 +1892,10 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1896 | RT_CACHE_STAT_INC(in_slow_mc); | 1892 | RT_CACHE_STAT_INC(in_slow_mc); |
1897 | 1893 | ||
1898 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1894 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
1899 | return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex); | 1895 | rth = rt_intern_hash(hash, rth, skb, dev->ifindex); |
1896 | err = 0; | ||
1897 | if (IS_ERR(rth)) | ||
1898 | err = PTR_ERR(rth); | ||
1900 | 1899 | ||
1901 | e_nobufs: | 1900 | e_nobufs: |
1902 | return -ENOBUFS; | 1901 | return -ENOBUFS; |
@@ -2051,7 +2050,10 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
2051 | /* put it into the cache */ | 2050 | /* put it into the cache */ |
2052 | hash = rt_hash(daddr, saddr, fl->iif, | 2051 | hash = rt_hash(daddr, saddr, fl->iif, |
2053 | rt_genid(dev_net(rth->dst.dev))); | 2052 | rt_genid(dev_net(rth->dst.dev))); |
2054 | return rt_intern_hash(hash, rth, NULL, skb, fl->iif); | 2053 | rth = rt_intern_hash(hash, rth, skb, fl->iif); |
2054 | if (IS_ERR(rth)) | ||
2055 | return PTR_ERR(rth); | ||
2056 | return 0; | ||
2055 | } | 2057 | } |
2056 | 2058 | ||
2057 | /* | 2059 | /* |
@@ -2194,7 +2196,10 @@ local_input: | |||
2194 | } | 2196 | } |
2195 | rth->rt_type = res.type; | 2197 | rth->rt_type = res.type; |
2196 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); | 2198 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
2197 | err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); | 2199 | rth = rt_intern_hash(hash, rth, skb, fl.iif); |
2200 | err = 0; | ||
2201 | if (IS_ERR(rth)) | ||
2202 | err = PTR_ERR(rth); | ||
2198 | goto out; | 2203 | goto out; |
2199 | 2204 | ||
2200 | no_route: | 2205 | no_route: |
@@ -2422,8 +2427,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2422 | * called with rcu_read_lock(); | 2427 | * called with rcu_read_lock(); |
2423 | */ | 2428 | */ |
2424 | 2429 | ||
2425 | static int ip_route_output_slow(struct net *net, struct rtable **rp, | 2430 | static struct rtable *ip_route_output_slow(struct net *net, |
2426 | const struct flowi *oldflp) | 2431 | const struct flowi *oldflp) |
2427 | { | 2432 | { |
2428 | u32 tos = RT_FL_TOS(oldflp); | 2433 | u32 tos = RT_FL_TOS(oldflp); |
2429 | struct flowi fl = { .fl4_dst = oldflp->fl4_dst, | 2434 | struct flowi fl = { .fl4_dst = oldflp->fl4_dst, |
@@ -2438,8 +2443,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2438 | unsigned int flags = 0; | 2443 | unsigned int flags = 0; |
2439 | struct net_device *dev_out = NULL; | 2444 | struct net_device *dev_out = NULL; |
2440 | struct rtable *rth; | 2445 | struct rtable *rth; |
2441 | int err; | ||
2442 | |||
2443 | 2446 | ||
2444 | res.fi = NULL; | 2447 | res.fi = NULL; |
2445 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 2448 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
@@ -2448,7 +2451,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2448 | 2451 | ||
2449 | rcu_read_lock(); | 2452 | rcu_read_lock(); |
2450 | if (oldflp->fl4_src) { | 2453 | if (oldflp->fl4_src) { |
2451 | err = -EINVAL; | 2454 | rth = ERR_PTR(-EINVAL); |
2452 | if (ipv4_is_multicast(oldflp->fl4_src) || | 2455 | if (ipv4_is_multicast(oldflp->fl4_src) || |
2453 | ipv4_is_lbcast(oldflp->fl4_src) || | 2456 | ipv4_is_lbcast(oldflp->fl4_src) || |
2454 | ipv4_is_zeronet(oldflp->fl4_src)) | 2457 | ipv4_is_zeronet(oldflp->fl4_src)) |
@@ -2499,13 +2502,13 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2499 | 2502 | ||
2500 | if (oldflp->oif) { | 2503 | if (oldflp->oif) { |
2501 | dev_out = dev_get_by_index_rcu(net, oldflp->oif); | 2504 | dev_out = dev_get_by_index_rcu(net, oldflp->oif); |
2502 | err = -ENODEV; | 2505 | rth = ERR_PTR(-ENODEV); |
2503 | if (dev_out == NULL) | 2506 | if (dev_out == NULL) |
2504 | goto out; | 2507 | goto out; |
2505 | 2508 | ||
2506 | /* RACE: Check return value of inet_select_addr instead. */ | 2509 | /* RACE: Check return value of inet_select_addr instead. */ |
2507 | if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { | 2510 | if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { |
2508 | err = -ENETUNREACH; | 2511 | rth = ERR_PTR(-ENETUNREACH); |
2509 | goto out; | 2512 | goto out; |
2510 | } | 2513 | } |
2511 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || | 2514 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || |
@@ -2563,7 +2566,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2563 | res.type = RTN_UNICAST; | 2566 | res.type = RTN_UNICAST; |
2564 | goto make_route; | 2567 | goto make_route; |
2565 | } | 2568 | } |
2566 | err = -ENETUNREACH; | 2569 | rth = ERR_PTR(-ENETUNREACH); |
2567 | goto out; | 2570 | goto out; |
2568 | } | 2571 | } |
2569 | 2572 | ||
@@ -2598,23 +2601,20 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2598 | 2601 | ||
2599 | make_route: | 2602 | make_route: |
2600 | rth = __mkroute_output(&res, &fl, oldflp, dev_out, flags); | 2603 | rth = __mkroute_output(&res, &fl, oldflp, dev_out, flags); |
2601 | if (IS_ERR(rth)) | 2604 | if (!IS_ERR(rth)) { |
2602 | err = PTR_ERR(rth); | ||
2603 | else { | ||
2604 | unsigned int hash; | 2605 | unsigned int hash; |
2605 | 2606 | ||
2606 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, | 2607 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
2607 | rt_genid(dev_net(dev_out))); | 2608 | rt_genid(dev_net(dev_out))); |
2608 | err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif); | 2609 | rth = rt_intern_hash(hash, rth, NULL, oldflp->oif); |
2609 | } | 2610 | } |
2610 | 2611 | ||
2611 | out: | 2612 | out: |
2612 | rcu_read_unlock(); | 2613 | rcu_read_unlock(); |
2613 | return err; | 2614 | return rth; |
2614 | } | 2615 | } |
2615 | 2616 | ||
2616 | int __ip_route_output_key(struct net *net, struct rtable **rp, | 2617 | struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) |
2617 | const struct flowi *flp) | ||
2618 | { | 2618 | { |
2619 | struct rtable *rth; | 2619 | struct rtable *rth; |
2620 | unsigned int hash; | 2620 | unsigned int hash; |
@@ -2639,15 +2639,14 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, | |||
2639 | dst_use(&rth->dst, jiffies); | 2639 | dst_use(&rth->dst, jiffies); |
2640 | RT_CACHE_STAT_INC(out_hit); | 2640 | RT_CACHE_STAT_INC(out_hit); |
2641 | rcu_read_unlock_bh(); | 2641 | rcu_read_unlock_bh(); |
2642 | *rp = rth; | 2642 | return rth; |
2643 | return 0; | ||
2644 | } | 2643 | } |
2645 | RT_CACHE_STAT_INC(out_hlist_search); | 2644 | RT_CACHE_STAT_INC(out_hlist_search); |
2646 | } | 2645 | } |
2647 | rcu_read_unlock_bh(); | 2646 | rcu_read_unlock_bh(); |
2648 | 2647 | ||
2649 | slow_output: | 2648 | slow_output: |
2650 | return ip_route_output_slow(net, rp, flp); | 2649 | return ip_route_output_slow(net, flp); |
2651 | } | 2650 | } |
2652 | EXPORT_SYMBOL_GPL(__ip_route_output_key); | 2651 | EXPORT_SYMBOL_GPL(__ip_route_output_key); |
2653 | 2652 | ||
@@ -2717,34 +2716,29 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
2717 | return rt ? &rt->dst : ERR_PTR(-ENOMEM); | 2716 | return rt ? &rt->dst : ERR_PTR(-ENOMEM); |
2718 | } | 2717 | } |
2719 | 2718 | ||
2720 | int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, | 2719 | struct rtable *ip_route_output_flow(struct net *net, struct flowi *flp, |
2721 | struct sock *sk) | 2720 | struct sock *sk) |
2722 | { | 2721 | { |
2723 | int err; | 2722 | struct rtable *rt = __ip_route_output_key(net, flp); |
2724 | 2723 | ||
2725 | if ((err = __ip_route_output_key(net, rp, flp)) != 0) | 2724 | if (IS_ERR(rt)) |
2726 | return err; | 2725 | return rt; |
2727 | 2726 | ||
2728 | if (flp->proto) { | 2727 | if (flp->proto) { |
2729 | if (!flp->fl4_src) | 2728 | if (!flp->fl4_src) |
2730 | flp->fl4_src = (*rp)->rt_src; | 2729 | flp->fl4_src = rt->rt_src; |
2731 | if (!flp->fl4_dst) | 2730 | if (!flp->fl4_dst) |
2732 | flp->fl4_dst = (*rp)->rt_dst; | 2731 | flp->fl4_dst = rt->rt_dst; |
2733 | *rp = (struct rtable *) xfrm_lookup(net, &(*rp)->dst, flp, sk, 0); | 2732 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, flp, sk, 0); |
2734 | if (IS_ERR(*rp)) { | ||
2735 | err = PTR_ERR(*rp); | ||
2736 | *rp = NULL; | ||
2737 | return err; | ||
2738 | } | ||
2739 | } | 2733 | } |
2740 | 2734 | ||
2741 | return 0; | 2735 | return rt; |
2742 | } | 2736 | } |
2743 | EXPORT_SYMBOL_GPL(ip_route_output_flow); | 2737 | EXPORT_SYMBOL_GPL(ip_route_output_flow); |
2744 | 2738 | ||
2745 | int ip_route_output_key(struct net *net, struct rtable **rp, struct flowi *flp) | 2739 | struct rtable *ip_route_output_key(struct net *net, struct flowi *flp) |
2746 | { | 2740 | { |
2747 | return ip_route_output_flow(net, rp, flp, NULL); | 2741 | return ip_route_output_flow(net, flp, NULL); |
2748 | } | 2742 | } |
2749 | EXPORT_SYMBOL(ip_route_output_key); | 2743 | EXPORT_SYMBOL(ip_route_output_key); |
2750 | 2744 | ||
@@ -2915,7 +2909,11 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2915 | .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, | 2909 | .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, |
2916 | .mark = mark, | 2910 | .mark = mark, |
2917 | }; | 2911 | }; |
2918 | err = ip_route_output_key(net, &rt, &fl); | 2912 | rt = ip_route_output_key(net, &fl); |
2913 | |||
2914 | err = 0; | ||
2915 | if (IS_ERR(rt)) | ||
2916 | err = PTR_ERR(rt); | ||
2919 | } | 2917 | } |
2920 | 2918 | ||
2921 | if (err) | 2919 | if (err) |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 47519205a014..0ad6ddf638a7 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -355,7 +355,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
355 | .fl_ip_sport = th->dest, | 355 | .fl_ip_sport = th->dest, |
356 | .fl_ip_dport = th->source }; | 356 | .fl_ip_dport = th->source }; |
357 | security_req_classify_flow(req, &fl); | 357 | security_req_classify_flow(req, &fl); |
358 | if (ip_route_output_key(sock_net(sk), &rt, &fl)) { | 358 | rt = ip_route_output_key(sock_net(sk), &fl); |
359 | if (IS_ERR(rt)) { | ||
359 | reqsk_free(req); | 360 | reqsk_free(req); |
360 | goto out; | 361 | goto out; |
361 | } | 362 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 05bc6d9455fc..f7e6c2c2d2bb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -152,7 +152,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
152 | __be16 orig_sport, orig_dport; | 152 | __be16 orig_sport, orig_dport; |
153 | struct rtable *rt; | 153 | struct rtable *rt; |
154 | __be32 daddr, nexthop; | 154 | __be32 daddr, nexthop; |
155 | int tmp; | ||
156 | int err; | 155 | int err; |
157 | 156 | ||
158 | if (addr_len < sizeof(struct sockaddr_in)) | 157 | if (addr_len < sizeof(struct sockaddr_in)) |
@@ -170,14 +169,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
170 | 169 | ||
171 | orig_sport = inet->inet_sport; | 170 | orig_sport = inet->inet_sport; |
172 | orig_dport = usin->sin_port; | 171 | orig_dport = usin->sin_port; |
173 | tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, | 172 | rt = ip_route_connect(nexthop, inet->inet_saddr, |
174 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, | 173 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, |
175 | IPPROTO_TCP, | 174 | IPPROTO_TCP, |
176 | orig_sport, orig_dport, sk, true); | 175 | orig_sport, orig_dport, sk, true); |
177 | if (tmp < 0) { | 176 | if (IS_ERR(rt)) { |
178 | if (tmp == -ENETUNREACH) | 177 | err = PTR_ERR(rt); |
178 | if (err == -ENETUNREACH) | ||
179 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 179 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
180 | return tmp; | 180 | return err; |
181 | } | 181 | } |
182 | 182 | ||
183 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { | 183 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { |
@@ -236,12 +236,14 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
236 | if (err) | 236 | if (err) |
237 | goto failure; | 237 | goto failure; |
238 | 238 | ||
239 | err = ip_route_newports(&rt, IPPROTO_TCP, | 239 | rt = ip_route_newports(rt, IPPROTO_TCP, |
240 | orig_sport, orig_dport, | 240 | orig_sport, orig_dport, |
241 | inet->inet_sport, inet->inet_dport, sk); | 241 | inet->inet_sport, inet->inet_dport, sk); |
242 | if (err) | 242 | if (IS_ERR(rt)) { |
243 | err = PTR_ERR(rt); | ||
244 | rt = NULL; | ||
243 | goto failure; | 245 | goto failure; |
244 | 246 | } | |
245 | /* OK, now commit destination to socket. */ | 247 | /* OK, now commit destination to socket. */ |
246 | sk->sk_gso_type = SKB_GSO_TCPV4; | 248 | sk->sk_gso_type = SKB_GSO_TCPV4; |
247 | sk_setup_caps(sk, &rt->dst); | 249 | sk_setup_caps(sk, &rt->dst); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ed9a5b7bee53..95e0c2c194a1 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -922,8 +922,9 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
922 | struct net *net = sock_net(sk); | 922 | struct net *net = sock_net(sk); |
923 | 923 | ||
924 | security_sk_classify_flow(sk, &fl); | 924 | security_sk_classify_flow(sk, &fl); |
925 | err = ip_route_output_flow(net, &rt, &fl, sk); | 925 | rt = ip_route_output_flow(net, &fl, sk); |
926 | if (err) { | 926 | if (IS_ERR(rt)) { |
927 | err = PTR_ERR(rt); | ||
927 | if (err == -ENETUNREACH) | 928 | if (err == -ENETUNREACH) |
928 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 929 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
929 | goto out; | 930 | goto out; |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 5f0f058dc376..45b821480427 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -26,18 +26,16 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, | |||
26 | .fl4_dst = daddr->a4, | 26 | .fl4_dst = daddr->a4, |
27 | .fl4_tos = tos, | 27 | .fl4_tos = tos, |
28 | }; | 28 | }; |
29 | struct dst_entry *dst; | ||
30 | struct rtable *rt; | 29 | struct rtable *rt; |
31 | int err; | ||
32 | 30 | ||
33 | if (saddr) | 31 | if (saddr) |
34 | fl.fl4_src = saddr->a4; | 32 | fl.fl4_src = saddr->a4; |
35 | 33 | ||
36 | err = __ip_route_output_key(net, &rt, &fl); | 34 | rt = __ip_route_output_key(net, &fl); |
37 | dst = &rt->dst; | 35 | if (!IS_ERR(rt)) |
38 | if (err) | 36 | return &rt->dst; |
39 | dst = ERR_PTR(err); | 37 | |
40 | return dst; | 38 | return ERR_CAST(rt); |
41 | } | 39 | } |
42 | 40 | ||
43 | static int xfrm4_get_saddr(struct net *net, | 41 | static int xfrm4_get_saddr(struct net *net, |