struct app_pipeline_routing_route {
struct pipeline_routing_route_key key;
- struct app_pipeline_routing_route_params params;
+ struct pipeline_routing_route_data data;
void *entry_ptr;
TAILQ_ENTRY(app_pipeline_routing_route) node;
&route->key.key.ipv4;
printf("IP Prefix = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 " => "
- "(Port = %" PRIu32 ", Next Hop IP = "
- "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ")\n",
+ ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
+ " => (Port = %" PRIu32,
+
(key->ip >> 24) & 0xFF,
(key->ip >> 16) & 0xFF,
(key->ip >> 8) & 0xFF,
key->ip & 0xFF,
key->depth,
- route->params.port_id,
+ route->data.port_id);
+
+ if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
+ printf(
+ ", Next Hop IP = %" PRIu32 ".%" PRIu32
+ ".%" PRIu32 ".%" PRIu32,
+
+ (route->data.ethernet.ip >> 24) & 0xFF,
+ (route->data.ethernet.ip >> 16) & 0xFF,
+ (route->data.ethernet.ip >> 8) & 0xFF,
+ route->data.ethernet.ip & 0xFF);
+ else
+ printf(
+ ", Next Hop HWaddress = %02" PRIx32
+ ":%02" PRIx32 ":%02" PRIx32
+ ":%02" PRIx32 ":%02" PRIx32
+ ":%02" PRIx32,
+
+ route->data.ethernet.macaddr.addr_bytes[0],
+ route->data.ethernet.macaddr.addr_bytes[1],
+ route->data.ethernet.macaddr.addr_bytes[2],
+ route->data.ethernet.macaddr.addr_bytes[3],
+ route->data.ethernet.macaddr.addr_bytes[4],
+ route->data.ethernet.macaddr.addr_bytes[5]);
+
+ if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
+ printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
+ route->data.l2.qinq.svlan,
+ route->data.l2.qinq.cvlan);
+
+ if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
+ uint32_t i;
+
+ printf(", MPLS labels");
+ for (i = 0; i < route->data.l2.mpls.n_labels; i++)
+ printf(" %" PRIu32,
+ route->data.l2.mpls.labels[i]);
+ }
- (route->params.ip >> 24) & 0xFF,
- (route->params.ip >> 16) & 0xFF,
- (route->params.ip >> 8) & 0xFF,
- route->params.ip & 0xFF);
+ printf(")\n");
}
}
print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
{
printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 ") => "
- "HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
+ ".%" PRIu32 ".%" PRIu32
+ ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
+
entry->key.key.ipv4.port_id,
(entry->key.key.ipv4.ip >> 24) & 0xFF,
(entry->key.key.ipv4.ip >> 16) & 0xFF,
app_pipeline_routing_add_route(struct app_params *app,
uint32_t pipeline_id,
struct pipeline_routing_route_key *key,
- struct app_pipeline_routing_route_params *route_params)
+ struct pipeline_routing_route_data *data)
{
struct pipeline_routing *p;
/* Check input arguments */
if ((app == NULL) ||
(key == NULL) ||
- (route_params == NULL))
+ (data == NULL))
return -1;
p = app_pipeline_data_fe(app, pipeline_id);
netmask = (~0) << (32 - depth);
key->key.ipv4.ip &= netmask;
- /* route params */
- if (route_params->port_id >= p->n_ports_out)
+ /* data */
+ if (data->port_id >= p->n_ports_out)
return -1;
}
break;
req->type = PIPELINE_MSG_REQ_CUSTOM;
req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
memcpy(&req->key, key, sizeof(*key));
- req->flags = route_params->flags;
- req->port_id = route_params->port_id;
- req->ip = route_params->ip;
+ memcpy(&req->data, data, sizeof(*data));
rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
if (rsp == NULL) {
}
memcpy(&entry->key, key, sizeof(*key));
- memcpy(&entry->params, route_params, sizeof(*route_params));
+ memcpy(&entry->data, data, sizeof(*data));
entry->entry_ptr = rsp->entry_ptr;
/* Commit entry */
return 0;
}
+static int
+parse_labels(char *string, uint32_t *labels, uint32_t *n_labels)
+{
+ uint32_t n_max_labels = *n_labels, count = 0;
+
+ /* Check for void list of labels */
+ if (strcmp(string, "<void>") == 0) {
+ *n_labels = 0;
+ return 0;
+ }
+
+ /* At least one label should be present */
+ for ( ; (*string != '\0'); ) {
+ char *next;
+ int value;
+
+ if (count >= n_max_labels)
+ return -1;
+
+ if (count > 0) {
+ if (string[0] != ':')
+ return -1;
+
+ string++;
+ }
+
+ value = strtol(string, &next, 10);
+ if (next == string)
+ return -1;
+ string = next;
+
+ labels[count++] = (uint32_t) value;
+ }
+
+ *n_labels = count;
+ return 0;
+}
+
+/*
+ * route add (mpls = no, qinq = no, arp = no)
+ */
+
+struct cmd_route_add1_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t route_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_ipaddr_t ip;
+ uint32_t depth;
+ cmdline_fixed_string_t port_string;
+ uint32_t port;
+ cmdline_fixed_string_t ether_string;
+ struct ether_addr macaddr;
+};
+
+static void
+cmd_route_add1_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ void *data)
+{
+ struct cmd_route_add1_result *params = parsed_result;
+ struct app_params *app = data;
+ struct pipeline_routing_route_key key;
+ struct pipeline_routing_route_data route_data;
+ int status;
+
+ /* Create route */
+ key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+ key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.depth = params->depth;
+
+ route_data.flags = 0;
+ route_data.port_id = params->port;
+ route_data.ethernet.macaddr = params->macaddr;
+
+ status = app_pipeline_routing_add_route(app,
+ params->p,
+ &key,
+ &route_data);
+
+ if (status != 0) {
+ printf("Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t cmd_route_add1_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_route_add1_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add1_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, route_string,
+ "route");
+
+static cmdline_parse_token_string_t cmd_route_add1_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, add_string,
+ "add");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add1_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add1_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add1_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add1_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add1_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add1_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, ether_string,
+ "ether");
+
+static cmdline_parse_token_etheraddr_t cmd_route_add1_macaddr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add1_result, macaddr);
+
+static cmdline_parse_inst_t cmd_route_add1 = {
+ .f = cmd_route_add1_parsed,
+ .data = NULL,
+ .help_str = "Route add (mpls = no, qinq = no, arp = no)",
+ .tokens = {
+ (void *)&cmd_route_add1_p_string,
+ (void *)&cmd_route_add1_p,
+ (void *)&cmd_route_add1_route_string,
+ (void *)&cmd_route_add1_add_string,
+ (void *)&cmd_route_add1_ip,
+ (void *)&cmd_route_add1_depth,
+ (void *)&cmd_route_add1_port_string,
+ (void *)&cmd_route_add1_port,
+ (void *)&cmd_route_add1_ether_string,
+ (void *)&cmd_route_add1_macaddr,
+ NULL,
+ },
+};
+
/*
- * route add
+ * route add (mpls = no, qinq = no, arp = yes)
*/
-struct cmd_route_add_result {
+struct cmd_route_add2_result {
cmdline_fixed_string_t p_string;
uint32_t p;
cmdline_fixed_string_t route_string;
cmdline_fixed_string_t add_string;
cmdline_ipaddr_t ip;
uint32_t depth;
+ cmdline_fixed_string_t port_string;
uint32_t port;
+ cmdline_fixed_string_t ether_string;
cmdline_ipaddr_t nh_ip;
};
static void
-cmd_route_add_parsed(
+cmd_route_add2_parsed(
void *parsed_result,
__rte_unused struct cmdline *cl,
void *data)
{
- struct cmd_route_add_result *params = parsed_result;
+ struct cmd_route_add2_result *params = parsed_result;
struct app_params *app = data;
struct pipeline_routing_route_key key;
- struct app_pipeline_routing_route_params rt_params;
+ struct pipeline_routing_route_data route_data;
int status;
/* Create route */
key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
key.key.ipv4.depth = params->depth;
- rt_params.flags = 0; /* remote route */
- rt_params.port_id = params->port;
- rt_params.ip = rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
+ route_data.flags = PIPELINE_ROUTING_ROUTE_ARP;
+ route_data.port_id = params->port;
+ route_data.ethernet.ip =
+ rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
status = app_pipeline_routing_add_route(app,
params->p,
&key,
- &rt_params);
+ &route_data);
if (status != 0) {
printf("Command failed\n");
}
}
-static cmdline_parse_token_string_t cmd_route_add_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, p_string,
+static cmdline_parse_token_string_t cmd_route_add2_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, p_string,
"p");
-static cmdline_parse_token_num_t cmd_route_add_p =
- TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, p, UINT32);
+static cmdline_parse_token_num_t cmd_route_add2_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, p, UINT32);
-static cmdline_parse_token_string_t cmd_route_add_route_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, route_string,
+static cmdline_parse_token_string_t cmd_route_add2_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, route_string,
"route");
-static cmdline_parse_token_string_t cmd_route_add_add_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_add_result, add_string,
+static cmdline_parse_token_string_t cmd_route_add2_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, add_string,
"add");
-static cmdline_parse_token_ipaddr_t cmd_route_add_ip =
- TOKEN_IPV4_INITIALIZER(struct cmd_route_add_result, ip);
+static cmdline_parse_token_ipaddr_t cmd_route_add2_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add2_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add2_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add2_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add2_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, ether_string,
+ "ether");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add2_nh_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, nh_ip);
+
+static cmdline_parse_inst_t cmd_route_add2 = {
+ .f = cmd_route_add2_parsed,
+ .data = NULL,
+ .help_str = "Route add (mpls = no, qinq = no, arp = yes)",
+ .tokens = {
+ (void *)&cmd_route_add2_p_string,
+ (void *)&cmd_route_add2_p,
+ (void *)&cmd_route_add2_route_string,
+ (void *)&cmd_route_add2_add_string,
+ (void *)&cmd_route_add2_ip,
+ (void *)&cmd_route_add2_depth,
+ (void *)&cmd_route_add2_port_string,
+ (void *)&cmd_route_add2_port,
+ (void *)&cmd_route_add2_ether_string,
+ (void *)&cmd_route_add2_nh_ip,
+ NULL,
+ },
+};
+
+/*
+ * route add (mpls = no, qinq = yes, arp = no)
+ */
+
+struct cmd_route_add3_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t route_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_ipaddr_t ip;
+ uint32_t depth;
+ cmdline_fixed_string_t port_string;
+ uint32_t port;
+ cmdline_fixed_string_t ether_string;
+ struct ether_addr macaddr;
+ cmdline_fixed_string_t qinq_string;
+ uint32_t svlan;
+ uint32_t cvlan;
+};
+
+static void
+cmd_route_add3_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ void *data)
+{
+ struct cmd_route_add3_result *params = parsed_result;
+ struct app_params *app = data;
+ struct pipeline_routing_route_key key;
+ struct pipeline_routing_route_data route_data;
+ int status;
+
+ /* Create route */
+ key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+ key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.depth = params->depth;
+
+ route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ;
+ route_data.port_id = params->port;
+ route_data.ethernet.macaddr = params->macaddr;
+ route_data.l2.qinq.svlan = params->svlan;
+ route_data.l2.qinq.cvlan = params->cvlan;
+
+ status = app_pipeline_routing_add_route(app,
+ params->p,
+ &key,
+ &route_data);
+
+ if (status != 0) {
+ printf("Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t cmd_route_add3_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_route_add3_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add3_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, route_string,
+ "route");
+
+static cmdline_parse_token_string_t cmd_route_add3_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, add_string,
+ "add");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add3_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add3_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add3_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add3_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add3_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add3_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, ether_string,
+ "ether");
+
+static cmdline_parse_token_etheraddr_t cmd_route_add3_macaddr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add3_result, macaddr);
+
+static cmdline_parse_token_string_t cmd_route_add3_qinq_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, qinq_string,
+ "qinq");
+
+static cmdline_parse_token_num_t cmd_route_add3_svlan =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, svlan, UINT32);
+
+static cmdline_parse_token_num_t cmd_route_add3_cvlan =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, cvlan, UINT32);
+
+static cmdline_parse_inst_t cmd_route_add3 = {
+ .f = cmd_route_add3_parsed,
+ .data = NULL,
+ .help_str = "Route add (qinq = yes, arp = no)",
+ .tokens = {
+ (void *)&cmd_route_add3_p_string,
+ (void *)&cmd_route_add3_p,
+ (void *)&cmd_route_add3_route_string,
+ (void *)&cmd_route_add3_add_string,
+ (void *)&cmd_route_add3_ip,
+ (void *)&cmd_route_add3_depth,
+ (void *)&cmd_route_add3_port_string,
+ (void *)&cmd_route_add3_port,
+ (void *)&cmd_route_add3_ether_string,
+ (void *)&cmd_route_add3_macaddr,
+ (void *)&cmd_route_add3_qinq_string,
+ (void *)&cmd_route_add3_svlan,
+ (void *)&cmd_route_add3_cvlan,
+ NULL,
+ },
+};
+
+/*
+ * route add (mpls = no, qinq = yes, arp = yes)
+ */
+
+struct cmd_route_add4_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t route_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_ipaddr_t ip;
+ uint32_t depth;
+ cmdline_fixed_string_t port_string;
+ uint32_t port;
+ cmdline_fixed_string_t ether_string;
+ cmdline_ipaddr_t nh_ip;
+ cmdline_fixed_string_t qinq_string;
+ uint32_t svlan;
+ uint32_t cvlan;
+};
+
+static void
+cmd_route_add4_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ void *data)
+{
+ struct cmd_route_add4_result *params = parsed_result;
+ struct app_params *app = data;
+ struct pipeline_routing_route_key key;
+ struct pipeline_routing_route_data route_data;
+ int status;
+
+ /* Create route */
+ key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+ key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.depth = params->depth;
+
+ route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ |
+ PIPELINE_ROUTING_ROUTE_ARP;
+ route_data.port_id = params->port;
+ route_data.ethernet.ip =
+ rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
+ route_data.l2.qinq.svlan = params->svlan;
+ route_data.l2.qinq.cvlan = params->cvlan;
+
+ status = app_pipeline_routing_add_route(app,
+ params->p,
+ &key,
+ &route_data);
+
+ if (status != 0) {
+ printf("Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t cmd_route_add4_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_route_add4_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add4_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, route_string,
+ "route");
+
+static cmdline_parse_token_string_t cmd_route_add4_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, add_string,
+ "add");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add4_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add4_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add4_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add4_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add4_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, ether_string,
+ "ether");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add4_nh_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, nh_ip);
+
+static cmdline_parse_token_string_t cmd_route_add4_qinq_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, qinq_string,
+ "qinq");
+
+static cmdline_parse_token_num_t cmd_route_add4_svlan =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, svlan, UINT32);
+
+static cmdline_parse_token_num_t cmd_route_add4_cvlan =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, cvlan, UINT32);
+
+static cmdline_parse_inst_t cmd_route_add4 = {
+ .f = cmd_route_add4_parsed,
+ .data = NULL,
+ .help_str = "Route add (qinq = yes, arp = yes)",
+ .tokens = {
+ (void *)&cmd_route_add4_p_string,
+ (void *)&cmd_route_add4_p,
+ (void *)&cmd_route_add4_route_string,
+ (void *)&cmd_route_add4_add_string,
+ (void *)&cmd_route_add4_ip,
+ (void *)&cmd_route_add4_depth,
+ (void *)&cmd_route_add4_port_string,
+ (void *)&cmd_route_add4_port,
+ (void *)&cmd_route_add4_ether_string,
+ (void *)&cmd_route_add4_nh_ip,
+ (void *)&cmd_route_add4_qinq_string,
+ (void *)&cmd_route_add4_svlan,
+ (void *)&cmd_route_add4_cvlan,
+ NULL,
+ },
+};
+
+/*
+ * route add (mpls = yes, qinq = no, arp = no)
+ */
+
+struct cmd_route_add5_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t route_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_ipaddr_t ip;
+ uint32_t depth;
+ cmdline_fixed_string_t port_string;
+ uint32_t port;
+ cmdline_fixed_string_t ether_string;
+ struct ether_addr macaddr;
+ cmdline_fixed_string_t mpls_string;
+ cmdline_fixed_string_t mpls_labels;
+};
+
+static void
+cmd_route_add5_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ void *data)
+{
+ struct cmd_route_add5_result *params = parsed_result;
+ struct app_params *app = data;
+ struct pipeline_routing_route_key key;
+ struct pipeline_routing_route_data route_data;
+ uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
+ uint32_t n_labels = RTE_DIM(mpls_labels);
+ uint32_t i;
+ int status;
+
+ /* Parse MPLS labels */
+ status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
+ if (status) {
+ printf("MPLS labels parse error\n");
+ return;
+ }
+
+ /* Create route */
+ key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+ key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.depth = params->depth;
+
+ route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS;
+ route_data.port_id = params->port;
+ route_data.ethernet.macaddr = params->macaddr;
+ for (i = 0; i < n_labels; i++)
+ route_data.l2.mpls.labels[i] = mpls_labels[i];
+ route_data.l2.mpls.n_labels = n_labels;
+
+ status = app_pipeline_routing_add_route(app,
+ params->p,
+ &key,
+ &route_data);
+
+ if (status != 0) {
+ printf("Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t cmd_route_add5_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_route_add5_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add5_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, route_string,
+ "route");
+
+static cmdline_parse_token_string_t cmd_route_add5_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, add_string,
+ "add");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add5_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add5_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add5_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add5_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add5_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add5_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, ether_string,
+ "ether");
+
+static cmdline_parse_token_etheraddr_t cmd_route_add5_macaddr =
+ TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add5_result, macaddr);
+
+static cmdline_parse_token_string_t cmd_route_add5_mpls_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_string,
+ "mpls");
+
+static cmdline_parse_token_string_t cmd_route_add5_mpls_labels =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_labels,
+ NULL);
+
+static cmdline_parse_inst_t cmd_route_add5 = {
+ .f = cmd_route_add5_parsed,
+ .data = NULL,
+ .help_str = "Route add (mpls = yes, arp = no)",
+ .tokens = {
+ (void *)&cmd_route_add5_p_string,
+ (void *)&cmd_route_add5_p,
+ (void *)&cmd_route_add5_route_string,
+ (void *)&cmd_route_add5_add_string,
+ (void *)&cmd_route_add5_ip,
+ (void *)&cmd_route_add5_depth,
+ (void *)&cmd_route_add5_port_string,
+ (void *)&cmd_route_add5_port,
+ (void *)&cmd_route_add5_ether_string,
+ (void *)&cmd_route_add5_macaddr,
+ (void *)&cmd_route_add5_mpls_string,
+ (void *)&cmd_route_add5_mpls_labels,
+ NULL,
+ },
+};
+
+/*
+ * route add (mpls = yes, qinq = no, arp = yes)
+ */
+
+struct cmd_route_add6_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t p;
+ cmdline_fixed_string_t route_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_ipaddr_t ip;
+ uint32_t depth;
+ cmdline_fixed_string_t port_string;
+ uint32_t port;
+ cmdline_fixed_string_t ether_string;
+ cmdline_ipaddr_t nh_ip;
+ cmdline_fixed_string_t mpls_string;
+ cmdline_fixed_string_t mpls_labels;
+};
+
+static void
+cmd_route_add6_parsed(
+ void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ void *data)
+{
+ struct cmd_route_add6_result *params = parsed_result;
+ struct app_params *app = data;
+ struct pipeline_routing_route_key key;
+ struct pipeline_routing_route_data route_data;
+ uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
+ uint32_t n_labels = RTE_DIM(mpls_labels);
+ uint32_t i;
+ int status;
+
+ /* Parse MPLS labels */
+ status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
+ if (status) {
+ printf("MPLS labels parse error\n");
+ return;
+ }
+
+ /* Create route */
+ key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+ key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
+ key.key.ipv4.depth = params->depth;
+
+ route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS |
+ PIPELINE_ROUTING_ROUTE_ARP;
+ route_data.port_id = params->port;
+ route_data.ethernet.ip =
+ rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
+ for (i = 0; i < n_labels; i++)
+ route_data.l2.mpls.labels[i] = mpls_labels[i];
+ route_data.l2.mpls.n_labels = n_labels;
+
+ status = app_pipeline_routing_add_route(app,
+ params->p,
+ &key,
+ &route_data);
+
+ if (status != 0) {
+ printf("Command failed\n");
+ return;
+ }
+}
+
+static cmdline_parse_token_string_t cmd_route_add6_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, p_string,
+ "p");
+
+static cmdline_parse_token_num_t cmd_route_add6_p =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, p, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add6_route_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, route_string,
+ "route");
+
+static cmdline_parse_token_string_t cmd_route_add6_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, add_string,
+ "add");
+
+static cmdline_parse_token_ipaddr_t cmd_route_add6_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, ip);
+
+static cmdline_parse_token_num_t cmd_route_add6_depth =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, depth, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add6_port_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, port_string,
+ "port");
+
+static cmdline_parse_token_num_t cmd_route_add6_port =
+ TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, port, UINT32);
+
+static cmdline_parse_token_string_t cmd_route_add6_ether_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, ether_string,
+ "ether");
-static cmdline_parse_token_num_t cmd_route_add_depth =
- TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, depth, UINT32);
+static cmdline_parse_token_ipaddr_t cmd_route_add6_nh_ip =
+ TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, nh_ip);
-static cmdline_parse_token_num_t cmd_route_add_port =
- TOKEN_NUM_INITIALIZER(struct cmd_route_add_result, port, UINT32);
+static cmdline_parse_token_string_t cmd_route_add6_mpls_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_string,
+ "mpls");
-static cmdline_parse_token_ipaddr_t cmd_route_add_nh_ip =
- TOKEN_IPV4_INITIALIZER(struct cmd_route_add_result, nh_ip);
+static cmdline_parse_token_string_t cmd_route_add6_mpls_labels =
+ TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_labels,
+ NULL);
-static cmdline_parse_inst_t cmd_route_add = {
- .f = cmd_route_add_parsed,
+static cmdline_parse_inst_t cmd_route_add6 = {
+ .f = cmd_route_add6_parsed,
.data = NULL,
- .help_str = "Route add",
+ .help_str = "Route add (mpls = yes, arp = yes)",
.tokens = {
- (void *)&cmd_route_add_p_string,
- (void *)&cmd_route_add_p,
- (void *)&cmd_route_add_route_string,
- (void *)&cmd_route_add_add_string,
- (void *)&cmd_route_add_ip,
- (void *)&cmd_route_add_depth,
- (void *)&cmd_route_add_port,
- (void *)&cmd_route_add_nh_ip,
+ (void *)&cmd_route_add6_p_string,
+ (void *)&cmd_route_add6_p,
+ (void *)&cmd_route_add6_route_string,
+ (void *)&cmd_route_add6_add_string,
+ (void *)&cmd_route_add6_ip,
+ (void *)&cmd_route_add6_depth,
+ (void *)&cmd_route_add6_port_string,
+ (void *)&cmd_route_add6_port,
+ (void *)&cmd_route_add6_ether_string,
+ (void *)&cmd_route_add6_nh_ip,
+ (void *)&cmd_route_add6_mpls_string,
+ (void *)&cmd_route_add6_mpls_labels,
NULL,
},
};
};
static cmdline_parse_ctx_t pipeline_cmds[] = {
- (cmdline_parse_inst_t *)&cmd_route_add,
+ (cmdline_parse_inst_t *)&cmd_route_add1,
+ (cmdline_parse_inst_t *)&cmd_route_add2,
+ (cmdline_parse_inst_t *)&cmd_route_add3,
+ (cmdline_parse_inst_t *)&cmd_route_add4,
+ (cmdline_parse_inst_t *)&cmd_route_add5,
+ (cmdline_parse_inst_t *)&cmd_route_add6,
(cmdline_parse_inst_t *)&cmd_route_del,
(cmdline_parse_inst_t *)&cmd_route_add_default,
(cmdline_parse_inst_t *)&cmd_route_del_default,
#include "pipeline_actions_common.h"
#include "hash_func.h"
+#define MPLS_LABEL(label, exp, s, ttl) \
+ (((((uint64_t) (label)) & 0xFFFFFLLU) << 12) | \
+ ((((uint64_t) (exp)) & 0x7LLU) << 9) | \
+ ((((uint64_t) (s)) & 0x1LLU) << 8) | \
+ (((uint64_t) (ttl)) & 0xFFLU))
+
+#define RTE_SCHED_PORT_HIERARCHY(subport, pipe, \
+ traffic_class, queue, color) \
+ ((((uint64_t) (queue)) & 0x3) | \
+ ((((uint64_t) (traffic_class)) & 0x3) << 2) | \
+ ((((uint64_t) (color)) & 0x3) << 4) | \
+ ((((uint64_t) (subport)) & 0xFFFF) << 16) | \
+ ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
+
+
+#define MAC_SRC_DEFAULT 0x112233445566
+
struct pipeline_routing {
struct pipeline p;
+ struct pipeline_routing_params params;
pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
-
- uint32_t n_routes;
- uint32_t n_arp_entries;
- uint32_t ip_da_offset;
- uint32_t arp_key_offset;
} __rte_cache_aligned;
+/*
+ * Message handlers
+ */
static void *
pipeline_routing_msg_req_custom_handler(struct pipeline *p, void *msg);
uint32_t flags;
uint32_t port_id; /* Output port ID */
uint32_t ip; /* Next hop IP address (only valid for remote routes) */
+
+ /* ether_l2 */
+ uint16_t data_offset;
+ uint16_t ether_l2_length;
+ uint64_t slab[4];
+ uint16_t slab_offset[4];
};
-static inline void
+struct layout {
+ uint16_t a;
+ uint32_t b;
+ uint16_t c;
+} __attribute__((__packed__));
+
+#define MACADDR_DST_WRITE(slab_ptr, slab) \
+{ \
+ struct layout *dst = (struct layout *) (slab_ptr); \
+ struct layout *src = (struct layout *) &(slab); \
+ \
+ dst->b = src->b; \
+ dst->c = src->c; \
+}
+
+static inline __attribute__((always_inline)) void
pkt_work_routing(
struct rte_mbuf *pkt,
struct rte_pipeline_table_entry *table_entry,
- void *arg)
+ void *arg,
+ int arp,
+ int qinq,
+ int qinq_sched,
+ int mpls,
+ int mpls_color_mark)
{
+ struct pipeline_routing *p_rt = arg;
+
struct routing_table_entry *entry =
(struct routing_table_entry *) table_entry;
- struct pipeline_routing *p_rt = arg;
+
+ struct ipv4_hdr *ip = (struct ipv4_hdr *)
+ RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.ip_hdr_offset);
+
+ enum rte_meter_color pkt_color = (enum rte_meter_color)
+ RTE_MBUF_METADATA_UINT32(pkt, p_rt->params.color_offset);
struct pipeline_routing_arp_key_ipv4 *arp_key =
(struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->arp_key_offset);
- uint32_t ip = RTE_MBUF_METADATA_UINT32(pkt, p_rt->ip_da_offset);
+ RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.arp_key_offset);
+
+ uint64_t *slab0_ptr, *slab1_ptr, *slab2_ptr, *slab3_ptr, sched;
+ uint32_t ip_da, nh_ip, port_id;
+ uint16_t total_length, data_offset, ether_l2_length;
+
+ /* Read */
+ total_length = rte_bswap16(ip->total_length);
+ ip_da = ip->dst_addr;
+ data_offset = entry->data_offset;
+ ether_l2_length = entry->ether_l2_length;
+ slab0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[0]);
+ slab1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[1]);
+ slab2_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[2]);
+ slab3_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[3]);
+
+ if (arp) {
+ port_id = entry->port_id;
+ nh_ip = entry->ip;
+ if (entry->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+ nh_ip = ip_da;
+ }
+
+ /* Compute */
+ total_length += ether_l2_length;
+
+ if (qinq && qinq_sched) {
+ uint32_t dscp = ip->type_of_service >> 2;
+ uint32_t svlan, cvlan, tc, tc_q;
+
+ if (qinq_sched == 1) {
+ uint64_t slab_qinq = rte_bswap64(entry->slab[0]);
+
+ svlan = (slab_qinq >> 48) & 0xFFF;
+ cvlan = (slab_qinq >> 16) & 0xFFF;
+ tc = (dscp >> 2) & 0x3;
+ tc_q = dscp & 0x3;
+ } else {
+ uint32_t ip_src = rte_bswap32(ip->src_addr);
- arp_key->port_id = entry->port_id;
- arp_key->ip = entry->ip;
- if (entry->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- arp_key->ip = ip;
+ svlan = 0;
+ cvlan = (ip_src >> 16) & 0xFFF;
+ tc = (ip_src >> 2) & 0x3;
+ tc_q = ip_src & 0x3;
+ }
+ sched = RTE_SCHED_PORT_HIERARCHY(svlan,
+ cvlan,
+ tc,
+ tc_q,
+ e_RTE_METER_GREEN);
+ }
+
+ /* Write */
+ pkt->data_off = data_offset;
+ pkt->data_len = total_length;
+ pkt->pkt_len = total_length;
+
+ if ((qinq == 0) && (mpls == 0)) {
+ *slab0_ptr = entry->slab[0];
+
+ if (arp == 0)
+ MACADDR_DST_WRITE(slab1_ptr, entry->slab[1]);
+ }
+
+ if (qinq) {
+ *slab0_ptr = entry->slab[0];
+ *slab1_ptr = entry->slab[1];
+
+ if (arp == 0)
+ MACADDR_DST_WRITE(slab2_ptr, entry->slab[2]);
+
+ if (qinq_sched) {
+ pkt->hash.sched.lo = sched & 0xFFFFFFFF;
+ pkt->hash.sched.hi = sched >> 32;
+ }
+ }
+
+ if (mpls) {
+ if (mpls_color_mark) {
+ uint64_t mpls_exp = rte_bswap64(
+ (MPLS_LABEL(0, pkt_color, 0, 0) << 32) |
+ MPLS_LABEL(0, pkt_color, 0, 0));
+
+ *slab0_ptr = entry->slab[0] | mpls_exp;
+ *slab1_ptr = entry->slab[1] | mpls_exp;
+ *slab2_ptr = entry->slab[2];
+ } else {
+ *slab0_ptr = entry->slab[0];
+ *slab1_ptr = entry->slab[1];
+ *slab2_ptr = entry->slab[2];
+ }
+
+ if (arp == 0)
+ MACADDR_DST_WRITE(slab3_ptr, entry->slab[3]);
+ }
+
+ if (arp) {
+ arp_key->port_id = port_id;
+ arp_key->ip = nh_ip;
+ }
}
-static inline void
+static inline __attribute__((always_inline)) void
pkt4_work_routing(
struct rte_mbuf **pkts,
struct rte_pipeline_table_entry **table_entries,
- void *arg)
+ void *arg,
+ int arp,
+ int qinq,
+ int qinq_sched,
+ int mpls,
+ int mpls_color_mark)
{
+ struct pipeline_routing *p_rt = arg;
+
struct routing_table_entry *entry0 =
(struct routing_table_entry *) table_entries[0];
struct routing_table_entry *entry1 =
(struct routing_table_entry *) table_entries[2];
struct routing_table_entry *entry3 =
(struct routing_table_entry *) table_entries[3];
- struct pipeline_routing *p_rt = arg;
+
+ struct ipv4_hdr *ip0 = (struct ipv4_hdr *)
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
+ p_rt->params.ip_hdr_offset);
+ struct ipv4_hdr *ip1 = (struct ipv4_hdr *)
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
+ p_rt->params.ip_hdr_offset);
+ struct ipv4_hdr *ip2 = (struct ipv4_hdr *)
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
+ p_rt->params.ip_hdr_offset);
+ struct ipv4_hdr *ip3 = (struct ipv4_hdr *)
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
+ p_rt->params.ip_hdr_offset);
+
+ enum rte_meter_color pkt0_color = (enum rte_meter_color)
+ RTE_MBUF_METADATA_UINT32(pkts[0], p_rt->params.color_offset);
+ enum rte_meter_color pkt1_color = (enum rte_meter_color)
+ RTE_MBUF_METADATA_UINT32(pkts[1], p_rt->params.color_offset);
+ enum rte_meter_color pkt2_color = (enum rte_meter_color)
+ RTE_MBUF_METADATA_UINT32(pkts[2], p_rt->params.color_offset);
+ enum rte_meter_color pkt3_color = (enum rte_meter_color)
+ RTE_MBUF_METADATA_UINT32(pkts[3], p_rt->params.color_offset);
struct pipeline_routing_arp_key_ipv4 *arp_key0 =
(struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[0], p_rt->arp_key_offset);
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
+ p_rt->params.arp_key_offset);
struct pipeline_routing_arp_key_ipv4 *arp_key1 =
(struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[1], p_rt->arp_key_offset);
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
+ p_rt->params.arp_key_offset);
struct pipeline_routing_arp_key_ipv4 *arp_key2 =
(struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[2], p_rt->arp_key_offset);
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
+ p_rt->params.arp_key_offset);
struct pipeline_routing_arp_key_ipv4 *arp_key3 =
(struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[3], p_rt->arp_key_offset);
+ RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
+ p_rt->params.arp_key_offset);
+
+ uint64_t *slab0_ptr0, *slab1_ptr0, *slab2_ptr0, *slab3_ptr0;
+ uint64_t *slab0_ptr1, *slab1_ptr1, *slab2_ptr1, *slab3_ptr1;
+ uint64_t *slab0_ptr2, *slab1_ptr2, *slab2_ptr2, *slab3_ptr2;
+ uint64_t *slab0_ptr3, *slab1_ptr3, *slab2_ptr3, *slab3_ptr3;
+ uint64_t sched0, sched1, sched2, sched3;
+
+ uint32_t ip_da0, nh_ip0, port_id0;
+ uint32_t ip_da1, nh_ip1, port_id1;
+ uint32_t ip_da2, nh_ip2, port_id2;
+ uint32_t ip_da3, nh_ip3, port_id3;
+
+ uint16_t total_length0, data_offset0, ether_l2_length0;
+ uint16_t total_length1, data_offset1, ether_l2_length1;
+ uint16_t total_length2, data_offset2, ether_l2_length2;
+ uint16_t total_length3, data_offset3, ether_l2_length3;
+
+ /* Read */
+ total_length0 = rte_bswap16(ip0->total_length);
+ total_length1 = rte_bswap16(ip1->total_length);
+ total_length2 = rte_bswap16(ip2->total_length);
+ total_length3 = rte_bswap16(ip3->total_length);
+
+ ip_da0 = ip0->dst_addr;
+ ip_da1 = ip1->dst_addr;
+ ip_da2 = ip2->dst_addr;
+ ip_da3 = ip3->dst_addr;
+
+ data_offset0 = entry0->data_offset;
+ data_offset1 = entry1->data_offset;
+ data_offset2 = entry2->data_offset;
+ data_offset3 = entry3->data_offset;
+
+ ether_l2_length0 = entry0->ether_l2_length;
+ ether_l2_length1 = entry1->ether_l2_length;
+ ether_l2_length2 = entry2->ether_l2_length;
+ ether_l2_length3 = entry3->ether_l2_length;
+
+ slab0_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
+ entry0->slab_offset[0]);
+ slab1_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
+ entry0->slab_offset[1]);
+ slab2_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
+ entry0->slab_offset[2]);
+ slab3_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
+ entry0->slab_offset[3]);
+
+ slab0_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
+ entry1->slab_offset[0]);
+ slab1_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
+ entry1->slab_offset[1]);
+ slab2_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
+ entry1->slab_offset[2]);
+ slab3_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
+ entry1->slab_offset[3]);
+
+ slab0_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
+ entry2->slab_offset[0]);
+ slab1_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
+ entry2->slab_offset[1]);
+ slab2_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
+ entry2->slab_offset[2]);
+ slab3_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
+ entry2->slab_offset[3]);
+
+ slab0_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
+ entry3->slab_offset[0]);
+ slab1_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
+ entry3->slab_offset[1]);
+ slab2_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
+ entry3->slab_offset[2]);
+ slab3_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
+ entry3->slab_offset[3]);
+
+ if (arp) {
+ port_id0 = entry0->port_id;
+ nh_ip0 = entry0->ip;
+ if (entry0->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+ nh_ip0 = ip_da0;
+
+ port_id1 = entry1->port_id;
+ nh_ip1 = entry1->ip;
+ if (entry1->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+ nh_ip1 = ip_da1;
+
+ port_id2 = entry2->port_id;
+ nh_ip2 = entry2->ip;
+ if (entry2->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+ nh_ip2 = ip_da2;
+
+ port_id3 = entry3->port_id;
+ nh_ip3 = entry3->ip;
+ if (entry3->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+ nh_ip3 = ip_da3;
+ }
- uint32_t ip0 = RTE_MBUF_METADATA_UINT32(pkts[0], p_rt->ip_da_offset);
- uint32_t ip1 = RTE_MBUF_METADATA_UINT32(pkts[1], p_rt->ip_da_offset);
- uint32_t ip2 = RTE_MBUF_METADATA_UINT32(pkts[2], p_rt->ip_da_offset);
- uint32_t ip3 = RTE_MBUF_METADATA_UINT32(pkts[3], p_rt->ip_da_offset);
+ /* Compute */
+ total_length0 += ether_l2_length0;
+ total_length1 += ether_l2_length1;
+ total_length2 += ether_l2_length2;
+ total_length3 += ether_l2_length3;
+
+ if (qinq && qinq_sched) {
+ uint32_t dscp0 = ip0->type_of_service >> 2;
+ uint32_t dscp1 = ip1->type_of_service >> 2;
+ uint32_t dscp2 = ip2->type_of_service >> 2;
+ uint32_t dscp3 = ip3->type_of_service >> 2;
+ uint32_t svlan0, cvlan0, tc0, tc_q0;
+ uint32_t svlan1, cvlan1, tc1, tc_q1;
+ uint32_t svlan2, cvlan2, tc2, tc_q2;
+ uint32_t svlan3, cvlan3, tc3, tc_q3;
+
+ if (qinq_sched == 1) {
+ uint64_t slab_qinq0 = rte_bswap64(entry0->slab[0]);
+ uint64_t slab_qinq1 = rte_bswap64(entry1->slab[0]);
+ uint64_t slab_qinq2 = rte_bswap64(entry2->slab[0]);
+ uint64_t slab_qinq3 = rte_bswap64(entry3->slab[0]);
+
+ svlan0 = (slab_qinq0 >> 48) & 0xFFF;
+ svlan1 = (slab_qinq1 >> 48) & 0xFFF;
+ svlan2 = (slab_qinq2 >> 48) & 0xFFF;
+ svlan3 = (slab_qinq3 >> 48) & 0xFFF;
+
+ cvlan0 = (slab_qinq0 >> 16) & 0xFFF;
+ cvlan1 = (slab_qinq1 >> 16) & 0xFFF;
+ cvlan2 = (slab_qinq2 >> 16) & 0xFFF;
+ cvlan3 = (slab_qinq3 >> 16) & 0xFFF;
+
+ tc0 = (dscp0 >> 2) & 0x3;
+ tc1 = (dscp1 >> 2) & 0x3;
+ tc2 = (dscp2 >> 2) & 0x3;
+ tc3 = (dscp3 >> 2) & 0x3;
+
+ tc_q0 = dscp0 & 0x3;
+ tc_q1 = dscp1 & 0x3;
+ tc_q2 = dscp2 & 0x3;
+ tc_q3 = dscp3 & 0x3;
+ } else {
+ uint32_t ip_src0 = rte_bswap32(ip0->src_addr);
+ uint32_t ip_src1 = rte_bswap32(ip1->src_addr);
+ uint32_t ip_src2 = rte_bswap32(ip2->src_addr);
+ uint32_t ip_src3 = rte_bswap32(ip3->src_addr);
+
+ svlan0 = 0;
+ svlan1 = 0;
+ svlan2 = 0;
+ svlan3 = 0;
+
+ cvlan0 = (ip_src0 >> 16) & 0xFFF;
+ cvlan1 = (ip_src1 >> 16) & 0xFFF;
+ cvlan2 = (ip_src2 >> 16) & 0xFFF;
+ cvlan3 = (ip_src3 >> 16) & 0xFFF;
+
+ tc0 = (ip_src0 >> 2) & 0x3;
+ tc1 = (ip_src1 >> 2) & 0x3;
+ tc2 = (ip_src2 >> 2) & 0x3;
+ tc3 = (ip_src3 >> 2) & 0x3;
+
+ tc_q0 = ip_src0 & 0x3;
+ tc_q1 = ip_src1 & 0x3;
+ tc_q2 = ip_src2 & 0x3;
+ tc_q3 = ip_src3 & 0x3;
+ }
- arp_key0->port_id = entry0->port_id;
- arp_key1->port_id = entry1->port_id;
- arp_key2->port_id = entry2->port_id;
- arp_key3->port_id = entry3->port_id;
+ sched0 = RTE_SCHED_PORT_HIERARCHY(svlan0,
+ cvlan0,
+ tc0,
+ tc_q0,
+ e_RTE_METER_GREEN);
+ sched1 = RTE_SCHED_PORT_HIERARCHY(svlan1,
+ cvlan1,
+ tc1,
+ tc_q1,
+ e_RTE_METER_GREEN);
+ sched2 = RTE_SCHED_PORT_HIERARCHY(svlan2,
+ cvlan2,
+ tc2,
+ tc_q2,
+ e_RTE_METER_GREEN);
+ sched3 = RTE_SCHED_PORT_HIERARCHY(svlan3,
+ cvlan3,
+ tc3,
+ tc_q3,
+ e_RTE_METER_GREEN);
- arp_key0->ip = entry0->ip;
- if (entry0->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- arp_key0->ip = ip0;
+ }
- arp_key1->ip = entry1->ip;
- if (entry1->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- arp_key1->ip = ip1;
+ /* Write */
+ pkts[0]->data_off = data_offset0;
+ pkts[1]->data_off = data_offset1;
+ pkts[2]->data_off = data_offset2;
+ pkts[3]->data_off = data_offset3;
+
+ pkts[0]->data_len = total_length0;
+ pkts[1]->data_len = total_length1;
+ pkts[2]->data_len = total_length2;
+ pkts[3]->data_len = total_length3;
+
+ pkts[0]->pkt_len = total_length0;
+ pkts[1]->pkt_len = total_length1;
+ pkts[2]->pkt_len = total_length2;
+ pkts[3]->pkt_len = total_length3;
+
+ if ((qinq == 0) && (mpls == 0)) {
+ *slab0_ptr0 = entry0->slab[0];
+ *slab0_ptr1 = entry1->slab[0];
+ *slab0_ptr2 = entry2->slab[0];
+ *slab0_ptr3 = entry3->slab[0];
+
+ if (arp == 0) {
+ MACADDR_DST_WRITE(slab1_ptr0, entry0->slab[1]);
+ MACADDR_DST_WRITE(slab1_ptr1, entry1->slab[1]);
+ MACADDR_DST_WRITE(slab1_ptr2, entry2->slab[1]);
+ MACADDR_DST_WRITE(slab1_ptr3, entry3->slab[1]);
+ }
+ }
+
+ if (qinq) {
+ *slab0_ptr0 = entry0->slab[0];
+ *slab0_ptr1 = entry1->slab[0];
+ *slab0_ptr2 = entry2->slab[0];
+ *slab0_ptr3 = entry3->slab[0];
+
+ *slab1_ptr0 = entry0->slab[1];
+ *slab1_ptr1 = entry1->slab[1];
+ *slab1_ptr2 = entry2->slab[1];
+ *slab1_ptr3 = entry3->slab[1];
+
+ if (arp == 0) {
+ MACADDR_DST_WRITE(slab2_ptr0, entry0->slab[2]);
+ MACADDR_DST_WRITE(slab2_ptr1, entry1->slab[2]);
+ MACADDR_DST_WRITE(slab2_ptr2, entry2->slab[2]);
+ MACADDR_DST_WRITE(slab2_ptr3, entry3->slab[2]);
+ }
- arp_key2->ip = entry2->ip;
- if (entry2->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- arp_key2->ip = ip2;
+ if (qinq_sched) {
+ pkts[0]->hash.sched.lo = sched0 & 0xFFFFFFFF;
+ pkts[0]->hash.sched.hi = sched0 >> 32;
+ pkts[1]->hash.sched.lo = sched1 & 0xFFFFFFFF;
+ pkts[1]->hash.sched.hi = sched1 >> 32;
+ pkts[2]->hash.sched.lo = sched2 & 0xFFFFFFFF;
+ pkts[2]->hash.sched.hi = sched2 >> 32;
+ pkts[3]->hash.sched.lo = sched3 & 0xFFFFFFFF;
+ pkts[3]->hash.sched.hi = sched3 >> 32;
+ }
+ }
- arp_key3->ip = entry3->ip;
- if (entry3->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- arp_key3->ip = ip3;
+ if (mpls) {
+ if (mpls_color_mark) {
+ uint64_t mpls_exp0 = rte_bswap64(
+ (MPLS_LABEL(0, pkt0_color, 0, 0) << 32) |
+ MPLS_LABEL(0, pkt0_color, 0, 0));
+ uint64_t mpls_exp1 = rte_bswap64(
+ (MPLS_LABEL(0, pkt1_color, 0, 0) << 32) |
+ MPLS_LABEL(0, pkt1_color, 0, 0));
+ uint64_t mpls_exp2 = rte_bswap64(
+ (MPLS_LABEL(0, pkt2_color, 0, 0) << 32) |
+ MPLS_LABEL(0, pkt2_color, 0, 0));
+ uint64_t mpls_exp3 = rte_bswap64(
+ (MPLS_LABEL(0, pkt3_color, 0, 0) << 32) |
+ MPLS_LABEL(0, pkt3_color, 0, 0));
+
+ *slab0_ptr0 = entry0->slab[0] | mpls_exp0;
+ *slab0_ptr1 = entry1->slab[0] | mpls_exp1;
+ *slab0_ptr2 = entry2->slab[0] | mpls_exp2;
+ *slab0_ptr3 = entry3->slab[0] | mpls_exp3;
+
+ *slab1_ptr0 = entry0->slab[1] | mpls_exp0;
+ *slab1_ptr1 = entry1->slab[1] | mpls_exp1;
+ *slab1_ptr2 = entry2->slab[1] | mpls_exp2;
+ *slab1_ptr3 = entry3->slab[1] | mpls_exp3;
+
+ *slab2_ptr0 = entry0->slab[2];
+ *slab2_ptr1 = entry1->slab[2];
+ *slab2_ptr2 = entry2->slab[2];
+ *slab2_ptr3 = entry3->slab[2];
+ } else {
+ *slab0_ptr0 = entry0->slab[0];
+ *slab0_ptr1 = entry1->slab[0];
+ *slab0_ptr2 = entry2->slab[0];
+ *slab0_ptr3 = entry3->slab[0];
+
+ *slab1_ptr0 = entry0->slab[1];
+ *slab1_ptr1 = entry1->slab[1];
+ *slab1_ptr2 = entry2->slab[1];
+ *slab1_ptr3 = entry3->slab[1];
+
+ *slab2_ptr0 = entry0->slab[2];
+ *slab2_ptr1 = entry1->slab[2];
+ *slab2_ptr2 = entry2->slab[2];
+ *slab2_ptr3 = entry3->slab[2];
+ }
+
+ if (arp == 0) {
+ MACADDR_DST_WRITE(slab3_ptr0, entry0->slab[3]);
+ MACADDR_DST_WRITE(slab3_ptr1, entry1->slab[3]);
+ MACADDR_DST_WRITE(slab3_ptr2, entry2->slab[3]);
+ MACADDR_DST_WRITE(slab3_ptr3, entry3->slab[3]);
+ }
+ }
+
+ if (arp) {
+ arp_key0->port_id = port_id0;
+ arp_key1->port_id = port_id1;
+ arp_key2->port_id = port_id2;
+ arp_key3->port_id = port_id3;
+
+ arp_key0->ip = nh_ip0;
+ arp_key1->ip = nh_ip1;
+ arp_key2->ip = nh_ip2;
+ arp_key3->ip = nh_ip3;
+ }
}
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit,
- pkt_work_routing,
- pkt4_work_routing);
+#define PKT_WORK_ROUTING_ETHERNET(arp) \
+static inline void \
+pkt_work_routing_ether_arp##arp( \
+ struct rte_mbuf *pkt, \
+ struct rte_pipeline_table_entry *table_entry, \
+ void *arg) \
+{ \
+ pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 0, 0);\
+}
+
+#define PKT4_WORK_ROUTING_ETHERNET(arp) \
+static inline void \
+pkt4_work_routing_ether_arp##arp( \
+ struct rte_mbuf **pkts, \
+ struct rte_pipeline_table_entry **table_entries, \
+ void *arg) \
+{ \
+ pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 0, 0);\
+}
+
+#define routing_table_ah_hit_ether(arp) \
+PKT_WORK_ROUTING_ETHERNET(arp) \
+PKT4_WORK_ROUTING_ETHERNET(arp) \
+PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_arp##arp, \
+ pkt_work_routing_ether_arp##arp, \
+ pkt4_work_routing_ether_arp##arp)
+
+routing_table_ah_hit_ether(0)
+routing_table_ah_hit_ether(1)
+
+#define PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
+static inline void \
+pkt_work_routing_ether_qinq_sched##sched##_arp##arp( \
+ struct rte_mbuf *pkt, \
+ struct rte_pipeline_table_entry *table_entry, \
+ void *arg) \
+{ \
+ pkt_work_routing(pkt, table_entry, arg, arp, 1, sched, 0, 0);\
+}
+
+#define PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
+static inline void \
+pkt4_work_routing_ether_qinq_sched##sched##_arp##arp( \
+ struct rte_mbuf **pkts, \
+ struct rte_pipeline_table_entry **table_entries, \
+ void *arg) \
+{ \
+ pkt4_work_routing(pkts, table_entries, arg, arp, 1, sched, 0, 0);\
+}
+
+#define routing_table_ah_hit_ether_qinq(sched, arp) \
+PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
+PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
+PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_qinq_sched##sched##_arp##arp,\
+ pkt_work_routing_ether_qinq_sched##sched##_arp##arp, \
+ pkt4_work_routing_ether_qinq_sched##sched##_arp##arp)
+
+routing_table_ah_hit_ether_qinq(0, 0)
+routing_table_ah_hit_ether_qinq(1, 0)
+routing_table_ah_hit_ether_qinq(2, 0)
+routing_table_ah_hit_ether_qinq(0, 1)
+routing_table_ah_hit_ether_qinq(1, 1)
+routing_table_ah_hit_ether_qinq(2, 1)
+
+#define PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
+static inline void \
+pkt_work_routing_ether_mpls_color##color##_arp##arp( \
+ struct rte_mbuf *pkt, \
+ struct rte_pipeline_table_entry *table_entry, \
+ void *arg) \
+{ \
+ pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 1, color);\
+}
+
+#define PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
+static inline void \
+pkt4_work_routing_ether_mpls_color##color##_arp##arp( \
+ struct rte_mbuf **pkts, \
+ struct rte_pipeline_table_entry **table_entries, \
+ void *arg) \
+{ \
+ pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 1, color);\
+}
+
+#define routing_table_ah_hit_ether_mpls(color, arp) \
+PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
+PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
+PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_mpls_color##color##_arp##arp,\
+ pkt_work_routing_ether_mpls_color##color##_arp##arp, \
+ pkt4_work_routing_ether_mpls_color##color##_arp##arp)
+
+routing_table_ah_hit_ether_mpls(0, 0)
+routing_table_ah_hit_ether_mpls(1, 0)
+routing_table_ah_hit_ether_mpls(0, 1)
+routing_table_ah_hit_ether_mpls(1, 1)
+
+static rte_pipeline_table_action_handler_hit
+get_routing_table_ah_hit(struct pipeline_routing *p)
+{
+ if (p->params.dbg_ah_disable)
+ return NULL;
+
+ switch (p->params.encap) {
+ case PIPELINE_ROUTING_ENCAP_ETHERNET:
+ return (p->params.n_arp_entries) ?
+ routing_table_ah_hit_ether_arp1 :
+ routing_table_ah_hit_ether_arp0;
+
+ case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
+ if (p->params.n_arp_entries)
+ switch (p->params.qinq_sched) {
+ case 0:
+ return routing_table_ah_hit_ether_qinq_sched0_arp1;
+ case 1:
+ return routing_table_ah_hit_ether_qinq_sched1_arp1;
+ case 2:
+ return routing_table_ah_hit_ether_qinq_sched2_arp1;
+ default:
+ return NULL;
+ }
+ else
+ switch (p->params.qinq_sched) {
+ case 0:
+ return routing_table_ah_hit_ether_qinq_sched0_arp0;
+ case 1:
+ return routing_table_ah_hit_ether_qinq_sched1_arp0;
+ case 2:
+ return routing_table_ah_hit_ether_qinq_sched2_arp0;
+ default:
+ return NULL;
+ }
+
+ case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
+ if (p->params.n_arp_entries)
+ if (p->params.mpls_color_mark)
+ return routing_table_ah_hit_ether_mpls_color1_arp1;
+ else
+ return routing_table_ah_hit_ether_mpls_color0_arp1;
+ else
+ if (p->params.mpls_color_mark)
+ return routing_table_ah_hit_ether_mpls_color1_arp0;
+ else
+ return routing_table_ah_hit_ether_mpls_color0_arp0;
+
+ default:
+ return NULL;
+ }
+}
/*
* ARP table
uint64_t macaddr;
};
+/**
+ * ARP table AH
+ */
static inline void
pkt_work_arp(
struct rte_mbuf *pkt,
{
struct arp_table_entry *entry = (struct arp_table_entry *) table_entry;
- /* Read: pkt buffer - mbuf */
- uint8_t *raw = rte_pktmbuf_mtod(pkt, uint8_t *);
+ /* Read */
+ uint64_t macaddr_dst = entry->macaddr;
+ uint64_t *slab_ptr = (uint64_t *) ((char *) pkt->buf_addr +
+ (pkt->data_off - 2));
- /* Read: table entry */
- uint64_t mac_addr_dst = entry->macaddr;
- uint64_t mac_addr_src = 0;
+ /* Compute */
- /* Compute: Ethernet header */
- uint64_t slab0 = mac_addr_dst | (mac_addr_src << 48);
- uint32_t slab1 = mac_addr_src >> 16;
-
- /* Write: pkt buffer - pkt headers */
- *((uint64_t *) raw) = slab0;
- *((uint32_t *) (raw + 8)) = slab1;
+ /* Write */
+ MACADDR_DST_WRITE(slab_ptr, macaddr_dst);
}
static inline void
struct arp_table_entry *entry3 =
(struct arp_table_entry *) table_entries[3];
- /* Read: pkt buffer - mbuf */
- uint8_t *raw0 = rte_pktmbuf_mtod(pkts[0], uint8_t *);
- uint8_t *raw1 = rte_pktmbuf_mtod(pkts[1], uint8_t *);
- uint8_t *raw2 = rte_pktmbuf_mtod(pkts[2], uint8_t *);
- uint8_t *raw3 = rte_pktmbuf_mtod(pkts[3], uint8_t *);
-
- /* Read: table entry */
- uint64_t mac_addr_dst0 = entry0->macaddr;
- uint64_t mac_addr_dst1 = entry1->macaddr;
- uint64_t mac_addr_dst2 = entry2->macaddr;
- uint64_t mac_addr_dst3 = entry3->macaddr;
-
- uint64_t mac_addr_src0 = 0;
- uint64_t mac_addr_src1 = 0;
- uint64_t mac_addr_src2 = 0;
- uint64_t mac_addr_src3 = 0;
-
- /* Compute: Ethernet header */
- uint64_t pkt0_slab0 = mac_addr_dst0 | (mac_addr_src0 << 48);
- uint64_t pkt1_slab0 = mac_addr_dst1 | (mac_addr_src1 << 48);
- uint64_t pkt2_slab0 = mac_addr_dst2 | (mac_addr_src2 << 48);
- uint64_t pkt3_slab0 = mac_addr_dst3 | (mac_addr_src3 << 48);
-
- uint32_t pkt0_slab1 = mac_addr_src0 >> 16;
- uint32_t pkt1_slab1 = mac_addr_src1 >> 16;
- uint32_t pkt2_slab1 = mac_addr_src2 >> 16;
- uint32_t pkt3_slab1 = mac_addr_src3 >> 16;
-
- /* Write: pkt buffer - pkt headers */
- *((uint64_t *) raw0) = pkt0_slab0;
- *((uint32_t *) (raw0 + 8)) = pkt0_slab1;
- *((uint64_t *) raw1) = pkt1_slab0;
- *((uint32_t *) (raw1 + 8)) = pkt1_slab1;
- *((uint64_t *) raw2) = pkt2_slab0;
- *((uint32_t *) (raw2 + 8)) = pkt2_slab1;
- *((uint64_t *) raw3) = pkt3_slab0;
- *((uint32_t *) (raw3 + 8)) = pkt3_slab1;
+ /* Read */
+ uint64_t macaddr_dst0 = entry0->macaddr;
+ uint64_t macaddr_dst1 = entry1->macaddr;
+ uint64_t macaddr_dst2 = entry2->macaddr;
+ uint64_t macaddr_dst3 = entry3->macaddr;
+
+ uint64_t *slab_ptr0 = (uint64_t *) ((char *) pkts[0]->buf_addr +
+ (pkts[0]->data_off - 2));
+ uint64_t *slab_ptr1 = (uint64_t *) ((char *) pkts[1]->buf_addr +
+ (pkts[1]->data_off - 2));
+ uint64_t *slab_ptr2 = (uint64_t *) ((char *) pkts[2]->buf_addr +
+ (pkts[2]->data_off - 2));
+ uint64_t *slab_ptr3 = (uint64_t *) ((char *) pkts[3]->buf_addr +
+ (pkts[3]->data_off - 2));
+
+ /* Compute */
+
+ /* Write */
+ MACADDR_DST_WRITE(slab_ptr0, macaddr_dst0);
+ MACADDR_DST_WRITE(slab_ptr1, macaddr_dst1);
+ MACADDR_DST_WRITE(slab_ptr2, macaddr_dst2);
+ MACADDR_DST_WRITE(slab_ptr3, macaddr_dst3);
}
PIPELINE_TABLE_AH_HIT(arp_table_ah_hit,
pkt_work_arp,
pkt4_work_arp);
-static int
-pipeline_routing_parse_args(struct pipeline_routing *p,
+static rte_pipeline_table_action_handler_hit
+get_arp_table_ah_hit(struct pipeline_routing *p)
+{
+ if (p->params.dbg_ah_disable)
+ return NULL;
+
+ return arp_table_ah_hit;
+}
+
+/*
+ * Argument parsing
+ */
+int
+pipeline_routing_parse_args(struct pipeline_routing_params *p,
struct pipeline_params *params)
{
uint32_t n_routes_present = 0;
+ uint32_t encap_present = 0;
+ uint32_t qinq_sched_present = 0;
+ uint32_t mpls_color_mark_present = 0;
uint32_t n_arp_entries_present = 0;
- uint32_t ip_da_offset_present = 0;
+ uint32_t ip_hdr_offset_present = 0;
uint32_t arp_key_offset_present = 0;
+ uint32_t color_offset_present = 0;
+ uint32_t dbg_ah_disable_present = 0;
uint32_t i;
+ /* default values */
+ p->n_routes = PIPELINE_ROUTING_N_ROUTES_DEFAULT;
+ p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
+ p->qinq_sched = 0;
+ p->mpls_color_mark = 0;
+ p->n_arp_entries = 0;
+ p->dbg_ah_disable = 0;
+
for (i = 0; i < params->n_args; i++) {
char *arg_name = params->args_name[i];
char *arg_value = params->args_value[i];
continue;
}
+ /* encap */
+ if (strcmp(arg_name, "encap") == 0) {
+ if (encap_present)
+ return -1;
+ encap_present = 1;
+
+ /* ethernet */
+ if (strcmp(arg_value, "ethernet") == 0) {
+ p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
+ continue;
+ }
+
+ /* ethernet_qinq */
+ if (strcmp(arg_value, "ethernet_qinq") == 0) {
+ p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ;
+ continue;
+ }
+
+ /* ethernet_mpls */
+ if (strcmp(arg_value, "ethernet_mpls") == 0) {
+ p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS;
+ continue;
+ }
+
+ /* any other */
+ return -1;
+ }
+
+ /* qinq_sched */
+ if (strcmp(arg_name, "qinq_sched") == 0) {
+ if (qinq_sched_present)
+ return -1;
+
+ qinq_sched_present = 1;
+
+ if (strcmp(arg_value, "no") == 0)
+ p->qinq_sched = 0;
+ else if (strcmp(arg_value, "yes") == 0)
+ p->qinq_sched = 1;
+ else if (strcmp(arg_value, "test") == 0)
+ p->qinq_sched = 2;
+ else
+ return -1;
+
+ continue;
+ }
+
+ /* mpls_color_mark */
+ if (strcmp(arg_name, "mpls_color_mark") == 0) {
+ if (mpls_color_mark_present)
+ return -1;
+
+ mpls_color_mark_present = 1;
+
+ if (strcmp(arg_value, "no") == 0)
+ p->mpls_color_mark = 0;
+ else if (strcmp(arg_value, "yes") == 0)
+ p->mpls_color_mark = 1;
+ else
+ return -1;
+
+ continue;
+ }
+
/* n_arp_entries */
if (strcmp(arg_name, "n_arp_entries") == 0) {
if (n_arp_entries_present)
n_arp_entries_present = 1;
p->n_arp_entries = atoi(arg_value);
- if (p->n_arp_entries == 0)
- return -1;
continue;
}
- /* ip_da_offset */
- if (strcmp(arg_name, "ip_da_offset") == 0) {
- if (ip_da_offset_present)
+ /* ip_hdr_offset */
+ if (strcmp(arg_name, "ip_hdr_offset") == 0) {
+ if (ip_hdr_offset_present)
return -1;
- ip_da_offset_present = 1;
+ ip_hdr_offset_present = 1;
- p->ip_da_offset = atoi(arg_value);
+ p->ip_hdr_offset = atoi(arg_value);
continue;
}
continue;
}
+ /* color_offset */
+ if (strcmp(arg_name, "color_offset") == 0) {
+ if (color_offset_present)
+ return -1;
+ color_offset_present = 1;
+
+ p->color_offset = atoi(arg_value);
+
+ continue;
+ }
+
+ /* debug */
+ if (strcmp(arg_name, "dbg_ah_disable") == 0) {
+ if (dbg_ah_disable_present)
+ return -1;
+ dbg_ah_disable_present = 1;
+
+ if (strcmp(arg_value, "no") == 0)
+ p->dbg_ah_disable = 0;
+ else if (strcmp(arg_value, "yes") == 0)
+ p->dbg_ah_disable = 1;
+ else
+ return -1;
+
+ continue;
+ }
+
/* any other */
return -1;
}
/* Check that mandatory arguments are present */
- if ((n_routes_present == 0) ||
- (n_arp_entries_present == 0) ||
- (ip_da_offset_present == 0) ||
- (n_arp_entries_present && (arp_key_offset_present == 0)))
+ if (ip_hdr_offset_present == 0)
+ return -1;
+
+ /* Check relations between arguments */
+ switch (p->encap) {
+ case PIPELINE_ROUTING_ENCAP_ETHERNET:
+ if (p->qinq_sched ||
+ p->mpls_color_mark ||
+ color_offset_present)
+ return -1;
+ break;
+
+ case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
+ if (p->mpls_color_mark ||
+ color_offset_present)
+ return -1;
+ break;
+
+ case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
+ if (p->qinq_sched)
+ return -1;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if ((p->n_arp_entries && (arp_key_offset_present == 0)) ||
+ ((p->n_arp_entries == 0) && arp_key_offset_present))
return -1;
return 0;
PLOG(p, HIGH, "Routing");
/* Parse arguments */
- if (pipeline_routing_parse_args(p_rt, params))
+ if (pipeline_routing_parse_args(&p_rt->params, params))
return NULL;
/* Pipeline */
{
struct rte_table_lpm_params table_lpm_params = {
.name = p->name,
- .n_rules = p_rt->n_routes,
+ .n_rules = p_rt->params.n_routes,
.entry_unique_size = sizeof(struct routing_table_entry),
- .offset = p_rt->ip_da_offset,
+ .offset = p_rt->params.ip_hdr_offset +
+ __builtin_offsetof(struct ipv4_hdr, dst_addr),
};
struct rte_pipeline_table_params table_params = {
.ops = &rte_table_lpm_ops,
.arg_create = &table_lpm_params,
- .f_action_hit = routing_table_ah_hit,
+ .f_action_hit = get_routing_table_ah_hit(p_rt),
.f_action_miss = NULL,
.arg_ah = p_rt,
.action_data_size =
}
/* ARP table configuration */
- if (p_rt->n_arp_entries) {
+ if (p_rt->params.n_arp_entries) {
struct rte_table_hash_key8_ext_params table_arp_params = {
- .n_entries = p_rt->n_arp_entries,
- .n_entries_ext = p_rt->n_arp_entries,
+ .n_entries = p_rt->params.n_arp_entries,
+ .n_entries_ext = p_rt->params.n_arp_entries,
.f_hash = hash_default_key8,
.seed = 0,
.signature_offset = 0, /* Unused */
- .key_offset = p_rt->arp_key_offset,
+ .key_offset = p_rt->params.arp_key_offset,
};
struct rte_pipeline_table_params table_params = {
.ops = &rte_table_hash_key8_ext_dosig_ops,
.arg_create = &table_arp_params,
- .f_action_hit = arp_table_ah_hit,
+ .f_action_hit = get_arp_table_ah_hit(p_rt),
.f_action_miss = NULL,
.arg_ah = p_rt,
.action_data_size = sizeof(struct arp_table_entry) -
void *
pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
{
+ struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
struct pipeline_routing_route_add_msg_req *req = msg;
struct pipeline_routing_route_add_msg_rsp *rsp = msg;
.depth = req->key.key.ipv4.depth,
};
- struct routing_table_entry entry = {
+ struct routing_table_entry entry_arp0 = {
+ .head = {
+ .action = RTE_PIPELINE_ACTION_PORT,
+ {.port_id = p->port_out_id[req->data.port_id]},
+ },
+
+ .flags = req->data.flags,
+ .port_id = req->data.port_id,
+ .ip = 0,
+ .data_offset = 0,
+ .ether_l2_length = 0,
+ .slab = {0},
+ .slab_offset = {0},
+ };
+
+ struct routing_table_entry entry_arp1 = {
.head = {
.action = RTE_PIPELINE_ACTION_TABLE,
{.table_id = p->table_id[1]},
},
- .flags = req->flags,
- .port_id = req->port_id,
- .ip = rte_bswap32(req->ip),
+ .flags = req->data.flags,
+ .port_id = req->data.port_id,
+ .ip = rte_bswap32(req->data.ethernet.ip),
+ .data_offset = 0,
+ .ether_l2_length = 0,
+ .slab = {0},
+ .slab_offset = {0},
};
- if (req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) {
+ struct rte_pipeline_table_entry *entry = (p_rt->params.n_arp_entries) ?
+ (struct rte_pipeline_table_entry *) &entry_arp1 :
+ (struct rte_pipeline_table_entry *) &entry_arp0;
+
+ if ((req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) ||
+ ((p_rt->params.n_arp_entries == 0) &&
+ (req->data.flags & PIPELINE_ROUTING_ROUTE_ARP)) ||
+ (p_rt->params.n_arp_entries &&
+ ((req->data.flags & PIPELINE_ROUTING_ROUTE_ARP) == 0)) ||
+ ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
+ (req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)) ||
+ ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
+ ((req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ) == 0)) ||
+ ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
+ (req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS)) ||
+ ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
+ ((req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) == 0))) {
rsp->status = -1;
return rsp;
}
+ /* 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_dst;
+ uint64_t ethertype = ETHER_TYPE_IPv4;
+
+ *((struct ether_addr *) &macaddr_dst) =
+ req->data.ethernet.macaddr;
+ macaddr_dst = rte_bswap64(macaddr_dst << 16);
+
+ entry_arp0.slab[0] =
+ rte_bswap64((macaddr_src << 16) | ethertype);
+ entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp0.slab[1] = rte_bswap64(macaddr_dst);
+ entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
+
+ entry_arp0.data_offset = entry_arp0.slab_offset[1] + 2
+ - sizeof(struct rte_mbuf);
+ entry_arp0.ether_l2_length = 14;
+ }
+
+ /* 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 ethertype = ETHER_TYPE_IPv4;
+
+ entry_arp1.slab[0] = rte_bswap64((macaddr_src << 16) |
+ ethertype);
+ entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp1.data_offset = entry_arp1.slab_offset[0] - 6
+ - sizeof(struct rte_mbuf);
+ entry_arp1.ether_l2_length = 14;
+ }
+
+ /* 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_dst;
+ uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
+ uint64_t ethertype_vlan = 0x8100;
+ uint64_t ethertype_qinq = 0x9100;
+ uint64_t svlan = req->data.l2.qinq.svlan;
+ uint64_t cvlan = req->data.l2.qinq.cvlan;
+
+ *((struct ether_addr *) &macaddr_dst) =
+ req->data.ethernet.macaddr;
+ macaddr_dst = rte_bswap64(macaddr_dst << 16);
+
+ entry_arp0.slab[0] = rte_bswap64((svlan << 48) |
+ (ethertype_vlan << 32) |
+ (cvlan << 16) |
+ 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_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
+
+ entry_arp0.slab[2] = rte_bswap64(macaddr_dst);
+ entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset - 3 * 8;
+
+ entry_arp0.data_offset = entry_arp0.slab_offset[2] + 2
+ - sizeof(struct rte_mbuf);
+ entry_arp0.ether_l2_length = 22;
+ }
+
+ /* 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 ethertype_ipv4 = ETHER_TYPE_IPv4;
+ uint64_t ethertype_vlan = 0x8100;
+ uint64_t ethertype_qinq = 0x9100;
+ uint64_t svlan = req->data.l2.qinq.svlan;
+ uint64_t cvlan = req->data.l2.qinq.cvlan;
+
+ entry_arp1.slab[0] = rte_bswap64((svlan << 48) |
+ (ethertype_vlan << 32) |
+ (cvlan << 16) |
+ 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_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
+
+ entry_arp1.data_offset = entry_arp1.slab_offset[1] - 6
+ - sizeof(struct rte_mbuf);
+ entry_arp1.ether_l2_length = 22;
+ }
+
+ /* 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_dst;
+ uint64_t ethertype_mpls = 0x8847;
+
+ uint64_t label0 = req->data.l2.mpls.labels[0];
+ uint64_t label1 = req->data.l2.mpls.labels[1];
+ uint64_t label2 = req->data.l2.mpls.labels[2];
+ uint64_t label3 = req->data.l2.mpls.labels[3];
+ uint32_t n_labels = req->data.l2.mpls.n_labels;
+
+ *((struct ether_addr *) &macaddr_dst) =
+ req->data.ethernet.macaddr;
+ macaddr_dst = rte_bswap64(macaddr_dst << 16);
+
+ switch (n_labels) {
+ case 1:
+ entry_arp0.slab[0] = 0;
+ entry_arp0.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp0.slab[1] = rte_bswap64(
+ MPLS_LABEL(label0, 0, 1, 0));
+ entry_arp0.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 8;
+ break;
+
+ case 2:
+ entry_arp0.slab[0] = 0;
+ entry_arp0.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp0.slab[1] = rte_bswap64(
+ (MPLS_LABEL(label0, 0, 0, 0) << 32) |
+ MPLS_LABEL(label1, 0, 1, 0));
+ entry_arp0.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 8;
+ break;
+
+ case 3:
+ entry_arp0.slab[0] = rte_bswap64(
+ (MPLS_LABEL(label1, 0, 0, 0) << 32) |
+ MPLS_LABEL(label2, 0, 1, 0));
+ entry_arp0.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp0.slab[1] = rte_bswap64(
+ MPLS_LABEL(label0, 0, 0, 0));
+ entry_arp0.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 2 * 8;
+ break;
+
+ case 4:
+ entry_arp0.slab[0] = rte_bswap64(
+ (MPLS_LABEL(label2, 0, 0, 0) << 32) |
+ MPLS_LABEL(label3, 0, 1, 0));
+ entry_arp0.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp0.slab[1] = rte_bswap64(
+ (MPLS_LABEL(label0, 0, 0, 0) << 32) |
+ MPLS_LABEL(label1, 0, 0, 0));
+ entry_arp0.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 2 * 8;
+ break;
+
+ default:
+ rsp->status = -1;
+ return rsp;
+ }
+
+ entry_arp0.slab[2] = rte_bswap64((macaddr_src << 16) |
+ ethertype_mpls);
+ entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset -
+ (n_labels * 4 + 8);
+
+ entry_arp0.slab[3] = rte_bswap64(macaddr_dst);
+ entry_arp0.slab_offset[3] = p_rt->params.ip_hdr_offset -
+ (n_labels * 4 + 2 * 8);
+
+ entry_arp0.data_offset = entry_arp0.slab_offset[3] + 2
+ - sizeof(struct rte_mbuf);
+ entry_arp0.ether_l2_length = n_labels * 4 + 14;
+ }
+
+ /* 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 ethertype_mpls = 0x8847;
+
+ uint64_t label0 = req->data.l2.mpls.labels[0];
+ uint64_t label1 = req->data.l2.mpls.labels[1];
+ uint64_t label2 = req->data.l2.mpls.labels[2];
+ uint64_t label3 = req->data.l2.mpls.labels[3];
+ uint32_t n_labels = req->data.l2.mpls.n_labels;
+
+ switch (n_labels) {
+ case 1:
+ entry_arp1.slab[0] = 0;
+ entry_arp1.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp1.slab[1] = rte_bswap64(
+ MPLS_LABEL(label0, 0, 1, 0));
+ entry_arp1.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 8;
+ break;
+
+ case 2:
+ entry_arp1.slab[0] = 0;
+ entry_arp1.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp1.slab[1] = rte_bswap64(
+ (MPLS_LABEL(label0, 0, 0, 0) << 32) |
+ MPLS_LABEL(label1, 0, 1, 0));
+ entry_arp1.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 8;
+ break;
+
+ case 3:
+ entry_arp1.slab[0] = rte_bswap64(
+ (MPLS_LABEL(label1, 0, 0, 0) << 32) |
+ MPLS_LABEL(label2, 0, 1, 0));
+ entry_arp1.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp1.slab[1] = rte_bswap64(
+ MPLS_LABEL(label0, 0, 0, 0));
+ entry_arp1.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 2 * 8;
+ break;
+
+ case 4:
+ entry_arp1.slab[0] = rte_bswap64(
+ (MPLS_LABEL(label2, 0, 0, 0) << 32) |
+ MPLS_LABEL(label3, 0, 1, 0));
+ entry_arp1.slab_offset[0] =
+ p_rt->params.ip_hdr_offset - 8;
+
+ entry_arp1.slab[1] = rte_bswap64(
+ (MPLS_LABEL(label0, 0, 0, 0) << 32) |
+ MPLS_LABEL(label1, 0, 0, 0));
+ entry_arp1.slab_offset[1] =
+ p_rt->params.ip_hdr_offset - 2 * 8;
+ break;
+
+ default:
+ rsp->status = -1;
+ return rsp;
+ }
+
+ entry_arp1.slab[2] = rte_bswap64((macaddr_src << 16) |
+ ethertype_mpls);
+ entry_arp1.slab_offset[2] = p_rt->params.ip_hdr_offset -
+ (n_labels * 4 + 8);
+
+ entry_arp1.data_offset = entry_arp1.slab_offset[2] - 6
+ - sizeof(struct rte_mbuf);
+ entry_arp1.ether_l2_length = n_labels * 4 + 14;
+ }
+
rsp->status = rte_pipeline_table_entry_add(p->p,
p->table_id[0],
&key,
- (struct rte_pipeline_table_entry *) &entry,
+ entry,
&rsp->key_found,
(struct rte_pipeline_table_entry **) &rsp->entry_ptr);
}
*((struct ether_addr *) &entry.macaddr) = req->macaddr;
+ entry.macaddr = entry.macaddr << 16;
rsp->status = rte_pipeline_table_entry_add(p->p,
p->table_id[1],