aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-12 00:00:52 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-12 18:08:42 -0500
commit78fbfd8a653ca972afe479517a40661bfff6d8c3 (patch)
tree9dccc5c16bf269d53d8499064ec95a998e84c646 /net/ipv4
parent1561747ddf9d28185548687b11aae7074d6129c4 (diff)
ipv4: Create and use route lookup helpers.
The idea here is this minimizes the number of places one has to edit in order to make changes to how flows are defined and used. Signed-off-by: David S. Miller <davem@davemloft.net>
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 }