diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-08 20:12:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-09 00:24:06 -0400 |
commit | 77968b78242ee25e2a4d759f0fca8dd52df6d479 (patch) | |
tree | 6de21f3a2efe49cb30ea8109fdfc79d30d6b27a3 /net/ipv4/ip_output.c | |
parent | e474995f290ff7bc236b549aa9a89ae445ee5b1b (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.c | 39 |
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 | */ |
1269 | struct sk_buff *__ip_make_skb(struct sock *sk, | 1269 | struct 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 | ||
1373 | int ip_push_pending_frames(struct sock *sk) | 1374 | int 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 | ||
1405 | struct sk_buff *ip_make_skb(struct sock *sk, | 1406 | struct 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); |