Hi Sowmini, > -----Original Message----- > From: Sowmini Varadhan <sovar...@linux.microsoft.com> > Sent: Thursday, August 12, 2021 9:18 PM > To: sowmin...@gmail.com; Iremonger, Bernard > <bernard.iremon...@intel.com>; dev@dpdk.org; > sovar...@linux.microsoft.com > Cc: tho...@monjalon.net > Subject: [PATCH 1/2] Hooks to allow the setting of filters on tcp flags
~/dpdk_21_08/devtools# ./check-git-log.sh -1 Wrong headline format: Hooks to allow the setting of filters on tcp flags The subject line should be prefixed with examples/flow_classify: examples/flow_classify: Hooks to allow the setting of filters on tcp flags > > The rte_eth_ntuple_filter allows tcp_flags which can check for things like > #define RTE_TCP_CWR_FLAG 0x80 /**< Congestion Window Reduced */ > #define RTE_TCP_ECE_FLAG 0x40 /**< ECN-Echo */ > #define RTE_TCP_URG_FLAG 0x20 /**< Urgent Pointer field significant */ > #define RTE_TCP_ACK_FLAG 0x10 /**< Acknowledgment field significant > */ > #define RTE_TCP_PSH_FLAG 0x08 /**< Push Function */ > #define RTE_TCP_RST_FLAG 0x04 /**< Reset the connection */ > #define RTE_TCP_SYN_FLAG 0x02 /**< Synchronize sequence numbers */ > #define RTE_TCP_FIN_FLAG 0x01 /**< No more data from sender */ but > there are no existing examples that demonstrate how to use this feature. > > This patch extends the exisiting classification support to allow an optional Typo: " exisiting" should be "existing" > flags in the input file. The flags string can be any concatenation of > characters > from {C, E, U, A, P, R, S, F} and "*" indicates "dont care". These flags are > set in > the ntuple_filter and are used to construct the tcp_spec and tcp_mask sent > to the driver > > The rte_acl_field_def is updated to use the (u8) tcp flag as lookup key. > Note that, as per > https://doc.dpdk.org/guides/prog_guide/packet_classif_access_ctrl.html > this field MUST be allocated fo4 4 bytes, thus it has sizeof(uint32_t). Typo: "fo4" should be "for" > > However, also note the XXX in this commit: additional updates are needed to > the rte_flow_classify_table_entry_add() so that it does not ignore any key > fields other than the 5-tuple. > > Signed-off-by: Sowmini Varadhan <sovar...@linux.microsoft.com> > --- > examples/flow_classify/flow_classify.c | 87 ++++++++++++++++++++-- > examples/flow_classify/ipv4_rules_file.txt | 22 +++--- > 2 files changed, 91 insertions(+), 18 deletions(-) > > diff --git a/examples/flow_classify/flow_classify.c > b/examples/flow_classify/flow_classify.c > index db71f5aa04..772b15adf2 100644 > --- a/examples/flow_classify/flow_classify.c > +++ b/examples/flow_classify/flow_classify.c > @@ -51,6 +51,7 @@ enum { > CB_FLD_DST_PORT_MASK, > CB_FLD_PROTO, > CB_FLD_PRIORITY, > + CB_FLD_TCP_FLAGS, > CB_FLD_NUM, > }; > > @@ -86,6 +87,7 @@ enum { > DST_FIELD_IPV4, > SRCP_FIELD_IPV4, > DSTP_FIELD_IPV4, > + TCP_FLAGS_FIELD, > NUM_FIELDS_IPV4 > }; > > @@ -93,7 +95,8 @@ enum { > PROTO_INPUT_IPV4, > SRC_INPUT_IPV4, > DST_INPUT_IPV4, > - SRCP_DESTP_INPUT_IPV4 > + SRCP_DESTP_INPUT_IPV4, > + TCP_FLAGS_INDEX, > }; > > static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { @@ -150,6 > +153,17 @@ static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { > sizeof(struct rte_ipv4_hdr) + > offsetof(struct rte_tcp_hdr, dst_port), > }, > + /* next field must be 4 bytes, even though flags is only 1 byte */ > + { > + /* rte_flags */ > + .type = RTE_ACL_FIELD_TYPE_BITMASK, > + .size = sizeof(uint32_t), > + .field_index = TCP_FLAGS_FIELD, > + .input_index = TCP_FLAGS_INDEX, > + .offset = sizeof(struct rte_ether_hdr) + > + sizeof(struct rte_ipv4_hdr) + > + offsetof(struct rte_tcp_hdr, tcp_flags), > + }, > }; > /* >8 End of creation of ACL table. */ > > @@ -285,12 +299,14 @@ lcore_main(struct flow_classifier *cls_app) > int ret; > int i = 0; > > - ret = rte_flow_classify_table_entry_delete(cls_app->cls, > - rules[7]); > - if (ret) > - printf("table_entry_delete failed [7] %d\n\n", ret); > - else > - printf("table_entry_delete succeeded [7]\n\n"); > + if (rules[7]) { > + ret = rte_flow_classify_table_entry_delete(cls_app->cls, > + rules[7]); > + if (ret) > + printf("table_entry_delete failed [7] %d\n\n", ret); > + else > + printf("table_entry_delete succeeded [7]\n\n"); > + } > > /* > * Check that the port is on the same NUMA node as the polling > thread @@ -410,6 +426,53 @@ parse_ipv4_net(char *in, uint32_t *addr, > uint32_t *mask_len) > return 0; > } > > +static int > +get_tcp_flags(char *in, struct rte_eth_ntuple_filter *ntuple_filter) { > + int len = strlen(in); > + int i; > + uint8_t flags = 0; > + > + if (strcmp(in, "*") == 0) { > + ntuple_filter->tcp_flags = 0; > + return 0; > + } > + > + for (i = 0; i < len; i++) { > + switch (in[i]) { > + case 'S': > + flags |= RTE_TCP_SYN_FLAG; > + break; > + case 'F': > + flags |= RTE_TCP_FIN_FLAG; > + break; > + case 'R': > + flags |= RTE_TCP_RST_FLAG; > + break; > + case 'P': > + flags |= RTE_TCP_PSH_FLAG; > + break; > + case 'A': > + flags |= RTE_TCP_ACK_FLAG; > + break; > + case 'U': > + flags |= RTE_TCP_URG_FLAG; > + break; > + case 'E': > + flags |= RTE_TCP_ECE_FLAG; > + break; > + case 'C': > + flags |= RTE_TCP_CWR_FLAG; > + break; > + default: > + fprintf(stderr, "unknown flag %c\n", in[i]); > + return -1; Probably better to return -EINVAL similar to other functions. > + } > + } > + ntuple_filter->tcp_flags = flags; > + return 0; > +} > + > static int > parse_ipv4_5tuple_rule(char *str, struct rte_eth_ntuple_filter > *ntuple_filter) { @@ -481,6 +544,8 @@ parse_ipv4_5tuple_rule(char *str, > struct rte_eth_ntuple_filter *ntuple_filter) > ntuple_filter->priority = (uint16_t)temp; > if (ntuple_filter->priority > FLOW_CLASSIFY_MAX_PRIORITY) > ret = -EINVAL; > + if (get_tcp_flags(in[CB_FLD_TCP_FLAGS], ntuple_filter)) > + return -EINVAL; > > return ret; > } > @@ -597,10 +662,13 @@ add_classify_rule(struct rte_eth_ntuple_filter > *ntuple_filter, > memset(&tcp_spec, 0, sizeof(tcp_spec)); > tcp_spec.hdr.src_port = ntuple_filter->src_port; > tcp_spec.hdr.dst_port = ntuple_filter->dst_port; > + tcp_spec.hdr.tcp_flags = ntuple_filter->tcp_flags; > > memset(&tcp_mask, 0, sizeof(tcp_mask)); > tcp_mask.hdr.src_port = ntuple_filter->src_port_mask; > tcp_mask.hdr.dst_port = ntuple_filter->dst_port_mask; > + if (tcp_spec.hdr.tcp_flags != 0) > + tcp_mask.hdr.tcp_flags = 0xff; > > tcp_item.type = RTE_FLOW_ITEM_TYPE_TCP; > tcp_item.spec = &tcp_spec; > @@ -655,6 +723,11 @@ add_classify_rule(struct rte_eth_ntuple_filter > *ntuple_filter, > return ret; > } > > + /* XXX but this only adds table_type of > + * RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE > + * i.e., it only ever does allocate_acl_ipv4_5tuple_rule() > + * so the tcp_flags is ignored! > + */ > rule = rte_flow_classify_table_entry_add( > cls_app->cls, &attr, pattern_ipv4_5tuple, > actions, &key_found, &error); > diff --git a/examples/flow_classify/ipv4_rules_file.txt > b/examples/flow_classify/ipv4_rules_file.txt > index dfa0631fcc..415573732a 100644 > --- a/examples/flow_classify/ipv4_rules_file.txt > +++ b/examples/flow_classify/ipv4_rules_file.txt > @@ -1,14 +1,14 @@ > #file format: > -#src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask > proto/mask priority > +#src_ip/masklen dst_ip/masklen src_port : mask dst_port : mask > +proto/mask priority tcp_flags > # > -2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 > -9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 > -9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 > -9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 > -6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 > -6.7.8.9/32 192.168.0.36/32 10 : 0xffff 11 : 0xffff 6/0xfe 5 > -6.7.8.9/24 192.168.0.36/24 10 : 0xffff 11 : 0xffff 6/0xfe 6 > -6.7.8.9/16 192.168.0.36/16 10 : 0xffff 11 : 0xffff 6/0xfe 7 > -6.7.8.9/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 8 > +2.2.2.3/24 2.2.2.7/24 32 : 0xffff 33 : 0xffff 17/0xff 0 * > +9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 17/0xff 1 * > +9.9.9.3/24 9.9.9.7/24 32 : 0xffff 33 : 0xffff 6/0xff 2 * > +9.9.8.3/24 9.9.8.7/24 32 : 0xffff 33 : 0xffff 6/0xff 3 * > +6.7.8.9/24 2.3.4.5/24 32 : 0x0000 33 : 0x0000 132/0xff 4 * > +6.7.8.9/32 192.168.0.36/32 10 : 0xffff 11 : 0xffff 6/0xfe 5 * > +6.7.8.9/24 192.168.0.36/24 10 : 0xffff 11 : 0xffff 6/0xfe 6 * > +6.7.8.9/16 192.168.0.36/16 10 : 0xffff 11 : 0xffff 6/0xfe 7 * > +6.7.8.9/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 8 * > #error rules > -#9.8.7.6/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 9 \ No newline at > end > of file > +#9.8.7.6/8 192.168.0.36/8 10 : 0xffff 11 : 0xffff 6/0xfe 9 * > -- > 2.17.1