Commit d218d111 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

tcp: Generalized TTL Security Mechanism

This patch adds the kernel portions needed to implement
RFC 5082 Generalized TTL Security Mechanism (GTSM).
It is a lightweight security measure against forged
packets causing DoS attacks (for BGP). 

This is already implemented the same way in BSD kernels.
For the necessary Quagga patch 
  http://www.gossamer-threads.com/lists/quagga/dev/17389

Description from Cisco
  http://www.cisco.com/en/US/docs/ios/12_3t/12_3t7/feature/guide/gt_btsh.html

It does add one byte to each socket structure, but I did
a little rearrangement to reuse a hole (on 64 bit), but it
does grow the structure on 32 bit

This should be documented on ip(4) man page and the Glibc in.h
file also needs update.  IPV6_MINHOPLIMIT should also be added
(although BSD doesn't support that).  

Only TCP is supported, but could also be added to UDP, DCCP, SCTP
if desired.
Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c8e00060
...@@ -84,6 +84,8 @@ struct in_addr { ...@@ -84,6 +84,8 @@ struct in_addr {
#define IP_ORIGDSTADDR 20 #define IP_ORIGDSTADDR 20
#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR #define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
#define IP_MINTTL 21
/* IP_MTU_DISCOVER values */ /* IP_MTU_DISCOVER values */
#define IP_PMTUDISC_DONT 0 /* Never send DF frames */ #define IP_PMTUDISC_DONT 0 /* Never send DF frames */
#define IP_PMTUDISC_WANT 1 /* Use per route hints */ #define IP_PMTUDISC_WANT 1 /* Use per route hints */
......
...@@ -122,10 +122,12 @@ struct inet_sock { ...@@ -122,10 +122,12 @@ struct inet_sock {
__be32 inet_saddr; __be32 inet_saddr;
__s16 uc_ttl; __s16 uc_ttl;
__u16 cmsg_flags; __u16 cmsg_flags;
struct ip_options *opt;
__be16 inet_sport; __be16 inet_sport;
__u16 inet_id; __u16 inet_id;
struct ip_options *opt;
__u8 tos; __u8 tos;
__u8 min_ttl;
__u8 mc_ttl; __u8 mc_ttl;
__u8 pmtudisc; __u8 pmtudisc;
__u8 recverr:1, __u8 recverr:1,
......
...@@ -451,7 +451,8 @@ static int do_ip_setsockopt(struct sock *sk, int level, ...@@ -451,7 +451,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
(1<<IP_TTL) | (1<<IP_HDRINCL) | (1<<IP_TTL) | (1<<IP_HDRINCL) |
(1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
(1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
(1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
(1<<IP_MINTTL))) ||
optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_TTL ||
optname == IP_MULTICAST_ALL || optname == IP_MULTICAST_ALL ||
optname == IP_MULTICAST_LOOP || optname == IP_MULTICAST_LOOP ||
...@@ -936,6 +937,14 @@ mc_msf_out: ...@@ -936,6 +937,14 @@ mc_msf_out:
inet->transparent = !!val; inet->transparent = !!val;
break; break;
case IP_MINTTL:
if (optlen < 1)
goto e_inval;
if (val < 0 || val > 255)
goto e_inval;
inet->min_ttl = val;
break;
default: default:
err = -ENOPROTOOPT; err = -ENOPROTOOPT;
break; break;
...@@ -1198,6 +1207,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, ...@@ -1198,6 +1207,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
case IP_TRANSPARENT: case IP_TRANSPARENT:
val = inet->transparent; val = inet->transparent;
break; break;
case IP_MINTTL:
val = inet->min_ttl;
break;
default: default:
release_sock(sk); release_sock(sk);
return -ENOPROTOOPT; return -ENOPROTOOPT;
......
...@@ -1649,6 +1649,9 @@ int tcp_v4_rcv(struct sk_buff *skb) ...@@ -1649,6 +1649,9 @@ int tcp_v4_rcv(struct sk_buff *skb)
if (!sk) if (!sk)
goto no_tcp_socket; goto no_tcp_socket;
if (iph->ttl < inet_sk(sk)->min_ttl)
goto discard_and_relse;
process: process:
if (sk->sk_state == TCP_TIME_WAIT) if (sk->sk_state == TCP_TIME_WAIT)
goto do_time_wait; goto do_time_wait;
......
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