Skip to content

Commit ff9e3c4

Browse files
committed
feat(rss): port IP_BIND_ADDRESS_NO_PORT (bind-then-connect) from upstream cb9b4d4 to FreeBSD 15.0
Defer source port allocation in in_pcbbind/in6_pcbbind when port==0 so connect() can pick an RSS-aware source port via the R-A INPLOOKUP_LPORT_RSS_CHECK path. v6 connect outer condition is relaxed under FSTACK to (in6p_laddr unspec || inp_lport==0) so bind-then-connect actually enters the RSS branch; the inner in6p_laddr overwrite is now guarded by IN6_IS_ADDR_UNSPECIFIED to preserve a user-bound v6 address. All hunks gated by #ifdef/#ifndef FSTACK; FSTACK off retains native FreeBSD 15.0 semantics (REUSEPORT_LB MPASS at L740 unaffected). Baseline 13.0 contains none of these three hunks; this is a fresh addition rather than a missed-port migration.
1 parent 35aa958 commit ff9e3c4

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

freebsd/netinet/in_pcb.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,13 +736,19 @@ in_pcbbind(struct inpcb *inp, struct sockaddr_in *sin, int flags,
736736
&inp->inp_lport, flags, cred);
737737
if (error)
738738
return (error);
739+
#ifdef FSTACK
740+
if (inp->inp_lport != 0) {
741+
#endif
739742
if (__predict_false((error = in_pcbinshash(inp)) != 0)) {
740743
MPASS(inp->inp_socket->so_options & SO_REUSEPORT_LB);
741744
inp->inp_laddr.s_addr = INADDR_ANY;
742745
inp->inp_lport = 0;
743746
inp->inp_flags &= ~INP_BOUNDFIB;
744747
return (error);
745748
}
749+
#ifdef FSTACK
750+
}
751+
#endif
746752
if (anonport)
747753
inp->inp_flags |= INP_ANONPORT;
748754
return (0);
@@ -1272,11 +1278,13 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
12721278
}
12731279
if (*lportp != 0)
12741280
lport = *lportp;
1281+
#ifndef FSTACK
12751282
if (lport == 0) {
12761283
error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
12771284
if (error != 0)
12781285
return (error);
12791286
}
1287+
#endif
12801288
*laddrp = laddr.s_addr;
12811289
*lportp = lport;
12821290
if ((flags & INPBIND_FIB) != 0)

freebsd/netinet6/in6_pcb.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,14 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, int flags,
352352
if ((flags & INPBIND_FIB) != 0)
353353
inp->inp_flags |= INP_BOUNDFIB;
354354
if (lport == 0) {
355+
#ifndef FSTACK
355356
if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0) {
356357
/* Undo an address bind that may have occurred. */
357358
inp->inp_flags &= ~INP_BOUNDFIB;
358359
inp->in6p_laddr = in6addr_any;
359360
return (error);
360361
}
362+
#endif
361363
} else {
362364
inp->inp_lport = lport;
363365
if (in_pcbinshash(inp) != 0) {
@@ -512,7 +514,11 @@ in6_pcbconnect(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred,
512514
&laddr6.sin6_addr : &inp->in6p_laddr, inp->inp_lport, 0,
513515
M_NODOM, RT_ALL_FIBS) != NULL)
514516
return (EADDRINUSE);
517+
#ifdef FSTACK
518+
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) || inp->inp_lport == 0) {
519+
#else
515520
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
521+
#endif
516522
if (inp->inp_lport == 0) {
517523
error = in_pcb_lport_dest(inp,
518524
(struct sockaddr *) &laddr6, &inp->inp_lport,
@@ -525,7 +531,8 @@ in6_pcbconnect(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred,
525531
if (error)
526532
return (error);
527533
}
528-
inp->in6p_laddr = laddr6.sin6_addr;
534+
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
535+
inp->in6p_laddr = laddr6.sin6_addr;
529536
}
530537
inp->in6p_faddr = sin6->sin6_addr;
531538
inp->inp_fport = sin6->sin6_port;

0 commit comments

Comments
 (0)