13395610eSKonstantin Ananyev/*
23395610eSKonstantin Ananyev * Copyright (c) 2016  Intel Corporation.
33395610eSKonstantin Ananyev * Licensed under the Apache License, Version 2.0 (the "License");
43395610eSKonstantin Ananyev * you may not use this file except in compliance with the License.
53395610eSKonstantin Ananyev * You may obtain a copy of the License at:
63395610eSKonstantin Ananyev *
73395610eSKonstantin Ananyev *     http://www.apache.org/licenses/LICENSE-2.0
83395610eSKonstantin Ananyev *
93395610eSKonstantin Ananyev * Unless required by applicable law or agreed to in writing, software
103395610eSKonstantin Ananyev * distributed under the License is distributed on an "AS IS" BASIS,
113395610eSKonstantin Ananyev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123395610eSKonstantin Ananyev * See the License for the specific language governing permissions and
133395610eSKonstantin Ananyev * limitations under the License.
143395610eSKonstantin Ananyev */
153395610eSKonstantin Ananyev
163395610eSKonstantin Ananyev#ifndef __FWDTBL_H__
173395610eSKonstantin Ananyev#define __FWDTBL_H__
183395610eSKonstantin Ananyev
193395610eSKonstantin Ananyevstruct fwd4_key {
203395610eSKonstantin Ananyev	uint32_t port;
213395610eSKonstantin Ananyev	struct in_addr addr;
223395610eSKonstantin Ananyev} __attribute__((__packed__));
233395610eSKonstantin Ananyev
243395610eSKonstantin Ananyevstruct fwd6_key {
253395610eSKonstantin Ananyev	uint32_t port;
263395610eSKonstantin Ananyev	struct in6_addr addr;
273395610eSKonstantin Ananyev} __attribute__((__packed__));
283395610eSKonstantin Ananyev
293395610eSKonstantin Ananyevunion fwd_key {
303395610eSKonstantin Ananyev	struct fwd4_key k4;
313395610eSKonstantin Ananyev	struct fwd6_key k6;
323395610eSKonstantin Ananyev};
333395610eSKonstantin Ananyev
343395610eSKonstantin Ananyevstatic struct rte_hash *
353395610eSKonstantin Ananyevfwd_tbl_key_prep(const struct netfe_lcore *fe, uint16_t family,
363395610eSKonstantin Ananyev	const struct sockaddr *sa, union fwd_key *key)
373395610eSKonstantin Ananyev{
383395610eSKonstantin Ananyev	struct rte_hash *h;
393395610eSKonstantin Ananyev	const struct sockaddr_in *sin4;
403395610eSKonstantin Ananyev	const struct sockaddr_in6 *sin6;
413395610eSKonstantin Ananyev
423395610eSKonstantin Ananyev	if (family == AF_INET) {
433395610eSKonstantin Ananyev		h = fe->fw4h;
443395610eSKonstantin Ananyev		sin4 = (const struct sockaddr_in *)sa;
453395610eSKonstantin Ananyev		key->k4.port = sin4->sin_port;
463395610eSKonstantin Ananyev		key->k4.addr = sin4->sin_addr;
473395610eSKonstantin Ananyev	} else {
483395610eSKonstantin Ananyev		h = fe->fw6h;
493395610eSKonstantin Ananyev		sin6 = (const struct sockaddr_in6 *)sa;
503395610eSKonstantin Ananyev		key->k6.port = sin6->sin6_port;
513395610eSKonstantin Ananyev		key->k6.addr = sin6->sin6_addr;
523395610eSKonstantin Ananyev	}
533395610eSKonstantin Ananyev
543395610eSKonstantin Ananyev	return h;
553395610eSKonstantin Ananyev}
563395610eSKonstantin Ananyev
573395610eSKonstantin Ananyevstatic int
583395610eSKonstantin Ananyevfwd_tbl_add(struct netfe_lcore *fe, uint16_t family, const struct sockaddr *sa,
593395610eSKonstantin Ananyev	struct netfe_stream *data)
603395610eSKonstantin Ananyev{
613395610eSKonstantin Ananyev	int32_t rc;
623395610eSKonstantin Ananyev	struct rte_hash *h;
633395610eSKonstantin Ananyev	union fwd_key key;
643395610eSKonstantin Ananyev
653395610eSKonstantin Ananyev	h = fwd_tbl_key_prep(fe, family, sa, &key);
663395610eSKonstantin Ananyev	rc = rte_hash_add_key_data(h, &key, data);
673395610eSKonstantin Ananyev	return rc;
683395610eSKonstantin Ananyev}
693395610eSKonstantin Ananyev
703395610eSKonstantin Ananyevstatic struct netfe_stream *
713395610eSKonstantin Ananyevfwd_tbl_lkp(struct netfe_lcore *fe, uint16_t family, const struct sockaddr *sa)
723395610eSKonstantin Ananyev{
733395610eSKonstantin Ananyev	int rc;
743395610eSKonstantin Ananyev	void *d;
753395610eSKonstantin Ananyev	struct rte_hash *h;
763395610eSKonstantin Ananyev	union fwd_key key;
773395610eSKonstantin Ananyev
783395610eSKonstantin Ananyev	h = fwd_tbl_key_prep(fe, family, sa, &key);
793395610eSKonstantin Ananyev	rc = rte_hash_lookup_data(h, &key, &d);
803395610eSKonstantin Ananyev	if (rc < 0)
813395610eSKonstantin Ananyev		d = NULL;
823395610eSKonstantin Ananyev	return d;
833395610eSKonstantin Ananyev}
843395610eSKonstantin Ananyev
853395610eSKonstantin Ananyevstatic int
863395610eSKonstantin Ananyevfwd_tbl_init(struct netfe_lcore *fe, uint16_t family, uint32_t lcore)
873395610eSKonstantin Ananyev{
883395610eSKonstantin Ananyev	int32_t rc;
893395610eSKonstantin Ananyev	struct rte_hash **h;
903395610eSKonstantin Ananyev	struct rte_hash_parameters hprm;
913395610eSKonstantin Ananyev	char buf[RTE_HASH_NAMESIZE];
923395610eSKonstantin Ananyev
933395610eSKonstantin Ananyev	if (family == AF_INET) {
943395610eSKonstantin Ananyev		snprintf(buf, sizeof(buf), "fwd4tbl@%u", lcore);
953395610eSKonstantin Ananyev		h = &fe->fw4h;
963395610eSKonstantin Ananyev		hprm.key_len = sizeof(struct fwd4_key);
973395610eSKonstantin Ananyev	} else {
983395610eSKonstantin Ananyev		snprintf(buf, sizeof(buf), "fwd6tbl@%u", lcore);
993395610eSKonstantin Ananyev		h = &fe->fw6h;
1003395610eSKonstantin Ananyev		hprm.key_len = sizeof(struct fwd6_key);
1013395610eSKonstantin Ananyev	}
1023395610eSKonstantin Ananyev
1033395610eSKonstantin Ananyev	hprm.name = buf;
1043395610eSKonstantin Ananyev	hprm.entries = RTE_MAX(2 * fe->snum, 0x10U);
1053395610eSKonstantin Ananyev	hprm.socket_id = rte_lcore_to_socket_id(lcore);
1063395610eSKonstantin Ananyev	hprm.hash_func = NULL;
1073395610eSKonstantin Ananyev	hprm.hash_func_init_val = 0;
1083395610eSKonstantin Ananyev
1093395610eSKonstantin Ananyev	*h = rte_hash_create(&hprm);
1103395610eSKonstantin Ananyev	if (*h == NULL)
1113395610eSKonstantin Ananyev		rc = (rte_errno != 0) ? -rte_errno : -ENOMEM;
1123395610eSKonstantin Ananyev	else
1133395610eSKonstantin Ananyev		rc = 0;
1143395610eSKonstantin Ananyev	return rc;
1153395610eSKonstantin Ananyev}
1163395610eSKonstantin Ananyev
1173395610eSKonstantin Ananyev#endif /* __FWDTBL_H__ */