From a86ef865f47b99b41e426e621cb3b5e3416a70ff Mon Sep 17 00:00:00 2001 From: hantwofish Date: Thu, 27 Jun 2024 19:53:07 +0800 Subject: [PATCH] [virtio]: distribute pkg by dst_port --- src/lstack/core/lstack_protocol_stack.c | 27 ++++++++++++++---- src/lstack/core/lstack_virtio.c | 9 ++++++ src/lstack/include/lstack_virtio.h | 2 ++ src/lstack/netif/lstack_ethdev.c | 37 +++++++++++++++++++++++-- src/lstack/netif/lstack_vdev.c | 2 ++ 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/lstack/core/lstack_protocol_stack.c b/src/lstack/core/lstack_protocol_stack.c index d6e3c86..e272a04 100644 --- a/src/lstack/core/lstack_protocol_stack.c +++ b/src/lstack/core/lstack_protocol_stack.c @@ -34,6 +34,7 @@ #include "lstack_control_plane.h" #include "posix/lstack_epoll.h" #include "lstack_stack_stat.h" +#include "lstack_virtio.h" #include "lstack_protocol_stack.h" #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) @@ -509,6 +510,9 @@ int stack_polling(uint32_t wakeup_tick) } } #endif + if (get_global_cfg_params()->flow_bifurcation) { + virtio_tap_process_rx(stack->port_id, stack->queue_id); + } return force_quit; } @@ -979,14 +983,25 @@ void stack_broadcast_arp(struct rte_mbuf *mbuf, struct protocol_stack *cur_stack } } #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) - ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); - if (ret != 0) { - cur_stack->stats.rx_allocmbuf_fail++; - return; + if (get_global_cfg_params()->kni_switch) { + ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + if (ret != 0) { + cur_stack->stats.rx_allocmbuf_fail++; + return; + } + copy_mbuf(mbuf_copy, mbuf); + kni_handle_tx(mbuf_copy); } - copy_mbuf(mbuf_copy, mbuf); - kni_handle_tx(mbuf_copy); #endif + if (get_global_cfg_params()->flow_bifurcation) { + ret = dpdk_alloc_pktmbuf(cur_stack->rxtx_mbuf_pool, &mbuf_copy, 1, true); + if (ret != 0) { + cur_stack->stats.rx_allocmbuf_fail++; + return; + } + copy_mbuf(mbuf_copy, mbuf); + virtio_tap_process_tx(stack->queue_id, mbuf_copy); + } return; } diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c index c3b3511..ad3088d 100644 --- a/src/lstack/core/lstack_virtio.c +++ b/src/lstack/core/lstack_virtio.c @@ -331,3 +331,12 @@ int virtio_port_create(int lstack_net_port) } return 0; } + +bool virtio_distribute_pkg_to_kernel(uint16_t dst_port) +{ + if (dst_port == VIRTIO_PORT_INVALID) { + return false; + } + + return (port_map_get(dst_port) == 0); +} \ No newline at end of file diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h index d40c754..615d9c9 100644 --- a/src/lstack/include/lstack_virtio.h +++ b/src/lstack/include/lstack_virtio.h @@ -14,6 +14,7 @@ #include +#define VIRTIO_PORT_INVALID 0xffff #define VIRTIO_MAX_QUEUE_NUM 8 // RTE_ETHER_ADDR_PRT_FMT RTE_ETHER_ADDR_BYTES are defined in dpdk 21.11 @@ -48,4 +49,5 @@ void virtio_tap_process_tx(uint16_t queue_id, struct rte_mbuf *mbuf_copy); int virtio_port_create(int lstack_net_port); struct virtio_instance* virtio_instance_get(void); +bool virtio_distribute_pkg_to_kernel(uint16_t dst_port); #endif \ No newline at end of file diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c index 3bfa8af..933c3e8 100644 --- a/src/lstack/netif/lstack_ethdev.c +++ b/src/lstack/netif/lstack_ethdev.c @@ -35,6 +35,7 @@ #include "lstack_thread_rpc.h" #include "lstack_flow.h" #include "lstack_tx_cache.h" +#include "lstack_virtio.h" #include "lstack_ethdev.h" /* FRAME_MTU + 14byte header */ @@ -149,6 +150,25 @@ void kni_handle_tx(struct rte_mbuf *mbuf) ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) +#define IS_ICMPV6_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \ + ((ptype & RTE_PTYPE_L4_ICMP) == RTE_PTYPE_L4_ICMP) && \ + (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) + +static uint16_t eth_dev_get_dst_port(struct rte_mbuf *pkt) +{ + uint16_t dst_port = VIRTIO_PORT_INVALID; + uint32_t packet_type = pkt->packet_type; + + void *l4_hdr = rte_pktmbuf_mtod_offset(pkt, void *, pkt->l2_len + pkt->l3_len); + + if (IS_IPV4_TCP_PKT(packet_type) || IS_IPV6_TCP_PKT(packet_type)) { + dst_port = rte_be_to_cpu_16(((struct rte_tcp_hdr *)l4_hdr)->dst_port); + } else if (IS_IPV4_UDP_PKT(packet_type) || IS_IPV6_UDP_PKT(packet_type)) { + dst_port = rte_be_to_cpu_16(((struct rte_udp_hdr *)l4_hdr)->dst_port); + } + return dst_port; +} + int32_t eth_dev_poll(void) { uint32_t nr_pkts; @@ -170,7 +190,8 @@ int32_t eth_dev_poll(void) int transfer_type = TRANSFER_CURRENT_THREAD; /* copy arp into other stack */ if (!use_ltran()) { - if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type))) { + if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type)) || + unlikely(IS_ICMPV6_PKT(stack->pkts[i]->packet_type))) { stack_broadcast_arp(stack->pkts[i], stack); /* copy arp into other process */ transfer_arp_to_other_process(stack->pkts[i]); @@ -178,17 +199,27 @@ int32_t eth_dev_poll(void) if (get_global_cfg_params()->tuple_filter && stack->queue_id == 0) { transfer_type = distribute_pakages(stack->pkts[i]); } + if (get_global_cfg_params()->flow_bifurcation) { + uint16_t dst_port = eth_dev_get_dst_port(stack->pkts[i]); + if (virtio_distribute_pkg_to_kernel(dst_port)) { + transfer_type = TRANSFER_KERNEL; + } + } } } if (likely(transfer_type == TRANSFER_CURRENT_THREAD)) { eth_dev_recv(stack->pkts[i], stack); } else if (transfer_type == TRANSFER_KERNEL) { + if (get_global_cfg_params()->flow_bifurcation) { + virtio_tap_process_tx(stack->queue_id, stack->pkts[i]); + } else { #if RTE_VERSION < RTE_VERSION_NUM(23, 11, 0, 0) - kni_handle_tx(stack->pkts[i]); + kni_handle_tx(stack->pkts[i]); #else - rte_pktmbuf_free(stack->pkts[i]); + rte_pktmbuf_free(stack->pkts[i]); #endif + } } else { /* transfer to other thread */ } diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c index 5ce69a9..cb3953e 100644 --- a/src/lstack/netif/lstack_vdev.c +++ b/src/lstack/netif/lstack_vdev.c @@ -115,6 +115,8 @@ static inline void vdev_pkts_parse(struct rte_mbuf **pkts, int pkt_num) } else if (iph6->proto == IPPROTO_UDP) { pkts[i]->l4_len = sizeof(struct rte_udp_hdr); pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP; + } else if (iph6->proto == IPPROTO_ICMPV6) { + pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_ICMP; } } else if (type == RTE_BE16(RTE_ETHER_TYPE_ARP)) { pkts[i]->packet_type = RTE_PTYPE_L2_ETHER_ARP; -- 2.33.0