aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-08 20:12:19 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-09 00:24:06 -0400
commit77968b78242ee25e2a4d759f0fca8dd52df6d479 (patch)
tree6de21f3a2efe49cb30ea8109fdfc79d30d6b27a3 /net/ipv4/ip_output.c
parente474995f290ff7bc236b549aa9a89ae445ee5b1b (diff)
ipv4: Pass flow keys down into datagram packet building engine.
This way ip_output.c no longer needs rt->rt_{src,dst}. We already have these keys sitting, ready and waiting, on the stack or in a socket structure. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r--net/ipv4/ip_output.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index b88ee5fdcbca..dca637b9d8ae 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1267,6 +1267,7 @@ static void ip_cork_release(struct inet_cork *cork)
1267 * and push them out. 1267 * and push them out.
1268 */ 1268 */
1269struct sk_buff *__ip_make_skb(struct sock *sk, 1269struct sk_buff *__ip_make_skb(struct sock *sk,
1270 struct flowi4 *fl4,
1270 struct sk_buff_head *queue, 1271 struct sk_buff_head *queue,
1271 struct inet_cork *cork) 1272 struct inet_cork *cork)
1272{ 1273{
@@ -1333,8 +1334,8 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
1333 ip_select_ident(iph, &rt->dst, sk); 1334 ip_select_ident(iph, &rt->dst, sk);
1334 iph->ttl = ttl; 1335 iph->ttl = ttl;
1335 iph->protocol = sk->sk_protocol; 1336 iph->protocol = sk->sk_protocol;
1336 iph->saddr = rt->rt_src; 1337 iph->saddr = fl4->saddr;
1337 iph->daddr = rt->rt_dst; 1338 iph->daddr = fl4->daddr;
1338 1339
1339 skb->priority = sk->sk_priority; 1340 skb->priority = sk->sk_priority;
1340 skb->mark = sk->sk_mark; 1341 skb->mark = sk->sk_mark;
@@ -1370,11 +1371,11 @@ int ip_send_skb(struct sk_buff *skb)
1370 return err; 1371 return err;
1371} 1372}
1372 1373
1373int ip_push_pending_frames(struct sock *sk) 1374int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4)
1374{ 1375{
1375 struct sk_buff *skb; 1376 struct sk_buff *skb;
1376 1377
1377 skb = ip_finish_skb(sk); 1378 skb = ip_finish_skb(sk, fl4);
1378 if (!skb) 1379 if (!skb)
1379 return 0; 1380 return 0;
1380 1381
@@ -1403,6 +1404,7 @@ void ip_flush_pending_frames(struct sock *sk)
1403} 1404}
1404 1405
1405struct sk_buff *ip_make_skb(struct sock *sk, 1406struct sk_buff *ip_make_skb(struct sock *sk,
1407 struct flowi4 *fl4,
1406 int getfrag(void *from, char *to, int offset, 1408 int getfrag(void *from, char *to, int offset,
1407 int len, int odd, struct sk_buff *skb), 1409 int len, int odd, struct sk_buff *skb),
1408 void *from, int length, int transhdrlen, 1410 void *from, int length, int transhdrlen,
@@ -1432,7 +1434,7 @@ struct sk_buff *ip_make_skb(struct sock *sk,
1432 return ERR_PTR(err); 1434 return ERR_PTR(err);
1433 } 1435 }
1434 1436
1435 return __ip_make_skb(sk, &queue, &cork); 1437 return __ip_make_skb(sk, fl4, &queue, &cork);
1436} 1438}
1437 1439
1438/* 1440/*
@@ -1461,6 +1463,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1461 struct inet_sock *inet = inet_sk(sk); 1463 struct inet_sock *inet = inet_sk(sk);
1462 struct ip_options_data replyopts; 1464 struct ip_options_data replyopts;
1463 struct ipcm_cookie ipc; 1465 struct ipcm_cookie ipc;
1466 struct flowi4 fl4;
1464 __be32 daddr; 1467 __be32 daddr;
1465 struct rtable *rt = skb_rtable(skb); 1468 struct rtable *rt = skb_rtable(skb);
1466 1469
@@ -1478,20 +1481,16 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1478 daddr = replyopts.opt.opt.faddr; 1481 daddr = replyopts.opt.opt.faddr;
1479 } 1482 }
1480 1483
1481 { 1484 flowi4_init_output(&fl4, arg->bound_dev_if, 0,
1482 struct flowi4 fl4; 1485 RT_TOS(ip_hdr(skb)->tos),
1483 1486 RT_SCOPE_UNIVERSE, sk->sk_protocol,
1484 flowi4_init_output(&fl4, arg->bound_dev_if, 0, 1487 ip_reply_arg_flowi_flags(arg),
1485 RT_TOS(ip_hdr(skb)->tos), 1488 daddr, rt->rt_spec_dst,
1486 RT_SCOPE_UNIVERSE, sk->sk_protocol, 1489 tcp_hdr(skb)->source, tcp_hdr(skb)->dest);
1487 ip_reply_arg_flowi_flags(arg), 1490 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
1488 daddr, rt->rt_spec_dst, 1491 rt = ip_route_output_key(sock_net(sk), &fl4);
1489 tcp_hdr(skb)->source, tcp_hdr(skb)->dest); 1492 if (IS_ERR(rt))
1490 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); 1493 return;
1491 rt = ip_route_output_key(sock_net(sk), &fl4);
1492 if (IS_ERR(rt))
1493 return;
1494 }
1495 1494
1496 /* And let IP do all the hard work. 1495 /* And let IP do all the hard work.
1497 1496
@@ -1512,7 +1511,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1512 arg->csumoffset) = csum_fold(csum_add(skb->csum, 1511 arg->csumoffset) = csum_fold(csum_add(skb->csum,
1513 arg->csum)); 1512 arg->csum));
1514 skb->ip_summed = CHECKSUM_NONE; 1513 skb->ip_summed = CHECKSUM_NONE;
1515 ip_push_pending_frames(sk); 1514 ip_push_pending_frames(sk, &fl4);
1516 } 1515 }
1517 1516
1518 bh_unlock_sock(sk); 1517 bh_unlock_sock(sk);