examples: use SPDX tag for Intel copyright files
[dpdk.git] / examples / ip_pipeline / pipeline / pipeline_routing_be.c
index 431c636..6258a1a 100644 (file)
@@ -1,34 +1,5 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2016 Intel Corporation
  */
 
 #include <stdio.h>
@@ -65,7 +36,9 @@
        ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
 
 
-#define MAC_SRC_DEFAULT 0x112233445566
+/* Network Byte Order (NBO) */
+#define SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr, ethertype)      \
+       (((uint64_t) macaddr) | (((uint64_t) rte_cpu_to_be_16(ethertype)) << 48))
 
 #ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
 #define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
@@ -75,6 +48,7 @@ struct pipeline_routing {
        struct pipeline p;
        struct pipeline_routing_params params;
        pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
+       uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
 } __rte_cache_aligned;
 
 /*
@@ -132,6 +106,10 @@ static void *
 pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p,
        void *msg);
 
+static void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p,
+       void *msg);
+
 static pipeline_msg_req_handler custom_handlers[] = {
        [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD] =
                pipeline_routing_msg_req_route_add_handler,
@@ -149,6 +127,8 @@ static pipeline_msg_req_handler custom_handlers[] = {
                pipeline_routing_msg_req_arp_add_default_handler,
        [PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT] =
                pipeline_routing_msg_req_arp_del_default_handler,
+       [PIPELINE_ROUTING_MSG_REQ_SET_MACADDR] =
+               pipeline_routing_msg_req_set_macaddr_handler,
 };
 
 /*
@@ -182,7 +162,7 @@ struct layout {
        dst->c = src->c;                                        \
 }
 
-static inline __attribute__((always_inline)) void
+static __rte_always_inline void
 pkt_work_routing(
        struct rte_mbuf *pkt,
        struct rte_pipeline_table_entry *table_entry,
@@ -308,7 +288,7 @@ pkt_work_routing(
        }
 }
 
-static inline __attribute__((always_inline)) void
+static __rte_always_inline void
 pkt4_work_routing(
        struct rte_mbuf **pkts,
        struct rte_pipeline_table_entry **table_entries,
@@ -921,6 +901,7 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
        struct pipeline_params *params)
 {
        uint32_t n_routes_present = 0;
+       uint32_t port_local_dest_present = 0;
        uint32_t encap_present = 0;
        uint32_t qinq_sched_present = 0;
        uint32_t mpls_color_mark_present = 0;
@@ -933,6 +914,7 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 
        /* default values */
        p->n_routes = PIPELINE_ROUTING_N_ROUTES_DEFAULT;
+       p->port_local_dest = params->n_ports_out - 1;
        p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
        p->qinq_sched = 0;
        p->mpls_color_mark = 0;
@@ -962,6 +944,23 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 
                        continue;
                }
+               /* port_local_dest */
+               if (strcmp(arg_name, "port_local_dest") == 0) {
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               port_local_dest_present == 0, params->name,
+                               arg_name);
+                       port_local_dest_present = 1;
+
+                       status = parser_read_uint32(&p->port_local_dest,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
+                               (p->port_local_dest < params->n_ports_out)),
+                               params->name, arg_name, arg_value);
+
+                       continue;
+               }
 
                /* encap */
                if (strcmp(arg_name, "encap") == 0) {
@@ -1321,17 +1320,20 @@ pipeline_routing_init(struct pipeline_params *params,
 
        /* ARP table configuration */
        if (p_rt->params.n_arp_entries) {
-               struct rte_table_hash_key8_ext_params table_arp_params = {
-                       .n_entries = p_rt->params.n_arp_entries,
-                       .n_entries_ext = p_rt->params.n_arp_entries,
+               struct rte_table_hash_params table_arp_params = {
+                       .name = p->name,
+                       .key_size = 8,
+                       .key_offset = p_rt->params.arp_key_offset,
+                       .key_mask = NULL,
+                       .n_keys = p_rt->params.n_arp_entries,
+                       .n_buckets =
+                               rte_align32pow2(p_rt->params.n_arp_entries / 4),
                        .f_hash = hash_default_key8,
                        .seed = 0,
-                       .signature_offset = 0, /* Unused */
-                       .key_offset = p_rt->params.arp_key_offset,
                };
 
                struct rte_pipeline_table_params table_params = {
-                       .ops = &rte_table_hash_key8_ext_dosig_ops,
+                       .ops = &rte_table_hash_key8_ext_ops,
                        .arg_create = &table_arp_params,
                        .f_action_hit = get_arp_table_ah_hit(p_rt),
                        .f_action_miss = NULL,
@@ -1418,27 +1420,6 @@ pipeline_routing_free(void *pipeline)
        return 0;
 }
 
-static int
-pipeline_routing_track(void *pipeline,
-       __rte_unused uint32_t port_in,
-       uint32_t *port_out)
-{
-       struct pipeline *p = (struct pipeline *) pipeline;
-
-       /* Check input arguments */
-       if ((p == NULL) ||
-               (port_in >= p->n_ports_in) ||
-               (port_out == NULL))
-               return -1;
-
-       if (p->n_ports_in == 1) {
-               *port_out = 0;
-               return 0;
-       }
-
-       return -1;
-}
-
 static int
 pipeline_routing_timer(void *pipeline)
 {
@@ -1534,7 +1515,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether - ARP off */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
                (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t macaddr_dst;
                uint64_t ethertype = ETHER_TYPE_IPv4;
 
@@ -1542,7 +1523,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
                macaddr_dst = rte_bswap64(macaddr_dst << 16);
 
                entry_arp0.slab[0] =
-                       rte_bswap64((macaddr_src << 16) | ethertype);
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
                entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
                entry_arp0.slab[1] = rte_bswap64(macaddr_dst);
@@ -1556,11 +1537,11 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether - ARP on */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
                p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t ethertype = ETHER_TYPE_IPv4;
 
-               entry_arp1.slab[0] = rte_bswap64((macaddr_src << 16) |
-                       ethertype);
+               entry_arp1.slab[0] =
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
                entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
                entry_arp1.data_offset = entry_arp1.slab_offset[0] - 6
@@ -1571,7 +1552,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether QinQ - ARP off */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
                (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t macaddr_dst;
                uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
                uint64_t ethertype_vlan = 0x8100;
@@ -1588,8 +1569,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
                        ethertype_ipv4);
                entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
-               entry_arp0.slab[1] = rte_bswap64((macaddr_src << 16) |
-                       ethertype_qinq);
+               entry_arp0.slab[1] =
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
                entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
 
                entry_arp0.slab[2] = rte_bswap64(macaddr_dst);
@@ -1603,7 +1584,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether QinQ - ARP on */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
                p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
                uint64_t ethertype_vlan = 0x8100;
                uint64_t ethertype_qinq = 0x9100;
@@ -1616,8 +1597,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
                        ethertype_ipv4);
                entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
-               entry_arp1.slab[1] = rte_bswap64((macaddr_src << 16) |
-                       ethertype_qinq);
+               entry_arp1.slab[1] =
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
                entry_arp1.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
 
                entry_arp1.data_offset = entry_arp1.slab_offset[1] - 6
@@ -1628,7 +1609,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether MPLS - ARP off */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
                (p_rt->params.n_arp_entries == 0)) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t macaddr_dst;
                uint64_t ethertype_mpls = 0x8847;
 
@@ -1697,8 +1678,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
                        return rsp;
                }
 
-               entry_arp0.slab[2] = rte_bswap64((macaddr_src << 16) |
-                       ethertype_mpls);
+               entry_arp0.slab[2] =
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
                entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset -
                        (n_labels * 4 + 8);
 
@@ -1714,7 +1695,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
        /* Ether MPLS - ARP on */
        if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
                p_rt->params.n_arp_entries) {
-               uint64_t macaddr_src = MAC_SRC_DEFAULT;
+               uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
                uint64_t ethertype_mpls = 0x8847;
 
                uint64_t label0 = req->data.l2.mpls.labels[0];
@@ -1779,8 +1760,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
                        return rsp;
                }
 
-               entry_arp1.slab[2] = rte_bswap64((macaddr_src << 16) |
-                       ethertype_mpls);
+               entry_arp1.slab[2] =
+                       SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
                entry_arp1.slab_offset[2] = p_rt->params.ip_hdr_offset -
                        (n_labels * 4 + 8);
 
@@ -1961,10 +1942,25 @@ pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg)
        return rsp;
 }
 
+void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p, void *msg)
+{
+       struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
+       struct pipeline_routing_set_macaddr_msg_req *req = msg;
+       struct pipeline_routing_set_macaddr_msg_rsp *rsp = msg;
+       uint32_t port_id;
+
+       for (port_id = 0; port_id < p->n_ports_out; port_id++)
+               p_rt->macaddr[port_id] = req->macaddr[port_id];
+
+       rsp->status = 0;
+
+       return rsp;
+}
+
 struct pipeline_be_ops pipeline_routing_be_ops = {
        .f_init = pipeline_routing_init,
        .f_free = pipeline_routing_free,
        .f_run = NULL,
        .f_timer = pipeline_routing_timer,
-       .f_track = pipeline_routing_track,
 };