dpdk_legacy.h revision aa97dd1c
1/*
2 * Copyright (c) 2016  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef MAIN_DPDK_LEGACY_H_
17#define MAIN_DPDK_LEGACY_H_
18
19#include "dpdk_version.h"
20
21/*
22 * UDP IPv4 destination lookup callback.
23 */
24static int
25lpm4_dst_lookup(void *data, const struct in_addr *addr,
26	struct tle_dest *res)
27{
28	int32_t rc;
29#ifdef DPDK_VERSION_GE_1604
30	uint32_t idx;
31#else
32	uint8_t idx;
33#endif
34	struct netbe_lcore *lc;
35	struct tle_dest *dst;
36
37	lc = data;
38
39	rc = rte_lpm_lookup(lc->lpm4, rte_be_to_cpu_32(addr->s_addr), &idx);
40	if (rc == 0) {
41		dst = &lc->dst4[idx];
42		rte_memcpy(res, dst, dst->l2_len + dst->l3_len +
43			offsetof(struct tle_dest, hdr));
44	}
45	return rc;
46}
47
48static int
49lcore_lpm_init(struct netbe_lcore *lc)
50{
51	int32_t sid;
52	char str[RTE_LPM_NAMESIZE];
53#ifdef DPDK_VERSION_GE_1604
54	const struct rte_lpm_config lpm4_cfg = {
55		.max_rules = MAX_RULES,
56		.number_tbl8s = MAX_TBL8,
57	};
58#endif
59	const struct rte_lpm6_config lpm6_cfg = {
60		.max_rules = MAX_RULES,
61		.number_tbl8s = MAX_TBL8,
62	};
63
64	sid = rte_lcore_to_socket_id(lc->id);
65
66	snprintf(str, sizeof(str), "LPM4%u\n", lc->id);
67#ifdef DPDK_VERSION_GE_1604
68	lc->lpm4 = rte_lpm_create(str, sid, &lpm4_cfg);
69#else
70	lc->lpm4 = rte_lpm_create(str, sid, MAX_RULES, 0);
71#endif
72	RTE_LOG(NOTICE, USER1, "%s(lcore=%u): lpm4=%p;\n",
73		__func__, lc->id, lc->lpm4);
74	if (lc->lpm4 == NULL)
75		return -ENOMEM;
76
77	snprintf(str, sizeof(str), "LPM6%u\n", lc->id);
78	lc->lpm6 = rte_lpm6_create(str, sid, &lpm6_cfg);
79	RTE_LOG(NOTICE, USER1, "%s(lcore=%u): lpm6=%p;\n",
80		__func__, lc->id, lc->lpm6);
81	if (lc->lpm6 == NULL)
82		return -ENOMEM;
83
84	return 0;
85}
86
87/*
88 * Helper functions, finds BE by given local and remote addresses.
89 */
90static int
91netbe_find4(const struct in_addr *laddr, const uint16_t lport,
92	const struct in_addr *raddr, const uint32_t belc)
93{
94	uint32_t i, j;
95#ifdef DPDK_VERSION_GE_1604
96	uint32_t idx;
97#else
98	uint8_t idx;
99#endif
100	struct netbe_lcore *bc;
101
102	/* we have exactly one BE, use it for all traffic */
103	if (becfg.cpu_num == 1)
104		return 0;
105
106	/* search by provided be_lcore */
107	if (belc != LCORE_ID_ANY) {
108		for (i = 0; i != becfg.cpu_num; i++) {
109			bc = becfg.cpu + i;
110			if (belc == bc->id)
111				return i;
112		}
113		RTE_LOG(NOTICE, USER1, "%s: no stream with be_lcore=%u\n",
114			__func__, belc);
115		return -ENOENT;
116	}
117
118	/* search by local address */
119	if (laddr->s_addr != INADDR_ANY) {
120		for (i = 0; i != becfg.cpu_num; i++) {
121			bc = becfg.cpu + i;
122			/* search by queue for the local port */
123			for (j = 0; j != bc->prtq_num; j++) {
124				if (laddr->s_addr == bc->prtq[j].port.ipv4) {
125
126					if (lport == 0)
127						return i;
128
129					if (verify_queue_for_port(bc->prtq + j,
130							lport) != 0)
131						return i;
132				}
133			}
134		}
135	}
136
137	/* search by remote address */
138	if (raddr->s_addr != INADDR_ANY) {
139		for (i = 0; i != becfg.cpu_num; i++) {
140			bc = becfg.cpu + i;
141			if (rte_lpm_lookup(bc->lpm4,
142					rte_be_to_cpu_32(raddr->s_addr),
143					&idx) == 0) {
144
145				if (lport == 0)
146					return i;
147
148				/* search by queue for the local port */
149				for (j = 0; j != bc->prtq_num; j++)
150					if (verify_queue_for_port(bc->prtq + j,
151							lport) != 0)
152						return i;
153			}
154		}
155	}
156
157	return -ENOENT;
158}
159
160#endif /* MAIN_DPDK_LEGACY_H_ */
161