diff --git a/README.md b/README.md index f540a5fb..5ede09dc 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Currently, besides authorized DNS server of DNSPod, there are various products i ## Quick Start # clone F-Stack - mkdir /data/f-stack + mkdir -p /data/f-stack git clone https://github.com/F-Stack/f-stack.git /data/f-stack # install libnuma-dev diff --git a/doc/F-Stack_API_Reference.md b/doc/F-Stack_API_Reference.md index 2df28587..0f426aa6 100644 --- a/doc/F-Stack_API_Reference.md +++ b/doc/F-Stack_API_Reference.md @@ -23,7 +23,7 @@ Initialize F-Stack,including DPDK/FreeBSD network stack, etc. #### ff_run void ff_run(loop_func_t loop, void *arg); -loop is a callbask function,the service logic is implemented by the user, and called by each poll of F-Stack . +loop is a callback function,the service logic is implemented by the user, and called by each poll of F-Stack . ### Control API @@ -220,3 +220,33 @@ However, it is supported only before F-Stack is started. #### Socket API for micro threads see `micro_thread/mt_api.h`. + +### Dispatch API + + Packet dispatch callback function, implemented by user. + + typedef int (*dispatch_func_t)(void *data, uint16_t *len, uint16_t queue_id, uint16_t nb_queues); + + void ff_regist_packet_dispatcher(dispatch_func_t func); + + Regist a packet dispath function. + +#### param + + - data + The data pointer of this packet. + - len + The length of this packet. + - queue_id + Current queue of this packet. + - nb_queues + Number of queues to be dispatched. + +#### return + + - 0 to (nb_queues - 1) + The queue id that the packet will be dispatched to. + - FF_DISPATCH_ERROR (-1) + Error occurs or packet is handled by user, packet will be freed. + - FF_DISPATCH_RESPONSE (-2) + Packet is handled by user, packet will be responsed. \ No newline at end of file diff --git a/doc/F-Stack_Quick_Start_Guide.md b/doc/F-Stack_Quick_Start_Guide.md index cd1d6df6..42078bd2 100644 --- a/doc/F-Stack_Quick_Start_Guide.md +++ b/doc/F-Stack_Quick_Start_Guide.md @@ -75,5 +75,5 @@ The mount point can be made permanent across reboots, by adding the following li # run with start.sh ./start.sh -b ./redis-server -o /path/to/redis.conf # or run like this: - #./redis-server --conf=config.ini --proc-type=primary --proc-id=0 /path/to/redis.conf + #./redis-server --conf config.ini --proc-type=primary --proc-id=0 /path/to/redis.conf diff --git a/freebsd/netinet/in_pcb.c b/freebsd/netinet/in_pcb.c index 22730aed..37d65330 100644 --- a/freebsd/netinet/in_pcb.c +++ b/freebsd/netinet/in_pcb.c @@ -1126,10 +1126,7 @@ if (lport == 0) ifp_sin.sin_len = sizeof(ifp_sin); ifa = ifa_ifwithnet((struct sockaddr *)&ifp_sin, 0, RT_ALL_FIBS); if (ifa == NULL) { - ifp_sin.sin_addr.s_addr = faddr.s_addr; - ifa = ifa_ifwithnet((struct sockaddr *)&ifp_sin, 0, RT_ALL_FIBS); - if ( ifa == NULL ) - return (EADDRNOTAVAIL); + return (EADDRNOTAVAIL); } ifp = ifa->ifa_ifp; while (lport == 0) { diff --git a/freebsd/netinet/tcp_usrreq.c b/freebsd/netinet/tcp_usrreq.c index 57c7bc18..b33efedc 100644 --- a/freebsd/netinet/tcp_usrreq.c +++ b/freebsd/netinet/tcp_usrreq.c @@ -1321,22 +1321,14 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) error = EADDRINUSE; goto out; } - - // inp->inp_lport != lport means in_pcbconnect_setup selected new port to inp->inp_lport. - // inp will inhash. - if (in_pcbinshash(inp) != 0) { - inp->inp_laddr.s_addr = INADDR_ANY; - inp->inp_lport = 0; - return (EAGAIN); - } } - else - { - // app call bind() and connect(), lport is set when bind, and the inp is inhashed in bind() function. - // in_pcbconnect_setup() update inp->inp_faddr/inp->inp_fport, so inp should be rehashed. - in_pcbrehash(inp); + + if (in_pcbinshash(inp) != 0) { + inp->inp_laddr.s_addr = INADDR_ANY; + inp->inp_lport = 0; + return (EAGAIN); } - + if (anonport) { inp->inp_flags |= INP_ANONPORT; } diff --git a/lib/ff_api.h b/lib/ff_api.h index 9f518bf1..39d09670 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -144,6 +144,8 @@ int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag, /* dispatch api begin */ +#define FF_DISPATCH_ERROR (-1) +#define FF_DISPATCH_RESPONSE (-2) /* * Packet dispatch callback function. @@ -160,11 +162,13 @@ int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag, * * @return 0 to (nb_queues - 1) * The queue id that the packet will be dispatched to. - * @return -1 + * @return FF_DISPATCH_ERROR (-1) * Error occurs or packet is handled by user, packet will be freed. +* @return FF_DISPATCH_RESPONSE (-2) + * Packet is handled by user, packet will be responsed. * */ -typedef int (*dispatch_func_t)(void *data, uint16_t len, +typedef int (*dispatch_func_t)(void *data, uint16_t *len, uint16_t queue_id, uint16_t nb_queues); /* regist a packet dispath function */ diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 600fc1ac..ddfbeb97 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -121,6 +121,8 @@ static dispatch_func_t packet_dispatcher; static uint16_t rss_reta_size[RTE_MAX_ETHPORTS]; +static inline int send_single_packet(struct rte_mbuf *m, uint8_t port); + struct ff_msg_ring { char ring_name[2][RTE_RING_NAMESIZE]; /* ring[0] for lcore recv msg, other send */ @@ -956,8 +958,14 @@ process_packets(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **bufs, } if (!pkts_from_ring && packet_dispatcher) { - int ret = (*packet_dispatcher)(data, len, queue_id, nb_queues); - if (ret < 0 || ret >= nb_queues) { + int ret = (*packet_dispatcher)(data, &len, queue_id, nb_queues); + if (ret == FF_DISPATCH_RESPONSE) { + rte_pktmbuf_pkt_len(rtem) = rte_pktmbuf_data_len(rtem) = len; + send_single_packet(rtem, port_id); + continue; + } + + if (ret == FF_DISPATCH_ERROR || ret >= nb_queues) { rte_pktmbuf_free(rtem); continue; }