Page MenuHomeFreeBSD

D2211.id4613.diff
No OneTemporary

D2211.id4613.diff

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

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)

Event Timeline