Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137792775
D2211.id4613.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D2211.id4613.diff
View Options
Index: contrib/ipfilter/tools/ipftest.c
===================================================================
--- contrib/ipfilter/tools/ipftest.c
+++ contrib/ipfilter/tools/ipftest.c
@@ -865,10 +865,20 @@
}
}
+unsigned
+ip_initid(void)
+{
+
+ return (0);
+}
+
void
-ip_fillid(struct ip *ip)
+ip_fillid(struct ip *ip, unsigned *pid)
{
static uint16_t ip_id;
- ip->ip_id = ip_id++;
+ if (pid != NULL)
+ ip->ip_id = (*pid)++
+ else
+ ip->ip_id = ip_id++;
}
Index: sys/contrib/ipfilter/netinet/fil.c
===================================================================
--- sys/contrib/ipfilter/netinet/fil.c
+++ sys/contrib/ipfilter/netinet/fil.c
@@ -6096,7 +6096,7 @@
id = (u_short)sum;
ip->ip_id = htons(id);
} else {
- ip_fillid(ip);
+ ip_fillid(ip, NULL);
id = ntohs(ip->ip_id);
if ((fin->fin_flx & FI_FRAG) != 0)
(void) ipf_frag_ipidnew(fin, (u_32_t)id);
Index: sys/contrib/ipfilter/netinet/ip_fil.h
===================================================================
--- sys/contrib/ipfilter/netinet/ip_fil.h
+++ sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1718,7 +1718,8 @@
extern void m_freem __P((mb_t *));
extern size_t msgdsize __P((mb_t *));
extern int bcopywrap __P((void *, void *, size_t));
-extern void ip_fillid(struct ip *);
+extern unsigned ip_initid(void);
+extern void ip_fillid(struct ip *, unsigned *);
#else /* #ifndef _KERNEL */
# if defined(__NetBSD__) && defined(PFIL_HOOKS)
extern void ipfilterattach __P((int));
Index: sys/contrib/ipfilter/netinet/ip_nat.h
===================================================================
--- sys/contrib/ipfilter/netinet/ip_nat.h
+++ sys/contrib/ipfilter/netinet/ip_nat.h
@@ -661,6 +661,7 @@
ipftq_t ipf_nat_pending;
ipftq_t ipf_nat_tcptq[IPF_TCP_NSTATES];
natstat_t ipf_nat_stats;
+ unsigned ipf_nat_ip_id; /* IP ID number */
} ipf_nat_softc_t ;
#define ipf_nat_map_max ipf_nat_map_mask.imt4_max
Index: sys/contrib/ipfilter/netinet/ip_nat.c
===================================================================
--- sys/contrib/ipfilter/netinet/ip_nat.c
+++ sys/contrib/ipfilter/netinet/ip_nat.c
@@ -319,6 +319,7 @@
bzero((char *)softn, sizeof(*softn));
+ softn->ipf_nat_ip_id = ip_initid();
softn->ipf_nat_tune = ipf_tune_array_copy(softn,
sizeof(ipf_nat_tuneables),
ipf_nat_tuneables);
@@ -5221,7 +5222,7 @@
}
ip = MTOD(m, ip_t *);
- ip_fillid(ip);
+ ip_fillid(ip, &softn->ipf_nat_ip_id);
s2 = ntohs(ip->ip_id);
s1 = ip->ip_len;
@@ -5666,7 +5667,7 @@
}
ip = MTOD(m, ip_t *);
- ip_fillid(ip);
+ ip_fillid(ip, &softn->ipf_nat_ip_id);
sum1 = ntohs(ip->ip_len);
ip->ip_len = ntohs(ip->ip_len);
ip->ip_len += fin->fin_plen;
Index: sys/net/if_gre.h
===================================================================
--- sys/net/if_gre.h
+++ sys/net/if_gre.h
@@ -82,6 +82,7 @@
#endif
} gre_uhdr;
const struct encaptab *gre_ecookie;
+ unsigned gre_ip_id; /* IP ID number */
};
#define GRE2IFP(sc) ((sc)->gre_ifp)
#define GRE_LOCK_INIT(sc) rm_init(&(sc)->gre_lock, "gre softc")
@@ -103,7 +104,7 @@
int gre_input(struct mbuf **, int *, int);
#ifdef INET
int in_gre_attach(struct gre_softc *);
-int in_gre_output(struct mbuf *, int, int);
+int in_gre_output(struct gre_softc *, struct mbuf *, int, int);
#endif
#ifdef INET6
int in6_gre_attach(struct gre_softc *);
Index: sys/net/if_gre.c
===================================================================
--- sys/net/if_gre.c
+++ sys/net/if_gre.c
@@ -909,7 +909,7 @@
switch (oaf) {
#ifdef INET
case AF_INET:
- error = in_gre_output(m, iaf, hlen);
+ error = in_gre_output(sc, m, iaf, hlen);
break;
#endif
#ifdef INET6
Index: sys/netinet/in_pcb.h
===================================================================
--- sys/netinet/in_pcb.h
+++ sys/netinet/in_pcb.h
@@ -220,6 +220,7 @@
struct llentry *inp_lle; /* cached L2 information */
struct rtentry *inp_rt; /* cached L3 information */
struct rwlock inp_lock;
+ unsigned inp_ip_id; /* (i) IP ID number */
};
#define inp_fport inp_inc.inc_fport
#define inp_lport inp_inc.inc_lport
Index: sys/netinet/in_pcb.c
===================================================================
--- sys/netinet/in_pcb.c
+++ sys/netinet/in_pcb.c
@@ -280,6 +280,7 @@
if (inp == NULL)
return (ENOBUFS);
bzero(inp, inp_zero_size);
+ inp->inp_ip_id = ip_initid();
inp->inp_pcbinfo = pcbinfo;
inp->inp_socket = so;
inp->inp_cred = crhold(so->so_cred);
Index: sys/netinet/ip_carp.c
===================================================================
--- sys/netinet/ip_carp.c
+++ sys/netinet/ip_carp.c
@@ -118,6 +118,8 @@
int sc_init_counter;
uint64_t sc_counter;
+ unsigned sc_ip_id; /* IP ID number */
+
/* authentication */
#define CARP_HMAC_PAD 64
unsigned char sc_key[CARP_KEY_LEN];
@@ -842,7 +844,7 @@
ip->ip_ttl = CARP_DFLTTL;
ip->ip_p = IPPROTO_CARP;
ip->ip_sum = 0;
- ip_fillid(ip);
+ ip_fillid(ip, &sc->sc_ip_id);
bzero(&sa, sizeof(sa));
sa.sa_family = AF_INET;
@@ -1477,6 +1479,7 @@
sc = malloc(sizeof(*sc), M_CARP, M_WAITOK|M_ZERO);
+ sc->sc_ip_id = ip_initid();
sc->sc_advbase = CARP_DFLTINTV;
sc->sc_vhid = -1; /* required setting */
sc->sc_init_counter = 1;
Index: sys/netinet/ip_gre.c
===================================================================
--- sys/netinet/ip_gre.c
+++ sys/netinet/ip_gre.c
@@ -125,7 +125,7 @@
}
int
-in_gre_output(struct mbuf *m, int af, int hlen)
+in_gre_output(struct gre_softc *sc, struct mbuf *m, int af, int hlen)
{
struct greip *gi;
@@ -145,7 +145,7 @@
#ifdef INET6
case AF_INET6:
gi->gi_ip.ip_tos = 0; /* XXX */
- ip_fillid(&gi->gi_ip);
+ ip_fillid(&gi->gi_ip, &sc->gre_ip_id);
break;
#endif
}
Index: sys/netinet/ip_id.c
===================================================================
--- sys/netinet/ip_id.c
+++ sys/netinet/ip_id.c
@@ -124,12 +124,12 @@
/*
* Non-random ID state engine is simply a per-cpu counter.
*/
-static VNET_DEFINE(counter_u64_t, ip_id);
+static VNET_DEFINE(unsigned, ip_id);
#define V_ip_id VNET(ip_id)
static int sysctl_ip_randomid(SYSCTL_HANDLER_ARGS);
static int sysctl_ip_id_change(SYSCTL_HANDLER_ARGS);
-static void ip_initid(int);
+static void ip_initid_array(int);
static uint16_t ip_randomid(void);
static void ipid_sysinit(void);
static void ipid_sysuninit(void);
@@ -165,7 +165,7 @@
if (new == V_ip_do_randomid)
return (0);
if (new == 1 && V_ip_do_randomid == 0)
- ip_initid(8192);
+ ip_initid_array(8192);
/* We don't free memory when turning random ID off, due to race. */
V_ip_do_randomid = new;
return (0);
@@ -180,7 +180,7 @@
error = sysctl_handle_int(oidp, &new, 0, req);
if (error == 0 && req->newptr) {
if (new >= 512 && new <= 32768)
- ip_initid(new);
+ ip_initid_array(new);
else
error = EINVAL;
}
@@ -188,7 +188,7 @@
}
static void
-ip_initid(int new_size)
+ip_initid_array(int new_size)
{
uint16_t *new_array;
bitstr_t *new_bits;
@@ -238,8 +238,16 @@
return (new_id);
}
+unsigned
+ip_initid(void)
+{
+ unsigned temp = 0;
+ arc4rand(&temp, sizeof(temp), 0);
+ return (temp);
+}
+
void
-ip_fillid(struct ip *ip)
+ip_fillid(struct ip *ip, unsigned *pid)
{
/*
@@ -252,23 +260,12 @@
ip->ip_id = 0;
else if (V_ip_do_randomid)
ip->ip_id = ip_randomid();
- else {
- counter_u64_add(V_ip_id, 1);
- /*
- * There are two issues about this trick, to be kept in mind.
- * 1) We can migrate between counter_u64_add() and next
- * line, and grab counter from other CPU, resulting in too
- * quick ID reuse. This is tolerable in our particular case,
- * since probability of such event is much lower then reuse
- * of ID due to legitimate overflow, that at modern Internet
- * speeds happens all the time.
- * 2) We are relying on the fact that counter(9) is based on
- * UMA_ZONE_PCPU uma(9) zone. We also take only last
- * sixteen bits of a counter, so we don't care about the
- * fact that machines with 32-bit word update their counters
- * not atomically.
- */
- ip->ip_id = htons((*(uint64_t *)zpcpu_get(V_ip_id)) & 0xffff);
+ else if (pid != NULL) {
+ /* no need to byteswap IP ID field */
+ ip->ip_id = atomic_fetchadd_int(pid, 1) & 0xFFFF;
+ } else { /* fallback to global IP ID counter */
+ /* no need to byteswap IP ID field */
+ ip->ip_id = atomic_fetchadd_int(&V_ip_id, 1) & 0xFFFF;
}
}
@@ -277,9 +274,7 @@
{
mtx_init(&V_ip_id_mtx, "ip_id_mtx", NULL, MTX_DEF);
- V_ip_id = counter_u64_alloc(M_WAITOK);
- for (int i = 0; i < mp_ncpus; i++)
- arc4rand(zpcpu_get_cpu(V_ip_id, i), sizeof(uint64_t), 0);
+ V_ip_id = ip_initid();
}
VNET_SYSINIT(ip_id, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, ipid_sysinit, NULL);
@@ -292,6 +287,5 @@
free(V_id_array, M_IPID);
free(V_id_bits, M_IPID);
}
- counter_u64_free(V_ip_id);
}
VNET_SYSUNINIT(ip_id, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, ipid_sysuninit, NULL);
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -898,6 +898,7 @@
* Look for queue of fragments
* of this datagram.
*/
+ /* XXX if TCP or UDP should check port numbers */
TAILQ_FOREACH(fp, head, ipq_list)
if (ip->ip_id == fp->ipq_id &&
ip->ip_src.s_addr == fp->ipq_src.s_addr &&
Index: sys/netinet/ip_mroute.h
===================================================================
--- sys/netinet/ip_mroute.h
+++ sys/netinet/ip_mroute.h
@@ -263,6 +263,7 @@
u_long v_pkt_out; /* # pkts out on interface */
u_long v_bytes_in; /* # bytes in on interface */
u_long v_bytes_out; /* # bytes out on interface */
+ unsigned v_ip_id; /* IP ID number */
};
#ifdef _KERNEL
Index: sys/netinet/ip_mroute.c
===================================================================
--- sys/netinet/ip_mroute.c
+++ sys/netinet/ip_mroute.c
@@ -920,6 +920,8 @@
vifp->v_pkt_out = 0;
vifp->v_bytes_in = 0;
vifp->v_bytes_out = 0;
+ /* setup default IP ID */
+ vifp->v_ip_id = ip_initid();
/* Adjust numvifs up if the vifi is higher than numvifs */
if (V_numvifs <= vifcp->vifc_vifi)
@@ -2512,7 +2514,7 @@
ip_outer->ip_tos = ip->ip_tos;
if (ip->ip_off & htons(IP_DF))
ip_outer->ip_off |= htons(IP_DF);
- ip_fillid(ip_outer);
+ ip_fillid(ip_outer, &vifp->v_ip_id);
pimhdr = (struct pim_encap_pimhdr *)((caddr_t)ip_outer
+ sizeof(pim_encap_iphdr));
*pimhdr = pim_encap_pimhdr;
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -175,7 +175,7 @@
if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
ip->ip_v = IPVERSION;
ip->ip_hl = hlen >> 2;
- ip_fillid(ip);
+ ip_fillid(ip, (inp != NULL) ? &inp->inp_ip_id : NULL);
IPSTAT_INC(ips_localout);
} else {
/* Header already set, fetch hlen from there */
Index: sys/netinet/ip_var.h
===================================================================
--- sys/netinet/ip_var.h
+++ sys/netinet/ip_var.h
@@ -227,7 +227,8 @@
void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
struct mbuf *);
void ip_slowtimo(void);
-void ip_fillid(struct ip *);
+unsigned ip_initid(void);
+void ip_fillid(struct ip *, unsigned *);
int rip_ctloutput(struct socket *, struct sockopt *);
void rip_ctlinput(int, struct sockaddr *, void *);
void rip_init(void);
Index: sys/netinet/raw_ip.c
===================================================================
--- sys/netinet/raw_ip.c
+++ sys/netinet/raw_ip.c
@@ -510,7 +510,7 @@
* but we got this limitation from the beginning of history.
*/
if (ip->ip_id == 0)
- ip_fillid(ip);
+ ip_fillid(ip, &inp->inp_ip_id);
/*
* XXX prevent ip_output from overwriting header fields.
Index: sys/netinet/sctp_output.c
===================================================================
--- sys/netinet/sctp_output.c
+++ sys/netinet/sctp_output.c
@@ -4106,7 +4106,7 @@
ip->ip_off = htons(0);
}
/* FreeBSD has a function for ip_id's */
- ip_fillid(ip);
+ ip_fillid(ip, &inp->ip_inp.inp.inp_ip_id);
ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
ip->ip_len = htons(packet_length);
@@ -10950,7 +10950,7 @@
ip->ip_hl = (sizeof(struct ip) >> 2);
ip->ip_tos = 0;
ip->ip_off = 0;
- ip_fillid(ip);
+ ip_fillid(ip, NULL);
ip->ip_ttl = MODULE_GLOBAL(ip_defttl);
if (port) {
ip->ip_p = IPPROTO_UDP;
Index: sys/netinet/sctp_pcb.c
===================================================================
--- sys/netinet/sctp_pcb.c
+++ sys/netinet/sctp_pcb.c
@@ -2458,6 +2458,9 @@
/* zap it */
bzero(inp, sizeof(*inp));
+ /* setup default IP ID */
+ inp->ip_inp.inp.inp_ip_id = ip_initid();
+
/* bump generations */
/* setup socket pointers */
inp->sctp_socket = so;
Index: sys/netipsec/xform_ipip.c
===================================================================
--- sys/netipsec/xform_ipip.c
+++ sys/netipsec/xform_ipip.c
@@ -175,7 +175,7 @@
default:
goto nofamily;
}
- ip_fillid(ipo);
+ ip_fillid(ipo, NULL);
otos = 0;
ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
Index: sys/netpfil/pf/if_pfsync.c
===================================================================
--- sys/netpfil/pf/if_pfsync.c
+++ sys/netpfil/pf/if_pfsync.c
@@ -214,6 +214,7 @@
uint32_t sc_bulk_creatorid;
struct callout sc_bulk_tmo;
struct callout sc_bulkfail_tmo;
+ unsigned sc_ip_id; /* IP ID number */
};
#define PFSYNC_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
@@ -298,6 +299,7 @@
return (EINVAL);
sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
+ sc->sc_ip_id = ip_initid();
sc->sc_flags |= PFSYNCF_OK;
for (q = 0; q < PFSYNC_S_COUNT; q++)
@@ -1538,7 +1540,7 @@
offset = sizeof(*ip);
ip->ip_len = htons(m->m_pkthdr.len);
- ip_fillid(ip);
+ ip_fillid(ip, &sc->sc_ip_id);
/* build the pfsync header */
ph = (struct pfsync_header *)(m->m_data + offset);
Index: sys/netpfil/pf/pf_norm.c
===================================================================
--- sys/netpfil/pf/pf_norm.c
+++ sys/netpfil/pf/pf_norm.c
@@ -2273,7 +2273,7 @@
if (flags & PFRULE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
uint16_t ip_id = h->ip_id;
- ip_fillid(h);
+ ip_fillid(h, NULL);
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 26, 9:25 PM (2 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26229101
Default Alt Text
D2211.id4613.diff (14 KB)
Attached To
Mode
D2211: Patch to reduce use of global IP ID value(s)
Attached
Detach File
Event Timeline
Log In to Comment