diff options
author | fabient <fabient@FreeBSD.org> | 2015-03-27 13:26:59 +0000 |
---|---|---|
committer | fabient <fabient@FreeBSD.org> | 2015-03-27 13:26:59 +0000 |
commit | d819d7978548c7aa0dcec14766cbe7700618352c (patch) | |
tree | ec33b57957c8f276d75aaacafa4869270836b062 /sys/netinet/ip_var.h | |
parent | 176aa763410f2b33c53b6a77eecb21f1871f0e63 (diff) | |
download | FreeBSD-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.h | 18 |
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 */ |