diff --git a/0050-enable-ipv6.patch b/0050-enable-ipv6.patch new file mode 100644 index 0000000..2337d2f --- /dev/null +++ b/0050-enable-ipv6.patch @@ -0,0 +1,734 @@ +From 480ef35615b5b0cb21818b117d4bedec42de93e4 Mon Sep 17 00:00:00 2001 +From: zhengjiebing +Date: Tue, 31 Oct 2023 04:24:34 +0800 +Subject: [PATCH] enable ipv6 + +--- + src/common/gazelle_opt.h | 3 +- + src/lstack/api/lstack_wrap.c | 93 ++++++---------- + src/lstack/core/lstack_cfg.c | 29 ++++- + src/lstack/core/lstack_control_plane.c | 4 +- + src/lstack/core/lstack_dpdk.c | 29 +++-- + src/lstack/core/lstack_lwip.c | 38 +++++-- + src/lstack/core/lstack_protocol_stack.c | 5 +- + src/lstack/include/lstack_cfg.h | 2 + + src/lstack/include/lstack_dpdk.h | 3 +- + src/lstack/netif/lstack_ethdev.c | 141 ++++++++++++++++-------- + src/lstack/netif/lstack_vdev.c | 36 +++--- + src/ltran/ltran_timer.c | 8 ++ + 12 files changed, 241 insertions(+), 150 deletions(-) + +diff --git a/src/common/gazelle_opt.h b/src/common/gazelle_opt.h +index 0479051..7316fc6 100644 +--- a/src/common/gazelle_opt.h ++++ b/src/common/gazelle_opt.h +@@ -54,7 +54,8 @@ + + #define MTU_DEFAULT_DATA_LEN 1460 + #define VLAN_HEAD_LEN 4 +-#define MBUF_MAX_DATA_LEN (MTU_DEFAULT_DATA_LEN - VLAN_HEAD_LEN) ++#define IPV6_EXTRA_HEAD_LEN 20 ++#define MBUF_MAX_DATA_LEN (MTU_DEFAULT_DATA_LEN - VLAN_HEAD_LEN - IPV6_EXTRA_HEAD_LEN) + + #define DPDK_PKT_BURST_SIZE 512 + +diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c +index 5bad513..9468003 100644 +--- a/src/lstack/api/lstack_wrap.c ++++ b/src/lstack/api/lstack_wrap.c +@@ -12,6 +12,8 @@ + + #define _GNU_SOURCE + #include ++#include ++#include + + #include + #include +@@ -184,28 +186,6 @@ static int32_t do_accept4(int32_t s, struct sockaddr *addr, socklen_t *addrlen, + return posix_api->accept4_fn(s, addr, addrlen, flags); + } + +-#define SIOCGIFADDR 0x8915 +-static int get_addr(struct sockaddr_in *sin, char *interface) +-{ +- int sockfd = 0; +- struct ifreq ifr; +- +- if ((sockfd = posix_api->socket_fn(AF_INET, SOCK_STREAM, 0)) < 0) return -1; +- +- memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)); +- snprintf_s(ifr.ifr_name, sizeof(ifr.ifr_name), (sizeof(ifr.ifr_name) - 1), "%s", interface); +- +- if (posix_api->ioctl_fn(sockfd, SIOCGIFADDR, &ifr) < 0) { +- posix_api->close_fn(sockfd); +- return -1; +- } +- posix_api->close_fn(sockfd); +- +- memcpy_s(sin, sizeof(struct sockaddr_in), &ifr.ifr_addr, sizeof(struct sockaddr_in)); +- +- return 0; +-} +- + static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen) + { + if (name == NULL) { +@@ -229,55 +209,39 @@ static int32_t do_bind(int32_t s, const struct sockaddr *name, socklen_t namelen + + bool is_dst_ip_localhost(const struct sockaddr *addr) + { +- struct sockaddr_in *servaddr = (struct sockaddr_in *) addr; +- char *line = NULL; +- char *p; +- size_t linel = 0; +- int linenum = 0; +- if (get_global_cfg_params()->host_addr.addr == servaddr->sin_addr.s_addr) { +- return true; +- } ++ struct ifaddrs *ifap; ++ struct ifaddrs *ifa; + +- FILE *ifh = fopen("/proc/net/dev", "r"); +- if (ifh == NULL) { +- LSTACK_LOG(ERR, LSTACK, "failed to open /proc/net/dev, errno is %d\n", errno); +- return false; ++ if (addr->sa_family == AF_INET) { ++ if (get_global_cfg_params()->host_addr.addr == ((struct sockaddr_in *)addr)->sin_addr.s_addr) { ++ return true; ++ } + } +- struct sockaddr_in* sin = malloc(sizeof(struct sockaddr_in)); +- if (sin == NULL) { +- LSTACK_LOG(ERR, LSTACK, "sockaddr_in malloc failed\n"); +- fclose(ifh); ++ ++ if (getifaddrs(&ifap) == -1) { ++ LSTACK_LOG(ERR, LSTACK, "get interface IP address failed\n"); + return false; + } + +- while (getdelim(&line, &linel, '\n', ifh) > 0) { +- /* 2: skip the first two lines, which are not nic name */ +- if (linenum++ < 2) { ++ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { ++ if (ifa->ifa_addr == NULL) { + continue; + } +- +- p = line; +- while (isspace(*p)) { +- ++p; +- } +- int n = strcspn(p, ": \t"); +- +- char interface[20] = {0}; /* 20: nic name len */ +- strncpy_s(interface, sizeof(interface), p, n); +- +- memset_s(sin, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); +- int ret = get_addr(sin, interface); +- if (ret == 0) { +- if (sin->sin_addr.s_addr == servaddr->sin_addr.s_addr) { +- free(sin); +- fclose(ifh); ++ if (ifa->ifa_addr->sa_family == AF_INET && addr->sa_family == AF_INET) { ++ struct sockaddr_in *if_addr = (struct sockaddr_in *)ifa->ifa_addr; ++ if (memcmp(&if_addr->sin_addr, &((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr)) == 0) { ++ freeifaddrs(ifap); ++ return true; ++ } ++ } else if (ifa->ifa_addr->sa_family == AF_INET6 && addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *if_addr = (struct sockaddr_in6 *)ifa->ifa_addr; ++ if (memcmp(&if_addr->sin6_addr, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof(struct in6_addr)) == 0) { ++ freeifaddrs(ifap); + return true; + } + } + } +- free(sin); +- fclose(ifh); +- ++ freeifaddrs(ifap); + return false; + } + +@@ -303,11 +267,15 @@ static int32_t do_connect(int32_t s, const struct sockaddr *name, socklen_t name + } + + int32_t ret = 0; ++ int32_t remote_port; ++ bool is_local = is_dst_ip_localhost(name); ++ ++ remote_port = htons(((struct sockaddr_in *)name)->sin_port); ++ + char listen_ring_name[RING_NAME_LEN]; +- int remote_port = htons(((struct sockaddr_in *)name)->sin_port); + snprintf_s(listen_ring_name, sizeof(listen_ring_name), sizeof(listen_ring_name) - 1, + "listen_rx_ring_%d", remote_port); +- if (is_dst_ip_localhost(name) && rte_ring_lookup(listen_ring_name) == NULL) { ++ if (is_local && rte_ring_lookup(listen_ring_name) == NULL) { + ret = posix_api->connect_fn(s, name, namelen); + SET_CONN_TYPE_HOST(sock->conn); + } else { +@@ -403,6 +371,7 @@ static inline int32_t do_socket(int32_t domain, int32_t type, int32_t protocol) + } + + if ((domain != AF_INET && domain != AF_UNSPEC) || ++ ((domain == AF_INET6) && !get_global_cfg_params()->ipv6_enable) || + ((type & SOCK_DGRAM) && !get_global_cfg_params()->udp_enable)) { + return posix_api->socket_fn(domain, type, protocol); + } +diff --git a/src/lstack/core/lstack_cfg.c b/src/lstack/core/lstack_cfg.c +index 729dccb..9f3143f 100644 +--- a/src/lstack/core/lstack_cfg.c ++++ b/src/lstack/core/lstack_cfg.c +@@ -46,6 +46,7 @@ static struct cfg_params g_config_params; + static config_t g_config; + + static int32_t parse_host_addr(void); ++static int32_t parse_host_addr6(void); + static int32_t parse_low_power_mode(void); + static int32_t parse_stack_cpu_number(void); + static int32_t parse_app_bind_numa(void); +@@ -75,6 +76,7 @@ static int32_t parse_bond_mode(void); + static int32_t parse_bond_slave_mac(void); + static int32_t parse_use_sockmap(void); + static int32_t parse_udp_enable(void); ++static int32_t parse_ipv6_enable(void); + static int32_t parse_nic_rxqueue_size(void); + static int32_t parse_nic_txqueue_size(void); + static int32_t parse_stack_thread_mode(void); +@@ -107,6 +109,7 @@ struct config_vector_t { + + static struct config_vector_t g_config_tbl[] = { + { "host_addr", parse_host_addr }, ++ { "host_addr6", parse_host_addr6 }, + { "gateway_addr", parse_gateway_addr }, + { "mask_addr", parse_mask_addr }, + { "use_ltran", parse_use_ltran }, +@@ -136,6 +139,7 @@ static struct config_vector_t g_config_tbl[] = { + { "bond_slave_mac", parse_bond_slave_mac }, + { "use_sockmap", parse_use_sockmap }, + { "udp_enable", parse_udp_enable }, ++ { "ipv6_enable", parse_ipv6_enable }, + { "nic_rxqueue_size", parse_nic_rxqueue_size}, + { "nic_txqueue_size", parse_nic_txqueue_size}, + { "stack_thread_mode", parse_stack_thread_mode }, +@@ -221,15 +225,29 @@ static int32_t parse_host_addr(void) + if (g_config_params.host_addr.addr == INADDR_NONE) { + return -EINVAL; + } ++ return 0; ++} + ++static int32_t parse_host_addr6(void) ++{ ++ char *value = NULL; ++ bool ok; ++ ++ ok = config_lookup_string(&g_config, "host_addr6", (const char **)&value); ++ if (!ok) { ++ return 0; ++ } ++ ++ if (ip6addr_aton(value, &g_config_params.host_addr6) == 0) { ++ return -EINVAL; ++ } + return 0; + } + + int32_t match_host_addr(uint32_t addr) + { + /* network byte order */ +- if (addr == g_config_params.host_addr.addr || +- addr == INADDR_ANY) { ++ if (addr == g_config_params.host_addr.addr || addr == INADDR_ANY) { + return 1; + } + return 0; +@@ -1251,3 +1269,10 @@ static int32_t parse_nic_vlan_mode(void) + } + return ret; + } ++ ++static int32_t parse_ipv6_enable(void) ++{ ++ int32_t ret; ++ PARSE_ARG(g_config_params.ipv6_enable, "ipv6_enable", 0, 0, 1, ret); ++ return ret; ++} +diff --git a/src/lstack/core/lstack_control_plane.c b/src/lstack/core/lstack_control_plane.c +index be156dc..f5049e9 100644 +--- a/src/lstack/core/lstack_control_plane.c ++++ b/src/lstack/core/lstack_control_plane.c +@@ -355,15 +355,13 @@ static int32_t reg_conn(enum tcp_list_state table_state, enum reg_ring_type reg_ + if (conn->conn_list[i].state != table_state) { + continue; + } +- + qtuple.protocol = 0; + qtuple.src_ip = conn->conn_list[i].lip; + qtuple.src_port = lwip_htons(conn->conn_list[i].l_port); + qtuple.dst_ip = conn->conn_list[i].rip; + qtuple.dst_port = lwip_htons(conn->conn_list[i].r_port); + +- if ((table_state == LISTEN_LIST) && +- (!match_host_addr(qtuple.src_ip))) { ++ if ((table_state == LISTEN_LIST) && (!match_host_addr(qtuple.src_ip))) { + continue; + } + +diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c +index 0776e50..6700357 100644 +--- a/src/lstack/core/lstack_dpdk.c ++++ b/src/lstack/core/lstack_dpdk.c +@@ -763,20 +763,33 @@ int32_t init_dpdk_ethdev(void) + return 0; + } + +-bool port_in_stack_queue(uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port) ++bool port_in_stack_queue(ip_addr_t src_ip, ip_addr_t dst_ip, uint16_t src_port, uint16_t dst_port) + { + struct protocol_stack_group *stack_group = get_protocol_stack_group(); + if (stack_group->reta_mask == 0 || stack_group->nb_queues <= 1) { + return true; + } + +- struct rte_ipv4_tuple tuple = {0}; +- tuple.src_addr = rte_be_to_cpu_32(src_ip); +- tuple.dst_addr = rte_be_to_cpu_32(dst_ip); +- tuple.sport = src_port; +- tuple.dport = dst_port; +- +- uint32_t hash = rte_softrss((uint32_t *)&tuple, RTE_THASH_V4_L4_LEN, g_default_rss_key); ++ union rte_thash_tuple tuple; ++ uint32_t hash = 0; ++ if (IP_IS_V4_VAL(src_ip)) { ++ tuple.v4.src_addr = rte_be_to_cpu_32(ip_2_ip4(&src_ip)->addr); ++ tuple.v4.dst_addr = rte_be_to_cpu_32(ip_2_ip4(&dst_ip)->addr); ++ tuple.v4.sport = src_port; ++ tuple.v4.dport = dst_port; ++ hash = rte_softrss((uint32_t *)&tuple, RTE_THASH_V4_L4_LEN, g_default_rss_key); ++ } else { ++ int i; ++ for (i = 0; i < 4; i++) { ++ *((uint32_t *)tuple.v6.src_addr + i) = ++ rte_be_to_cpu_32(*((const uint32_t *)src_ip.u_addr.ip6.addr + i)); ++ *((uint32_t *)tuple.v6.dst_addr + i) = ++ rte_be_to_cpu_32(*((const uint32_t *)dst_ip.u_addr.ip6.addr + i)); ++ } ++ tuple.v6.sport = src_port; ++ tuple.v6.dport = dst_port; ++ hash = rte_softrss((uint32_t *)&tuple, RTE_THASH_V6_L4_LEN, g_default_rss_key); ++ } + + uint32_t reta_index = hash & stack_group->reta_mask; + +diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c +index 3baddec..c8b4e8f 100644 +--- a/src/lstack/core/lstack_lwip.c ++++ b/src/lstack/core/lstack_lwip.c +@@ -123,7 +123,7 @@ static struct pbuf *init_mbuf_to_pbuf(struct rte_mbuf *mbuf, pbuf_layer layer, u + pbuf->allow_in = 1; + pbuf->head = 0; + pbuf->last = pbuf; +- pbuf->addr.addr = 0; ++ pbuf->addr = *IP_ANY_TYPE; + pbuf->port = 0; + pthread_spin_init(&pbuf->pbuf_lock, PTHREAD_PROCESS_SHARED); + } +@@ -441,10 +441,21 @@ static inline ssize_t app_buff_write(struct lwip_sock *sock, void *buf, size_t l + ssize_t send_len = do_app_write(pbufs, buf, len, write_num); + + if (addr) { +- struct sockaddr_in *saddr = (struct sockaddr_in *)addr; +- for (int i = 0; i < write_num; i++) { +- pbufs[i]->addr.addr = saddr->sin_addr.s_addr; +- pbufs[i]->port = lwip_ntohs((saddr)->sin_port); ++ if (addr->sa_family == AF_INET) { ++ struct sockaddr_in *saddr = (struct sockaddr_in *)addr; ++ for (int i = 0; i < write_num; i++) { ++ pbufs[i]->addr.u_addr.ip4.addr = saddr->sin_addr.s_addr; ++ pbufs[i]->port = lwip_ntohs((saddr)->sin_port); ++ } ++ } else if (addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)addr; ++ for (int i = 0; i < write_num; i++) { ++ memcpy_s(pbufs[i]->addr.u_addr.ip6.addr, sizeof(pbufs[i]->addr.u_addr.ip6.addr), ++ saddr->sin6_addr.s6_addr, sizeof(saddr->sin6_addr.s6_addr)); ++ pbufs[i]->port = lwip_ntohs((saddr)->sin6_port); ++ } ++ } else { ++ return 0; + } + } + +@@ -573,10 +584,15 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si + if (wakeup) { + wakeup->stat.app_write_cnt += write_num; + } +- if (addr) { ++ if (addr->sa_family == AF_INET) { + struct sockaddr_in *saddr = (struct sockaddr_in *)addr; +- last_pbuf->addr.addr = saddr->sin_addr.s_addr; ++ last_pbuf->addr.u_addr.ip4.addr = saddr->sin_addr.s_addr; + last_pbuf->port = lwip_ntohs((saddr)->sin_port); ++ } else if (addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)addr; ++ memcpy_s(last_pbuf->addr.u_addr.ip6.addr, sizeof(last_pbuf->addr.u_addr.ip6.addr), ++ saddr->sin6_addr.s6_addr, sizeof(saddr->sin6_addr.s6_addr)); ++ last_pbuf->port = lwip_ntohs((saddr)->sin6_port); + } + } else { + (void)rpc_call_replenish(stack, sock); +@@ -1122,8 +1138,8 @@ static void copy_pcb_to_conn(struct gazelle_stat_lstack_conn_info *conn, const s + { + struct netconn *netconn = (struct netconn *)pcb->callback_arg; + +- conn->lip = pcb->local_ip.addr; +- conn->rip = pcb->remote_ip.addr; ++ conn->lip = ip_2_ip4(&pcb->local_ip)->addr; ++ conn->rip = ip_2_ip4(&pcb->remote_ip)->addr; + conn->l_port = pcb->local_port; + conn->r_port = pcb->remote_port; + conn->in_send = pcb->snd_queuelen; +@@ -1173,7 +1189,7 @@ void do_lwip_clone_sockopt(struct lwip_sock *dst_sock, struct lwip_sock *src_soc + + int32_t do_lwip_socket(int domain, int type, int protocol) + { +- int32_t fd = lwip_socket(AF_INET, type, 0); ++ int32_t fd = lwip_socket(domain, type, 0); + if (fd < 0) { + return fd; + } +@@ -1216,7 +1232,7 @@ uint32_t do_lwip_get_conntable(struct gazelle_stat_lstack_conn_info *conn, + for (struct tcp_pcb_listen *pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL && conn_num < max_num; + pcbl = pcbl->next) { + conn[conn_num].state = LISTEN_LIST; +- conn[conn_num].lip = pcbl->local_ip.addr; ++ conn[conn_num].lip = ip_2_ip4(&pcbl->local_ip)->addr; + conn[conn_num].l_port = pcbl->local_port; + conn[conn_num].tcp_sub_state = pcbl->state; + struct netconn *netconn = (struct netconn *)pcbl->callback_arg; +diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c +index 74a17d4..54cf9e8 100644 +--- a/src/lstack/core/lstack_protocol_stack.c ++++ b/src/lstack/core/lstack_protocol_stack.c +@@ -936,10 +936,11 @@ void stack_create_shadow_fd(struct rpc_msg *msg) + return; + } + ++ int domain = addr->sa_family; + if (NETCONN_IS_UDP(sock)) { +- clone_fd = do_lwip_socket(AF_INET, SOCK_DGRAM, 0); ++ clone_fd = do_lwip_socket(domain, SOCK_DGRAM, 0); + } else { +- clone_fd = do_lwip_socket(AF_INET, SOCK_STREAM, 0); ++ clone_fd = do_lwip_socket(domain, SOCK_STREAM, 0); + } + + if (clone_fd < 0) { +diff --git a/src/lstack/include/lstack_cfg.h b/src/lstack/include/lstack_cfg.h +index a7b99af..e3edc57 100644 +--- a/src/lstack/include/lstack_cfg.h ++++ b/src/lstack/include/lstack_cfg.h +@@ -68,6 +68,7 @@ struct cfg_nic_params { + + struct cfg_params { + ip4_addr_t host_addr; ++ ip6_addr_t host_addr6; + ip4_addr_t netmask; + ip4_addr_t gateway_addr; + uint8_t mac_addr[ETHER_ADDR_LEN]; +@@ -116,6 +117,7 @@ struct cfg_params { + struct rte_ether_addr bond_slave_mac_addr[GAZELLE_MAX_BOND_NUM]; + bool use_sockmap; + bool udp_enable; ++ bool ipv6_enable; + struct cfg_nic_params nic; + bool stack_mode_rtc; + }; +diff --git a/src/lstack/include/lstack_dpdk.h b/src/lstack/include/lstack_dpdk.h +index 1a054d6..3a621d0 100644 +--- a/src/lstack/include/lstack_dpdk.h ++++ b/src/lstack/include/lstack_dpdk.h +@@ -13,6 +13,7 @@ + #ifndef _GAZELLE_DPDK_H_ + #define _GAZELLE_DPDK_H_ + ++#include + #include "gazelle_opt.h" + #include "gazelle_dfx_msg.h" + +@@ -53,7 +54,7 @@ int dpdk_ethdev_start(void); + void dpdk_skip_nic_init(void); + int32_t dpdk_init_lstack_kni(void); + void dpdk_restore_pci(void); +-bool port_in_stack_queue(uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port); ++bool port_in_stack_queue(ip_addr_t src_ip, ip_addr_t dst_ip, uint16_t src_port, uint16_t dst_port); + uint16_t get_port_id(void); + struct rte_mempool *create_pktmbuf_mempool(const char *name, uint32_t nb_mbuf, + uint32_t mbuf_cache_size, uint16_t queue_id, unsigned numa_id); +diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c +index 6914cff..02aa611 100644 +--- a/src/lstack/netif/lstack_ethdev.c ++++ b/src/lstack/netif/lstack_ethdev.c +@@ -16,9 +16,11 @@ + #include + #include + #include ++#include + + #include + #include ++#include + #include + #include + #include +@@ -664,57 +666,92 @@ void concat_mbuf_and_queue_id(struct rte_mbuf *mbuf, uint16_t queue_id, + sprintf_s(mbuf_and_queue_id, write_len, "%lu%s%u", mbuf, SPLIT_DELIM, queue_id); + } + +-int distribute_pakages(struct rte_mbuf *mbuf) +-{ +- struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr)); +- uint8_t ip_version = (iph->version_ihl & 0xf0) >> IPV4_VERSION_OFFSET; +- if (likely(ip_version == IPV4_VERSION)) { +- if (likely(iph->next_proto_id == IPPROTO_TCP)) { +- int each_process_queue_num = get_global_cfg_params()->num_queue; +- +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); +- uint16_t dst_port = tcp_hdr->dst_port; +- uint32_t user_process_idx; +- +- if (g_listen_ports[dst_port] != INVAILD_PROCESS_IDX) { +- user_process_idx = g_listen_ports[dst_port]; +- } else { +- user_process_idx = g_user_ports[dst_port]; ++static int mbuf_to_idx(struct rte_mbuf *mbuf, uint16_t *dst_port) ++{ ++ struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); ++ u16_t type = rte_be_to_cpu_16(ethh->ether_type); ++ uint32_t index = 0; ++ if (type == RTE_ETHER_TYPE_IPV4) { ++ struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr)); ++ uint8_t ip_version = (iph->version_ihl & 0xf0) >> IPV4_VERSION_OFFSET; ++ if (likely(ip_version == IPV4_VERSION)) { ++ if (likely(iph->next_proto_id == IPPROTO_TCP)) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); ++ *dst_port = tcp_hdr->dst_port; ++ ++ if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { ++ uint32_t src_ip = iph->src_addr; ++ uint16_t src_port = tcp_hdr->src_port; ++ index = rte_jhash_3words(src_ip, src_port | ((*dst_port) << 16), 0, 0); ++ } else { ++ return -1; ++ } + } ++ } ++ } else if (type == RTE_ETHER_TYPE_IPV6) { ++ struct rte_ipv6_hdr *iph = rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv6_hdr *, sizeof(struct rte_ether_hdr)); ++ if (likely(iph->proto == IPPROTO_TCP)) { ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr)); ++ *dst_port = tcp_hdr->dst_port; + +- if (user_process_idx == INVAILD_PROCESS_IDX) { +- return TRANSFER_KERNEL; +- } + if (unlikely(tcp_hdr->tcp_flags == TCP_SYN)) { +- uint32_t src_ip = iph->src_addr; ++ uint32_t *src_ip = (uint32_t *) &iph->src_addr; + uint16_t src_port = tcp_hdr->src_port; +- uint32_t index = rte_jhash_3words(src_ip, src_port | ((dst_port) << 16), 0, 0); +- index = index % each_process_queue_num; +- uint16_t queue_id = 0; +- if (get_global_cfg_params()->seperate_send_recv) { +- queue_id = user_process_idx * each_process_queue_num + (index / 2) * 2; +- } else { +- queue_id = user_process_idx * each_process_queue_num + index; +- } +- if (queue_id != 0) { +- if (user_process_idx == 0) { +- transfer_tcp_to_thread(mbuf, queue_id); +- } else { +- char mbuf_and_queue_id[TRANSFER_TCP_MUBF_LEN]; +- concat_mbuf_and_queue_id(mbuf, queue_id, mbuf_and_queue_id, TRANSFER_TCP_MUBF_LEN); +- transfer_pkt_to_other_process(mbuf_and_queue_id, user_process_idx, +- TRANSFER_TCP_MUBF_LEN, false); +- } +- return TRANSFER_OTHER_THREAD; +- } else { +- return TRANSFER_CURRENT_THREAD; +- } ++ uint32_t v = rte_jhash_3words(src_ip[0], src_ip[1], src_ip[2], 0); ++ index = rte_jhash_3words(src_ip[3], src_port | ((*dst_port) << 16), v, 0); + } else { +- return TRANSFER_CURRENT_THREAD; ++ return -1; + } + } ++ } else { ++ return -1; ++ } ++ return index; ++} ++ ++int distribute_pakages(struct rte_mbuf *mbuf) ++{ ++ uint16_t dst_port = 0; ++ uint32_t index = mbuf_to_idx(mbuf, &dst_port); ++ if (index == -1) { ++ return TRANSFER_CURRENT_THREAD; ++ } ++ ++ uint16_t queue_id = 0; ++ uint32_t user_process_idx = 0; ++ int each_process_queue_num = get_global_cfg_params()->num_queue; ++ index = index % each_process_queue_num; ++ if (g_listen_ports[dst_port] != INVAILD_PROCESS_IDX) { ++ user_process_idx = g_listen_ports[dst_port]; ++ } else { ++ user_process_idx = g_user_ports[dst_port]; ++ } ++ ++ if (user_process_idx == INVAILD_PROCESS_IDX) { ++ return TRANSFER_KERNEL; ++ } ++ ++ if (get_global_cfg_params()->seperate_send_recv) { ++ queue_id = user_process_idx * each_process_queue_num + (index / 2) * 2; ++ } else { ++ queue_id = user_process_idx * each_process_queue_num + index; ++ } ++ if (queue_id != 0) { ++ if (user_process_idx == 0) { ++ transfer_tcp_to_thread(mbuf, queue_id); ++ } else { ++ char mbuf_and_queue_id[TRANSFER_TCP_MUBF_LEN]; ++ concat_mbuf_and_queue_id(mbuf, queue_id, mbuf_and_queue_id, TRANSFER_TCP_MUBF_LEN); ++ transfer_pkt_to_other_process(mbuf_and_queue_id, user_process_idx, ++ TRANSFER_TCP_MUBF_LEN, false); ++ } ++ return TRANSFER_OTHER_THREAD; ++ } else { ++ return TRANSFER_CURRENT_THREAD; + } ++ + return TRANSFER_KERNEL; + } + +@@ -874,10 +911,11 @@ static err_t eth_dev_init(struct netif *netif) + + netif->name[0] = 'e'; + netif->name[1] = 't'; +- netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; ++ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6; + netif->mtu = FRAME_MTU; + netif->output = etharp_output; + netif->linkoutput = eth_dev_output; ++ netif->output_ip6 = ethip6_output; + + int32_t ret; + ret = memcpy_s(netif->hwaddr, sizeof(netif->hwaddr), cfg->mac_addr, ETHER_ADDR_LEN); +@@ -914,11 +952,20 @@ int32_t ethdev_init(struct protocol_stack *stack) + + netif_set_default(&stack->netif); + +- struct netif *netif = netif_add(&stack->netif, &cfg->host_addr, &cfg->netmask, &cfg->gateway_addr, NULL, +- eth_dev_init, ethernet_input); ++ struct netif *netif; ++ if (!ip4_addr_isany(&cfg->host_addr)) { ++ netif = netif_add(&stack->netif, &cfg->host_addr, &cfg->netmask, ++ &cfg->gateway_addr, NULL, eth_dev_init, ethernet_input); ++ } else { ++ netif = netif_add(&stack->netif, NULL, NULL, NULL, NULL, eth_dev_init, ethernet_input); ++ } + if (netif == NULL) { + LSTACK_LOG(ERR, LSTACK, "netif_add failed\n"); +- return ERR_IF; ++ return ERR_IF; ++ } ++ if (!ip6_addr_isany(&cfg->host_addr6)) { ++ netif_ip6_addr_set(&stack->netif, 0, &cfg->host_addr6); ++ netif_ip6_addr_set_state(&stack->netif, 0, IP6_ADDR_VALID); + } + + netif_set_link_up(&stack->netif); +diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c +index 4a93f87..d57ce59 100644 +--- a/src/lstack/netif/lstack_vdev.c ++++ b/src/lstack/netif/lstack_vdev.c +@@ -90,24 +90,34 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt + + for (uint32_t i = 0; i < pkt_num; i++) { + struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *); ++ u16_t type = ethh->ether_type; + +- if (unlikely(RTE_BE16(RTE_ETHER_TYPE_IPV4) != ethh->ether_type)) { +- continue; +- } + pkts[i]->l2_len = sizeof(struct rte_ether_hdr); + +- struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *, +- sizeof(struct rte_ether_hdr)); +- if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) { +- continue; +- } +- pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr); ++ if (type == RTE_BE16(RTE_ETHER_TYPE_IPV4)) { ++ struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *, ++ sizeof(struct rte_ether_hdr)); ++ if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) { ++ continue; ++ } ++ pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr); + +- struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, +- sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); +- pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)); ++ pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); + +- pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP; ++ } else if (type == RTE_BE16(RTE_ETHER_TYPE_IPV6)) { ++ pkts[i]->l3_len = sizeof(struct rte_ipv6_hdr); ++ ++ struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *, ++ sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr)); ++ pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr); ++ ++ pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP; ++ } else { ++ continue; ++ } + } + pkt_num = rte_gro_reassemble_burst(pkts, pkt_num, &gro_param); + +diff --git a/src/ltran/ltran_timer.c b/src/ltran/ltran_timer.c +index 85ea324..749b8e0 100644 +--- a/src/ltran/ltran_timer.c ++++ b/src/ltran/ltran_timer.c +@@ -24,6 +24,14 @@ + #include "ltran_tcp_conn.h" + #include "ltran_instance.h" + #include "ltran_timer.h" ++/* undefine lwip_ntohs in lwip/def.h */ ++#ifdef ntohs ++#undef ntohs ++#endif ++#ifdef htons ++#undef htons ++#endif ++ + + static uint64_t g_cycles_per_us = 0; + +-- +2.27.0 + diff --git a/gazelle.spec b/gazelle.spec index 131d0ec..76c1d90 100644 --- a/gazelle.spec +++ b/gazelle.spec @@ -2,7 +2,7 @@ Name: gazelle Version: 1.0.2 -Release: 13 +Release: 14 Summary: gazelle is a high performance user-mode stack License: MulanPSL-2.0 URL: https://gitee.com/openeuler/gazelle @@ -65,6 +65,7 @@ Patch9046: 0046-build-fix-ltran-build-error.patch Patch9047: 0047-cfg-fix-lstack-mempool-lookup-failed-in-ltran-mode.patch Patch9048: 0048-add-tx-package-timeout.patch Patch9049: 0049-modif-mem.patch +Patch9050: 0050-enable-ipv6.patch %description %{name} is a high performance user-mode stack. @@ -106,6 +107,9 @@ install -Dpm 0640 %{_builddir}/%{name}-%{version}/src/ltran/ltran.conf %{b %config(noreplace) %{conf_path}/ltran.conf %changelog +* Sat Nov 18 2023 yinbin6 - 1.0.2-14 +- enable ipv6 + * Sat Nov 18 2023 yinbin6 - 1.0.2-13 - modif mem - add tx package timeout