diff mbox series

[ovs-dev,37/62] Add Intel init patch

Message ID 20201228092520.11807-38-taoyunxiang@cmss.chinamobile.com
State Not Applicable
Headers show
Series DPDK Offload API to test | expand

Commit Message

Tao YunXiang Dec. 28, 2020, 9:24 a.m. UTC
From: Rongyin <rongyin@cmss.chinamobile.com>

Code Source From: Self Code

Description:

     Add Intel init patch

Jira:  #[Optional]
市场项目编号(名称):[Optional]
---
 lib/dp-packet.h           |   6 ++
 lib/netdev-offload-dpdk.c | 211 +++++++++++++++++++++++++++++++++++++---------
 lib/packets.h             |  22 +++++
 3 files changed, 197 insertions(+), 42 deletions(-)
diff mbox series

Patch

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index 9f8991f..9e415cb 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -1082,6 +1082,12 @@  dp_packet_batch_init_packet_fields(struct dp_packet_batch *batch)
     DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
         dp_packet_reset_cutlen(packet);
         packet->packet_type = htonl(PT_ETH);
+        /* Packet mbuf allocated by SP/EP device mempool
+         * and OVS doesn't know about it and all OVS required
+         * initializations missed. OVS needs mbuf orignation to do
+         * various opertions like cleanup, etc..
+         */
+        packet->source = DPBUF_DPDK;
     }
 }
 
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 13b46a5..21a4058 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -29,6 +29,7 @@ 
 #include "openvswitch/vlog.h"
 #include "packets.h"
 #include "uuid.h"
+#include <netinet/icmp6.h>
 #include "id-pool.h"
 #include "odp-util.h"
 
@@ -234,6 +235,31 @@  dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
         } else {
             ds_put_cstr(s, "  Mask = null\n");
         }
+    } else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
+       const struct rte_flow_item_ipv6 *ipv6_spec = item->spec;
+       const struct rte_flow_item_ipv6 *ipv6_mask = item->mask;
+
+       ds_put_cstr(s, "rte flow ipv6 pattern:\n");
+       if (ipv6_spec) {
+           ds_put_format(s,
+                         " proto=0x%"PRIx8
+                         ", src="IP6_FMT", dst="IP6_FMT"\n",
+                         ipv6_spec->hdr.proto,
+                         IP6_ARGS(ipv6_spec->hdr.src_addr),
+                         IP6_ARGS(ipv6_spec->hdr.dst_addr));
+       } else {
+           ds_put_cstr(s, "  Spec = null\n");
+       }
+       if (ipv6_mask) {
+           ds_put_format(s,
+                         " proto=0x%"PRIx8
+                         ", src="IP6_FMT", dst="IP6_FMT"\n",
+                         ipv6_mask->hdr.proto,
+                         IP6_ARGS(ipv6_mask->hdr.src_addr),
+                         IP6_ARGS(ipv6_mask->hdr.dst_addr));
+       } else {
+           ds_put_cstr(s, "  Mask = null\n");
+       }
     } else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
         const struct rte_flow_item_udp *udp_spec = item->spec;
         const struct rte_flow_item_udp *udp_mask = item->mask;
@@ -295,11 +321,33 @@  dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
             ds_put_format(s,
                           "  Mask: icmp_type=0x%"PRIx8
                           ", icmp_code=0x%"PRIx8"\n",
-                          icmp_spec->hdr.icmp_type,
-                          icmp_spec->hdr.icmp_code);
+                          icmp_mask->hdr.icmp_type,
+                          icmp_mask->hdr.icmp_code);
         } else {
             ds_put_cstr(s, "  Mask = null\n");
         }
+    } else if (item->type == RTE_FLOW_ITEM_TYPE_ICMP6) {
+       const struct rte_flow_item_icmp6 *icmp6_spec = item->spec;
+       const struct rte_flow_item_icmp6 *icmp6_mask = item->mask;
+
+       ds_put_cstr(s, "rte flow icmpv6 pattern:\n");
+       if (icmp6_spec) {
+           ds_put_format(s,
+                         "  Spec: icmp6_type=%"PRIu8", icmp6_code=%"PRIu8"\n",
+                         icmp6_spec->type,
+                         icmp6_spec->code);
+       } else {
+           ds_put_cstr(s, "  Spec = null\n");
+       }
+       if (icmp6_mask) {
+           ds_put_format(s,
+                         "  Mask: icmp6_type=0x%"PRIx8
+                         ", icmp6_code=0x%"PRIx8"\n",
+                         icmp6_mask->type,
+                         icmp6_mask->code);
+       } else {
+           ds_put_cstr(s, "  Mask = null\n");
+       }
     } else if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
         const struct rte_flow_item_tcp *tcp_spec = item->spec;
         const struct rte_flow_item_tcp *tcp_mask = item->mask;
@@ -459,7 +507,16 @@  dump_flow_action(struct ds *s, const struct rte_flow_action *actions)
          
         if (vlan_tci) {
             ds_put_format(s, "rte flow vlan-push action:\n");
-            ds_put_format(s, "vlan-encap: tci=%"PRIu16"\n",ntohs(vlan_tci->ethertype));
+            ds_put_format(s, "vlan-encap: tpid=%"PRIu16"\n",ntohs(vlan_tci->ethertype));
+        } else {
+            ds_put_format(s, "vlan-encap: null\n");
+        }
+    } else if (actions->type == RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID) {
+        const struct rte_flow_action_of_set_vlan_vid *vid = actions->conf;
+         
+        if (vid) {
+            ds_put_format(s, "rte flow vlan-push action:\n");
+            ds_put_format(s, "vlan-encap: vid=%"PRIu16"\n",ntohs(vid->vlan_vid));
         } else {
             ds_put_format(s, "vlan-encap: null\n");
         }
@@ -706,6 +763,12 @@  parse_geneve_match(struct flow_patterns *patterns,
                    const struct match *match)
 {
     struct rte_flow_item_geneve *vx_spec, *vx_mask;
+    /* TBD 
+    uint8_t data_len;
+    uint32_t len,opt_data;
+    struct geneve_opt *opt;
+    uint8_t i;
+     */
 
     if (is_all_zeros(&match->wc.masks.tunnel, sizeof match->wc.masks.tunnel)) {
         return -1;
@@ -729,7 +792,20 @@  parse_geneve_match(struct flow_patterns *patterns,
                        htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
 
     add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_GENEVE, vx_spec, vx_mask);
-    /* TBD: add option hdr */
+
+    /* TBD: add option hdr 
+    len = match->flow.tunnel.metadata.present.len;
+    if (len > 0) {
+        opt = &match->flow.tunnel.metadata.opts.gnv;
+        data_len = opt->length*4;
+        uint8_t *buf = (opt+1);
+        for (i=0; i<data_len; i++) {
+            uint8_t val = *buf[i];
+            opt_data = opt_data | val ;
+            opt_data = (i==data_len-1)? opt_data: opt_data<< 8;
+        }
+    }
+    */
     return 0;
 }
 
@@ -821,6 +897,15 @@  parse_flow_match(struct flow_patterns *patterns,
     if (match->flow.dl_type == htons(ETH_TYPE_IP)) {
         struct rte_flow_item_ipv4 *spec, *mask;
 
+        /* Vista Creek PAC N3000 hardware doesn't support IPv4 Multicast
+         * messages acceleration. So, checking for the same and returning
+         * from here if it matches.
+         */
+        if (ip_is_multicast(match->flow.nw_dst)) {
+            VLOG_DBG("IPV4 multicast address not supported");
+            return -1;
+        }
+
         spec = xzalloc(sizeof *spec);
         mask = xzalloc(sizeof *mask);
 
@@ -850,16 +935,19 @@  parse_flow_match(struct flow_patterns *patterns,
          */
         proto = spec->hdr.next_proto_id ;
         next_proto_mask = &mask->hdr.next_proto_id;
-    } else {
-        /* if eth_type is not IP ,just transit eth rte_flow */
-        add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
-        return 0;
-    }
-
-    /* IP v6 */
-    if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
+    } else if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
+        /* IP v6 */
         struct rte_flow_item_ipv6 *spec, *mask;
 
+        /* Vista Creek PAC N3000 hardware doesn't support IPv6 Multicast
+         * messages acceleration. So, checking for the same and returning
+         * from here if it matches.
+         */
+        if (ipv6_addr_is_multicast(&match->flow.ipv6_dst)) {
+            VLOG_DBG("IPV6 multicast address not supported");
+            return -1;
+        }
+
         spec = xzalloc(sizeof *spec);
         mask = xzalloc(sizeof *mask);
 
@@ -892,10 +980,15 @@  parse_flow_match(struct flow_patterns *patterns,
         /* Save proto for L4 protocol setup */
         proto = spec->hdr.proto & mask->hdr.proto;
         next_proto_mask = &mask->hdr.proto;
+    } else {
+        /* if eth_type is not IP ,just transit eth rte_flow */
+        add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
+        return 0;
     }
 
     if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP  &&
-        proto != IPPROTO_SCTP && proto != IPPROTO_TCP  ){
+        proto != IPPROTO_SCTP && proto != IPPROTO_TCP  &&
+        proto != IPPROTO_ICMPV6 ){
         VLOG_DBG("L4 Protocol (%u) not supported", proto);
         return -1;
     }
@@ -989,6 +1082,34 @@  parse_flow_match(struct flow_patterns *patterns,
         if (next_proto_mask) {
             *next_proto_mask = 0;
         }
+    } else if (proto == IPPROTO_ICMPV6) {
+        struct rte_flow_item_icmp6 *spec, *mask;
+
+        /* Vista Creek PAC N3000 hardware doesn't support IPv6 NS and NA
+         * messages acceleration. So, checking for the same and returning from here
+         * if it matches.
+         */
+        if (match->flow.tp_src == ntohs(ND_NEIGHBOR_SOLICIT) ||
+            match->flow.tp_src == ntohs(ND_NEIGHBOR_ADVERT) ) {
+            VLOG_DBG("IPv6 NS and ND messages HW acceleration not supported");
+            return -1;
+        }
+
+        spec = xzalloc(sizeof *spec);
+        mask = xzalloc(sizeof *mask);
+
+        spec->type = (uint8_t) ntohs(match->flow.tp_src);
+        spec->code = (uint8_t) ntohs(match->flow.tp_dst);
+
+        mask->type = (uint8_t) ntohs(match->wc.masks.tp_src);
+        mask->code = (uint8_t) ntohs(match->wc.masks.tp_dst);
+
+        add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP6, spec, mask);
+
+        /* proto == ICMPV6 and ITEM_TYPE_ICMPV6, thus no need for proto match. */
+        if (next_proto_mask) {
+            *next_proto_mask = 0;
+        }
     }
 
     add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
@@ -1043,32 +1164,6 @@  add_flow_mark_rss_actions(struct flow_actions *actions,
     add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL);
 }
 
-static struct rte_flow *
-netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns,
-                             struct netdev *netdev,
-                             uint32_t flow_mark)
-{
-    struct flow_actions actions = { .actions = NULL, .cnt = 0 };
-    const struct rte_flow_attr flow_attr = {
-        .group = 0,
-        .priority = 0,
-        .ingress = 1,
-        .egress = 0
-    };
-    struct rte_flow *flow;
-    /* work around : not do mark rss action
-    struct rte_flow_error error;
-
-    add_flow_mark_rss_actions(&actions, flow_mark, netdev);
-
-    flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
-                                           actions.actions, &error);
-
-    */
-    free_flow_actions(&actions);
-    return flow;
-}
-
 static void
 add_count_action(struct flow_actions *actions)
 {
@@ -1214,6 +1309,17 @@  parse_set_actions(struct flow_actions *actions,
                 VLOG_DBG_RL(&rl, "Unsupported IPv4 set action");
                 return -1;
             }
+        } else if (nl_attr_type(sa) == OVS_KEY_ATTR_IPV6) {
+            const struct ovs_key_ipv6 *key = nl_attr_get(sa);
+            const struct ovs_key_ipv6 *mask = masked ? key + 1 : NULL;
+
+            add_set_flow_action(ipv6_src, RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC);
+            add_set_flow_action(ipv6_dst, RTE_FLOW_ACTION_TYPE_SET_IPV6_DST);
+
+            if (mask && !is_all_zeros(mask, sizeof *mask)) {
+                VLOG_DBG_RL(&rl, "Unsupported IPv6 set action");
+                return -1;
+            }
         } else if (nl_attr_type(sa) == OVS_KEY_ATTR_TCP) {
             const struct ovs_key_tcp *key = nl_attr_get(sa);
             const struct ovs_key_tcp *mask = masked ? key + 1 : NULL;
@@ -1474,11 +1580,21 @@  parse_clone_actions(struct netdev *netdev,
         } else if (clone_type == OVS_ACTION_ATTR_PUSH_VLAN) {
             const struct ovs_action_push_vlan *vlan = nl_attr_get(ca);
             struct rte_flow_action_of_push_vlan *vlan_tci;
+            struct rte_flow_action_of_set_vlan_vid *vid;
 
+            if (vlan == NULL) {
+                VLOG_DBG_RL(&rl, "VLAN attribute info null...");
+                return -1;
+            }
             vlan_tci = xzalloc(sizeof *vlan_tci);
-            vlan_tci->ethertype = vlan->vlan_tci & ~htons(VLAN_CFI);
+            vlan_tci->ethertype = vlan->vlan_tpid;
             add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN,
                             vlan_tci);
+
+            vid = xzalloc(sizeof *vid);
+            vid->vlan_vid = vlan->vlan_tci & ~htons(VLAN_CFI);
+            add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID, vid);
+
         } else if (clone_type == OVS_ACTION_ATTR_POP_VLAN) {
             add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, NULL);
         } else {
@@ -1540,11 +1656,22 @@  parse_flow_actions(struct netdev *netdev,
         } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_VLAN) {
             const struct ovs_action_push_vlan *vlan = nl_attr_get(nla);
             struct rte_flow_action_of_push_vlan *vlan_tci;
+            struct rte_flow_action_of_set_vlan_vid *vid;
+
+            if (vlan == NULL) {
+                VLOG_DBG_RL(&rl, "VLAN attribute info null...");
+                return -1;
+            }
 
             vlan_tci = xzalloc(sizeof *vlan_tci);
-            vlan_tci->ethertype = vlan->vlan_tci & ~htons(VLAN_CFI);
+            vlan_tci->ethertype = vlan->vlan_tpid;
             add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN,
                             vlan_tci);
+
+            vid = xzalloc(sizeof *vid);
+            vid->vlan_vid = vlan->vlan_tci & ~htons(VLAN_CFI);
+            add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID, vid);
+
         } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) {
             add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, NULL);
         } else {
@@ -1637,9 +1764,9 @@  netdev_offload_dpdk_add_flow(struct netdev *netdev,
     if (!flow) {
         /* If we failed to offload the rule actions fallback to MARK+RSS
          * actions.
-         */
         flow = netdev_offload_dpdk_mark_rss(&patterns, netdev,
                                             info->flow_mark);
+         */
         actions_offloaded = false;
     }
 
diff --git a/lib/packets.h b/lib/packets.h
index 5d7f82c..9d5d241 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -632,6 +632,28 @@  mpls_lse_to_bos(ovs_be32 mpls_lse)
     (ntohl(ip) >> 8) & 0xff,                    \
     ntohl(ip) & 0xff
 
+#define IP6_FMT "%"PRIx8"%"PRIx8":%"PRIx8"%"PRIx8 \
+    ":%"PRIx8"%"PRIx8":%"PRIx8"%"PRIx8            \
+    ":%"PRIx8"%"PRIx8":%"PRIx8"%"PRIx8            \
+    ":%"PRIx8"%"PRIx8":%"PRIx8"%"PRIx8
+#define IP6_ARGS(ip6) \
+    ntohs(ip6[0]),    \
+    ntohs(ip6[1]),    \
+    ntohs(ip6[2]),    \
+    ntohs(ip6[3]),    \
+    ntohs(ip6[4]),    \
+    ntohs(ip6[5]),    \
+    ntohs(ip6[6]),    \
+    ntohs(ip6[7]),    \
+    ntohs(ip6[8]),    \
+    ntohs(ip6[9]),    \
+    ntohs(ip6[10]),   \
+    ntohs(ip6[11]),   \
+    ntohs(ip6[12]),   \
+    ntohs(ip6[13]),   \
+    ntohs(ip6[14]),   \
+    ntohs(ip6[15])
+
 /* Example:
  *
  * char *string = "1 33.44.55.66 2";