Skip to content

Commit e54aa43

Browse files
committed
Add the feature fo ff_rss_check table to improve the performance of ff_rss_check().
More info see "rss_check" section in config.ini.
1 parent c6c73eb commit e54aa43

File tree

10 files changed

+547
-49
lines changed

10 files changed

+547
-49
lines changed

config.ini

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,29 @@ gateway=192.168.1.1
207207
#up_delay=10
208208
#down_delay=50
209209

210+
# ff_rss_check table config section
211+
# To enable or disable static ff_rss_check table.
212+
# If enable it, F-Stack will init the table while the APP is starting.
213+
# Then the APP connect to a sever as client, it will try select a local port from the inited table first.
214+
#
215+
# This feature will greatly improve the performance of selecting local port
216+
# when the F-Stack application actively access remote services as a client and not set keep-alive.
217+
# If the local port is idle, it only needs to be selected once,
218+
# and no longer needs to be selected multiple times (the average number of times is about the total number of processes).
219+
# And the performance of selecting available local ports at a time is also improved compared to ff_rss_check().
220+
# If get rss local port failed, it will be fallback to ff_rss_check().
221+
#
222+
# enable : 0 means disable, 1 means enable. Default 0.
223+
# rss_tbl : Set 4-tuple for ff_rss_check table, Required argumnet.
224+
# <porit_id> <daddr(local addr)> <saddr(remote addr)> <sport(remote port)>
225+
# Separated by space in one 4-tuple, and separated by semicolon between multi 4-tuples.
226+
# The max supported num of 2-tuple with saddr and sport is 4 * 4 = 16.
227+
# The max supported num of daddr with one same saddr and sport is 4.
228+
# So the max combination num of 4-tuple is 16 * 4 = 64, other config will be ignored.
229+
[rss_check]
230+
enable=0
231+
rss_tbl=0 192.168.1.1 192.168.2.1 80;0 192.168.1.1 192.168.2.1 443
232+
210233
# Kni config: if enabled and method=reject,
211234
# all packets that do not belong to the following tcp_port and udp_port
212235
# will transmit to kernel; if method=accept, all packets that belong to

freebsd/netinet/in_pcb.c

Lines changed: 95 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,17 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp,
700700
#ifdef INET6
701701
struct in6_addr *laddr6 = NULL, *faddr6 = NULL;
702702
#endif
703+
#ifdef FSTACK
704+
u_short rss_first, rss_last, *rss_portrange;
705+
/* 0:not init, 1:init successed, -1:init failed */
706+
static int rss_tbl_init = 0;
707+
int rss_check_flag = lookupflags & INPLOOKUP_LPORT_RSS_CHECK;
708+
int rss_ret, rss_port_idx, rss_match = 0;
709+
struct ifaddr *ifa;
710+
struct ifnet *ifp;
711+
712+
lookupflags = lookupflags & (~INPLOOKUP_LPORT_RSS_CHECK);
713+
#endif
703714

704715
pcbinfo = inp->inp_pcbinfo;
705716

@@ -780,20 +791,81 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp,
780791
tmpinp = NULL;
781792
lport = *lportp;
782793

794+
#ifdef FSTACK
795+
if (rss_check_flag) {
796+
if (rss_tbl_init == 0) {
797+
rss_ret = ff_rss_tbl_set_portrange(first, last);
798+
if (rss_ret < 0)
799+
rss_tbl_init = -1;
800+
else
801+
rss_tbl_init = 1;
802+
}
803+
804+
if (rss_tbl_init == 1) {
805+
rss_ret = ff_rss_tbl_get_portrange(faddr.s_addr, laddr.s_addr, fport,
806+
&rss_first, &rss_last, &rss_portrange);
807+
if (rss_ret < 0) {
808+
if (rss_ret != -ENOENT)
809+
rss_tbl_init = -1;
810+
} else {
811+
/* [0] store last port idx */
812+
rss_match = 1;
813+
count = rss_last - rss_first + 1;
814+
if (dorandom)
815+
rss_portrange[0] = rss_first + (arc4random() % (count));
816+
}
817+
}
818+
819+
if (!rss_match) {
820+
lsa->sa_len = sizeof(struct sockaddr_in);
821+
ifa = ifa_ifwithnet(lsa, 0, RT_ALL_FIBS);
822+
if (ifa == NULL) {
823+
fsa->sa_len = sizeof(struct sockaddr_in);
824+
ifa = ifa_ifwithnet(fsa, 0, RT_ALL_FIBS);
825+
if ( ifa == NULL )
826+
return (EADDRNOTAVAIL);
827+
}
828+
ifp = ifa->ifa_ifp;
829+
}
830+
}
831+
832+
if (!rss_check_flag || !rss_match) {
833+
#endif
783834
if (dorandom)
784835
*lastport = first + (arc4random() % (last - first));
785836

786837
count = last - first;
838+
#ifdef FSTACK
839+
}
840+
#endif
787841

788842
do {
789843
if (count-- < 0) /* completely used? */
790844
return (EADDRNOTAVAIL);
845+
#ifdef FSTACK
846+
if (rss_check_flag && rss_match) {
847+
rss_portrange[0]++;
848+
if (rss_portrange[0] < rss_first || rss_portrange[0] > rss_last)
849+
rss_portrange[0] = rss_first;
850+
*lastport = rss_portrange[rss_portrange[0]];
851+
}
852+
853+
if (!rss_check_flag || !rss_match) {
854+
#endif
791855
++*lastport;
792856
if (*lastport < first || *lastport > last)
793857
*lastport = first;
858+
#ifdef FSTACK
859+
}
860+
#endif
794861
lport = htons(*lastport);
795862

796-
if (fsa != NULL) {
863+
#ifdef FSTACK
864+
if (!rss_check_flag && fsa != NULL)
865+
#else
866+
if (fsa != NULL)
867+
#endif
868+
{
797869
#ifdef INET
798870
if (lsa->sa_family == AF_INET) {
799871
tmpinp = in_pcblookup_hash_locked(pcbinfo,
@@ -818,8 +890,26 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, u_short *lportp,
818890
else
819891
#endif
820892
#ifdef INET
893+
{
821894
tmpinp = in_pcblookup_local(pcbinfo, laddr,
822895
lport, lookupflags, cred);
896+
#ifdef FSTACK
897+
if (rss_check_flag && !rss_match && tmpinp == NULL) {
898+
int rss;
899+
/* Note:
900+
* LOOPBACK not support rss.
901+
*/
902+
if ((ifp->if_softc == NULL) && (ifp->if_flags & IFF_LOOPBACK))
903+
break;
904+
rss = ff_rss_check(ifp->if_softc, faddr.s_addr, laddr.s_addr,
905+
fport, lport);
906+
if (rss)
907+
break;
908+
else
909+
tmpinp++; /* Set not NULL to find another lport */
910+
}
911+
#endif
912+
}
823913
#endif
824914
}
825915
} while (tmpinp != NULL);
@@ -1483,9 +1573,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
14831573
return (EADDRINUSE);
14841574
}
14851575
} else {
1486-
#ifndef FSTACK
14871576
struct sockaddr_in lsin, fsin;
1488-
14891577
bzero(&lsin, sizeof(lsin));
14901578
bzero(&fsin, sizeof(fsin));
14911579
lsin.sin_family = AF_INET;
@@ -1494,52 +1582,13 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
14941582
fsin.sin_addr = faddr;
14951583
error = in_pcb_lport_dest(inp, (struct sockaddr *) &lsin,
14961584
&lport, (struct sockaddr *)& fsin, fport, cred,
1585+
#ifndef FSTACK
14971586
INPLOOKUP_WILDCARD);
1498-
if (error)
1499-
return (error);
15001587
#else
1501-
struct ifaddr *ifa;
1502-
struct ifnet *ifp;
1503-
struct sockaddr_in ifp_sin;
1504-
unsigned loop_count = 0;
1505-
bzero(&ifp_sin, sizeof(ifp_sin));
1506-
ifp_sin.sin_addr.s_addr = laddr.s_addr;
1507-
ifp_sin.sin_family = AF_INET;
1508-
ifp_sin.sin_len = sizeof(ifp_sin);
1509-
ifa = ifa_ifwithnet((struct sockaddr *)&ifp_sin, 0, RT_ALL_FIBS);
1510-
if (ifa == NULL) {
1511-
ifp_sin.sin_addr.s_addr = faddr.s_addr;
1512-
ifa = ifa_ifwithnet((struct sockaddr *)&ifp_sin, 0, RT_ALL_FIBS);
1513-
if ( ifa == NULL )
1514-
return (EADDRNOTAVAIL);
1515-
}
1516-
ifp = ifa->ifa_ifp;
1517-
while (lport == 0) {
1518-
int rss;
1519-
error = in_pcb_lport(inp, &laddr, &lport, cred, INPLOOKUP_WILDCARD);
1520-
if (error)
1521-
return (error);
1522-
/* Note:
1523-
* LOOPBACK not support rss.
1524-
*/
1525-
if ((ifp->if_softc == NULL) && (ifp->if_flags & IFF_LOOPBACK))
1526-
break;
1527-
rss = ff_rss_check(ifp->if_softc, faddr.s_addr, laddr.s_addr,
1528-
fport, lport);
1529-
if (rss) {
1530-
break;
1531-
}
1532-
lport = 0;
1533-
/* Note:
1534-
* if all ports are completely used, just return.
1535-
* this ugly code is not a correct way, it just lets loop quit.
1536-
* we will fix it as soon as possible.
1537-
*/
1538-
if (++loop_count >= 65535) {
1539-
return (EADDRNOTAVAIL);
1540-
}
1541-
}
1588+
INPLOOKUP_WILDCARD | INPLOOKUP_LPORT_RSS_CHECK);
15421589
#endif
1590+
if (error)
1591+
return (error);
15431592
}
15441593
*laddrp = laddr.s_addr;
15451594
*lportp = lport;

freebsd/netinet/in_pcb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,9 @@ int inp_so_options(const struct inpcb *inp);
761761
#define INPLOOKUP_WILDCARD 0x00000001 /* Allow wildcard sockets. */
762762
#define INPLOOKUP_RLOCKPCB 0x00000002 /* Return inpcb read-locked. */
763763
#define INPLOOKUP_WLOCKPCB 0x00000004 /* Return inpcb write-locked. */
764+
#ifdef FSTACK
765+
#define INPLOOKUP_LPORT_RSS_CHECK 0x80000000 /* F-Stack lport RSS check */
766+
#endif
764767

765768
#define INPLOOKUP_MASK (INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB | \
766769
INPLOOKUP_WLOCKPCB)

lib/ff_api.symlist

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ ff_swi_net_excute
6868
ff_adapt_user_thread_add
6969
ff_adapt_user_thread_exit
7070
ff_switch_curthread
71-
ff_restore_curthread
71+
ff_restore_curthread
72+
ff_rss_tbl_init
73+
ff_veth_get_softc
74+
ff_veth_free_softc

lib/ff_config.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <stdint.h>
3131
#include <getopt.h>
3232
#include <ctype.h>
33+
#include <arpa/inet.h>
3334
#include <rte_config.h>
3435
#include <rte_string_fns.h>
3536

@@ -515,7 +516,7 @@ ipfw_pr_cfg_handler(struct ff_port_cfg *cur_port_cfg, struct ff_vlan_cfg *cur_vl
515516
vip_addr_str);
516517
free(vipfw_pr_cfg_p);
517518
return 1;
518-
};
519+
}
519520

520521
vipfw_pr_cfg_p[i].addr = vip_addr_mask_array[0];
521522
vipfw_pr_cfg_p[i].netmask = vip_addr_mask_array[1];
@@ -855,6 +856,81 @@ bond_cfg_handler(struct ff_config *cfg, const char *section,
855856
return 1;
856857
}
857858

859+
static int
860+
rss_tbl_cfg_handler(struct ff_config *cfg, struct ff_rss_check_cfg *cur)
861+
{
862+
//vip cfg
863+
int ret, nb_rss_tbl, i, j, k;
864+
char *rss_tbl_array[FF_RSS_TBL_MAX_ENTRIES], *rss_tbl_4tuble_array[4], *rss_tbl_str;
865+
struct ff_rss_tbl_cfg *rss_tbl_cfg_p;
866+
867+
rss_tbl_str = cur->rss_tbl_str;
868+
869+
ret = rte_strsplit(rss_tbl_str, strlen(rss_tbl_str), &rss_tbl_array[0], FF_RSS_TBL_MAX_ENTRIES, ';');
870+
if (ret <= 0) {
871+
fprintf(stdout, "rss_tbl_cfg_handler nb_rss_tbl is 0, not set rss_tbl or set invalid rss_tbl %s\n",
872+
rss_tbl_str);
873+
return 1;
874+
}
875+
876+
nb_rss_tbl = ret;
877+
878+
rss_tbl_cfg_p = &cur->rss_tbl_cfgs[0];
879+
880+
for (i = 0; i < nb_rss_tbl; i++) {
881+
rss_tbl_str = rss_tbl_array[i];
882+
/* port_id, daddr(local), saddr(remote), sport */
883+
ret = rte_strsplit(rss_tbl_str, strlen(rss_tbl_str), &rss_tbl_4tuble_array[0], 4, ' ');
884+
if (ret != 4) {
885+
fprintf(stdout, "rss_tbl_cfg_handler daddr/saddr/sport format error %s\n",
886+
rss_tbl_str);
887+
return 1;
888+
}
889+
890+
/* Note: daddr must be include by port_id's addr or vip_addr, but here not check it now */
891+
rss_tbl_cfg_p[i].port_id = atoi(rss_tbl_4tuble_array[0]);
892+
inet_pton(AF_INET, rss_tbl_4tuble_array[1], (void *)&(rss_tbl_cfg_p[i].daddr));
893+
inet_pton(AF_INET, rss_tbl_4tuble_array[2], (void *)&(rss_tbl_cfg_p[i].saddr));
894+
rss_tbl_cfg_p[i].sport = htons(atoi(rss_tbl_4tuble_array[3]));
895+
}
896+
897+
cur->nb_rss_tbl = nb_rss_tbl;
898+
899+
return 1;
900+
}
901+
902+
static int
903+
rss_check_cfg_handler(struct ff_config *cfg, const char *section,
904+
const char *name, const char *value)
905+
{
906+
if (cfg->dpdk.port_cfgs == NULL && cfg->dpdk.vlan_cfgs == NULL) {
907+
fprintf(stderr, "rss_check_cfg_handler: must config dpdk.port or dpdk.vlan first\n");
908+
return 0;
909+
}
910+
911+
if (cfg->dpdk.rss_check_cfgs == NULL) {
912+
struct ff_rss_check_cfg *rcc = calloc(1, sizeof(struct ff_rss_check_cfg));
913+
if (rcc == NULL) {
914+
fprintf(stderr, "rss_check_cfg_handler malloc failed\n");
915+
return 0;
916+
}
917+
cfg->dpdk.rss_check_cfgs = rcc;
918+
}
919+
920+
struct ff_rss_check_cfg *cur = cfg->dpdk.rss_check_cfgs;
921+
922+
if (strcmp(name, "enable") == 0) {
923+
cur->enable = atoi(value);
924+
} else if (strcmp(name, "rss_tbl") == 0) {
925+
cur->rss_tbl_str = strdup(value);
926+
if (cur->rss_tbl_str) {
927+
return rss_tbl_cfg_handler(cfg, cur);
928+
}
929+
}
930+
931+
return 1;
932+
}
933+
858934
static int
859935
ini_parse_handler(void* user, const char* section, const char* name,
860936
const char* value)
@@ -955,6 +1031,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
9551031
} else if (strcmp(name, "savepath") == 0) {
9561032
pconfig->pcap.save_path = strdup(value);
9571033
}
1034+
} else if (strcmp(section, "rss_check") == 0) {
1035+
return rss_check_cfg_handler(pconfig, section, name, value);
9581036
}
9591037

9601038
return 1;

0 commit comments

Comments
 (0)