diff options
author | Francesco Fusco <ffusco@redhat.com> | 2013-09-24 09:43:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-28 18:21:52 -0400 |
commit | aa6615814533c634190019ee3a5b10490026d545 (patch) | |
tree | 08543d020bd7e2500046143440d58cd031f9754c /net/ipv4/ip_output.c | |
parent | f02db315b8d888570cb0d4496cfbb7e4acb047cb (diff) |
ipv4: processing ancillary IP_TOS or IP_TTL
If IP_TOS or IP_TTL are specified as ancillary data, then sendmsg() sends out
packets with the specified TTL or TOS overriding the socket values specified
with the traditional setsockopt().
The struct inet_cork stores the values of TOS, TTL and priority that are
passed through the struct ipcm_cookie. If there are user-specified TOS
(tos != -1) or TTL (ttl != 0) in the struct ipcm_cookie, these values are
used to override the per-socket values. In case of TOS also the priority
is changed accordingly.
Two helper functions get_rttos and get_rtconn_flags are defined to take
into account the presence of a user specified TOS value when computing
RT_TOS and RT_CONN_FLAGS.
Signed-off-by: Francesco Fusco <ffusco@redhat.com>
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 | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index a04d872c54f9..7d8357bb2ba6 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -1060,6 +1060,9 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, | |||
1060 | rt->dst.dev->mtu : dst_mtu(&rt->dst); | 1060 | rt->dst.dev->mtu : dst_mtu(&rt->dst); |
1061 | cork->dst = &rt->dst; | 1061 | cork->dst = &rt->dst; |
1062 | cork->length = 0; | 1062 | cork->length = 0; |
1063 | cork->ttl = ipc->ttl; | ||
1064 | cork->tos = ipc->tos; | ||
1065 | cork->priority = ipc->priority; | ||
1063 | cork->tx_flags = ipc->tx_flags; | 1066 | cork->tx_flags = ipc->tx_flags; |
1064 | 1067 | ||
1065 | return 0; | 1068 | return 0; |
@@ -1311,7 +1314,9 @@ struct sk_buff *__ip_make_skb(struct sock *sk, | |||
1311 | if (cork->flags & IPCORK_OPT) | 1314 | if (cork->flags & IPCORK_OPT) |
1312 | opt = cork->opt; | 1315 | opt = cork->opt; |
1313 | 1316 | ||
1314 | if (rt->rt_type == RTN_MULTICAST) | 1317 | if (cork->ttl != 0) |
1318 | ttl = cork->ttl; | ||
1319 | else if (rt->rt_type == RTN_MULTICAST) | ||
1315 | ttl = inet->mc_ttl; | 1320 | ttl = inet->mc_ttl; |
1316 | else | 1321 | else |
1317 | ttl = ip_select_ttl(inet, &rt->dst); | 1322 | ttl = ip_select_ttl(inet, &rt->dst); |
@@ -1319,7 +1324,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, | |||
1319 | iph = ip_hdr(skb); | 1324 | iph = ip_hdr(skb); |
1320 | iph->version = 4; | 1325 | iph->version = 4; |
1321 | iph->ihl = 5; | 1326 | iph->ihl = 5; |
1322 | iph->tos = inet->tos; | 1327 | iph->tos = (cork->tos != -1) ? cork->tos : inet->tos; |
1323 | iph->frag_off = df; | 1328 | iph->frag_off = df; |
1324 | iph->ttl = ttl; | 1329 | iph->ttl = ttl; |
1325 | iph->protocol = sk->sk_protocol; | 1330 | iph->protocol = sk->sk_protocol; |
@@ -1331,7 +1336,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, | |||
1331 | ip_options_build(skb, opt, cork->addr, rt, 0); | 1336 | ip_options_build(skb, opt, cork->addr, rt, 0); |
1332 | } | 1337 | } |
1333 | 1338 | ||
1334 | skb->priority = sk->sk_priority; | 1339 | skb->priority = (cork->tos != -1) ? cork->priority: sk->sk_priority; |
1335 | skb->mark = sk->sk_mark; | 1340 | skb->mark = sk->sk_mark; |
1336 | /* | 1341 | /* |
1337 | * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec | 1342 | * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec |
@@ -1481,6 +1486,8 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, | |||
1481 | ipc.addr = daddr; | 1486 | ipc.addr = daddr; |
1482 | ipc.opt = NULL; | 1487 | ipc.opt = NULL; |
1483 | ipc.tx_flags = 0; | 1488 | ipc.tx_flags = 0; |
1489 | ipc.ttl = 0; | ||
1490 | ipc.tos = -1; | ||
1484 | 1491 | ||
1485 | if (replyopts.opt.opt.optlen) { | 1492 | if (replyopts.opt.opt.optlen) { |
1486 | ipc.opt = &replyopts.opt; | 1493 | ipc.opt = &replyopts.opt; |