net/txgbe: add security type in flow action
authorJiawen Wu <jiawenwu@trustnetic.com>
Fri, 18 Dec 2020 09:37:02 +0000 (17:37 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 13 Jan 2021 17:51:58 +0000 (18:51 +0100)
Add security type in flow action.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
drivers/net/txgbe/txgbe_flow.c
drivers/net/txgbe/txgbe_ipsec.c
drivers/net/txgbe/txgbe_ipsec.h

index 488949c..57a4f2e 100644 (file)
@@ -129,6 +129,9 @@ const struct rte_flow_action *next_no_void_action(
  * END
  * other members in mask and spec should set to 0x00.
  * item->last should be NULL.
+ *
+ * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY.
+ *
  */
 static int
 cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
@@ -177,6 +180,43 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
        memset(&eth_null, 0, sizeof(struct rte_flow_item_eth));
        memset(&vlan_null, 0, sizeof(struct rte_flow_item_vlan));
 
+#ifdef RTE_LIB_SECURITY
+       /**
+        *  Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY
+        */
+       act = next_no_void_action(actions, NULL);
+       if (act->type == RTE_FLOW_ACTION_TYPE_SECURITY) {
+               const void *conf = act->conf;
+               /* check if the next not void item is END */
+               act = next_no_void_action(actions, act);
+               if (act->type != RTE_FLOW_ACTION_TYPE_END) {
+                       memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+                       rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION,
+                               act, "Not supported action.");
+                       return -rte_errno;
+               }
+
+               /* get the IP pattern*/
+               item = next_no_void_pattern(pattern, NULL);
+               while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
+                               item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
+                       if (item->last ||
+                                       item->type == RTE_FLOW_ITEM_TYPE_END) {
+                               rte_flow_error_set(error, EINVAL,
+                                       RTE_FLOW_ERROR_TYPE_ITEM,
+                                       item, "IP pattern missing.");
+                               return -rte_errno;
+                       }
+                       item = next_no_void_pattern(pattern, item);
+               }
+
+               filter->proto = IPPROTO_ESP;
+               return txgbe_crypto_add_ingress_sa_from_flow(conf, item->spec,
+                                       item->type == RTE_FLOW_ITEM_TYPE_IPV6);
+       }
+#endif
+
        /* the first not void item can be MAC or IPv4 */
        item = next_no_void_pattern(pattern, NULL);
 
@@ -547,6 +587,12 @@ txgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
        if (ret)
                return ret;
 
+#ifdef RTE_LIB_SECURITY
+       /* ESP flow not really a flow */
+       if (filter->proto == IPPROTO_ESP)
+               return 0;
+#endif
+
        /* txgbe doesn't support tcp flags */
        if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
                memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
@@ -2672,6 +2718,12 @@ txgbe_flow_create(struct rte_eth_dev *dev,
        ret = txgbe_parse_ntuple_filter(dev, attr, pattern,
                        actions, &ntuple_filter, error);
 
+#ifdef RTE_LIB_SECURITY
+       /* ESP flow not really a flow*/
+       if (ntuple_filter.proto == IPPROTO_ESP)
+               return flow;
+#endif
+
        if (!ret) {
                ret = txgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
                if (!ret) {
index 6e6006f..daa523b 100644 (file)
@@ -655,6 +655,36 @@ txgbe_crypto_enable_ipsec(struct rte_eth_dev *dev)
        return 0;
 }
 
+int
+txgbe_crypto_add_ingress_sa_from_flow(const void *sess,
+                                     const void *ip_spec,
+                                     uint8_t is_ipv6)
+{
+       struct txgbe_crypto_session *ic_session =
+                       get_sec_session_private_data(sess);
+
+       if (ic_session->op == TXGBE_OP_AUTHENTICATED_DECRYPTION) {
+               if (is_ipv6) {
+                       const struct rte_flow_item_ipv6 *ipv6 = ip_spec;
+                       ic_session->src_ip.type = IPv6;
+                       ic_session->dst_ip.type = IPv6;
+                       rte_memcpy(ic_session->src_ip.ipv6,
+                                  ipv6->hdr.src_addr, 16);
+                       rte_memcpy(ic_session->dst_ip.ipv6,
+                                  ipv6->hdr.dst_addr, 16);
+               } else {
+                       const struct rte_flow_item_ipv4 *ipv4 = ip_spec;
+                       ic_session->src_ip.type = IPv4;
+                       ic_session->dst_ip.type = IPv4;
+                       ic_session->src_ip.ipv4 = ipv4->hdr.src_addr;
+                       ic_session->dst_ip.ipv4 = ipv4->hdr.dst_addr;
+               }
+               return txgbe_crypto_add_sa(ic_session);
+       }
+
+       return 0;
+}
+
 static struct rte_security_ops txgbe_security_ops = {
        .session_create = txgbe_crypto_create_session,
        .session_get_size = txgbe_crypto_session_get_size,
index 58e1855..5edd6b5 100644 (file)
@@ -90,5 +90,8 @@ struct txgbe_ipsec {
 };
 
 int txgbe_crypto_enable_ipsec(struct rte_eth_dev *dev);
+int txgbe_crypto_add_ingress_sa_from_flow(const void *sess,
+                                         const void *ip_spec,
+                                         uint8_t is_ipv6);
 
 #endif /*TXGBE_IPSEC_H_*/