@@ -275,3 +275,32 @@
return 0;
}
+
+int
+nfp_flower_cmsg_tun_neigh_v6_rule(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_flower_cmsg_tun_neigh_v6 *payload)
+{
+ uint16_t cnt;
+ size_t msg_len;
+ struct rte_mbuf *mbuf;
+ struct nfp_flower_cmsg_tun_neigh_v6 *msg;
+
+ mbuf = rte_pktmbuf_alloc(app_fw_flower->ctrl_pktmbuf_pool);
+ if (mbuf == NULL) {
+ PMD_DRV_LOG(DEBUG, "Failed to alloc mbuf for v6 tun neigh");
+ return -ENOMEM;
+ }
+
+ msg_len = sizeof(struct nfp_flower_cmsg_tun_neigh_v6);
+ msg = nfp_flower_cmsg_init(mbuf, NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6, msg_len);
+ memcpy(msg, payload, msg_len);
+
+ cnt = nfp_flower_ctrl_vnic_xmit(app_fw_flower, mbuf);
+ if (cnt == 0) {
+ PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+ rte_pktmbuf_free(mbuf);
+ return -EIO;
+ }
+
+ return 0;
+}
@@ -160,6 +160,42 @@ struct nfp_flower_cmsg_tun_neigh_v4 {
};
/*
+ * NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6
+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +---------------------------------------------------------------+
+ * 0 | DST_IPV6 [0] |
+ * +---------------------------------------------------------------+
+ * 1 | DST_IPV6 [1] |
+ * +---------------------------------------------------------------+
+ * 2 | DST_IPV6 [2] |
+ * +---------------------------------------------------------------+
+ * 3 | DST_IPV6 [3] |
+ * +---------------------------------------------------------------+
+ * 4 | SRC_IPV6 [0] |
+ * +---------------------------------------------------------------+
+ * 5 | SRC_IPV6 [1] |
+ * +---------------------------------------------------------------+
+ * 6 | SRC_IPV6 [2] |
+ * +---------------------------------------------------------------+
+ * 7 | SRC_IPV6 [3] |
+ * +---------------------------------------------------------------+
+ * 8 | DST_MAC_B5_B4_B3_B2 |
+ * +-------------------------------+-------------------------------+
+ * 9 | DST_MAC_B1_B0 | SRC_MAC_B5_B4 |
+ * +-------------------------------+-------------------------------+
+ * 10 | SRC_MAC_B3_B2_B1_B0 |
+ * +---------------+---------------+---------------+---------------+
+ * 11 | Egress Port (NFP internal) |
+ * +---------------------------------------------------------------+
+ */
+struct nfp_flower_cmsg_tun_neigh_v6 {
+ uint8_t dst_ipv6[16];
+ uint8_t src_ipv6[16];
+ struct nfp_flower_tun_neigh common;
+};
+
+/*
* NFP_FLOWER_CMSG_TYPE_FLOW_STATS
* Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
* -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
@@ -629,6 +665,8 @@ struct nfp_fl_act_pre_tun {
};
};
+#define NFP_FL_PRE_TUN_IPV6 (1 << 0)
+
/*
* Set tunnel
* 3 2 1
@@ -676,5 +714,7 @@ int nfp_flower_cmsg_flow_add(struct nfp_app_fw_flower *app_fw_flower,
struct rte_flow *flow);
int nfp_flower_cmsg_tun_neigh_v4_rule(struct nfp_app_fw_flower *app_fw_flower,
struct nfp_flower_cmsg_tun_neigh_v4 *payload);
+int nfp_flower_cmsg_tun_neigh_v6_rule(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_flower_cmsg_tun_neigh_v6 *payload);
#endif /* _NFP_CMSG_H_ */
@@ -1782,6 +1782,16 @@ struct nfp_mask_id_entry {
}
__rte_unused static void
+nfp_flow_pre_tun_v6_process(struct nfp_fl_act_pre_tun *pre_tun,
+ const uint8_t ipv6_dst[])
+{
+ pre_tun->head.jump_id = NFP_FL_ACTION_OPCODE_PRE_TUNNEL;
+ pre_tun->head.len_lw = sizeof(struct nfp_fl_act_pre_tun) >> NFP_FL_LW_SIZ;
+ pre_tun->flags = rte_cpu_to_be_16(NFP_FL_PRE_TUN_IPV6);
+ memcpy(pre_tun->ipv6_dst, ipv6_dst, sizeof(pre_tun->ipv6_dst));
+}
+
+__rte_unused static void
nfp_flow_set_tun_process(struct nfp_fl_act_set_tun *set_tun,
enum nfp_flower_tun_type tun_type,
uint64_t tun_id,
@@ -1845,7 +1855,7 @@ struct nfp_mask_id_entry {
return nfp_flower_cmsg_tun_neigh_v4_rule(app_fw_flower, &payload);
}
-__rte_unused static int
+static int
nfp_flower_del_tun_neigh_v4(struct nfp_app_fw_flower *app_fw_flower,
rte_be32_t ipv4)
{
@@ -1857,6 +1867,99 @@ struct nfp_mask_id_entry {
return nfp_flower_cmsg_tun_neigh_v4_rule(app_fw_flower, &payload);
}
+__rte_unused static int
+nfp_flower_add_tun_neigh_v6_encap(struct nfp_app_fw_flower *app_fw_flower,
+ struct nfp_fl_rule_metadata *nfp_flow_meta,
+ struct nfp_fl_tun *tun,
+ const struct rte_ether_hdr *eth,
+ const struct rte_flow_item_ipv6 *ipv6)
+{
+ struct nfp_fl_tun *tmp;
+ struct nfp_flow_priv *priv;
+ struct nfp_flower_in_port *port;
+ struct nfp_flower_cmsg_tun_neigh_v6 payload;
+
+ tun->payload.v6_flag = 1;
+ memcpy(tun->payload.dst.dst_ipv6, ipv6->hdr.dst_addr, sizeof(tun->payload.dst.dst_ipv6));
+ memcpy(tun->payload.src.src_ipv6, ipv6->hdr.src_addr, sizeof(tun->payload.src.src_ipv6));
+ memcpy(tun->payload.dst_addr, eth->dst_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
+ memcpy(tun->payload.src_addr, eth->src_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
+
+ tun->ref_cnt = 1;
+ priv = app_fw_flower->flow_priv;
+ LIST_FOREACH(tmp, &priv->nn_list, next) {
+ if (memcmp(&tmp->payload, &tun->payload, sizeof(struct nfp_fl_tun_entry)) == 0) {
+ tmp->ref_cnt++;
+ return 0;
+ }
+ }
+
+ LIST_INSERT_HEAD(&priv->nn_list, tun, next);
+
+ port = (struct nfp_flower_in_port *)((char *)nfp_flow_meta +
+ sizeof(struct nfp_fl_rule_metadata) +
+ sizeof(struct nfp_flower_meta_tci));
+
+ memset(&payload, 0, sizeof(struct nfp_flower_cmsg_tun_neigh_v6));
+ memcpy(payload.dst_ipv6, ipv6->hdr.dst_addr, sizeof(payload.dst_ipv6));
+ memcpy(payload.src_ipv6, ipv6->hdr.src_addr, sizeof(payload.src_ipv6));
+ memcpy(payload.common.dst_mac, eth->dst_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
+ memcpy(payload.common.src_mac, eth->src_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
+ payload.common.port_id = port->in_port;
+
+ return nfp_flower_cmsg_tun_neigh_v6_rule(app_fw_flower, &payload);
+}
+
+static int
+nfp_flower_del_tun_neigh_v6(struct nfp_app_fw_flower *app_fw_flower,
+ uint8_t *ipv6)
+{
+ struct nfp_flower_cmsg_tun_neigh_v6 payload;
+
+ memset(&payload, 0, sizeof(struct nfp_flower_cmsg_tun_neigh_v6));
+ memcpy(payload.dst_ipv6, ipv6, sizeof(payload.dst_ipv6));
+
+ return nfp_flower_cmsg_tun_neigh_v6_rule(app_fw_flower, &payload);
+}
+
+__rte_unused static int
+nfp_flower_del_tun_neigh(struct nfp_app_fw_flower *app_fw_flower,
+ struct rte_flow *nfp_flow)
+{
+ int ret;
+ bool flag = false;
+ struct nfp_fl_tun *tmp;
+ struct nfp_fl_tun *tun;
+
+ tun = &nfp_flow->tun;
+ LIST_FOREACH(tmp, &app_fw_flower->flow_priv->nn_list, next) {
+ ret = memcmp(&tmp->payload, &tun->payload, sizeof(struct nfp_fl_tun_entry));
+ if (ret == 0) {
+ tmp->ref_cnt--;
+ flag = true;
+ break;
+ }
+ }
+
+ if (!flag) {
+ PMD_DRV_LOG(DEBUG, "Can't find nn entry in the nn list");
+ return -EINVAL;
+ }
+
+ if (tmp->ref_cnt == 0) {
+ LIST_REMOVE(tmp, next);
+ if (tmp->payload.v6_flag != 0) {
+ return nfp_flower_del_tun_neigh_v6(app_fw_flower,
+ tmp->payload.dst.dst_ipv6);
+ } else {
+ return nfp_flower_del_tun_neigh_v4(app_fw_flower,
+ tmp->payload.dst.dst_ipv4);
+ }
+ }
+
+ return 0;
+}
+
static int
nfp_flow_compile_action(__rte_unused struct nfp_flower_representor *representor,
const struct rte_flow_action actions[],