summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_var.h
diff options
context:
space:
mode:
authorfabient <fabient@FreeBSD.org>2015-03-27 13:26:59 +0000
committerfabient <fabient@FreeBSD.org>2015-03-27 13:26:59 +0000
commitd819d7978548c7aa0dcec14766cbe7700618352c (patch)
treeec33b57957c8f276d75aaacafa4869270836b062 /sys/netinet/ip_var.h
parent176aa763410f2b33c53b6a77eecb21f1871f0e63 (diff)
downloadFreeBSD-src-d819d7978548c7aa0dcec14766cbe7700618352c.zip
FreeBSD-src-d819d7978548c7aa0dcec14766cbe7700618352c.tar.gz
On multi CPU systems, we may emit successive packets with the same id.
Fix the race by using an atomic operation. Differential Revision: https://reviews.freebsd.org/D2141 Obtained from: emeric.poupon@stormshield.eu MFC after: 1 week Sponsored by: Stormshield
Diffstat (limited to 'sys/netinet/ip_var.h')
-rw-r--r--sys/netinet/ip_var.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 9f44101..00d7a97 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -174,7 +174,7 @@ struct inpcb;
struct route;
struct sockopt;
-VNET_DECLARE(u_short, ip_id); /* ip packet ctr, for ids */
+VNET_DECLARE(uint32_t, ip_id); /* ip packet ctr, for ids */
VNET_DECLARE(int, ip_defttl); /* default IP ttl */
VNET_DECLARE(int, ipforwarding); /* ip forwarding */
#ifdef IPSTEALTH
@@ -228,7 +228,7 @@ struct in_ifaddr *
void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
struct mbuf *);
void ip_slowtimo(void);
-u_int16_t ip_randomid(void);
+uint16_t ip_randomid(void);
int rip_ctloutput(struct socket *, struct sockopt *);
void rip_ctlinput(int, struct sockaddr *, void *);
void rip_init(void);
@@ -305,8 +305,18 @@ extern int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *);
VNET_DECLARE(int, ip_do_randomid);
#define V_ip_do_randomid VNET(ip_do_randomid)
-#define ip_newid() ((V_ip_do_randomid != 0) ? ip_randomid() : \
- htons(V_ip_id++))
+static __inline uint16_t
+ip_newid(void)
+{
+ uint16_t res;
+
+ if (V_ip_do_randomid != 0)
+ return (ip_randomid());
+ else {
+ res = atomic_fetchadd_32(&V_ip_id, 1) & 0xFFFF;
+ return (htons(res));
+ }
+}
#endif /* _KERNEL */
OpenPOWER on IntegriCloud