aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
authorFrancesco Fusco <ffusco@redhat.com>2013-09-24 09:43:09 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-28 18:21:52 -0400
commitaa6615814533c634190019ee3a5b10490026d545 (patch)
tree08543d020bd7e2500046143440d58cd031f9754c /net/ipv4/ip_output.c
parentf02db315b8d888570cb0d4496cfbb7e4acb047cb (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.c13
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;