commit
ccf8955843
|
@ -27,3 +27,4 @@ app/nginx-1.16.0/objs/
|
||||||
app/nginx-1.16.0/Makefile
|
app/nginx-1.16.0/Makefile
|
||||||
dpdk/.ci/
|
dpdk/.ci/
|
||||||
dpdk/.travis.yml
|
dpdk/.travis.yml
|
||||||
|
.vscode/
|
||||||
|
|
|
@ -2,6 +2,42 @@
|
||||||
|
|
||||||
F-Stack is an open source network framework based on DPDK.
|
F-Stack is an open source network framework based on DPDK.
|
||||||
|
|
||||||
|
2019.11 F-Stack v1.20
|
||||||
|
|
||||||
|
1. F-Stack lib:
|
||||||
|
|
||||||
|
- Fix some bugs. Corresponding upstream changeset from Freebsd releng-11.0/release-11.1/release-11.2/release-11.3/release-12
|
||||||
|
- Fix bug of bind and connect. @jin.hao
|
||||||
|
- Fix F-stack compile error in Red Hat 8.0 with gcc 8.2.1.
|
||||||
|
- Add IPv6 supported.
|
||||||
|
- Add `make install`, and you can not must set `FF_DPDK` and `FF_PATH`.
|
||||||
|
- Add `FF_USE_PAGE_ARRAY` compile switch in `Makefile`, turn on it will not use mcopy when transmit packetes from bsd to dpdk. @jin.hao
|
||||||
|
- Add vlan supported. @dragonorloong
|
||||||
|
- Add bonding suopported. *Note: some bond driver can not work with multi processes.*
|
||||||
|
- Add `pkt_tx_delay` parameter in `config.ini`.
|
||||||
|
- Add `tx_csum_offoad_skip` parameter in `config.ini`. @JayathS
|
||||||
|
|
||||||
|
2. Nginx:
|
||||||
|
|
||||||
|
- Upgrade to 1.16.1.
|
||||||
|
|
||||||
|
3. Redis:
|
||||||
|
|
||||||
|
- Upgrade to 5.0.5
|
||||||
|
|
||||||
|
4. Tools:
|
||||||
|
|
||||||
|
- Fix the crash bug while excute `ff_netstat -n`.
|
||||||
|
- IPv6 supported.
|
||||||
|
- Add `make install`, and you can use `ff_<tool_name>` to run F-Stack tools.
|
||||||
|
- `ff_traffic` support `-P <max process id>` to show traffic info of all processes.
|
||||||
|
- `ff_top` support `-P <max process id>` to show cpu usage of all processes.
|
||||||
|
- All tools can work in one time.
|
||||||
|
|
||||||
|
5. DPDK:
|
||||||
|
|
||||||
|
- Upgrade to 18.11.5 LTS.
|
||||||
|
|
||||||
2019.11 F-Stack v1.13
|
2019.11 F-Stack v1.13
|
||||||
|
|
||||||
1. F-Stack lib:
|
1. F-Stack lib:
|
||||||
|
|
|
@ -589,6 +589,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
|
||||||
pconfig->dpdk.pkt_tx_delay = atoi(value);
|
pconfig->dpdk.pkt_tx_delay = atoi(value);
|
||||||
} else if (MATCH("kni", "enable")) {
|
} else if (MATCH("kni", "enable")) {
|
||||||
pconfig->kni.enable= atoi(value);
|
pconfig->kni.enable= atoi(value);
|
||||||
|
} else if (MATCH("kni", "kni_action")) {
|
||||||
|
pconfig->kni.kni_action= strdup(value);
|
||||||
} else if (MATCH("kni", "method")) {
|
} else if (MATCH("kni", "method")) {
|
||||||
pconfig->kni.method= strdup(value);
|
pconfig->kni.method= strdup(value);
|
||||||
} else if (MATCH("kni", "tcp_port")) {
|
} else if (MATCH("kni", "tcp_port")) {
|
||||||
|
@ -814,11 +816,21 @@ ff_check_config(struct ff_config *cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cfg->pcap.save_len < PCAP_SAVE_MINLEN )
|
if(cfg->kni.kni_action) {
|
||||||
|
if (strcasecmp(cfg->kni.kni_action,"alltokni") &&
|
||||||
|
strcasecmp(cfg->kni.kni_action,"alltoff") &&
|
||||||
|
strcasecmp(cfg->kni.kni_action,"default")){
|
||||||
|
fprintf(stderr, "conf kni.kni_action[alltokni|alltoff|default] is error(%s)\n",
|
||||||
|
cfg->kni.kni_action);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->pcap.save_len < PCAP_SAVE_MINLEN)
|
||||||
cfg->pcap.save_len = PCAP_SAVE_MINLEN;
|
cfg->pcap.save_len = PCAP_SAVE_MINLEN;
|
||||||
if (cfg->pcap.snap_len < PCAP_SNAP_MINLEN)
|
if (cfg->pcap.snap_len < PCAP_SNAP_MINLEN)
|
||||||
cfg->pcap.snap_len = PCAP_SNAP_MINLEN;
|
cfg->pcap.snap_len = PCAP_SNAP_MINLEN;
|
||||||
if ( cfg->pcap.save_path==NULL || strlen(cfg->pcap.save_path) ==0)
|
if (cfg->pcap.save_path==NULL || strlen(cfg->pcap.save_path) ==0)
|
||||||
cfg->pcap.save_path = strdup(".");
|
cfg->pcap.save_path = strdup(".");
|
||||||
|
|
||||||
#define CHECK_VALID(n) \
|
#define CHECK_VALID(n) \
|
||||||
|
|
|
@ -149,6 +149,7 @@ struct ff_config {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int enable;
|
int enable;
|
||||||
|
char *kni_action;
|
||||||
char *method;
|
char *method;
|
||||||
char *tcp_port;
|
char *tcp_port;
|
||||||
char *udp_port;
|
char *udp_port;
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
|
|
||||||
int enable_kni;
|
int enable_kni;
|
||||||
static int kni_accept;
|
static int kni_accept;
|
||||||
|
static int knictl_action = FF_KNICTL_ACTION_DEFAULT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int numa_on;
|
static int numa_on;
|
||||||
|
@ -480,6 +481,21 @@ init_msg_ring(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FF_KNI
|
#ifdef FF_KNI
|
||||||
|
|
||||||
|
static enum FF_KNICTL_CMD get_kni_action(const char *c){
|
||||||
|
if (!c)
|
||||||
|
return FF_KNICTL_ACTION_DEFAULT;
|
||||||
|
if (0 == strcasecmp(c, "alltokni")){
|
||||||
|
return FF_KNICTL_ACTION_ALL_TO_KNI;
|
||||||
|
} else if (0 == strcasecmp(c, "alltoff")){
|
||||||
|
return FF_KNICTL_ACTION_ALL_TO_FF;
|
||||||
|
} else if (0 == strcasecmp(c, "default")){
|
||||||
|
return FF_KNICTL_ACTION_DEFAULT;
|
||||||
|
} else {
|
||||||
|
return FF_KNICTL_ACTION_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_kni(void)
|
init_kni(void)
|
||||||
{
|
{
|
||||||
|
@ -488,6 +504,8 @@ init_kni(void)
|
||||||
if(strcasecmp(ff_global_cfg.kni.method, "accept") == 0)
|
if(strcasecmp(ff_global_cfg.kni.method, "accept") == 0)
|
||||||
kni_accept = 1;
|
kni_accept = 1;
|
||||||
|
|
||||||
|
knictl_action = get_kni_action(ff_global_cfg.kni.kni_action);
|
||||||
|
|
||||||
ff_kni_init(nb_ports, ff_global_cfg.kni.tcp_port,
|
ff_kni_init(nb_ports, ff_global_cfg.kni.tcp_port,
|
||||||
ff_global_cfg.kni.udp_port);
|
ff_global_cfg.kni.udp_port);
|
||||||
|
|
||||||
|
@ -1108,10 +1126,22 @@ process_packets(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
|
||||||
#endif
|
#endif
|
||||||
ff_veth_input(ctx, rtem);
|
ff_veth_input(ctx, rtem);
|
||||||
#ifdef FF_KNI
|
#ifdef FF_KNI
|
||||||
} else if (enable_kni &&
|
} else if (enable_kni) {
|
||||||
|
if (knictl_action == FF_KNICTL_ACTION_ALL_TO_KNI){
|
||||||
|
ff_kni_enqueue(port_id, rtem);
|
||||||
|
} else if (knictl_action == FF_KNICTL_ACTION_ALL_TO_FF){
|
||||||
|
ff_veth_input(ctx, rtem);
|
||||||
|
} else if (knictl_action == FF_KNICTL_ACTION_DEFAULT){
|
||||||
|
if (enable_kni &&
|
||||||
((filter == FILTER_KNI && kni_accept) ||
|
((filter == FILTER_KNI && kni_accept) ||
|
||||||
(filter == FILTER_UNKNOWN && !kni_accept)) ) {
|
(filter == FILTER_UNKNOWN && !kni_accept)) ) {
|
||||||
ff_kni_enqueue(port_id, rtem);
|
ff_kni_enqueue(port_id, rtem);
|
||||||
|
} else {
|
||||||
|
ff_veth_input(ctx, rtem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ff_veth_input(ctx, rtem);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ff_veth_input(ctx, rtem);
|
ff_veth_input(ctx, rtem);
|
||||||
|
@ -1256,6 +1286,26 @@ handle_traffic_msg(struct ff_msg *msg)
|
||||||
msg->result = 0;
|
msg->result = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FF_KNI
|
||||||
|
static inline void
|
||||||
|
handle_knictl_msg(struct ff_msg *msg)
|
||||||
|
{
|
||||||
|
if (msg->knictl.kni_cmd == FF_KNICTL_CMD_SET){
|
||||||
|
switch (msg->knictl.kni_action){
|
||||||
|
case FF_KNICTL_ACTION_ALL_TO_FF: knictl_action = FF_KNICTL_ACTION_ALL_TO_FF; msg->result = 0; printf("new kni action: alltoff\n"); break;
|
||||||
|
case FF_KNICTL_ACTION_ALL_TO_KNI: knictl_action = FF_KNICTL_ACTION_ALL_TO_KNI; msg->result = 0; printf("new kni action: alltokni\n"); break;
|
||||||
|
case FF_KNICTL_ACTION_DEFAULT: knictl_action = FF_KNICTL_ACTION_DEFAULT; msg->result = 0; printf("new kni action: default\n"); break;
|
||||||
|
default: msg->result = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (msg->knictl.kni_cmd == FF_KNICTL_CMD_GET){
|
||||||
|
msg->knictl.kni_action = knictl_action;
|
||||||
|
} else {
|
||||||
|
msg->result = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
handle_default_msg(struct ff_msg *msg)
|
handle_default_msg(struct ff_msg *msg)
|
||||||
{
|
{
|
||||||
|
@ -1294,6 +1344,11 @@ handle_msg(struct ff_msg *msg, uint16_t proc_id)
|
||||||
case FF_TRAFFIC:
|
case FF_TRAFFIC:
|
||||||
handle_traffic_msg(msg);
|
handle_traffic_msg(msg);
|
||||||
break;
|
break;
|
||||||
|
#ifdef FF_KNI
|
||||||
|
case FF_KNICTL:
|
||||||
|
handle_knictl_msg(msg);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
handle_default_msg(msg);
|
handle_default_msg(msg);
|
||||||
break;
|
break;
|
||||||
|
|
21
lib/ff_msg.h
21
lib/ff_msg.h
|
@ -44,6 +44,7 @@ enum FF_MSG_TYPE {
|
||||||
FF_NGCTL,
|
FF_NGCTL,
|
||||||
FF_IPFW_CTL,
|
FF_IPFW_CTL,
|
||||||
FF_TRAFFIC,
|
FF_TRAFFIC,
|
||||||
|
FF_KNICTL,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* to add other msg type before FF_MSG_NUM
|
* to add other msg type before FF_MSG_NUM
|
||||||
|
@ -106,6 +107,25 @@ struct ff_traffic_args {
|
||||||
uint64_t tx_bytes;
|
uint64_t tx_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FF_KNICTL_CMD {
|
||||||
|
FF_KNICTL_CMD_GET,
|
||||||
|
FF_KNICTL_CMD_SET,
|
||||||
|
FF_KNICTL_CMD_UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FF_KNICTL_ACTION {
|
||||||
|
FF_KNICTL_ACTION_DEFAULT,
|
||||||
|
FF_KNICTL_ACTION_ALL_TO_KNI,
|
||||||
|
FF_KNICTL_ACTION_ALL_TO_FF,
|
||||||
|
FF_KNICTL_ACTION_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ff_knictl_args {
|
||||||
|
int kni_cmd;
|
||||||
|
int kni_action;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define MAX_MSG_BUF_SIZE 10240
|
#define MAX_MSG_BUF_SIZE 10240
|
||||||
|
|
||||||
/* structure of ipc msg */
|
/* structure of ipc msg */
|
||||||
|
@ -126,6 +146,7 @@ struct ff_msg {
|
||||||
struct ff_ngctl_args ngctl;
|
struct ff_ngctl_args ngctl;
|
||||||
struct ff_ipfw_args ipfw;
|
struct ff_ipfw_args ipfw;
|
||||||
struct ff_traffic_args traffic;
|
struct ff_traffic_args traffic;
|
||||||
|
struct ff_knictl_args knictl;
|
||||||
};
|
};
|
||||||
} __attribute__((packed)) __rte_cache_aligned;
|
} __attribute__((packed)) __rte_cache_aligned;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl ipfw arp traffic
|
SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl ipfw arp traffic knictl
|
||||||
PREFIX_BIN=/usr/local/bin
|
PREFIX_BIN=/usr/local/bin
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
@ -20,6 +20,7 @@ install:
|
||||||
ln -sf ${PREFIX_BIN}/f-stack/sysctl ${PREFIX_BIN}/ff_sysctl
|
ln -sf ${PREFIX_BIN}/f-stack/sysctl ${PREFIX_BIN}/ff_sysctl
|
||||||
ln -sf ${PREFIX_BIN}/f-stack/top ${PREFIX_BIN}/ff_top
|
ln -sf ${PREFIX_BIN}/f-stack/top ${PREFIX_BIN}/ff_top
|
||||||
ln -sf ${PREFIX_BIN}/f-stack/traffic ${PREFIX_BIN}/ff_traffic
|
ln -sf ${PREFIX_BIN}/f-stack/traffic ${PREFIX_BIN}/ff_traffic
|
||||||
|
ln -sf ${PREFIX_BIN}/f-stack/knictl ${PREFIX_BIN}/knictl
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -rf ${PREFIX_BIN}/f-stack
|
rm -rf ${PREFIX_BIN}/f-stack
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
|
||||||
|
TOPDIR?=${CURDIR}/../..
|
||||||
|
|
||||||
|
PROG=knictl
|
||||||
|
|
||||||
|
include ${TOPDIR}/tools/prog.mk
|
|
@ -0,0 +1,149 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "ff_ipc.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf(" knictl [-p <f-stack proc_id>] [-P <max proc_id>] "
|
||||||
|
"[-a alltokni/alltoff/default][-n]\n use `-a` to set kni action\n use `-n` to show \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FF_KNICTL_CMD get_action(const char *c){
|
||||||
|
if (!c)
|
||||||
|
return FF_KNICTL_ACTION_MAX;
|
||||||
|
if (0 == strcasecmp(c, "alltokni")){
|
||||||
|
return FF_KNICTL_ACTION_ALL_TO_KNI;
|
||||||
|
} else if (0 == strcasecmp(c, "alltoff")){
|
||||||
|
return FF_KNICTL_ACTION_ALL_TO_FF;
|
||||||
|
} else if (0 == strcasecmp(c, "default")){
|
||||||
|
return FF_KNICTL_ACTION_DEFAULT;
|
||||||
|
} else {
|
||||||
|
return FF_KNICTL_ACTION_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * get_action_str(enum FF_KNICTL_CMD cmd){
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case FF_KNICTL_ACTION_ALL_TO_KNI:
|
||||||
|
return "alltokni";
|
||||||
|
break;
|
||||||
|
case FF_KNICTL_ACTION_ALL_TO_FF:
|
||||||
|
return "alltoff";
|
||||||
|
break;
|
||||||
|
case FF_KNICTL_ACTION_DEFAULT:
|
||||||
|
return "default";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int knictl_status(struct ff_knictl_args *knictl){
|
||||||
|
int ret;
|
||||||
|
struct ff_msg *msg, *retmsg = NULL;
|
||||||
|
|
||||||
|
msg = ff_ipc_msg_alloc();
|
||||||
|
if (msg == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->msg_type = FF_KNICTL;
|
||||||
|
msg->knictl = *knictl;
|
||||||
|
ret = ff_ipc_send(msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = EPIPE;
|
||||||
|
ff_ipc_msg_free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (retmsg != NULL) {
|
||||||
|
ff_ipc_msg_free(retmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ff_ipc_recv(&retmsg, msg->msg_type);
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = EPIPE;
|
||||||
|
ff_ipc_msg_free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (msg != retmsg);
|
||||||
|
|
||||||
|
*knictl = retmsg->knictl;
|
||||||
|
|
||||||
|
ff_ipc_msg_free(msg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ch, has_action = 0, i;
|
||||||
|
enum FF_KNICTL_CMD cmd;
|
||||||
|
struct ff_knictl_args knictl = {.kni_cmd = FF_KNICTL_CMD_GET};
|
||||||
|
struct ff_knictl_args pknictl[RTE_MAX_LCORE];
|
||||||
|
int proc_id = 0, max_proc_id = -1;
|
||||||
|
|
||||||
|
ff_ipc_init();
|
||||||
|
while ((ch = getopt(argc, argv, "hp:P:a:n")) != -1) {
|
||||||
|
switch(ch) {
|
||||||
|
case 'p':
|
||||||
|
proc_id = atoi(optarg);
|
||||||
|
ff_set_proc_id(proc_id);
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
max_proc_id = atoi(optarg);
|
||||||
|
if (max_proc_id < 0 || max_proc_id >= RTE_MAX_LCORE) {
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
if (has_action){
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
has_action = 1;
|
||||||
|
cmd = knictl.kni_cmd = FF_KNICTL_CMD_SET;
|
||||||
|
knictl.kni_action = get_action(optarg);
|
||||||
|
if (knictl.kni_action < FF_KNICTL_ACTION_DEFAULT || knictl.kni_action >= FF_KNICTL_ACTION_MAX){
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (has_action){
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
has_action = 1;
|
||||||
|
cmd = knictl.kni_cmd = FF_KNICTL_CMD_GET;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (max_proc_id == -1){
|
||||||
|
printf(" using default proc id\n");
|
||||||
|
int ret = knictl_status(&knictl);
|
||||||
|
printf(" %s to %s knictl type: %s\n", ret ? "fail": "success", knictl.kni_cmd == FF_KNICTL_CMD_GET ? "get" : "set", get_action_str(knictl.kni_action));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int proc_id = 0;
|
||||||
|
for (; proc_id < max_proc_id; proc_id++){
|
||||||
|
pknictl[proc_id] = knictl;
|
||||||
|
ff_set_proc_id(proc_id);
|
||||||
|
int ret = knictl_status(&pknictl[proc_id]);
|
||||||
|
printf(" %s to %s knictl type: %s, proc_id: %d\n", ret ? "fail": "success", pknictl[proc_id].kni_cmd == FF_KNICTL_CMD_GET ? "get" : "set", get_action_str(pknictl[proc_id].kni_action), proc_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue