Skip to content

Commit 22462f5

Browse files
committed
feat(rss): migrate IPv4 RSS port-range selection hooks to FreeBSD 15.0
Restore the FSTACK RSS local-port selection logic in in_pcb_lport_dest and the ff_in_pcbladdr hook in in_pcbconnect (dropped during the 13.0->15.0 upgrade), adapted to 15.0 (const inpcb, merged in_pcbconnect, RT_ALL_FIBS lookups). INPLOOKUP_LPORT_RSS_CHECK is cleared at entry. Adds 0.1 unit tests and fixes a pre-existing test_ff_dpdk_if link gap (no-op ff_tcp_hpts_softclock stub).
1 parent e5389cb commit 22462f5

2 files changed

Lines changed: 356 additions & 5 deletions

File tree

freebsd/netinet/in_pcb.c

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@
107107

108108
#include <security/mac/mac_framework.h>
109109

110+
#ifdef FSTACK
111+
#include "ff_host_interface.h"
112+
#endif
113+
110114
#define INPCBLBGROUP_SIZMIN 8
111115
#define INPCBLBGROUP_SIZMAX 256
112116

@@ -768,6 +772,17 @@ in_pcb_lport_dest(const struct inpcb *inp, struct sockaddr *lsa,
768772
#ifdef INET6
769773
struct in6_addr *laddr6, *faddr6;
770774
#endif
775+
#ifdef FSTACK
776+
u_short rss_first, rss_last, *rss_portrange;
777+
/* 0:not init, 1:init successed, -1:init failed */
778+
static int rss_tbl_init = 0;
779+
int rss_check_flag = lookupflags & INPLOOKUP_LPORT_RSS_CHECK;
780+
int rss_ret, rss_match = 0, dorandom;
781+
struct ifaddr *ifa = NULL;
782+
struct ifnet *ifp = NULL;
783+
784+
lookupflags &= ~INPLOOKUP_LPORT_RSS_CHECK;
785+
#endif
771786

772787
pcbinfo = inp->inp_pcbinfo;
773788

@@ -827,20 +842,85 @@ in_pcb_lport_dest(const struct inpcb *inp, struct sockaddr *lsa,
827842

828843
tmpinp = NULL;
829844

845+
#ifdef FSTACK
846+
dorandom = (V_ipport_randomized && first != last) ? 1 : 0;
847+
848+
if (rss_check_flag) {
849+
if (rss_tbl_init == 0) {
850+
rss_ret = ff_rss_tbl_set_portrange(first, last);
851+
rss_tbl_init = (rss_ret < 0) ? -1 : 1;
852+
}
853+
854+
if (rss_tbl_init == 1) {
855+
rss_ret = ff_rss_tbl_get_portrange(faddr.s_addr,
856+
laddr.s_addr, fport, &rss_first, &rss_last,
857+
&rss_portrange);
858+
if (rss_ret < 0) {
859+
if (rss_ret != -ENOENT)
860+
rss_tbl_init = -1;
861+
} else {
862+
/* rss_portrange[0] holds last-selected idx. */
863+
rss_match = 1;
864+
count = rss_last - rss_first + 1;
865+
if (dorandom)
866+
rss_portrange[0] = rss_first +
867+
(arc4random() % count);
868+
}
869+
}
870+
871+
if (!rss_match) {
872+
/* Locate egress ifp for per-queue ff_rss_check(). */
873+
lsa->sa_len = sizeof(struct sockaddr_in);
874+
ifa = ifa_ifwithnet(lsa, 0, RT_ALL_FIBS);
875+
if (ifa == NULL) {
876+
fsa->sa_len = sizeof(struct sockaddr_in);
877+
ifa = ifa_ifwithnet(fsa, 0, RT_ALL_FIBS);
878+
if (ifa == NULL)
879+
return (EADDRNOTAVAIL);
880+
}
881+
ifp = ifa->ifa_ifp;
882+
}
883+
}
884+
885+
if (!rss_check_flag || !rss_match) {
886+
if (dorandom)
887+
*lastport = first + (arc4random() % (last - first));
888+
count = last - first;
889+
}
890+
#else
830891
if (V_ipport_randomized)
831892
*lastport = first + (arc4random() % (last - first));
832893

833894
count = last - first;
895+
#endif
834896

835897
do {
836898
if (count-- < 0) /* completely used? */
837899
return (EADDRNOTAVAIL);
900+
#ifdef FSTACK
901+
if (rss_check_flag && rss_match) {
902+
rss_portrange[0]++;
903+
if (rss_portrange[0] < rss_first ||
904+
rss_portrange[0] > rss_last)
905+
rss_portrange[0] = rss_first;
906+
*lastport = rss_portrange[rss_portrange[0]];
907+
} else {
908+
++*lastport;
909+
if (*lastport < first || *lastport > last)
910+
*lastport = first;
911+
}
912+
#else
838913
++*lastport;
839914
if (*lastport < first || *lastport > last)
840915
*lastport = first;
916+
#endif
841917
lport = htons(*lastport);
842918

919+
#ifdef FSTACK
920+
if (!rss_check_flag && fsa != NULL) {
921+
#else
843922
if (fsa != NULL) {
923+
#endif
844924
#ifdef INET
845925
if (lsa->sa_family == AF_INET) {
846926
tmpinp = in_pcblookup_hash_locked(pcbinfo,
@@ -874,8 +954,25 @@ in_pcb_lport_dest(const struct inpcb *inp, struct sockaddr *lsa,
874954
else
875955
#endif
876956
#ifdef INET
957+
{
877958
tmpinp = in_pcblookup_local(pcbinfo, laddr,
878959
lport, RT_ALL_FIBS, lookupflags, cred);
960+
#ifdef FSTACK
961+
if (rss_check_flag && !rss_match &&
962+
tmpinp == NULL) {
963+
/* LOOPBACK does not support RSS. */
964+
if (ifp->if_softc == NULL &&
965+
(ifp->if_flags & IFF_LOOPBACK))
966+
break;
967+
if (ff_rss_check(ifp->if_softc,
968+
faddr.s_addr, laddr.s_addr,
969+
fport, lport))
970+
break;
971+
/* not local queue: keep searching */
972+
tmpinp++;
973+
}
974+
#endif
975+
}
879976
#endif
880977
}
881978
} while (tmpinp != NULL);
@@ -1126,9 +1223,16 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
11261223
faddr = sin->sin_addr;
11271224

11281225
if (in_nullhost(inp->inp_laddr)) {
1129-
error = in_pcbladdr(inp, &faddr, &laddr, cred);
1130-
if (error)
1131-
return (error);
1226+
#ifdef FSTACK
1227+
laddr.s_addr = INADDR_ANY;
1228+
ff_in_pcbladdr(AF_INET, &faddr, sin->sin_port, &laddr);
1229+
if (laddr.s_addr == INADDR_ANY)
1230+
#endif
1231+
{
1232+
error = in_pcbladdr(inp, &faddr, &laddr, cred);
1233+
if (error)
1234+
return (error);
1235+
}
11321236
} else
11331237
laddr = inp->inp_laddr;
11341238

@@ -1144,7 +1248,11 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
11441248

11451249
error = in_pcb_lport_dest(inp, (struct sockaddr *)&lsin,
11461250
&lport, (struct sockaddr *)&fsin, sin->sin_port, cred,
1251+
#ifdef FSTACK
1252+
INPLOOKUP_WILDCARD | INPLOOKUP_LPORT_RSS_CHECK);
1253+
#else
11471254
INPLOOKUP_WILDCARD);
1255+
#endif
11481256
if (error)
11491257
return (error);
11501258
} else if (in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr,

0 commit comments

Comments
 (0)