Get rid of the RANDOM_IP_ID option and make it a sysctl. NetBSD

have already done this, so I have styled the patch on their work:

        1) introduce a ip_newid() static inline function that checks
        the sysctl and then decides if it should return a sequential
        or random IP ID.

        2) named the sysctl net.inet.ip.random_id

        3) IPv6 flow IDs and fragment IDs are now always random.
        Flow IDs and frag IDs are significantly less common in the
        IPv6 world (ie. rarely generated per-packet), so there should
        be smaller performance concerns.

The sysctl defaults to 0 (sequential IP IDs).

Reviewed by:	andre, silby, mlaier, ume
Based on:	NetBSD
MFC after:	2 months
This commit is contained in:
dwmalone 2004-08-14 15:32:40 +00:00
parent 4841831748
commit 6eb626afc8
23 changed files with 29 additions and 130 deletions

View File

@ -539,7 +539,7 @@ device musycc # LMC/SBE LMC1504 quad T1/E1
# The `pflog' device provides the pflog0 interface which logs packets.
# The `pfsync' device provides the pfsync0 interface used for
# synchronization of firewall state tables (over the net).
# Requires option PFIL_HOOKS and (when used as a module) option RANDOM_IP_ID
# Requires option PFIL_HOOKS
#
# The PPP_BSDCOMP option enables support for compress(1) style entire
# packet compression, the PPP_DEFLATE is for zlib/gzip style compression.
@ -647,13 +647,6 @@ options TCPDEBUG
# functions. See mbuf(9) for a list of available test cases.
options MBUF_STRESS_TEST
# RANDOM_IP_ID causes the ID field in IP packets to be randomized
# instead of incremented by 1 with each packet generated. This
# option closes a minor information leak which allows remote
# observers to determine the rate of packet generation on the
# machine by watching the counter.
options RANDOM_IP_ID
# Statically Link in accept filters
options ACCEPT_FILTER_DATA
options ACCEPT_FILTER_HTTP

View File

@ -361,7 +361,6 @@ NETATALK opt_atalk.h
PPP_BSDCOMP opt_ppp.h
PPP_DEFLATE opt_ppp.h
PPP_FILTER opt_ppp.h
RANDOM_IP_ID
SLIP_IFF_OPTS opt_slip.h
TCPDEBUG
TCP_SIGNATURE opt_inet.h

View File

@ -30,7 +30,6 @@
#ifdef __FreeBSD__
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_random_ip_id.h"
#endif
#ifndef __FreeBSD__
@ -107,10 +106,6 @@ struct pfsync_softc pfsyncif;
int pfsync_sync_ok;
struct pfsyncstats pfsyncstats;
#ifndef RANDOM_IP_ID
extern u_int16_t ip_randomid(void);
#endif
#ifdef __FreeBSD__
/*

View File

@ -30,7 +30,6 @@
#ifdef __FreeBSD__
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_random_ip_id.h" /* or ip_var does not export it */
#include "opt_pf.h"
#define NPFLOG DEV_PFLOG
#else
@ -168,9 +167,6 @@ RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
/* Private prototypes */
#ifndef RANDOM_IP_ID
extern u_int16_t ip_randomid(void);
#endif
void pf_ip2key(struct pf_fragment *, struct ip *);
void pf_remove_fragment(struct pf_fragment *);
void pf_flush_fragments(void);

View File

@ -3,19 +3,11 @@
.PATH: ${.CURDIR}/../../netinet
KMOD= ip_mroute
SRCS= ip_mroute.c opt_mac.h opt_mrouting.h opt_random_ip_id.h
SRCS= ip_mroute.c opt_mac.h opt_mrouting.h
CFLAGS+= -DMROUTE_KLD
RANDOM_IP_ID?= 0 # 0/1 - should jibe with kernel configuration
opt_mrouting.h:
echo "#define MROUTING 1" > ${.TARGET}
opt_random_ip_id.h:
touch ${.TARGET}
.if ${RANDOM_IP_ID} > 0
echo "#define RANDOM_IP_ID 1" > ${.TARGET}
.endif
.include <bsd.kmod.mk>

View File

@ -7,8 +7,8 @@
KMOD= pf
SRCS = pf.c pf_if.c pf_subr.c pf_osfp.c pf_ioctl.c pf_norm.c pf_table.c \
if_pflog.c \
in4_cksum.c ip_id.c \
opt_pf.h opt_inet.h opt_inet6.h opt_bpf.h opt_random_ip_id.h
in4_cksum.c \
opt_pf.h opt_inet.h opt_inet6.h opt_bpf.h
CFLAGS+= -Wall -I${.CURDIR}/../../contrib/pf
@ -29,7 +29,4 @@ opt_inet6.h:
opt_bpf.h:
echo "#define DEV_BPF 1" > opt_bpf.h
opt_random_ip_id.h:
echo "#define RANDOM_IP_ID 1" > opt_random_ip_id.h
.include <bsd.kmod.mk>

View File

@ -57,14 +57,12 @@
* This avoids reuse issues caused by reseeding.
*/
#include "opt_random_ip_id.h"
#include "opt_pf.h"
#include <sys/param.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/random.h>
#if defined(RANDOM_IP_ID) || defined(DEV_PF)
#define RU_OUT 180 /* Time after wich will be reseeded */
#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
#define RU_GEN 2 /* Starting generator */
@ -209,4 +207,3 @@ ip_randomid(void)
return (ru_seed ^ pmod(ru_g,ru_seed2 ^ ru_x,RU_N)) | ru_msb;
}
#endif /* RANDOM_IP_ID || DEV_PF */

View File

@ -39,7 +39,6 @@
#include "opt_ipsec.h"
#include "opt_mac.h"
#include "opt_pfil_hooks.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -135,6 +134,11 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_RW,
&ip_sendsourcequench, 0,
"Enable the transmission of source quench packets");
int ip_do_randomid = 0;
SYSCTL_INT(_net_inet_ip, OID_AUTO, random_id, CTLFLAG_RW,
&ip_do_randomid, 0,
"Assign random ip_id values");
/*
* XXX - Setting ip_checkinterface mostly implements the receive side of
* the Strong ES model described in RFC 1122, but since the routing table
@ -281,9 +285,7 @@ ip_init()
maxnipq = nmbclusters / 32;
maxfragsperpacket = 16;
#ifndef RANDOM_IP_ID
ip_id = time_second & 0xffff;
#endif
ipintrq.ifq_maxlen = ipqmaxlen;
mtx_init(&ipintrq.ifq_mtx, "ip_inq", NULL, MTX_DEF);
netisr_register(NETISR_IP, ip_input, &ipintrq, NETISR_MPSAFE);

View File

@ -22,7 +22,6 @@
#include "opt_mac.h"
#include "opt_mrouting.h"
#include "opt_random_ip_id.h"
#ifdef PIM
#define _PIM_VT 1
@ -1884,11 +1883,7 @@ encap_send(struct ip *ip, struct vif *vifp, struct mbuf *m)
*/
ip_copy = mtod(mb_copy, struct ip *);
*ip_copy = multicast_encap_iphdr;
#ifdef RANDOM_IP_ID
ip_copy->ip_id = ip_randomid();
#else
ip_copy->ip_id = htons(ip_id++);
#endif
ip_copy->ip_id = ip_newid();
ip_copy->ip_len += len;
ip_copy->ip_src = vifp->v_lcl_addr;
ip_copy->ip_dst = vifp->v_rmt_addr;
@ -3093,11 +3088,7 @@ pim_register_send_rp(struct ip *ip, struct vif *vifp,
*/
ip_outer = mtod(mb_first, struct ip *);
*ip_outer = pim_encap_iphdr;
#ifdef RANDOM_IP_ID
ip_outer->ip_id = ip_randomid();
#else
ip_outer->ip_id = htons(ip_id++);
#endif
ip_outer->ip_id = ip_newid();
ip_outer->ip_len = len + sizeof(pim_encap_iphdr) + sizeof(pim_encap_pimhdr);
ip_outer->ip_src = viftable[vifi].v_lcl_addr;
ip_outer->ip_dst = rt->mfc_rp;

View File

@ -37,7 +37,6 @@
#include "opt_ipsec.h"
#include "opt_mac.h"
#include "opt_pfil_hooks.h"
#include "opt_random_ip_id.h"
#include "opt_mbuf_stress_test.h"
#include <sys/param.h>
@ -216,11 +215,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro,
if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
ip->ip_v = IPVERSION;
ip->ip_hl = hlen >> 2;
#ifdef RANDOM_IP_ID
ip->ip_id = ip_randomid();
#else
ip->ip_id = htons(ip_id++);
#endif
ip->ip_id = ip_newid();
ipstat.ips_localout++;
} else {
hlen = ip->ip_hl << 2;

View File

@ -142,9 +142,7 @@ struct route;
struct sockopt;
extern struct ipstat ipstat;
#ifndef RANDOM_IP_ID
extern u_short ip_id; /* ip packet ctr, for ids */
#endif
extern int ip_defttl; /* default IP ttl */
extern int ipforwarding; /* ip forwarding */
extern int ip_doopts; /* process or ignore IP options */
@ -178,10 +176,7 @@ void ip_slowtimo(void);
struct mbuf *
ip_srcroute(void);
void ip_stripoptions(struct mbuf *, struct mbuf *);
#ifdef RANDOM_IP_ID
u_int16_t
ip_randomid(void);
#endif
u_int16_t ip_randomid(void);
int rip_ctloutput(struct socket *, struct sockopt *);
void rip_ctlinput(int, struct sockaddr *, void *);
void rip_init(void);
@ -201,6 +196,18 @@ extern struct pfil_head inet_pfil_hook;
void in_delayed_cksum(struct mbuf *m);
static __inline uint16_t ip_newid(void);
extern int ip_do_randomid;
static __inline uint16_t
ip_newid(void)
{
if (ip_do_randomid)
return ip_randomid();
return htons(ip_id++);
}
#endif /* _KERNEL */
#endif /* !_NETINET_IP_VAR_H_ */

View File

@ -33,7 +33,6 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_mac.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/jail.h>
@ -304,11 +303,7 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
return EINVAL;
}
if (ip->ip_id == 0)
#ifdef RANDOM_IP_ID
ip->ip_id = ip_randomid();
#else
ip->ip_id = htons(ip_id++);
#endif
ip->ip_id = ip_newid();
/* XXX prevent ip_output from overwriting header fields */
flags |= IP_RAWOUTPUT;
ipstat.ips_rawout++;

View File

@ -38,7 +38,6 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_mac.h"
#include "opt_random_ip_id.h"
#include "opt_tcpdebug.h"
#include "opt_tcp_sack.h"
@ -958,11 +957,7 @@ syncache_add(inc, to, th, sop, m)
if (inc->inc_isipv6 &&
(sc->sc_tp->t_inpcb->in6p_flags & IN6P_AUTOFLOWLABEL)) {
sc->sc_flowlabel =
#ifdef RANDOM_IP_ID
(htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
#else
(htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
#endif
}
#endif
}

View File

@ -33,7 +33,6 @@
#include "opt_ipsec.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_random_ip_id.h"
#include "opt_tcpdebug.h"
#include <sys/param.h>
@ -946,12 +945,8 @@ tcp6_connect(tp, nam, td)
/* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
if (inp->in6p_flags & IN6P_AUTOFLOWLABEL)
inp->in6p_flowinfo |=
#ifdef RANDOM_IP_ID
inp->in6p_flowinfo |=
(htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
#else
(htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
#endif
in_pcbrehash(inp);
/* Compute window scaling to request. */

View File

@ -30,8 +30,6 @@
* SUCH DAMAGE.
*/
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@ -98,9 +96,6 @@ frag6_init()
IP6Q_LOCK_INIT();
#ifndef RANDOM_IP_ID
ip6_id = arc4random();
#endif
ip6q.ip6q_next = ip6q.ip6q_prev = &ip6q;
}

View File

@ -65,7 +65,6 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -389,11 +388,7 @@ in6_pcbconnect(inp, nam, cred)
inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
if (inp->in6p_flags & IN6P_AUTOFLOWLABEL)
inp->in6p_flowinfo |=
#ifdef RANDOM_IP_ID
(htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
#else
(htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
#endif
in_pcbrehash(inp);
#ifdef IPSEC

View File

@ -64,7 +64,6 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/socket.h>
@ -290,9 +289,6 @@ int ip6_maxfrags; /* initialized in frag6.c:frag6_init() */
int ip6_log_interval = 5;
int ip6_hdrnestlimit = 50; /* appropriate? */
int ip6_dad_count = 1; /* DupAddrDetectionTransmits */
#ifndef RANDOM_IP_ID
u_int32_t ip6_flow_seq;
#endif
int ip6_auto_flowlabel = 1;
int ip6_gif_hlim = 0;
int ip6_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */
@ -300,9 +296,6 @@ int ip6_rr_prune = 5; /* router renumbering prefix
* walk list every 5 sec. */
int ip6_v6only = 1;
#ifndef RANDOM_IP_ID
u_int32_t ip6_id = 0UL;
#endif
int ip6_keepfaith = 0;
time_t ip6_log_time = (time_t)0L;

View File

@ -86,8 +86,6 @@
* This avoids reuse issues caused by reseeding.
*/
#include "opt_random_ip_id.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/kernel.h>
@ -100,8 +98,6 @@
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#ifdef RANDOM_IP_ID
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffffU
#endif
@ -267,5 +263,3 @@ ip6_randomflowlabel(void)
return randomid(&randomtab_20) & 0xfffff;
}
#endif /* RANDOM_IP_ID */

View File

@ -66,7 +66,6 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_pfil_hooks.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -197,9 +196,6 @@ ip6_init()
addrsel_policy_init();
nd6_init();
frag6_init();
#ifndef RANDOM_IP_ID
ip6_flow_seq = arc4random();
#endif
ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
}

View File

@ -66,7 +66,6 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_pfil_hooks.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/malloc.h>
@ -1036,11 +1035,7 @@ skip_ipsec2:;
} else {
struct mbuf **mnext, *m_frgpart;
struct ip6_frag *ip6f;
#ifdef RANDOM_IP_ID
u_int32_t id = htonl(ip6_randomid());
#else
u_int32_t id = htonl(ip6_id++);
#endif
u_char nextproto;
struct ip6ctlparam ip6cp;
u_int32_t mtu32;

View File

@ -283,9 +283,6 @@ struct ip6aux {
#define IPV6_MINMTU 0x04 /* use minimum MTU (IPV6_USE_MIN_MTU) */
extern struct ip6stat ip6stat; /* statistics */
#ifndef RANDOM_IP_ID
extern u_int32_t ip6_id; /* fragment identifier */
#endif
extern int ip6_defhlim; /* default hop limit */
extern int ip6_defmcasthlim; /* default multicast hop limit */
extern int ip6_forwarding; /* act as router? */
@ -309,9 +306,6 @@ extern time_t ip6_log_time;
extern int ip6_hdrnestlimit; /* upper limit of # of extension headers */
extern int ip6_dad_count; /* DupAddrDetectionTransmits */
#ifndef RANDOM_IP_ID
extern u_int32_t ip6_flow_seq;
#endif
extern int ip6_auto_flowlabel;
extern int ip6_auto_linklocal;
@ -399,10 +393,8 @@ struct in6_addr *in6_selectsrc __P((struct sockaddr_in6 *,
int in6_selectroute __P((struct sockaddr_in6 *, struct ip6_pktopts *,
struct ip6_moptions *, struct route_in6 *, struct ifnet **,
struct rtentry **, int));
#ifdef RANDOM_IP_ID
u_int32_t ip6_randomid __P((void));
u_int32_t ip6_randomflowlabel __P((void));
#endif
#endif /* _KERNEL */
#endif /* !_NETINET6_IP6_VAR_H_ */

View File

@ -37,7 +37,6 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -2156,11 +2155,7 @@ ipsec4_encapsulate(m, sav)
ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
"leave ip_len as is (invalid packet)\n"));
}
#ifdef RANDOM_IP_ID
ip->ip_id = ip_randomid();
#else
ip->ip_id = htons(ip_id++);
#endif
ip->ip_id = ip_newid();
bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
&ip->ip_src, sizeof(ip->ip_src));
bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,

View File

@ -41,7 +41,6 @@
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_random_ip_id.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -450,11 +449,7 @@ ipip_output(
ipo->ip_src = saidx->src.sin.sin_addr;
ipo->ip_dst = saidx->dst.sin.sin_addr;
#ifdef RANDOM_IP_ID
ipo->ip_id = ip_randomid();
#else
ipo->ip_id = htons(ip_id++);
#endif
ipo->ip_id = ip_newid();
/* If the inner protocol is IP... */
if (tp == IPVERSION) {