aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c20
-rw-r--r--net/ipv4/arp.c12
-rw-r--r--net/ipv4/igmp.c34
-rw-r--r--net/ipv4/ip_gre.c49
-rw-r--r--net/ipv4/ip_output.c33
-rw-r--r--net/ipv4/ipip.c36
-rw-r--r--net/ipv4/ipmr.c24
7 files changed, 75 insertions, 133 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 35a502055018..807d83c02ef6 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1157,22 +1157,10 @@ int inet_sk_rebuild_header(struct sock *sk)
1157 daddr = inet->inet_daddr; 1157 daddr = inet->inet_daddr;
1158 if (inet->opt && inet->opt->srr) 1158 if (inet->opt && inet->opt->srr)
1159 daddr = inet->opt->faddr; 1159 daddr = inet->opt->faddr;
1160 { 1160 rt = ip_route_output_ports(sock_net(sk), sk, daddr, inet->inet_saddr,
1161 struct flowi fl = { 1161 inet->inet_dport, inet->inet_sport,
1162 .oif = sk->sk_bound_dev_if, 1162 sk->sk_protocol, RT_CONN_FLAGS(sk),
1163 .mark = sk->sk_mark, 1163 sk->sk_bound_dev_if);
1164 .fl4_dst = daddr,
1165 .fl4_src = inet->inet_saddr,
1166 .fl4_tos = RT_CONN_FLAGS(sk),
1167 .proto = sk->sk_protocol,
1168 .flags = inet_sk_flowi_flags(sk),
1169 .fl_ip_sport = inet->inet_sport,
1170 .fl_ip_dport = inet->inet_dport,
1171 };
1172
1173 security_sk_classify_flow(sk, &fl);
1174 rt = ip_route_output_flow(sock_net(sk), &fl, sk);
1175 }
1176 if (!IS_ERR(rt)) { 1164 if (!IS_ERR(rt)) {
1177 err = 0; 1165 err = 0;
1178 sk_setup_caps(sk, &rt->dst); 1166 sk_setup_caps(sk, &rt->dst);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index fa9988da1da4..090d273d7865 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -433,14 +433,12 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
433 433
434static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) 434static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
435{ 435{
436 struct flowi fl = { .fl4_dst = sip,
437 .fl4_src = tip };
438 struct rtable *rt; 436 struct rtable *rt;
439 int flag = 0; 437 int flag = 0;
440 /*unsigned long now; */ 438 /*unsigned long now; */
441 struct net *net = dev_net(dev); 439 struct net *net = dev_net(dev);
442 440
443 rt = ip_route_output_key(net, &fl); 441 rt = ip_route_output(net, sip, tip, 0, 0);
444 if (IS_ERR(rt)) 442 if (IS_ERR(rt))
445 return 1; 443 return 1;
446 if (rt->dst.dev != dev) { 444 if (rt->dst.dev != dev) {
@@ -1062,9 +1060,7 @@ static int arp_req_set(struct net *net, struct arpreq *r,
1062 if (r->arp_flags & ATF_PERM) 1060 if (r->arp_flags & ATF_PERM)
1063 r->arp_flags |= ATF_COM; 1061 r->arp_flags |= ATF_COM;
1064 if (dev == NULL) { 1062 if (dev == NULL) {
1065 struct flowi fl = { .fl4_dst = ip, 1063 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
1066 .fl4_tos = RTO_ONLINK };
1067 struct rtable *rt = ip_route_output_key(net, &fl);
1068 1064
1069 if (IS_ERR(rt)) 1065 if (IS_ERR(rt))
1070 return PTR_ERR(rt); 1066 return PTR_ERR(rt);
@@ -1185,9 +1181,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
1185 1181
1186 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; 1182 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1187 if (dev == NULL) { 1183 if (dev == NULL) {
1188 struct flowi fl = { .fl4_dst = ip, 1184 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
1189 .fl4_tos = RTO_ONLINK };
1190 struct rtable *rt = ip_route_output_key(net, &fl);
1191 if (IS_ERR(rt)) 1185 if (IS_ERR(rt))
1192 return PTR_ERR(rt); 1186 return PTR_ERR(rt);
1193 dev = rt->dst.dev; 1187 dev = rt->dst.dev;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 12b65ccca8e9..1fd3d9ce8398 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -321,15 +321,12 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
321 } 321 }
322 igmp_skb_size(skb) = size; 322 igmp_skb_size(skb) = size;
323 323
324 { 324 rt = ip_route_output_ports(net, NULL, IGMPV3_ALL_MCR, 0,
325 struct flowi fl = { .oif = dev->ifindex, 325 0, 0,
326 .fl4_dst = IGMPV3_ALL_MCR, 326 IPPROTO_IGMP, 0, dev->ifindex);
327 .proto = IPPROTO_IGMP }; 327 if (IS_ERR(rt)) {
328 rt = ip_route_output_key(net, &fl); 328 kfree_skb(skb);
329 if (IS_ERR(rt)) { 329 return NULL;
330 kfree_skb(skb);
331 return NULL;
332 }
333 } 330 }
334 if (rt->rt_src == 0) { 331 if (rt->rt_src == 0) {
335 kfree_skb(skb); 332 kfree_skb(skb);
@@ -667,14 +664,12 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
667 else 664 else
668 dst = group; 665 dst = group;
669 666
670 { 667 rt = ip_route_output_ports(net, NULL, dst, 0,
671 struct flowi fl = { .oif = dev->ifindex, 668 0, 0,
672 .fl4_dst = dst, 669 IPPROTO_IGMP, 0, dev->ifindex);
673 .proto = IPPROTO_IGMP }; 670 if (IS_ERR(rt))
674 rt = ip_route_output_key(net, &fl); 671 return -1;
675 if (IS_ERR(rt)) 672
676 return -1;
677 }
678 if (rt->rt_src == 0) { 673 if (rt->rt_src == 0) {
679 ip_rt_put(rt); 674 ip_rt_put(rt);
680 return -1; 675 return -1;
@@ -1441,7 +1436,6 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
1441/* RTNL is locked */ 1436/* RTNL is locked */
1442static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) 1437static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
1443{ 1438{
1444 struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr };
1445 struct net_device *dev = NULL; 1439 struct net_device *dev = NULL;
1446 struct in_device *idev = NULL; 1440 struct in_device *idev = NULL;
1447 1441
@@ -1456,7 +1450,9 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
1456 } 1450 }
1457 1451
1458 if (!dev) { 1452 if (!dev) {
1459 struct rtable *rt = ip_route_output_key(net, &fl); 1453 struct rtable *rt = ip_route_output(net,
1454 imr->imr_multiaddr.s_addr,
1455 0, 0, 0);
1460 if (!IS_ERR(rt)) { 1456 if (!IS_ERR(rt)) {
1461 dev = rt->dst.dev; 1457 dev = rt->dst.dev;
1462 ip_rt_put(rt); 1458 ip_rt_put(rt);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 71465955520b..da5941f18c3c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -769,20 +769,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
769 tos = ipv6_get_dsfield((struct ipv6hdr *)old_iph); 769 tos = ipv6_get_dsfield((struct ipv6hdr *)old_iph);
770 } 770 }
771 771
772 { 772 rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr,
773 struct flowi fl = { 773 tunnel->parms.o_key, RT_TOS(tos),
774 .oif = tunnel->parms.link, 774 tunnel->parms.link);
775 .fl4_dst = dst, 775 if (IS_ERR(rt)) {
776 .fl4_src = tiph->saddr, 776 dev->stats.tx_carrier_errors++;
777 .fl4_tos = RT_TOS(tos), 777 goto tx_error;
778 .proto = IPPROTO_GRE,
779 .fl_gre_key = tunnel->parms.o_key
780 };
781 rt = ip_route_output_key(dev_net(dev), &fl);
782 if (IS_ERR(rt)) {
783 dev->stats.tx_carrier_errors++;
784 goto tx_error;
785 }
786 } 778 }
787 tdev = rt->dst.dev; 779 tdev = rt->dst.dev;
788 780
@@ -946,15 +938,11 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
946 /* Guess output device to choose reasonable mtu and needed_headroom */ 938 /* Guess output device to choose reasonable mtu and needed_headroom */
947 939
948 if (iph->daddr) { 940 if (iph->daddr) {
949 struct flowi fl = { 941 struct rtable *rt = ip_route_output_gre(dev_net(dev),
950 .oif = tunnel->parms.link, 942 iph->daddr, iph->saddr,
951 .fl4_dst = iph->daddr, 943 tunnel->parms.o_key,
952 .fl4_src = iph->saddr, 944 RT_TOS(iph->tos),
953 .fl4_tos = RT_TOS(iph->tos), 945 tunnel->parms.link);
954 .proto = IPPROTO_GRE,
955 .fl_gre_key = tunnel->parms.o_key
956 };
957 struct rtable *rt = ip_route_output_key(dev_net(dev), &fl);
958 946
959 if (!IS_ERR(rt)) { 947 if (!IS_ERR(rt)) {
960 tdev = rt->dst.dev; 948 tdev = rt->dst.dev;
@@ -1208,15 +1196,12 @@ static int ipgre_open(struct net_device *dev)
1208 struct ip_tunnel *t = netdev_priv(dev); 1196 struct ip_tunnel *t = netdev_priv(dev);
1209 1197
1210 if (ipv4_is_multicast(t->parms.iph.daddr)) { 1198 if (ipv4_is_multicast(t->parms.iph.daddr)) {
1211 struct flowi fl = { 1199 struct rtable *rt = ip_route_output_gre(dev_net(dev),
1212 .oif = t->parms.link, 1200 t->parms.iph.daddr,
1213 .fl4_dst = t->parms.iph.daddr, 1201 t->parms.iph.saddr,
1214 .fl4_src = t->parms.iph.saddr, 1202 t->parms.o_key,
1215 .fl4_tos = RT_TOS(t->parms.iph.tos), 1203 RT_TOS(t->parms.iph.tos),
1216 .proto = IPPROTO_GRE, 1204 t->parms.link);
1217 .fl_gre_key = t->parms.o_key
1218 };
1219 struct rtable *rt = ip_route_output_key(dev_net(dev), &fl);
1220 1205
1221 if (IS_ERR(rt)) 1206 if (IS_ERR(rt))
1222 return -EADDRNOTAVAIL; 1207 return -EADDRNOTAVAIL;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 171f483b21d5..916152dbdce4 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -339,26 +339,19 @@ int ip_queue_xmit(struct sk_buff *skb)
339 if(opt && opt->srr) 339 if(opt && opt->srr)
340 daddr = opt->faddr; 340 daddr = opt->faddr;
341 341
342 { 342 /* If this fails, retransmit mechanism of transport layer will
343 struct flowi fl = { .oif = sk->sk_bound_dev_if, 343 * keep trying until route appears or the connection times
344 .mark = sk->sk_mark, 344 * itself out.
345 .fl4_dst = daddr, 345 */
346 .fl4_src = inet->inet_saddr, 346 rt = ip_route_output_ports(sock_net(sk), sk,
347 .fl4_tos = RT_CONN_FLAGS(sk), 347 daddr, inet->inet_saddr,
348 .proto = sk->sk_protocol, 348 inet->inet_dport,
349 .flags = inet_sk_flowi_flags(sk), 349 inet->inet_sport,
350 .fl_ip_sport = inet->inet_sport, 350 sk->sk_protocol,
351 .fl_ip_dport = inet->inet_dport }; 351 RT_CONN_FLAGS(sk),
352 352 sk->sk_bound_dev_if);
353 /* If this fails, retransmit mechanism of transport layer will 353 if (IS_ERR(rt))
354 * keep trying until route appears or the connection times 354 goto no_route;
355 * itself out.
356 */
357 security_sk_classify_flow(sk, &fl);
358 rt = ip_route_output_flow(sock_net(sk), &fl, sk);
359 if (IS_ERR(rt))
360 goto no_route;
361 }
362 sk_setup_caps(sk, &rt->dst); 355 sk_setup_caps(sk, &rt->dst);
363 } 356 }
364 skb_dst_set_noref(skb, &rt->dst); 357 skb_dst_set_noref(skb, &rt->dst);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 65008f45addc..bfc17c5914e7 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -460,20 +460,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
460 goto tx_error_icmp; 460 goto tx_error_icmp;
461 } 461 }
462 462
463 { 463 rt = ip_route_output_ports(dev_net(dev), NULL,
464 struct flowi fl = { 464 dst, tiph->saddr,
465 .oif = tunnel->parms.link, 465 0, 0,
466 .fl4_dst = dst, 466 IPPROTO_IPIP, RT_TOS(tos),
467 .fl4_src= tiph->saddr, 467 tunnel->parms.link);
468 .fl4_tos = RT_TOS(tos), 468 if (IS_ERR(rt)) {
469 .proto = IPPROTO_IPIP 469 dev->stats.tx_carrier_errors++;
470 }; 470 goto tx_error_icmp;
471
472 rt = ip_route_output_key(dev_net(dev), &fl);
473 if (IS_ERR(rt)) {
474 dev->stats.tx_carrier_errors++;
475 goto tx_error_icmp;
476 }
477 } 471 }
478 tdev = rt->dst.dev; 472 tdev = rt->dst.dev;
479 473
@@ -584,14 +578,12 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
584 iph = &tunnel->parms.iph; 578 iph = &tunnel->parms.iph;
585 579
586 if (iph->daddr) { 580 if (iph->daddr) {
587 struct flowi fl = { 581 struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL,
588 .oif = tunnel->parms.link, 582 iph->daddr, iph->saddr,
589 .fl4_dst = iph->daddr, 583 0, 0,
590 .fl4_src = iph->saddr, 584 IPPROTO_IPIP,
591 .fl4_tos = RT_TOS(iph->tos), 585 RT_TOS(iph->tos),
592 .proto = IPPROTO_IPIP 586 tunnel->parms.link);
593 };
594 struct rtable *rt = ip_route_output_key(dev_net(dev), &fl);
595 587
596 if (!IS_ERR(rt)) { 588 if (!IS_ERR(rt)) {
597 tdev = rt->dst.dev; 589 tdev = rt->dst.dev;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 74909bac8817..594a3004367b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1611,25 +1611,19 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
1611#endif 1611#endif
1612 1612
1613 if (vif->flags & VIFF_TUNNEL) { 1613 if (vif->flags & VIFF_TUNNEL) {
1614 struct flowi fl = { 1614 rt = ip_route_output_ports(net, NULL,
1615 .oif = vif->link, 1615 vif->remote, vif->local,
1616 .fl4_dst = vif->remote, 1616 0, 0,
1617 .fl4_src = vif->local, 1617 IPPROTO_IPIP,
1618 .fl4_tos = RT_TOS(iph->tos), 1618 RT_TOS(iph->tos), vif->link);
1619 .proto = IPPROTO_IPIP
1620 };
1621 rt = ip_route_output_key(net, &fl);
1622 if (IS_ERR(rt)) 1619 if (IS_ERR(rt))
1623 goto out_free; 1620 goto out_free;
1624 encap = sizeof(struct iphdr); 1621 encap = sizeof(struct iphdr);
1625 } else { 1622 } else {
1626 struct flowi fl = { 1623 rt = ip_route_output_ports(net, NULL, iph->daddr, 0,
1627 .oif = vif->link, 1624 0, 0,
1628 .fl4_dst = iph->daddr, 1625 IPPROTO_IPIP,
1629 .fl4_tos = RT_TOS(iph->tos), 1626 RT_TOS(iph->tos), vif->link);
1630 .proto = IPPROTO_IPIP
1631 };
1632 rt = ip_route_output_key(net, &fl);
1633 if (IS_ERR(rt)) 1627 if (IS_ERR(rt))
1634 goto out_free; 1628 goto out_free;
1635 } 1629 }