Commit f9c72ecd authored by David S. Miller's avatar David S. Miller

[IPV4]: Respect hoplimit route metric.

parent 16daa730
......@@ -113,7 +113,7 @@ struct inet_opt {
__u16 dport; /* Destination port */
__u16 num; /* Local port */
__u32 saddr; /* Sending source */
int ttl; /* TTL setting */
int uc_ttl; /* Unicast TTL */
int tos; /* TOS */
unsigned cmsg_flags;
struct ip_options *opt;
......
......@@ -398,7 +398,7 @@ static int inet_create(struct socket *sock, int protocol)
sk->protocol = protocol;
sk->backlog_rcv = sk->prot->backlog_rcv;
inet->ttl = sysctl_ip_default_ttl;
inet->uc_ttl = -1;
inet->mc_loop = 1;
inet->mc_ttl = 1;
inet->mc_index = 0;
......
......@@ -185,8 +185,6 @@ struct icmp_err icmp_err_convert[] = {
},
};
extern int sysctl_ip_default_ttl;
/* Control parameters for ECHO replies. */
int sysctl_icmp_echo_ignore_all;
int sysctl_icmp_echo_ignore_broadcasts;
......@@ -384,7 +382,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
icmp_out_count(icmp_param->data.icmph.type);
inet->tos = skb->nh.iph->tos;
inet->ttl = sysctl_ip_default_ttl;
daddr = ipc.addr = rt->rt_src;
ipc.opt = NULL;
if (icmp_param->replyopts.optlen) {
......@@ -539,7 +536,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
icmp_param.offset = skb_in->nh.raw - skb_in->data;
icmp_out_count(icmp_param.data.icmph.type);
inet_sk(icmp_socket->sk)->tos = tos;
inet_sk(icmp_socket->sk)->ttl = sysctl_ip_default_ttl;
ipc.addr = iph->saddr;
ipc.opt = &icmp_param.replyopts;
if (icmp_param.replyopts.srr) {
......@@ -1126,7 +1122,7 @@ void __init icmp_init(struct net_proto_family *ops)
per_cpu(__icmp_socket, i)->sk->allocation = GFP_ATOMIC;
per_cpu(__icmp_socket, i)->sk->sndbuf = SK_WMEM_MAX * 2;
inet = inet_sk(per_cpu(__icmp_socket, i)->sk);
inet->ttl = MAXTTL;
inet->uc_ttl = -1;
inet->pmtudisc = IP_PMTUDISC_DONT;
/* Unhash it so that IP input processing does not even
......
......@@ -860,7 +860,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
#endif
else
iph->ttl = sysctl_ip_default_ttl;
iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
}
((u16*)(iph+1))[0] = tunnel->parms.o_flags;
......
......@@ -112,6 +112,15 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
return 0;
}
static inline int ip_select_ttl(struct inet_opt *inet, struct dst_entry *dst)
{
int ttl = inet->uc_ttl;
if (ttl < 0)
ttl = dst_metric(dst, RTAX_HOPLIMIT);
return ttl;
}
/*
* Add an ip header to a skbuff and send it out.
*
......@@ -136,7 +145,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = inet->ttl;
iph->ttl = ip_select_ttl(inet, &rt->u.dst);
iph->daddr = rt->rt_dst;
iph->saddr = rt->rt_src;
iph->protocol = sk->protocol;
......@@ -341,7 +350,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = inet->ttl;
iph->ttl = ip_select_ttl(inet, &rt->u.dst);
iph->protocol = sk->protocol;
iph->saddr = rt->rt_src;
iph->daddr = rt->rt_dst;
......@@ -1120,7 +1129,7 @@ int ip_push_pending_frames(struct sock *sk)
if (rt->rt_type == RTN_MULTICAST)
ttl = inet->mc_ttl;
else
ttl = inet->ttl;
ttl = ip_select_ttl(inet, &rt->u.dst);
iph = (struct iphdr *)skb->data;
iph->version = 4;
......
......@@ -501,11 +501,9 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
case IP_TTL:
if (optlen<1)
goto e_inval;
if(val==-1)
val = sysctl_ip_default_ttl;
if(val<1||val>255)
if (val != -1 && (val < 1 || val>255))
goto e_inval;
inet->ttl = val;
inet->uc_ttl = val;
break;
case IP_HDRINCL:
if(sk->type!=SOCK_RAW) {
......@@ -911,7 +909,9 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
val = inet->tos;
break;
case IP_TTL:
val = inet->ttl;
val = (inet->uc_ttl == -1 ?
sysctl_ip_default_ttl :
inet->uc_ttl);
break;
case IP_HDRINCL:
val = inet->hdrincl;
......
......@@ -111,7 +111,6 @@ fold_field(void *mib[], int nr)
*/
static int snmp_seq_show(struct seq_file *seq, void *v)
{
extern int sysctl_ip_default_ttl;
int i;
seq_printf(seq, "Ip: Forwarding DefaultTTL InReceives InHdrErrors "
......
......@@ -1317,6 +1317,9 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
rt->rt_gateway = FIB_RES_GW(*res);
memcpy(rt->u.dst.metrics, fi->fib_metrics,
sizeof(rt->u.dst.metrics));
if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
rt->u.dst.metrics[RTAX_HOPLIMIT-1] =
sysctl_ip_default_ttl;
if (fi->fib_mtu == 0) {
rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) &&
......
......@@ -74,7 +74,6 @@
#include <linux/seq_file.h>
extern int sysctl_ip_dynaddr;
extern int sysctl_ip_default_ttl;
int sysctl_tcp_tw_reuse;
int sysctl_tcp_low_latency;
......@@ -1213,7 +1212,6 @@ static void tcp_v4_send_reset(struct sk_buff *skb)
sizeof(struct tcphdr), IPPROTO_TCP, 0);
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
inet_sk(tcp_socket->sk)->ttl = sysctl_ip_default_ttl;
ip_send_reply(tcp_socket->sk, skb, &arg, sizeof rth);
TCP_INC_STATS_BH(TcpOutSegs);
......@@ -2619,7 +2617,7 @@ void __init tcp_v4_init(struct net_proto_family *ops)
if (err < 0)
panic("Failed to create the TCP control socket.\n");
tcp_socket->sk->allocation = GFP_ATOMIC;
inet_sk(tcp_socket->sk)->ttl = MAXTTL;
inet_sk(tcp_socket->sk)->uc_ttl = -1;
/* Unhash it so that IP input processing does not even
* see it, we do not wish this socket to see incoming
......
......@@ -227,7 +227,7 @@ static int inet6_create(struct socket *sock, int protocol)
/* Init the ipv4 part of the socket since we can have sockets
* using v6 API for ipv4.
*/
inet->ttl = 64;
inet->uc_ttl = -1;
inet->mc_loop = 1;
inet->mc_ttl = 1;
......
......@@ -547,7 +547,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
/* Init the ipv4 part of the socket since we can have sockets
* using v6 API for ipv4.
*/
newinet->ttl = sysctl_ip_default_ttl;
newinet->uc_ttl = -1;
newinet->mc_loop = 1;
newinet->mc_ttl = 1;
newinet->mc_index = 0;
......
......@@ -545,7 +545,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk,
newinet->pmtudisc = inet->pmtudisc;
newinet->id = 0;
newinet->ttl = sysctl_ip_default_ttl;
newinet->uc_ttl = -1;
newinet->mc_loop = 1;
newinet->mc_ttl = 1;
newinet->mc_index = 0;
......@@ -602,7 +602,7 @@ int sctp_ctl_sock_init(void)
return err;
}
sctp_ctl_socket->sk->allocation = GFP_ATOMIC;
inet_sk(sctp_ctl_socket->sk)->ttl = MAXTTL;
inet_sk(sctp_ctl_socket->sk)->uc_ttl = -1;
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment