From 1ddd0f08985acde530e95e15c35781197f145d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fengbojiang=28=E5=A7=9C=E5=87=A4=E6=B3=A2=29?= Date: Fri, 22 Jan 2021 17:12:05 +0800 Subject: [PATCH] Add `ff_regist_pcblddr_fun` to regist a pcb lddr function in F-Stack. If There are multiple ips, and F-Stack client application can choose a source ip by yourself, instead always use the first ip. --- freebsd/netinet/in_pcb.c | 5 +++++ lib/ff_api.h | 30 ++++++++++++++++++++++++++++++ lib/ff_dpdk_if.c | 29 +++++++++++++++++++++++++++++ lib/ff_host_interface.h | 2 ++ 4 files changed, 66 insertions(+) diff --git a/freebsd/netinet/in_pcb.c b/freebsd/netinet/in_pcb.c index d22b3d6c1..ea6b6c2a7 100644 --- a/freebsd/netinet/in_pcb.c +++ b/freebsd/netinet/in_pcb.c @@ -1064,6 +1064,11 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } +#ifdef FSTACK + if (laddr.s_addr == INADDR_ANY) { + ff_in_pcbladdr(AF_INET, &faddr, fport, &laddr); + } +#endif if (laddr.s_addr == INADDR_ANY) { error = in_pcbladdr(inp, &faddr, &laddr, cred); /* diff --git a/lib/ff_api.h b/lib/ff_api.h index 74b223ee0..e97ade4c9 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -46,6 +46,8 @@ struct linux_sockaddr { #define AF_INET6_LINUX 10 #define PF_INET6_LINUX AF_INET6_LINUX +#define AF_INET6_FREEBSD 28 +#define PF_INET6_FREEBSD AF_INET6_FREEBSD typedef int (*loop_func_t)(void *arg); @@ -179,6 +181,34 @@ void ff_regist_packet_dispatcher(dispatch_func_t func); /* dispatch api end */ +/* pcb lddr api begin */ +/* + * pcb lddr callback function. + * Implemented by user. + * + * @param family + * The remote server addr, should be AF_INET or AF_INET6. + * @param dst_addr + * The remote server addr, should be (in_addr *) or (in6_addr *). + * @param dst_port + * The remote server port. + * @param src_addr + * Return parameter. + * The local addr, should be (in_addr *) or (in6_addr *). + * If set (INADDR_ANY) or (in6addr_any), the app then will + * call `in_pcbladdr()` to get laddr. + * + * @return error_no + * 0 means success. + * + */ +typedef int (*pcblddr_func_t)(uint16_t family, void *dst_addr, + uint16_t dst_port, void *src_addr); + +/* regist a pcb lddr function */ +void ff_regist_pcblddr_fun(pcblddr_func_t func); + +/* pcb lddr api end */ /* internal api begin */ diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 47282c0e7..7664adf85 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -116,6 +116,8 @@ struct lcore_conf lcore_conf; struct rte_mempool *pktmbuf_pool[NB_SOCKETS]; +static pcblddr_func_t pcblddr_fun; + static struct rte_ring **dispatch_ring[RTE_MAX_ETHPORTS]; static dispatch_func_t packet_dispatcher; @@ -1993,6 +1995,33 @@ toeplitz_hash(unsigned keylen, const uint8_t *key, return (hash); } +int +ff_in_pcbladdr(uint16_t family, void *faddr, uint16_t fport, void *laddr) +{ + int ret = 0; + uint16_t fa; + + if (!pcblddr_fun) + return ret; + + if (family == AF_INET) + fa = AF_INET; + else if (family == AF_INET6_FREEBSD) + fa = AF_INET6_LINUX; + else + return EADDRNOTAVAIL; + + ret = (*pcblddr_fun)(fa, faddr, fport, laddr); + + return ret; +} + +void +ff_regist_pcblddr_fun(pcblddr_func_t func) +{ + pcblddr_fun = func; +} + int ff_rss_check(void *softc, uint32_t saddr, uint32_t daddr, uint16_t sport, uint16_t dport) diff --git a/lib/ff_host_interface.h b/lib/ff_host_interface.h index e9d4318d6..429e6ebdd 100644 --- a/lib/ff_host_interface.h +++ b/lib/ff_host_interface.h @@ -73,6 +73,8 @@ char *ff_getenv(const char *name); void ff_os_errno(int error); +int ff_in_pcbladdr(uint16_t family, void *faddr, uint16_t fport, void *laddr); + int ff_rss_check(void *softc, uint32_t saddr, uint32_t daddr, uint16_t sport, uint16_t dport);