@@ -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;
}
}
@@ -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;
}
@@ -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";
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(-)