diff --git a/README.md b/README.md index aa60ad08d..1b1a7ae40 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,12 @@ If you find value in our project, please consider giving it a star. Your support #### 1.1.1 ST2110 features * Narrow and wide pacing. Please see [compliance](doc/compliance.md) page for the ST2110 narrow report on our software solution. -* ST2110-10, ST2110-20, ST2110-21, ST2110-30, ST2110-40, ST2110-22, ST2022-7 +* ST2110-10, ST2110-20, ST2110-21, ST2110-30, ST2110-40, ST2022-7 * 1080p, 720p, 4k, 8k and other * FPS: 120, 119.88, 100, 60, 59.94, 50, 30, 29.97, 25, 24, 23.98 * All video formats listed in ST2110-20, including YUV 4:2:2 10-bit and others, are supported. * CSC support status: [status](doc/convert.md) +* ST2110-22 with encoder/decoder [plugin](doc/plugin.md) interface. * ST2022-6 by RTP passthrough interface. ### 1.2 Architecture diff --git a/app/src/args.c b/app/src/args.c index 0ca4f405e..c1d92afb8 100644 --- a/app/src/args.c +++ b/app/src/args.c @@ -112,6 +112,7 @@ enum st_args_cmd { ST_ARG_SHARED_TX_QUEUES, ST_ARG_SHARED_RX_QUEUES, ST_ARG_RX_USE_CNI, + ST_ARG_RX_UDP_PORT_ONLY, ST_ARG_VIRTIO_USER, ST_ARG_VIDEO_SHA_CHECK, ST_ARG_MAX, @@ -227,6 +228,7 @@ static struct option st_app_args_options[] = { {"shared_tx_queues", no_argument, 0, ST_ARG_SHARED_TX_QUEUES}, {"shared_rx_queues", no_argument, 0, ST_ARG_SHARED_RX_QUEUES}, {"rx_use_cni", no_argument, 0, ST_ARG_RX_USE_CNI}, + {"rx_udp_port_only", no_argument, 0, ST_ARG_RX_UDP_PORT_ONLY}, {"virtio_user", no_argument, 0, ST_ARG_VIRTIO_USER}, {"video_sha_check", no_argument, 0, ST_ARG_VIDEO_SHA_CHECK}, @@ -690,6 +692,9 @@ int st_app_parse_args(struct st_app_context* ctx, struct mtl_init_params* p, int case ST_ARG_RX_USE_CNI: p->flags |= MTL_FLAG_RX_USE_CNI; break; + case ST_ARG_RX_UDP_PORT_ONLY: + p->flags |= MTL_FLAG_RX_UDP_PORT_ONLY; + break; case ST_ARG_VIRTIO_USER: p->flags |= MTL_FLAG_VIRTIO_USER; break; diff --git a/config/4k_rx_1port_1v.json b/config/4k_rx_1port_1v.json index 67227127b..c92438f91 100644 --- a/config/4k_rx_1port_1v.json +++ b/config/4k_rx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.84.189" } ], diff --git a/config/4k_tx_1port_1v.json b/config/4k_tx_1port_1v.json index 97907d92d..01580a60f 100644 --- a/config/4k_tx_1port_1v.json +++ b/config/4k_tx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.84.188" } ], diff --git a/config/8k_rx_1port_1v.json b/config/8k_rx_1port_1v.json index f086c1a68..711297a77 100644 --- a/config/8k_rx_1port_1v.json +++ b/config/8k_rx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.84.189" } ], diff --git a/config/8k_tx_1port_1v.json b/config/8k_tx_1port_1v.json index c2cd64e1f..5a18ceb18 100644 --- a/config/8k_tx_1port_1v.json +++ b/config/8k_tx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.84.188" } ], diff --git a/config/test_rx_1port_1v.json b/config/test_rx_1port_1v.json index 129ce4b1f..a56a9efbc 100644 --- a/config/test_rx_1port_1v.json +++ b/config/test_rx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.84.189" } ], diff --git a/config/test_rx_1port_1v_1a_1anc.json b/config/test_rx_1port_1v_1a_1anc.json index 4ca0937b8..ceb9e278e 100644 --- a/config/test_rx_1port_1v_1a_1anc.json +++ b/config/test_rx_1port_1v_1a_1anc.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.68.189" } ], diff --git a/config/test_rx_2port_1v_1a.json b/config/test_rx_2port_1v_1a.json index 11b595400..5f59d4063 100644 --- a/config/test_rx_2port_1v_1a.json +++ b/config/test_rx_2port_1v_1a.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:4b:00.0", + "name": "0000:af:01.0", "ip": "192.168.88.189" }, { - "name": "0000:4b:00.1", + "name": "0000:af:01.1", "ip": "192.168.88.199" } ], diff --git a/config/test_rx_2port_1v_1a_1anc.json b/config/test_rx_2port_1v_1a_1anc.json index 1ad200736..5905b5573 100644 --- a/config/test_rx_2port_1v_1a_1anc.json +++ b/config/test_rx_2port_1v_1a_1anc.json @@ -3,12 +3,12 @@ "user_timestamp": "1111111", "interfaces": [ { - "name": "0000:4b:00.0", + "name": "0000:af:01.0", "driver": "uio", "ip": "192.168.88.189" }, { - "name": "0000:4b:00.1", + "name": "0000:af:01.1", "driver": "uio", "ip": "192.168.88.199" } diff --git a/config/test_rx_st20p.json b/config/test_rx_st20p.json index bf22db602..a05d200e5 100644 --- a/config/test_rx_st20p.json +++ b/config/test_rx_st20p.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:4b:00.0", + "name": "0000:af:01.0", "ip": "192.168.96.1" }, { - "name": "0000:4b:00.1", + "name": "0000:af:01.1", "ip": "192.168.96.2" } ], diff --git a/config/test_rx_st22p.json b/config/test_rx_st22p.json index ecc59e2e8..a3254b7cb 100644 --- a/config/test_rx_st22p.json +++ b/config/test_rx_st22p.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:4b:00.0", + "name": "0000:af:01.0", "ip": "192.168.96.1" }, { - "name": "0000:4b:00.1", + "name": "0000:af:01.1", "ip": "192.168.96.2" } ], diff --git a/config/test_tx_1port_1v.json b/config/test_tx_1port_1v.json index 88901b01c..172fe7131 100644 --- a/config/test_tx_1port_1v.json +++ b/config/test_tx_1port_1v.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.84.188" } ], diff --git a/config/test_tx_1port_1v_1a_1anc.json b/config/test_tx_1port_1v_1a_1anc.json index c5e32c1ca..ba7415442 100644 --- a/config/test_tx_1port_1v_1a_1anc.json +++ b/config/test_tx_1port_1v_1a_1anc.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.68.188" } ], diff --git a/config/test_tx_1port_1v_2dest.json b/config/test_tx_1port_1v_2dest.json index bdb5362d2..eacce4af0 100644 --- a/config/test_tx_1port_1v_2dest.json +++ b/config/test_tx_1port_1v_2dest.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:4b:00.0", + "name": "0000:af:01.0", "ip": "192.168.96.188" } ], diff --git a/config/test_tx_2port_1v_1a.json b/config/test_tx_2port_1v_1a.json index 472c2c9de..ad9db110f 100644 --- a/config/test_tx_2port_1v_1a.json +++ b/config/test_tx_2port_1v_1a.json @@ -1,7 +1,7 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.88.188" }, { diff --git a/config/test_tx_2port_1v_1a_1anc.json b/config/test_tx_2port_1v_1a_1anc.json index 96ec68d3e..f08734147 100644 --- a/config/test_tx_2port_1v_1a_1anc.json +++ b/config/test_tx_2port_1v_1a_1anc.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.88.188" }, { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "driver": "uio", "ip": "192.168.88.198" } diff --git a/config/test_tx_2port_1v_1a_1anc_50fps.json b/config/test_tx_2port_1v_1a_1anc_50fps.json index 45984288e..2b25ee488 100644 --- a/config/test_tx_2port_1v_1a_1anc_50fps.json +++ b/config/test_tx_2port_1v_1a_1anc_50fps.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.88.188" }, { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.88.198" } ], diff --git a/config/test_tx_2port_1v_1a_1anc_rtp.json b/config/test_tx_2port_1v_1a_1anc_rtp.json index 79aa738ac..0495040bb 100644 --- a/config/test_tx_2port_1v_1a_1anc_rtp.json +++ b/config/test_tx_2port_1v_1a_1anc_rtp.json @@ -1,11 +1,11 @@ { "interfaces": [ { - "name": "0000:af:00.0", + "name": "0000:af:01.0", "ip": "192.168.88.188" }, { - "name": "0000:af:00.1", + "name": "0000:af:01.1", "ip": "192.168.88.198" } ], diff --git a/include/mtl_api.h b/include/mtl_api.h index 6ee85d419..956032931 100644 --- a/include/mtl_api.h +++ b/include/mtl_api.h @@ -442,6 +442,12 @@ enum st21_tx_pacing_way { * Use CNI based queue for RX. */ #define MTL_FLAG_RX_USE_CNI (MTL_BIT64(45)) +/** + * Flag bit in flags of struct mtl_init_params, debug usage only. + * To exclusively use port only for flow, the application must ensure that all RX streams + * have unique UDP port numbers. + */ +#define MTL_FLAG_RX_UDP_PORT_ONLY (MTL_BIT64(46)) /** * The structure describing how to init af_xdp interface. diff --git a/lib/src/mt_flow.c b/lib/src/mt_flow.c index 029806fcc..6642c0a27 100644 --- a/lib/src/mt_flow.c +++ b/lib/src/mt_flow.c @@ -90,6 +90,7 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q, bool has_port_flow = true; uint16_t port_id = inf->port_id; + enum mtl_port port = inf->port; memset(&error, 0, sizeof(error)); @@ -100,6 +101,13 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q, /* no port flow requested */ if (flow->flags & MT_RXQ_FLOW_F_NO_PORT) has_port_flow = false; + if (mt_get_user_params(inf->parent)->flags & MTL_FLAG_RX_UDP_PORT_ONLY) { + if (has_ip_flow) { + info("%s(%d), no ip flow as MTL_FLAG_RX_UDP_PORT_ONLY is set\n", __func__, port); + has_ip_flow = false; + } + } + /* only raw flow can be applied on the hdr split queue */ if (mt_if_hdr_split_pool(inf, q)) { return rte_rx_flow_create_raw(inf, q, flow); @@ -162,7 +170,7 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q, ret = rte_flow_validate(port_id, &attr, pattern, action, &error); if (ret < 0) { - err("%s(%d), rte_flow_validate fail %d for queue %d, %s\n", __func__, port_id, ret, q, + err("%s(%d), rte_flow_validate fail %d for queue %d, %s\n", __func__, port, ret, q, mt_string_safe(error.message)); return NULL; } @@ -171,14 +179,18 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q, r_flow = rte_flow_create(port_id, &attr, pattern, action, &error); mt_pthread_mutex_unlock(&inf->vf_cmd_mutex); if (!r_flow) { - err("%s(%d), rte_flow_create fail for queue %d, %s\n", __func__, port_id, q, + err("%s(%d), rte_flow_create fail for queue %d, %s\n", __func__, port, q, mt_string_safe(error.message)); return NULL; } - uint8_t* ip = flow->dip_addr; - info("%s(%d), queue %u succ, ip %u.%u.%u.%u port %u\n", __func__, inf->port, q, ip[0], - ip[1], ip[2], ip[3], flow->dst_port); + if (has_ip_flow) { + uint8_t* ip = flow->dip_addr; + info("%s(%d), queue %u succ, ip %u.%u.%u.%u port %u\n", __func__, port, q, ip[0], + ip[1], ip[2], ip[3], flow->dst_port); + } else { + info("%s(%d), queue %u succ, port %u\n", __func__, port, q, flow->dst_port); + } return r_flow; } diff --git a/lib/src/mt_socket.c b/lib/src/mt_socket.c index 49c43d669..e14a13a4f 100644 --- a/lib/src/mt_socket.c +++ b/lib/src/mt_socket.c @@ -390,6 +390,7 @@ int mt_socket_add_flow(struct mtl_main_impl* impl, enum mtl_port port, uint16_t int flow_id = -1; uint8_t start_queue = mt_afxdp_start_queue(impl, port); const char* if_name = mt_kernel_if_name(impl, port); + bool has_ip_flow = true; if (flow->flags & MT_RXQ_FLOW_F_SYS_QUEUE) { err("%s(%d), sys_queue not supported\n", __func__, port); @@ -400,7 +401,17 @@ int mt_socket_add_flow(struct mtl_main_impl* impl, enum mtl_port port, uint16_t return -EIO; } - if (flow->flags & MT_RXQ_FLOW_F_NO_IP) { + /* no ip flow requested */ + if (flow->flags & MT_RXQ_FLOW_F_NO_IP) has_ip_flow = false; + + if (mt_get_user_params(impl)->flags & MTL_FLAG_RX_UDP_PORT_ONLY) { + if (has_ip_flow) { + info("%s(%d), no ip flow as MTL_FLAG_RX_UDP_PORT_ONLY is set\n", __func__, port); + has_ip_flow = false; + } + } + + if (!has_ip_flow) { snprintf(cmd, sizeof(cmd), "ethtool -N %s flow-type udp4 dst-port %u action %u", if_name, flow->dst_port, queue_id + start_queue); } else if (mt_is_multicast_ip(flow->dip_addr)) {