git: 70703aa922b4 - main - netinet: allow per protocol random IP id control, single out IPSEC

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 04 Mar 2025 16:55:13 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=70703aa922b41faedfd72211633884bb580ceeac

commit 70703aa922b41faedfd72211633884bb580ceeac
Author:     acazuc <acazuc@acazuc.fr>
AuthorDate: 2025-03-03 13:21:15 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-03-04 16:45:32 +0000

    netinet: allow per protocol random IP id control, single out IPSEC
    
    A globally enabled random IP id generation maybe useful in most IP
    contexts, but it may be unnecessary in the case of IPsec encapsulated
    packets because IPsec can be configured to use anti-replay windows.
    
    This commit adds a new net.inet.ipsec.random_id sysctl to control whether
    or not IPsec packets should use random IP id generation.
    
    Rest of the protocols/modules are still controlled by the global
    net.inet.ip.random_id, but can be easily augmented with a knob.
    
    Reviewed by:            glebius
    Sponsored by:           Stormshield
    Differential Revision:  https://reviews.freebsd.org/D49164
---
 share/man/man4/ipsec.4                   |  6 +++++-
 sys/netinet/ip_carp.c                    |  4 ++--
 sys/netinet/ip_gre.c                     |  2 +-
 sys/netinet/ip_id.c                      | 22 +++++++++++-----------
 sys/netinet/ip_mroute.c                  |  2 +-
 sys/netinet/ip_output.c                  |  2 +-
 sys/netinet/ip_var.h                     |  4 +++-
 sys/netinet/raw_ip.c                     |  2 +-
 sys/netinet/sctp_output.c                |  4 ++--
 sys/netipsec/ipsec.c                     |  4 ++++
 sys/netipsec/ipsec.h                     |  3 +++
 sys/netipsec/ipsec_output.c              |  2 +-
 sys/netpfil/ipfilter/netinet/fil.c       |  2 +-
 sys/netpfil/ipfilter/netinet/ip_nat.c    |  4 ++--
 sys/netpfil/ipfw/nat64/nat64_translate.c |  4 ++--
 sys/netpfil/pf/if_pfsync.c               |  2 +-
 sys/netpfil/pf/pf.c                      |  4 ++--
 sys/netpfil/pf/pf_norm.c                 |  2 +-
 18 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/share/man/man4/ipsec.4 b/share/man/man4/ipsec.4
index 96a10dfb7700..9fd6207c2f14 100644
--- a/share/man/man4/ipsec.4
+++ b/share/man/man4/ipsec.4
@@ -27,7 +27,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 6, 2017
+.Dd March 4, 2025
 .Dt IPSEC 4
 .Os
 .Sh NAME
@@ -239,6 +239,7 @@ for tweaking the kernel's IPsec behavior:
 .It "net.inet.ipsec.debug	integer	yes"
 .It "net.inet.ipsec.natt_cksum_policy	integer	yes"
 .It "net.inet.ipsec.check_policy_history	integer	yes"
+.It "net.inet.ipsec.random_id		integer	yes"
 .It "net.inet6.ipsec6.ecn	integer	yes"
 .It "net.inet6.ipsec6.debug	integer	yes"
 .El
@@ -298,6 +299,9 @@ have been decrypted and authenticated.
 If this variable is set to a non-zero value, each packet handled by IPsec
 is checked against the history of IPsec security associations.
 The IPsec security protocol, mode, and SA addresses must match.
+.It Li ipsec.random_id
+Enables randomization of encapsulated IPv4 packets ID.
+By default, ID randomization is not enabled.
 .El
 .Pp
 Variables under the
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 6fde7bd70c6b..c01d1bdd8cff 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1256,7 +1256,7 @@ carp_send_ad_locked(struct carp_softc *sc)
 		ip->ip_ttl = CARP_DFLTTL;
 		ip->ip_p = IPPROTO_CARP;
 		ip->ip_sum = 0;
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 
 		ifa = carp_best_ifa(AF_INET, sc->sc_carpdev);
 		if (ifa != NULL) {
@@ -1395,7 +1395,7 @@ vrrp_send_ad_locked(struct carp_softc *sc)
 		ip->ip_ttl = CARP_DFLTTL;
 		ip->ip_p = IPPROTO_CARP;
 		ip->ip_sum = 0;
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 
 		ifa = carp_best_ifa(AF_INET, sc->sc_carpdev);
 		if (ifa != NULL) {
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index c9356edb0608..01a6ef4cd670 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -534,7 +534,7 @@ in_gre_output(struct mbuf *m, int af, int hlen)
 #ifdef INET6
 	case AF_INET6:
 		gi->gi_ip.ip_tos = 0; /* XXX */
-		ip_fillid(&gi->gi_ip);
+		ip_fillid(&gi->gi_ip, V_ip_random_id);
 		break;
 #endif
 	}
diff --git a/sys/netinet/ip_id.c b/sys/netinet/ip_id.c
index 12dd6c8bf972..738b7eceb448 100644
--- a/sys/netinet/ip_id.c
+++ b/sys/netinet/ip_id.c
@@ -97,9 +97,9 @@
  * user wants to, we can turn on random ID generation.
  */
 VNET_DEFINE_STATIC(int, ip_rfc6864) = 1;
-VNET_DEFINE_STATIC(int, ip_do_randomid) = 0;
 #define	V_ip_rfc6864		VNET(ip_rfc6864)
-#define	V_ip_do_randomid	VNET(ip_do_randomid)
+
+VNET_DEFINE(int, ip_random_id) = 0;
 
 /*
  * Random ID state engine.
@@ -126,7 +126,7 @@ VNET_DEFINE_STATIC(struct mtx, ip_id_mtx);
 VNET_DEFINE_STATIC(counter_u64_t, ip_id);
 #define	V_ip_id		VNET(ip_id)
 
-static int	sysctl_ip_randomid(SYSCTL_HANDLER_ARGS);
+static int	sysctl_ip_random_id(SYSCTL_HANDLER_ARGS);
 static int	sysctl_ip_id_change(SYSCTL_HANDLER_ARGS);
 static void	ip_initid(int);
 static uint16_t ip_randomid(void);
@@ -136,7 +136,7 @@ static void	ipid_sysuninit(void);
 SYSCTL_DECL(_net_inet_ip);
 SYSCTL_PROC(_net_inet_ip, OID_AUTO, random_id,
     CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    &VNET_NAME(ip_do_randomid), 0, sysctl_ip_randomid, "IU",
+    &VNET_NAME(ip_random_id), 0, sysctl_ip_random_id, "IU",
     "Assign random ip_id values");
 SYSCTL_INT(_net_inet_ip, OID_AUTO, rfc6864, CTLFLAG_VNET | CTLFLAG_RW,
     &VNET_NAME(ip_rfc6864), 0,
@@ -151,22 +151,22 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, random_id_total, CTLFLAG_RD | CTLFLAG_VNET,
     &VNET_NAME(random_id_total), 0, "Count of IP IDs created");
 
 static int
-sysctl_ip_randomid(SYSCTL_HANDLER_ARGS)
+sysctl_ip_random_id(SYSCTL_HANDLER_ARGS)
 {
 	int error, new;
 
-	new = V_ip_do_randomid;
+	new = V_ip_random_id;
 	error = sysctl_handle_int(oidp, &new, 0, req);
 	if (error || req->newptr == NULL)
 		return (error);
 	if (new != 0 && new != 1)
 		return (EINVAL);
-	if (new == V_ip_do_randomid)
+	if (new == V_ip_random_id)
 		return (0);
-	if (new == 1 && V_ip_do_randomid == 0)
+	if (new == 1 && V_ip_random_id == 0)
 		ip_initid(8192);
 	/* We don't free memory when turning random ID off, due to race. */
-	V_ip_do_randomid = new;
+	V_ip_random_id = new;
 	return (0);
 }
 
@@ -238,7 +238,7 @@ ip_randomid(void)
 }
 
 void
-ip_fillid(struct ip *ip)
+ip_fillid(struct ip *ip, bool do_randomid)
 {
 
 	/*
@@ -249,7 +249,7 @@ ip_fillid(struct ip *ip)
 	 */
 	if (V_ip_rfc6864 && (ip->ip_off & htons(IP_DF)) == htons(IP_DF))
 		ip->ip_id = 0;
-	else if (V_ip_do_randomid)
+	else if (do_randomid)
 		ip->ip_id = ip_randomid();
 	else {
 		counter_u64_add(V_ip_id, 1);
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index e224d2e6daf5..d30bd42ec578 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -2466,7 +2466,7 @@ pim_register_send_rp(struct ip *ip, struct vif *vifp, struct mbuf *mb_copy,
 	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, V_ip_random_id);
 	pimhdr = (struct pim_encap_pimhdr *)((caddr_t)ip_outer
 			+ sizeof(pim_encap_iphdr));
 	*pimhdr = pim_encap_pimhdr;
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 35aaf85d6a4e..9d72300e8b68 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -368,7 +368,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
 	if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = hlen >> 2;
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 	} else {
 		/* Header already set, fetch hlen from there */
 		hlen = ip->ip_hl << 2;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 0f2ed8c43e64..18ca5861a40e 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -204,6 +204,7 @@ extern int	(*legal_vif_num)(int);
 extern u_long	(*ip_mcast_src)(int);
 VNET_DECLARE(int, rsvp_on);
 VNET_DECLARE(int, drop_redirect);
+VNET_DECLARE(int, ip_random_id);
 
 #define	V_ip_id			VNET(ip_id)
 #define	V_ip_defttl		VNET(ip_defttl)
@@ -216,6 +217,7 @@ VNET_DECLARE(int, drop_redirect);
 #define	V_ip_mrouter		VNET(ip_mrouter)
 #define	V_rsvp_on		VNET(rsvp_on)
 #define	V_drop_redirect		VNET(drop_redirect)
+#define	V_ip_random_id		VNET(ip_random_id)
 
 void	inp_freemoptions(struct ip_moptions *);
 int	inp_getmoptions(struct inpcb *, struct sockopt *);
@@ -235,7 +237,7 @@ struct mbuf *
 	ip_reass(struct mbuf *);
 void	ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
 	    struct mbuf *);
-void	ip_fillid(struct ip *);
+void	ip_fillid(struct ip *, bool);
 int	rip_ctloutput(struct socket *, struct sockopt *);
 int	ipip_input(struct mbuf **, int *, int);
 int	rsvp_input(struct mbuf **, int *, int);
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 0d677d954f11..7b6104da5402 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -601,7 +601,7 @@ rip_send(struct socket *so, int pruflags, struct mbuf *m, struct sockaddr *nam,
 		 * but we got this limitation from the beginning of history.
 		 */
 		if (ip->ip_id == 0)
-			ip_fillid(ip);
+			ip_fillid(ip, V_ip_random_id);
 
 		/*
 		 * XXX prevent ip_output from overwriting header fields.
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 02ad901259f4..e4bdb4291972 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -4071,7 +4071,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				ip->ip_off = htons(0);
 			}
 			/* FreeBSD has a function for ip_id's */
-			ip_fillid(ip);
+			ip_fillid(ip, V_ip_random_id);
 
 			ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
 			ip->ip_len = htons(packet_length);
@@ -11197,7 +11197,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
 		ip->ip_hl = (sizeof(struct ip) >> 2);
 		ip->ip_tos = 0;
 		ip->ip_off = htons(IP_DF);
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 		ip->ip_ttl = MODULE_GLOBAL(ip_defttl);
 		if (port) {
 			ip->ip_p = IPPROTO_UDP;
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 8d604a24eeea..6bacc68b7441 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -119,6 +119,7 @@ VNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE;
 VNET_DEFINE(int, ip4_ah_net_deflev) = IPSEC_LEVEL_USE;
 /* ECN ignore(-1)/forbidden(0)/allowed(1) */
 VNET_DEFINE(int, ip4_ipsec_ecn) = 0;
+VNET_DEFINE(int, ip4_ipsec_random_id) = 0;
 
 VNET_DEFINE_STATIC(int, ip4_filtertunnel) = 0;
 #define	V_ip4_filtertunnel VNET(ip4_filtertunnel)
@@ -201,6 +202,9 @@ SYSCTL_INT(_net_inet_ipsec, IPSECCTL_MIN_PMTU, min_pmtu,
 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, ecn,
 	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_ecn), 0,
 	"Explicit Congestion Notification handling.");
+SYSCTL_INT(_net_inet_ipsec, IPSECCTL_RANDOM_ID, random_id,
+	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_random_id), 0,
+	"Assign random ip_id values.");
 SYSCTL_INT(_net_inet_ipsec, OID_AUTO, crypto_support,
 	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(crypto_support), 0,
 	"Crypto driver selection.");
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
index f8c5b10e7bd6..3acb6a4044f1 100644
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -260,6 +260,7 @@ struct ipsecstat {
 #define	IPSECCTL_DEBUG			12
 #define	IPSECCTL_ESP_RANDPAD		13
 #define	IPSECCTL_MIN_PMTU		14
+#define	IPSECCTL_RANDOM_ID		15
 
 #ifdef _KERNEL
 #include <sys/counter.h>
@@ -293,6 +294,7 @@ VNET_DECLARE(int, ip4_ah_net_deflev);
 VNET_DECLARE(int, ip4_ipsec_dfbit);
 VNET_DECLARE(int, ip4_ipsec_min_pmtu);
 VNET_DECLARE(int, ip4_ipsec_ecn);
+VNET_DECLARE(int, ip4_ipsec_random_id);
 VNET_DECLARE(int, crypto_support);
 VNET_DECLARE(int, async_crypto);
 VNET_DECLARE(int, natt_cksum_policy);
@@ -310,6 +312,7 @@ VNET_DECLARE(int, natt_cksum_policy);
 #define	V_ip4_ipsec_dfbit	VNET(ip4_ipsec_dfbit)
 #define	V_ip4_ipsec_min_pmtu	VNET(ip4_ipsec_min_pmtu)
 #define	V_ip4_ipsec_ecn		VNET(ip4_ipsec_ecn)
+#define	V_ip4_ipsec_random_id	VNET(ip4_ipsec_random_id)
 #define	V_crypto_support	VNET(crypto_support)
 #define	V_async_crypto		VNET(async_crypto)
 #define	V_natt_cksum_policy	VNET(natt_cksum_policy)
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 8d8a304e7af4..b394ff81d9c6 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -1200,7 +1200,7 @@ ipsec_encap(struct mbuf **mp, struct secasindex *saidx)
 		ip->ip_src = saidx->src.sin.sin_addr;
 		ip->ip_dst = saidx->dst.sin.sin_addr;
 		ip_ecn_ingress(V_ip4_ipsec_ecn, &ip->ip_tos, &itos);
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip4_ipsec_random_id);
 		break;
 #endif /* INET */
 #ifdef INET6
diff --git a/sys/netpfil/ipfilter/netinet/fil.c b/sys/netpfil/ipfilter/netinet/fil.c
index c1b49196b712..2a75190a3ec7 100644
--- a/sys/netpfil/ipfilter/netinet/fil.c
+++ b/sys/netpfil/ipfilter/netinet/fil.c
@@ -5952,7 +5952,7 @@ ipf_updateipid(fr_info_t *fin)
 		id = (u_short)sum;
 		ip->ip_id = htons(id);
 	} else {
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 		id = ntohs(ip->ip_id);
 		if ((fin->fin_flx & FI_FRAG) != 0)
 			(void) ipf_frag_ipidnew(fin, (u_32_t)id);
diff --git a/sys/netpfil/ipfilter/netinet/ip_nat.c b/sys/netpfil/ipfilter/netinet/ip_nat.c
index b8a0e7d2075b..a13c6129a287 100644
--- a/sys/netpfil/ipfilter/netinet/ip_nat.c
+++ b/sys/netpfil/ipfilter/netinet/ip_nat.c
@@ -5117,7 +5117,7 @@ ipf_nat_out(fr_info_t *fin, nat_t *nat, int natadd, u_32_t nflags)
 		}
 
 		ip = MTOD(m, ip_t *);
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 		s2 = ntohs(ip->ip_id);
 
 		s1 = ip->ip_len;
@@ -5560,7 +5560,7 @@ ipf_nat_in(fr_info_t *fin, nat_t *nat, int natadd, u_32_t nflags)
 		}
 
 		ip = MTOD(m, ip_t *);
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 		sum1 = ntohs(ip->ip_len);
 		ip->ip_len = ntohs(ip->ip_len);
 		ip->ip_len += fin->fin_plen;
diff --git a/sys/netpfil/ipfw/nat64/nat64_translate.c b/sys/netpfil/ipfw/nat64/nat64_translate.c
index 2924a9b2d19a..393780c969fe 100644
--- a/sys/netpfil/ipfw/nat64/nat64_translate.c
+++ b/sys/netpfil/ipfw/nat64/nat64_translate.c
@@ -520,7 +520,7 @@ nat64_init_ip4hdr(const struct ip6_hdr *ip6, const struct ip6_frag *frag,
 		ip->ip_ttl -= IPV6_HLIMDEC;
 	ip->ip_sum = 0;
 	ip->ip_p = (proto == IPPROTO_ICMPV6) ? IPPROTO_ICMP: proto;
-	ip_fillid(ip);
+	ip_fillid(ip, V_ip_random_id);
 	if (frag != NULL) {
 		ip->ip_off = htons(ntohs(frag->ip6f_offlg) >> 3);
 		if (frag->ip6f_offlg & IP6F_MORE_FRAG)
@@ -845,7 +845,7 @@ nat64_icmp_reflect(struct mbuf *m, uint8_t type,
 	oip->ip_len = htons(n->m_pkthdr.len);
 	oip->ip_ttl = V_ip_defttl;
 	oip->ip_p = IPPROTO_ICMP;
-	ip_fillid(oip);
+	ip_fillid(oip, V_ip_random_id);
 	oip->ip_off = htons(IP_DF);
 	oip->ip_src = ip->ip_dst;
 	oip->ip_dst = ip->ip_src;
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 98a2367b79b0..b2aaf3add25c 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -1900,7 +1900,7 @@ pfsync_sendout(int schedswi, int c)
 
 		len -= sizeof(union inet_template) - sizeof(struct ip);
 		ip->ip_len = htons(len);
-		ip_fillid(ip);
+		ip_fillid(ip, V_ip_random_id);
 		break;
 	    }
 #endif
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 349b10c346a7..e0b664772544 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3527,7 +3527,7 @@ pf_translate_af(struct pf_pdesc *pd)
 		ip4->ip_hl = hlen >> 2;
 		ip4->ip_tos = pd->tos;
 		ip4->ip_len = htons(hlen + (pd->tot_len - pd->off));
-		ip_fillid(ip4);
+		ip_fillid(ip4, V_ip_random_id);
 		ip4->ip_ttl = pd->ttl;
 		ip4->ip_p = pd->proto;
 		ip4->ip_src = pd->nsaddr.v4;
@@ -3630,7 +3630,7 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
 		ip4->ip_v = IPVERSION;
 		ip4->ip_hl = sizeof(*ip4) >> 2;
 		ip4->ip_len = htons(sizeof(*ip4) + pd2->tot_len - olen);
-		ip_fillid(ip4);
+		ip_fillid(ip4, V_ip_random_id);
 		ip4->ip_off = htons(IP_DF);
 		ip4->ip_ttl = pd2->ttl;
 		if (pd2->proto == IPPROTO_ICMPV6)
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 98539be8c6ce..fd72fec62a3b 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -2254,7 +2254,7 @@ pf_scrub(struct pf_pdesc *pd)
 	    pd->act.flags & PFSTATE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
 		uint16_t ip_id = h->ip_id;
 
-		ip_fillid(h);
+		ip_fillid(h, V_ip_random_id);
 		h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
 	}
 #endif