aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-12 01:12:47 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-12 18:08:48 -0500
commit9d6ec938019c6b16cb9ec96598ebe8f20de435fe (patch)
tree9b850eb7fd48a6e5ffc15f47afd2e3edc93f5290 /net
parent68a5e3dd0a0056d8b349f9eea3756adda53ec17a (diff)
ipv4: Use flowi4 in public route lookup interfaces.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/ipv4.c20
-rw-r--r--net/ipv4/icmp.c59
-rw-r--r--net/ipv4/inet_connection_sock.c26
-rw-r--r--net/ipv4/ip_output.c22
-rw-r--r--net/ipv4/netfilter.c26
-rw-r--r--net/ipv4/raw.c32
-rw-r--r--net/ipv4/route.c36
-rw-r--r--net/ipv4/syncookies.c24
-rw-r--r--net/ipv4/udp.c26
-rw-r--r--net/ipv4/xfrm4_policy.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c12
-rw-r--r--net/netfilter/xt_TEE.c14
-rw-r--r--net/sctp/protocol.c30
13 files changed, 172 insertions, 165 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index d934b2040230..be984706126b 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -465,18 +465,18 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
465 struct sk_buff *skb) 465 struct sk_buff *skb)
466{ 466{
467 struct rtable *rt; 467 struct rtable *rt;
468 struct flowi fl = { 468 struct flowi4 fl4 = {
469 .flowi_oif = skb_rtable(skb)->rt_iif, 469 .flowi4_oif = skb_rtable(skb)->rt_iif,
470 .fl4_dst = ip_hdr(skb)->saddr, 470 .daddr = ip_hdr(skb)->saddr,
471 .fl4_src = ip_hdr(skb)->daddr, 471 .saddr = ip_hdr(skb)->daddr,
472 .fl4_tos = RT_CONN_FLAGS(sk), 472 .flowi4_tos = RT_CONN_FLAGS(sk),
473 .flowi_proto = sk->sk_protocol, 473 .flowi4_proto = sk->sk_protocol,
474 .fl4_sport = dccp_hdr(skb)->dccph_dport, 474 .uli.ports.sport = dccp_hdr(skb)->dccph_dport,
475 .fl4_dport = dccp_hdr(skb)->dccph_sport, 475 .uli.ports.dport = dccp_hdr(skb)->dccph_sport,
476 }; 476 };
477 477
478 security_skb_classify_flow(skb, &fl); 478 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
479 rt = ip_route_output_flow(net, &fl, sk); 479 rt = ip_route_output_flow(net, &fl4, sk);
480 if (IS_ERR(rt)) { 480 if (IS_ERR(rt)) {
481 IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); 481 IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
482 return NULL; 482 return NULL;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 8d091954625b..8eca3c28cbc3 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -353,14 +353,14 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
353 daddr = icmp_param->replyopts.faddr; 353 daddr = icmp_param->replyopts.faddr;
354 } 354 }
355 { 355 {
356 struct flowi fl = { 356 struct flowi4 fl4 = {
357 .fl4_dst = daddr, 357 .daddr = daddr,
358 .fl4_src = rt->rt_spec_dst, 358 .saddr = rt->rt_spec_dst,
359 .fl4_tos = RT_TOS(ip_hdr(skb)->tos), 359 .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
360 .flowi_proto = IPPROTO_ICMP, 360 .flowi4_proto = IPPROTO_ICMP,
361 }; 361 };
362 security_skb_classify_flow(skb, &fl); 362 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
363 rt = ip_route_output_key(net, &fl); 363 rt = ip_route_output_key(net, &fl4);
364 if (IS_ERR(rt)) 364 if (IS_ERR(rt))
365 goto out_unlock; 365 goto out_unlock;
366 } 366 }
@@ -378,30 +378,31 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
378 int type, int code, 378 int type, int code,
379 struct icmp_bxm *param) 379 struct icmp_bxm *param)
380{ 380{
381 struct flowi fl = { 381 struct flowi4 fl4 = {
382 .fl4_dst = (param->replyopts.srr ? 382 .daddr = (param->replyopts.srr ?
383 param->replyopts.faddr : iph->saddr), 383 param->replyopts.faddr : iph->saddr),
384 .fl4_src = saddr, 384 .saddr = saddr,
385 .fl4_tos = RT_TOS(tos), 385 .flowi4_tos = RT_TOS(tos),
386 .flowi_proto = IPPROTO_ICMP, 386 .flowi4_proto = IPPROTO_ICMP,
387 .fl4_icmp_type = type, 387 .uli.icmpt.type = type,
388 .fl4_icmp_code = code, 388 .uli.icmpt.code = code,
389 }; 389 };
390 struct rtable *rt, *rt2; 390 struct rtable *rt, *rt2;
391 int err; 391 int err;
392 392
393 security_skb_classify_flow(skb_in, &fl); 393 security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4));
394 rt = __ip_route_output_key(net, &fl); 394 rt = __ip_route_output_key(net, &fl4);
395 if (IS_ERR(rt)) 395 if (IS_ERR(rt))
396 return rt; 396 return rt;
397 397
398 /* No need to clone since we're just using its address. */ 398 /* No need to clone since we're just using its address. */
399 rt2 = rt; 399 rt2 = rt;
400 400
401 if (!fl.fl4_src) 401 if (!fl4.saddr)
402 fl.fl4_src = rt->rt_src; 402 fl4.saddr = rt->rt_src;
403 403
404 rt = (struct rtable *) xfrm_lookup(net, &rt->dst, &fl, NULL, 0); 404 rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
405 flowi4_to_flowi(&fl4), NULL, 0);
405 if (!IS_ERR(rt)) { 406 if (!IS_ERR(rt)) {
406 if (rt != rt2) 407 if (rt != rt2)
407 return rt; 408 return rt;
@@ -410,27 +411,27 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
410 } else 411 } else
411 return rt; 412 return rt;
412 413
413 err = xfrm_decode_session_reverse(skb_in, &fl, AF_INET); 414 err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
414 if (err) 415 if (err)
415 goto relookup_failed; 416 goto relookup_failed;
416 417
417 if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { 418 if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) {
418 rt2 = __ip_route_output_key(net, &fl); 419 rt2 = __ip_route_output_key(net, &fl4);
419 if (IS_ERR(rt2)) 420 if (IS_ERR(rt2))
420 err = PTR_ERR(rt2); 421 err = PTR_ERR(rt2);
421 } else { 422 } else {
422 struct flowi fl2 = {}; 423 struct flowi4 fl4_2 = {};
423 unsigned long orefdst; 424 unsigned long orefdst;
424 425
425 fl2.fl4_dst = fl.fl4_src; 426 fl4_2.daddr = fl4.saddr;
426 rt2 = ip_route_output_key(net, &fl2); 427 rt2 = ip_route_output_key(net, &fl4_2);
427 if (IS_ERR(rt2)) { 428 if (IS_ERR(rt2)) {
428 err = PTR_ERR(rt2); 429 err = PTR_ERR(rt2);
429 goto relookup_failed; 430 goto relookup_failed;
430 } 431 }
431 /* Ugh! */ 432 /* Ugh! */
432 orefdst = skb_in->_skb_refdst; /* save old refdst */ 433 orefdst = skb_in->_skb_refdst; /* save old refdst */
433 err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, 434 err = ip_route_input(skb_in, fl4.daddr, fl4.saddr,
434 RT_TOS(tos), rt2->dst.dev); 435 RT_TOS(tos), rt2->dst.dev);
435 436
436 dst_release(&rt2->dst); 437 dst_release(&rt2->dst);
@@ -441,7 +442,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
441 if (err) 442 if (err)
442 goto relookup_failed; 443 goto relookup_failed;
443 444
444 rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, &fl, NULL, XFRM_LOOKUP_ICMP); 445 rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst,
446 flowi4_to_flowi(&fl4), NULL,
447 XFRM_LOOKUP_ICMP);
445 if (!IS_ERR(rt2)) { 448 if (!IS_ERR(rt2)) {
446 dst_release(&rt->dst); 449 dst_release(&rt->dst);
447 rt = rt2; 450 rt = rt2;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 10a8e9523578..beecc1272169 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -356,22 +356,22 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
356 struct rtable *rt; 356 struct rtable *rt;
357 const struct inet_request_sock *ireq = inet_rsk(req); 357 const struct inet_request_sock *ireq = inet_rsk(req);
358 struct ip_options *opt = inet_rsk(req)->opt; 358 struct ip_options *opt = inet_rsk(req)->opt;
359 struct flowi fl = { 359 struct flowi4 fl4 = {
360 .flowi_oif = sk->sk_bound_dev_if, 360 .flowi4_oif = sk->sk_bound_dev_if,
361 .flowi_mark = sk->sk_mark, 361 .flowi4_mark = sk->sk_mark,
362 .fl4_dst = ((opt && opt->srr) ? 362 .daddr = ((opt && opt->srr) ?
363 opt->faddr : ireq->rmt_addr), 363 opt->faddr : ireq->rmt_addr),
364 .fl4_src = ireq->loc_addr, 364 .saddr = ireq->loc_addr,
365 .fl4_tos = RT_CONN_FLAGS(sk), 365 .flowi4_tos = RT_CONN_FLAGS(sk),
366 .flowi_proto = sk->sk_protocol, 366 .flowi4_proto = sk->sk_protocol,
367 .flowi_flags = inet_sk_flowi_flags(sk), 367 .flowi4_flags = inet_sk_flowi_flags(sk),
368 .fl4_sport = inet_sk(sk)->inet_sport, 368 .uli.ports.sport = inet_sk(sk)->inet_sport,
369 .fl4_dport = ireq->rmt_port, 369 .uli.ports.dport = ireq->rmt_port,
370 }; 370 };
371 struct net *net = sock_net(sk); 371 struct net *net = sock_net(sk);
372 372
373 security_req_classify_flow(req, &fl); 373 security_req_classify_flow(req, flowi4_to_flowi(&fl4));
374 rt = ip_route_output_flow(net, &fl, sk); 374 rt = ip_route_output_flow(net, &fl4, sk);
375 if (IS_ERR(rt)) 375 if (IS_ERR(rt))
376 goto no_route; 376 goto no_route;
377 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) 377 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 67e5f7130322..2b9cc40397ee 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1474,18 +1474,18 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1474 } 1474 }
1475 1475
1476 { 1476 {
1477 struct flowi fl = { 1477 struct flowi4 fl4 = {
1478 .flowi_oif = arg->bound_dev_if, 1478 .flowi4_oif = arg->bound_dev_if,
1479 .fl4_dst = daddr, 1479 .daddr = daddr,
1480 .fl4_src = rt->rt_spec_dst, 1480 .saddr = rt->rt_spec_dst,
1481 .fl4_tos = RT_TOS(ip_hdr(skb)->tos), 1481 .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
1482 .fl4_sport = tcp_hdr(skb)->dest, 1482 .uli.ports.sport = tcp_hdr(skb)->dest,
1483 .fl4_dport = tcp_hdr(skb)->source, 1483 .uli.ports.dport = tcp_hdr(skb)->source,
1484 .flowi_proto = sk->sk_protocol, 1484 .flowi4_proto = sk->sk_protocol,
1485 .flowi_flags = ip_reply_arg_flowi_flags(arg), 1485 .flowi4_flags = ip_reply_arg_flowi_flags(arg),
1486 }; 1486 };
1487 security_skb_classify_flow(skb, &fl); 1487 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
1488 rt = ip_route_output_key(sock_net(sk), &fl); 1488 rt = ip_route_output_key(sock_net(sk), &fl4);
1489 if (IS_ERR(rt)) 1489 if (IS_ERR(rt))
1490 return; 1490 return;
1491 } 1491 }
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 6f40ba511c6b..f3c0b549b8e1 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -16,7 +16,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
16 struct net *net = dev_net(skb_dst(skb)->dev); 16 struct net *net = dev_net(skb_dst(skb)->dev);
17 const struct iphdr *iph = ip_hdr(skb); 17 const struct iphdr *iph = ip_hdr(skb);
18 struct rtable *rt; 18 struct rtable *rt;
19 struct flowi fl = {}; 19 struct flowi4 fl4 = {};
20 unsigned long orefdst; 20 unsigned long orefdst;
21 unsigned int hh_len; 21 unsigned int hh_len;
22 unsigned int type; 22 unsigned int type;
@@ -31,14 +31,14 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
31 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. 31 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
32 */ 32 */
33 if (addr_type == RTN_LOCAL) { 33 if (addr_type == RTN_LOCAL) {
34 fl.fl4_dst = iph->daddr; 34 fl4.daddr = iph->daddr;
35 if (type == RTN_LOCAL) 35 if (type == RTN_LOCAL)
36 fl.fl4_src = iph->saddr; 36 fl4.saddr = iph->saddr;
37 fl.fl4_tos = RT_TOS(iph->tos); 37 fl4.flowi4_tos = RT_TOS(iph->tos);
38 fl.flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 38 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
39 fl.flowi_mark = skb->mark; 39 fl4.flowi4_mark = skb->mark;
40 fl.flowi_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; 40 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
41 rt = ip_route_output_key(net, &fl); 41 rt = ip_route_output_key(net, &fl4);
42 if (IS_ERR(rt)) 42 if (IS_ERR(rt))
43 return -1; 43 return -1;
44 44
@@ -48,8 +48,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
48 } else { 48 } else {
49 /* non-local src, find valid iif to satisfy 49 /* non-local src, find valid iif to satisfy
50 * rp-filter when calling ip_route_input. */ 50 * rp-filter when calling ip_route_input. */
51 fl.fl4_dst = iph->saddr; 51 fl4.daddr = iph->saddr;
52 rt = ip_route_output_key(net, &fl); 52 rt = ip_route_output_key(net, &fl4);
53 if (IS_ERR(rt)) 53 if (IS_ERR(rt))
54 return -1; 54 return -1;
55 55
@@ -68,10 +68,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
68 68
69#ifdef CONFIG_XFRM 69#ifdef CONFIG_XFRM
70 if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && 70 if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
71 xfrm_decode_session(skb, &fl, AF_INET) == 0) { 71 xfrm_decode_session(skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
72 struct dst_entry *dst = skb_dst(skb); 72 struct dst_entry *dst = skb_dst(skb);
73 skb_dst_set(skb, NULL); 73 skb_dst_set(skb, NULL);
74 dst = xfrm_lookup(net, dst, &fl, skb->sk, 0); 74 dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), skb->sk, 0);
75 if (IS_ERR(dst)) 75 if (IS_ERR(dst))
76 return -1; 76 return -1;
77 skb_dst_set(skb, dst); 77 skb_dst_set(skb, dst);
@@ -223,7 +223,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
223 223
224static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) 224static int nf_ip_route(struct dst_entry **dst, struct flowi *fl)
225{ 225{
226 struct rtable *rt = ip_route_output_key(&init_net, fl); 226 struct rtable *rt = ip_route_output_key(&init_net, &fl->u.ip4);
227 if (IS_ERR(rt)) 227 if (IS_ERR(rt))
228 return PTR_ERR(rt); 228 return PTR_ERR(rt);
229 *dst = &rt->dst; 229 *dst = &rt->dst;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 333b826c1871..452e178d962d 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -402,7 +402,7 @@ error:
402 return err; 402 return err;
403} 403}
404 404
405static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 405static int raw_probe_proto_opt(struct flowi4 *fl4, struct msghdr *msg)
406{ 406{
407 struct iovec *iov; 407 struct iovec *iov;
408 u8 __user *type = NULL; 408 u8 __user *type = NULL;
@@ -418,7 +418,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
418 if (!iov) 418 if (!iov)
419 continue; 419 continue;
420 420
421 switch (fl->flowi_proto) { 421 switch (fl4->flowi4_proto) {
422 case IPPROTO_ICMP: 422 case IPPROTO_ICMP:
423 /* check if one-byte field is readable or not. */ 423 /* check if one-byte field is readable or not. */
424 if (iov->iov_base && iov->iov_len < 1) 424 if (iov->iov_base && iov->iov_len < 1)
@@ -433,8 +433,8 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
433 code = iov->iov_base; 433 code = iov->iov_base;
434 434
435 if (type && code) { 435 if (type && code) {
436 if (get_user(fl->fl4_icmp_type, type) || 436 if (get_user(fl4->uli.icmpt.type, type) ||
437 get_user(fl->fl4_icmp_code, code)) 437 get_user(fl4->uli.icmpt.code, code))
438 return -EFAULT; 438 return -EFAULT;
439 probed = 1; 439 probed = 1;
440 } 440 }
@@ -548,23 +548,25 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
548 } 548 }
549 549
550 { 550 {
551 struct flowi fl = { .flowi_oif = ipc.oif, 551 struct flowi4 fl4 = {
552 .flowi_mark = sk->sk_mark, 552 .flowi4_oif = ipc.oif,
553 .fl4_dst = daddr, 553 .flowi4_mark = sk->sk_mark,
554 .fl4_src = saddr, 554 .daddr = daddr,
555 .fl4_tos = tos, 555 .saddr = saddr,
556 .flowi_proto = inet->hdrincl ? IPPROTO_RAW : 556 .flowi4_tos = tos,
557 sk->sk_protocol, 557 .flowi4_proto = (inet->hdrincl ?
558 .flowi_flags = FLOWI_FLAG_CAN_SLEEP, 558 IPPROTO_RAW :
559 sk->sk_protocol),
560 .flowi4_flags = FLOWI_FLAG_CAN_SLEEP,
559 }; 561 };
560 if (!inet->hdrincl) { 562 if (!inet->hdrincl) {
561 err = raw_probe_proto_opt(&fl, msg); 563 err = raw_probe_proto_opt(&fl4, msg);
562 if (err) 564 if (err)
563 goto done; 565 goto done;
564 } 566 }
565 567
566 security_sk_classify_flow(sk, &fl); 568 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
567 rt = ip_route_output_flow(sock_net(sk), &fl, sk); 569 rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
568 if (IS_ERR(rt)) { 570 if (IS_ERR(rt)) {
569 err = PTR_ERR(rt); 571 err = PTR_ERR(rt);
570 goto done; 572 goto done;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 9e938f95cea8..5655095a89e0 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2626,7 +2626,7 @@ out:
2626 return rth; 2626 return rth;
2627} 2627}
2628 2628
2629struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) 2629struct rtable *__ip_route_output_key(struct net *net, const struct flowi4 *flp4)
2630{ 2630{
2631 struct rtable *rth; 2631 struct rtable *rth;
2632 unsigned int hash; 2632 unsigned int hash;
@@ -2634,17 +2634,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
2634 if (!rt_caching(net)) 2634 if (!rt_caching(net))
2635 goto slow_output; 2635 goto slow_output;
2636 2636
2637 hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->flowi_oif, rt_genid(net)); 2637 hash = rt_hash(flp4->daddr, flp4->saddr, flp4->flowi4_oif, rt_genid(net));
2638 2638
2639 rcu_read_lock_bh(); 2639 rcu_read_lock_bh();
2640 for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth; 2640 for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth;
2641 rth = rcu_dereference_bh(rth->dst.rt_next)) { 2641 rth = rcu_dereference_bh(rth->dst.rt_next)) {
2642 if (rth->rt_key_dst == flp->fl4_dst && 2642 if (rth->rt_key_dst == flp4->daddr &&
2643 rth->rt_key_src == flp->fl4_src && 2643 rth->rt_key_src == flp4->saddr &&
2644 rt_is_output_route(rth) && 2644 rt_is_output_route(rth) &&
2645 rth->rt_oif == flp->flowi_oif && 2645 rth->rt_oif == flp4->flowi4_oif &&
2646 rth->rt_mark == flp->flowi_mark && 2646 rth->rt_mark == flp4->flowi4_mark &&
2647 !((rth->rt_tos ^ flp->fl4_tos) & 2647 !((rth->rt_tos ^ flp4->flowi4_tos) &
2648 (IPTOS_RT_MASK | RTO_ONLINK)) && 2648 (IPTOS_RT_MASK | RTO_ONLINK)) &&
2649 net_eq(dev_net(rth->dst.dev), net) && 2649 net_eq(dev_net(rth->dst.dev), net) &&
2650 !rt_is_expired(rth)) { 2650 !rt_is_expired(rth)) {
@@ -2658,7 +2658,7 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
2658 rcu_read_unlock_bh(); 2658 rcu_read_unlock_bh();
2659 2659
2660slow_output: 2660slow_output:
2661 return ip_route_output_slow(net, &flp->u.ip4); 2661 return ip_route_output_slow(net, flp4);
2662} 2662}
2663EXPORT_SYMBOL_GPL(__ip_route_output_key); 2663EXPORT_SYMBOL_GPL(__ip_route_output_key);
2664 2664
@@ -2733,20 +2733,22 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
2733 return rt ? &rt->dst : ERR_PTR(-ENOMEM); 2733 return rt ? &rt->dst : ERR_PTR(-ENOMEM);
2734} 2734}
2735 2735
2736struct rtable *ip_route_output_flow(struct net *net, struct flowi *flp, 2736struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
2737 struct sock *sk) 2737 struct sock *sk)
2738{ 2738{
2739 struct rtable *rt = __ip_route_output_key(net, flp); 2739 struct rtable *rt = __ip_route_output_key(net, flp4);
2740 2740
2741 if (IS_ERR(rt)) 2741 if (IS_ERR(rt))
2742 return rt; 2742 return rt;
2743 2743
2744 if (flp->flowi_proto) { 2744 if (flp4->flowi4_proto) {
2745 if (!flp->fl4_src) 2745 if (!flp4->saddr)
2746 flp->fl4_src = rt->rt_src; 2746 flp4->saddr = rt->rt_src;
2747 if (!flp->fl4_dst) 2747 if (!flp4->daddr)
2748 flp->fl4_dst = rt->rt_dst; 2748 flp4->daddr = rt->rt_dst;
2749 rt = (struct rtable *) xfrm_lookup(net, &rt->dst, flp, sk, 0); 2749 rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
2750 flowi4_to_flowi(flp4),
2751 sk, 0);
2750 } 2752 }
2751 2753
2752 return rt; 2754 return rt;
@@ -2920,7 +2922,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2920 .flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, 2922 .flowi4_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
2921 .flowi4_mark = mark, 2923 .flowi4_mark = mark,
2922 }; 2924 };
2923 rt = ip_route_output_key(net, flowi4_to_flowi(&fl4)); 2925 rt = ip_route_output_key(net, &fl4);
2924 2926
2925 err = 0; 2927 err = 0;
2926 if (IS_ERR(rt)) 2928 if (IS_ERR(rt))
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index d90529d45ee6..e3b5b754311c 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -345,19 +345,19 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
345 * no easy way to do this. 345 * no easy way to do this.
346 */ 346 */
347 { 347 {
348 struct flowi fl = { 348 struct flowi4 fl4 = {
349 .flowi_mark = sk->sk_mark, 349 .flowi4_mark = sk->sk_mark,
350 .fl4_dst = ((opt && opt->srr) ? 350 .daddr = ((opt && opt->srr) ?
351 opt->faddr : ireq->rmt_addr), 351 opt->faddr : ireq->rmt_addr),
352 .fl4_src = ireq->loc_addr, 352 .saddr = ireq->loc_addr,
353 .fl4_tos = RT_CONN_FLAGS(sk), 353 .flowi4_tos = RT_CONN_FLAGS(sk),
354 .flowi_proto = IPPROTO_TCP, 354 .flowi4_proto = IPPROTO_TCP,
355 .flowi_flags = inet_sk_flowi_flags(sk), 355 .flowi4_flags = inet_sk_flowi_flags(sk),
356 .fl4_sport = th->dest, 356 .uli.ports.sport = th->dest,
357 .fl4_dport = th->source, 357 .uli.ports.dport = th->source,
358 }; 358 };
359 security_req_classify_flow(req, &fl); 359 security_req_classify_flow(req, flowi4_to_flowi(&fl4));
360 rt = ip_route_output_key(sock_net(sk), &fl); 360 rt = ip_route_output_key(sock_net(sk), &fl4);
361 if (IS_ERR(rt)) { 361 if (IS_ERR(rt)) {
362 reqsk_free(req); 362 reqsk_free(req);
363 goto out; 363 goto out;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 116e4a8bfb73..25c080798bd0 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -908,22 +908,22 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
908 rt = (struct rtable *)sk_dst_check(sk, 0); 908 rt = (struct rtable *)sk_dst_check(sk, 0);
909 909
910 if (rt == NULL) { 910 if (rt == NULL) {
911 struct flowi fl = { 911 struct flowi4 fl4 = {
912 .flowi_oif = ipc.oif, 912 .flowi4_oif = ipc.oif,
913 .flowi_mark = sk->sk_mark, 913 .flowi4_mark = sk->sk_mark,
914 .fl4_dst = faddr, 914 .daddr = faddr,
915 .fl4_src = saddr, 915 .saddr = saddr,
916 .fl4_tos = tos, 916 .flowi4_tos = tos,
917 .flowi_proto = sk->sk_protocol, 917 .flowi4_proto = sk->sk_protocol,
918 .flowi_flags = (inet_sk_flowi_flags(sk) | 918 .flowi4_flags = (inet_sk_flowi_flags(sk) |
919 FLOWI_FLAG_CAN_SLEEP), 919 FLOWI_FLAG_CAN_SLEEP),
920 .fl4_sport = inet->inet_sport, 920 .uli.ports.sport = inet->inet_sport,
921 .fl4_dport = dport, 921 .uli.ports.dport = dport,
922 }; 922 };
923 struct net *net = sock_net(sk); 923 struct net *net = sock_net(sk);
924 924
925 security_sk_classify_flow(sk, &fl); 925 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
926 rt = ip_route_output_flow(net, &fl, sk); 926 rt = ip_route_output_flow(net, &fl4, sk);
927 if (IS_ERR(rt)) { 927 if (IS_ERR(rt)) {
928 err = PTR_ERR(rt); 928 err = PTR_ERR(rt);
929 rt = NULL; 929 rt = NULL;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index b7b0921b425d..b111f468fa29 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -22,16 +22,16 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
22 const xfrm_address_t *saddr, 22 const xfrm_address_t *saddr,
23 const xfrm_address_t *daddr) 23 const xfrm_address_t *daddr)
24{ 24{
25 struct flowi fl = { 25 struct flowi4 fl4 = {
26 .fl4_dst = daddr->a4, 26 .daddr = daddr->a4,
27 .fl4_tos = tos, 27 .flowi4_tos = tos,
28 }; 28 };
29 struct rtable *rt; 29 struct rtable *rt;
30 30
31 if (saddr) 31 if (saddr)
32 fl.fl4_src = saddr->a4; 32 fl4.saddr = saddr->a4;
33 33
34 rt = __ip_route_output_key(net, &fl); 34 rt = __ip_route_output_key(net, &fl4);
35 if (!IS_ERR(rt)) 35 if (!IS_ERR(rt))
36 return &rt->dst; 36 return &rt->dst;
37 37
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index cc8071f68903..7dc00e313611 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -165,14 +165,14 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
165 return 0; 165 return 0;
166 refdst_drop(orefdst); 166 refdst_drop(orefdst);
167 } else { 167 } else {
168 struct flowi fl = { 168 struct flowi4 fl4 = {
169 .fl4_dst = iph->daddr, 169 .daddr = iph->daddr,
170 .fl4_src = iph->saddr, 170 .saddr = iph->saddr,
171 .fl4_tos = RT_TOS(iph->tos), 171 .flowi4_tos = RT_TOS(iph->tos),
172 .flowi_mark = skb->mark, 172 .flowi4_mark = skb->mark,
173 }; 173 };
174 174
175 rt = ip_route_output_key(net, &fl); 175 rt = ip_route_output_key(net, &fl4);
176 if (IS_ERR(rt)) 176 if (IS_ERR(rt))
177 return 0; 177 return 0;
178 if (!(rt->rt_flags & RTCF_LOCAL)) { 178 if (!(rt->rt_flags & RTCF_LOCAL)) {
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index cb14ae2de15d..d8c00f9342ae 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -62,18 +62,18 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
62 const struct iphdr *iph = ip_hdr(skb); 62 const struct iphdr *iph = ip_hdr(skb);
63 struct net *net = pick_net(skb); 63 struct net *net = pick_net(skb);
64 struct rtable *rt; 64 struct rtable *rt;
65 struct flowi fl; 65 struct flowi4 fl4;
66 66
67 memset(&fl, 0, sizeof(fl)); 67 memset(&fl4, 0, sizeof(fl4));
68 if (info->priv) { 68 if (info->priv) {
69 if (info->priv->oif == -1) 69 if (info->priv->oif == -1)
70 return false; 70 return false;
71 fl.flowi_oif = info->priv->oif; 71 fl4.flowi4_oif = info->priv->oif;
72 } 72 }
73 fl.fl4_dst = info->gw.ip; 73 fl4.daddr = info->gw.ip;
74 fl.fl4_tos = RT_TOS(iph->tos); 74 fl4.flowi4_tos = RT_TOS(iph->tos);
75 fl.fl4_scope = RT_SCOPE_UNIVERSE; 75 fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
76 rt = ip_route_output_key(net, &fl); 76 rt = ip_route_output_key(net, &fl4);
77 if (IS_ERR(rt)) 77 if (IS_ERR(rt))
78 return false; 78 return false;
79 79
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b6fa2940e30b..31c04568b23c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -468,30 +468,30 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
468 union sctp_addr *saddr) 468 union sctp_addr *saddr)
469{ 469{
470 struct rtable *rt; 470 struct rtable *rt;
471 struct flowi fl; 471 struct flowi4 fl4;
472 struct sctp_bind_addr *bp; 472 struct sctp_bind_addr *bp;
473 struct sctp_sockaddr_entry *laddr; 473 struct sctp_sockaddr_entry *laddr;
474 struct dst_entry *dst = NULL; 474 struct dst_entry *dst = NULL;
475 union sctp_addr dst_saddr; 475 union sctp_addr dst_saddr;
476 476
477 memset(&fl, 0x0, sizeof(struct flowi)); 477 memset(&fl4, 0x0, sizeof(struct flowi4));
478 fl.fl4_dst = daddr->v4.sin_addr.s_addr; 478 fl4.daddr = daddr->v4.sin_addr.s_addr;
479 fl.fl4_dport = daddr->v4.sin_port; 479 fl4.uli.ports.dport = daddr->v4.sin_port;
480 fl.flowi_proto = IPPROTO_SCTP; 480 fl4.flowi4_proto = IPPROTO_SCTP;
481 if (asoc) { 481 if (asoc) {
482 fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); 482 fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
483 fl.flowi_oif = asoc->base.sk->sk_bound_dev_if; 483 fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if;
484 fl.fl4_sport = htons(asoc->base.bind_addr.port); 484 fl4.uli.ports.sport = htons(asoc->base.bind_addr.port);
485 } 485 }
486 if (saddr) { 486 if (saddr) {
487 fl.fl4_src = saddr->v4.sin_addr.s_addr; 487 fl4.saddr = saddr->v4.sin_addr.s_addr;
488 fl.fl4_sport = saddr->v4.sin_port; 488 fl4.uli.ports.sport = saddr->v4.sin_port;
489 } 489 }
490 490
491 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", 491 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
492 __func__, &fl.fl4_dst, &fl.fl4_src); 492 __func__, &fl4.daddr, &fl4.saddr);
493 493
494 rt = ip_route_output_key(&init_net, &fl); 494 rt = ip_route_output_key(&init_net, &fl4);
495 if (!IS_ERR(rt)) 495 if (!IS_ERR(rt))
496 dst = &rt->dst; 496 dst = &rt->dst;
497 497
@@ -533,9 +533,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
533 continue; 533 continue;
534 if ((laddr->state == SCTP_ADDR_SRC) && 534 if ((laddr->state == SCTP_ADDR_SRC) &&
535 (AF_INET == laddr->a.sa.sa_family)) { 535 (AF_INET == laddr->a.sa.sa_family)) {
536 fl.fl4_src = laddr->a.v4.sin_addr.s_addr; 536 fl4.saddr = laddr->a.v4.sin_addr.s_addr;
537 fl.fl4_sport = laddr->a.v4.sin_port; 537 fl4.uli.ports.sport = laddr->a.v4.sin_port;
538 rt = ip_route_output_key(&init_net, &fl); 538 rt = ip_route_output_key(&init_net, &fl4);
539 if (!IS_ERR(rt)) { 539 if (!IS_ERR(rt)) {
540 dst = &rt->dst; 540 dst = &rt->dst;
541 goto out_unlock; 541 goto out_unlock;