diff options
author | Konstantin Ananyev <konstantin.ananyev@intel.com> | 2017-02-21 18:12:20 +0000 |
---|---|---|
committer | Konstantin Ananyev <konstantin.ananyev@intel.com> | 2017-02-24 16:37:08 +0000 |
commit | aa97dd1ce910b839fed46ad55d1e70e403f5a930 (patch) | |
tree | f6f0fd494eaf499859bff9f20f5ddfac9ab99233 /examples/udpfwd/parse.c | |
parent | f5f10013ffef8e4ac1071087b8492fe6380d98fe (diff) |
Introduce first version of TCP code.
Supported functionality:
- open/close
- listen/accept/connect
- send/recv
In order to achieve that libtle_udp library was
reworked into libtle_l4p library that supports
both TCP and UDP protocols.
New libtle_timer library was introduced
(thanks to Cisco guys and Dave Barach <dbarach@cisco.com>
for sharing their timer code with us).
Sample application was also reworked significantly
to support both TCP and UDP traffic handling.
New UT were introduced.
Change-Id: I806b05011f521e89b58db403cfdd484a37beb775
Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Karol Latecki <karolx.latecki@intel.com>
Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Diffstat (limited to 'examples/udpfwd/parse.c')
-rw-r--r-- | examples/udpfwd/parse.c | 638 |
1 files changed, 0 insertions, 638 deletions
diff --git a/examples/udpfwd/parse.c b/examples/udpfwd/parse.c deleted file mode 100644 index f46c7df..0000000 --- a/examples/udpfwd/parse.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "netbe.h" -#include "parse.h" - -#define DEF_LINE_NUM 0x400 - -static const struct { - const char *name; - uint16_t op; -} name2feop[] = { - { .name = "rx", .op = RXONLY,}, - { .name = "tx", .op = TXONLY,}, - { .name = "echo", .op = RXTX,}, - { .name = "fwd", .op = FWD,}, -}; - -static int -parse_ipv4_val(__rte_unused const char *key, const char *val, void *prm) -{ - union parse_val *rv; - - rv = prm; - if (inet_pton(AF_INET, val, &rv->in.addr4) != 1) - return -EINVAL; - rv->in.family = AF_INET; - return 0; -} - -static int -parse_ipv6_val(__rte_unused const char *key, const char *val, void *prm) -{ - union parse_val *rv; - - rv = prm; - if (inet_pton(AF_INET6, val, &rv->in.addr6) != 1) - return -EINVAL; - rv->in.family = AF_INET6; - return 0; -} - -static int -parse_ip_val(__rte_unused const char *key, const char *val, void *prm) -{ - if (parse_ipv6_val(key, val, prm) != 0 && - parse_ipv4_val(key, val, prm) != 0) - return -EINVAL; - return 0; -} - -#define PARSE_UINT8x16(s, v, l) \ -do { \ - char *end; \ - unsigned long t; \ - errno = 0; \ - t = strtoul((s), &end, 16); \ - if (errno != 0 || end[0] != (l) || t > UINT8_MAX) \ - return -EINVAL; \ - (s) = end + 1; \ - (v) = t; \ -} while (0) - -static int -parse_mac_val(__rte_unused const char *key, const char *val, void *prm) -{ - union parse_val *rv; - const char *s; - - rv = prm; - s = val; - - PARSE_UINT8x16(s, rv->mac.addr_bytes[0], ':'); - PARSE_UINT8x16(s, rv->mac.addr_bytes[1], ':'); - PARSE_UINT8x16(s, rv->mac.addr_bytes[2], ':'); - PARSE_UINT8x16(s, rv->mac.addr_bytes[3], ':'); - PARSE_UINT8x16(s, rv->mac.addr_bytes[4], ':'); - PARSE_UINT8x16(s, rv->mac.addr_bytes[5], 0); - return 0; -} - -static int -parse_feop_val(__rte_unused const char *key, const char *val, void *prm) -{ - uint32_t i; - union parse_val *rv; - - rv = prm; - for (i = 0; i != RTE_DIM(name2feop); i++) { - if (strcmp(val, name2feop[i].name) == 0) { - rv->u64 = name2feop[i].op; - return 0; - } - } - - return -EINVAL; -} - -static int -parse_lcore_list_val(__rte_unused const char *key, const char *val, void *prm) -{ - union parse_val *rv; - unsigned long a, b; - uint32_t i; - char *end; - - rv = prm; - errno = 0; - a = strtoul(val, &end, 0); - if (errno != 0 || (end[0] != 0 && end[0] != '-') || a > UINT32_MAX) - return -EINVAL; - - if (end[0] == '-') { - val = end + 1; - errno = 0; - b = strtoul(val, &end, 0); - if (errno != 0 || end[0] != 0 || b > UINT32_MAX) - return -EINVAL; - } else - b = a; - - if (a <= b) { - for (i = a; i <= b; i++) - CPU_SET(i, &rv->cpuset); - } else { - RTE_LOG(ERR, USER1, - "%s: lcores not in ascending order\n", __func__); - return -EINVAL; - } - - return 0; -} - -static int -parse_kvargs(const char *arg, const char *keys_man[], uint32_t nb_man, - const char *keys_opt[], uint32_t nb_opt, - const arg_handler_t hndl[], union parse_val val[]) -{ - uint32_t j, k; - struct rte_kvargs *kvl; - - kvl = rte_kvargs_parse(arg, NULL); - if (kvl == NULL) { - RTE_LOG(ERR, USER1, - "%s: invalid parameter: %s\n", - __func__, arg); - return -EINVAL; - } - - for (j = 0; j != nb_man; j++) { - if (rte_kvargs_count(kvl, keys_man[j]) == 0) { - RTE_LOG(ERR, USER1, - "%s: %s missing mandatory key: %s\n", - __func__, arg, keys_man[j]); - rte_kvargs_free(kvl); - return -EINVAL; - } - } - - for (j = 0; j != nb_man; j++) { - if (rte_kvargs_process(kvl, keys_man[j], hndl[j], - val + j) != 0) { - RTE_LOG(ERR, USER1, - "%s: %s invalid value for man key: %s\n", - __func__, arg, keys_man[j]); - rte_kvargs_free(kvl); - return -EINVAL; - } - } - - for (j = 0; j != nb_opt; j++) { - k = j + nb_man; - if (rte_kvargs_process(kvl, keys_opt[j], hndl[k], - val + k) != 0) { - RTE_LOG(ERR, USER1, - "%s: %s invalid value for opt key: %s\n", - __func__, arg, keys_opt[j]); - rte_kvargs_free(kvl); - return -EINVAL; - } - } - - rte_kvargs_free(kvl); - return 0; -} - -int -parse_netbe_arg(struct netbe_port *prt, const char *arg, rte_cpuset_t *cpuset) -{ - int32_t rc; - uint32_t i, j, nc; - - static const char *keys_man[] = { - "port", - "lcore", - }; - - static const char *keys_opt[] = { - "mtu", - "rx_offload", - "tx_offload", - "ipv4", - "ipv6", - }; - - static const arg_handler_t hndl[] = { - parse_uint_val, - parse_lcore_list_val, - parse_uint_val, - parse_uint_val, - parse_uint_val, - parse_ipv4_val, - parse_ipv6_val, - }; - - union parse_val val[RTE_DIM(hndl)]; - - memset(val, 0, sizeof(val)); - val[2].u64 = ETHER_MAX_VLAN_FRAME_LEN - ETHER_CRC_LEN; - - rc = parse_kvargs(arg, keys_man, RTE_DIM(keys_man), - keys_opt, RTE_DIM(keys_opt), hndl, val); - if (rc != 0) - return rc; - - prt->id = val[0].u64; - - for (i = 0, nc = 0; i < RTE_MAX_LCORE; i++) - nc += CPU_ISSET(i, &val[1].cpuset); - prt->lcore = rte_zmalloc(NULL, nc * sizeof(prt->lcore[0]), - RTE_CACHE_LINE_SIZE); - prt->nb_lcore = nc; - - for (i = 0, j = 0; i < RTE_MAX_LCORE; i++) - if (CPU_ISSET(i, &val[1].cpuset)) - prt->lcore[j++] = i; - CPU_OR(cpuset, cpuset, &val[1].cpuset); - - prt->mtu = val[2].u64; - prt->rx_offload = val[3].u64; - prt->tx_offload = val[4].u64; - prt->ipv4 = val[5].in.addr4.s_addr; - prt->ipv6 = val[6].in.addr6; - - return 0; -} - -static int -check_netbe_dest(const struct netbe_dest *dst) -{ - if (dst->port >= RTE_MAX_ETHPORTS) { - RTE_LOG(ERR, USER1, "%s(line=%u) invalid port=%u", - __func__, dst->line, dst->port); - return -EINVAL; - } else if ((dst->family == AF_INET && - dst->prfx > sizeof(struct in_addr) * CHAR_BIT) || - (dst->family == AF_INET6 && - dst->prfx > sizeof(struct in6_addr) * CHAR_BIT)) { - RTE_LOG(ERR, USER1, "%s(line=%u) invalid masklen=%u", - __func__, dst->line, dst->prfx); - return -EINVAL; - } else if (dst->mtu > ETHER_MAX_JUMBO_FRAME_LEN - ETHER_CRC_LEN) { - RTE_LOG(ERR, USER1, "%s(line=%u) invalid mtu=%u", - __func__, dst->line, dst->mtu); - return -EINVAL; - } - return 0; -} - -static int -parse_netbe_dest(struct netbe_dest *dst, const char *arg) -{ - int32_t rc; - - static const char *keys_man[] = { - "port", - "addr", - "masklen", - "mac", - }; - - static const char *keys_opt[] = { - "mtu", - }; - - static const arg_handler_t hndl[] = { - parse_uint_val, - parse_ip_val, - parse_uint_val, - parse_mac_val, - parse_uint_val, - }; - - union parse_val val[RTE_DIM(hndl)]; - - /* set default values. */ - memset(val, 0, sizeof(val)); - val[4].u64 = ETHER_MAX_JUMBO_FRAME_LEN - ETHER_CRC_LEN; - - rc = parse_kvargs(arg, keys_man, RTE_DIM(keys_man), - keys_opt, RTE_DIM(keys_opt), hndl, val); - if (rc != 0) - return rc; - - dst->port = val[0].u64; - dst->family = val[1].in.family; - if (val[1].in.family == AF_INET) - dst->ipv4 = val[1].in.addr4; - else - dst->ipv6 = val[1].in.addr6; - dst->prfx = val[2].u64; - memcpy(&dst->mac, &val[3].mac, sizeof(dst->mac)); - dst->mtu = val[4].u64; - - return 0; -} - -int -netbe_parse_dest(const char *fname, struct netbe_dest_prm *prm) -{ - uint32_t i, ln, n, num; - int32_t rc; - size_t sz; - char *s; - FILE *f; - struct netbe_dest *dp; - char line[LINE_MAX]; - - f = fopen(fname, "r"); - if (f == NULL) { - RTE_LOG(ERR, USER1, "%s failed to open file \"%s\"\n", - __func__, fname); - return -EINVAL; - } - - n = 0; - num = 0; - dp = NULL; - - for (ln = 0; fgets(line, sizeof(line), f) != NULL; ln++) { - - /* skip spaces at the start. */ - for (s = line; isspace(s[0]); s++) - ; - - /* skip comment line. */ - if (s[0] == '#' || s[0] == 0) - continue; - - /* skip spaces at the end. */ - for (i = strlen(s); i-- != 0 && isspace(s[i]); s[i] = 0) - ; - - if (n == num) { - num += DEF_LINE_NUM; - sz = sizeof(dp[0]) * num; - dp = realloc(dp, sizeof(dp[0]) * num); - if (dp == NULL) { - RTE_LOG(ERR, USER1, - "%s(%s) allocation of %zu bytes " - "failed\n", - __func__, fname, sz); - rc = -ENOMEM; - break; - } - memset(&dp[n], 0, sizeof(dp[0]) * (num - n)); - } - - dp[n].line = ln + 1; - if ((rc = parse_netbe_dest(dp + n, s)) != 0 || - (rc = check_netbe_dest(dp + n)) != 0) { - RTE_LOG(ERR, USER1, "%s(%s) failed to parse line %u\n", - __func__, fname, dp[n].line); - break; - } - n++; - } - - fclose(f); - - if (rc != 0) { - free(dp); - dp = NULL; - n = 0; - } - - prm->dest = dp; - prm->nb_dest = n; - return rc; -} - -static void -pv2saddr(struct sockaddr_storage *ss, const union parse_val *pva, - const union parse_val *pvp) -{ - ss->ss_family = pva->in.family; - if (pva->in.family == AF_INET) { - struct sockaddr_in *si = (struct sockaddr_in *)ss; - si->sin_addr = pva->in.addr4; - si->sin_port = rte_cpu_to_be_16((uint16_t)pvp->u64); - } else { - struct sockaddr_in6 *si = (struct sockaddr_in6 *)ss; - si->sin6_addr = pva->in.addr6; - si->sin6_port = rte_cpu_to_be_16((uint16_t)pvp->u64); - } -} - -static int -parse_netfe_arg(struct netfe_stream_prm *sp, const char *arg) -{ - int32_t rc; - - static const char *keys_man[] = { - "lcore", - "op", - "laddr", - "lport", - "raddr", - "rport", - }; - - static const char *keys_opt[] = { - "txlen", - "fwladdr", - "fwlport", - "fwraddr", - "fwrport", - "belcore", - }; - - static const arg_handler_t hndl[] = { - parse_uint_val, - parse_feop_val, - parse_ip_val, - parse_uint_val, - parse_ip_val, - parse_uint_val, - parse_uint_val, - parse_ip_val, - parse_uint_val, - parse_ip_val, - parse_uint_val, - parse_uint_val, - }; - - union parse_val val[RTE_DIM(hndl)]; - - memset(val, 0, sizeof(val)); - val[11].u64 = LCORE_ID_ANY; - rc = parse_kvargs(arg, keys_man, RTE_DIM(keys_man), - keys_opt, RTE_DIM(keys_opt), hndl, val); - if (rc != 0) - return rc; - sp->lcore = val[0].u64; - sp->op = val[1].u64; - pv2saddr(&sp->sprm.prm.local_addr, val + 2, val + 3); - pv2saddr(&sp->sprm.prm.remote_addr, val + 4, val + 5); - sp->txlen = val[6].u64; - pv2saddr(&sp->fprm.prm.local_addr, val + 7, val + 8); - pv2saddr(&sp->fprm.prm.remote_addr, val + 9, val + 10); - sp->be_lcore = val[11].u64; - - return 0; -} - -static const char * -format_feop(uint16_t op) -{ - uint32_t i; - - for (i = 0; i != RTE_DIM(name2feop); i++) { - if (name2feop[i].op == op) - return name2feop[i].name; - } - - return NULL; -} - -static int -is_addr_wc(const struct sockaddr_storage *sp) -{ - const struct sockaddr_in *i4; - const struct sockaddr_in6 *i6; - - if (sp->ss_family == AF_INET) { - i4 = (const struct sockaddr_in *)sp; - return (i4->sin_addr.s_addr == INADDR_ANY); - } else if (sp->ss_family == AF_INET6) { - i6 = (const struct sockaddr_in6 *)sp; - return (memcmp(&i6->sin6_addr, &in6addr_any, - sizeof(i6->sin6_addr)) == 0); - } - return 0; -} - -static int -check_netfe_arg(const struct netfe_stream_prm *sp) -{ - char buf[INET6_ADDRSTRLEN]; - - if (sp->sprm.prm.local_addr.ss_family != - sp->sprm.prm.remote_addr.ss_family) { - RTE_LOG(ERR, USER1, "invalid arg at line %u: " - "laddr and raddr for different protocols\n", - sp->line); - return -EINVAL; - } - - if (sp->op == TXONLY) { - if (sp->txlen > RTE_MBUF_DEFAULT_DATAROOM || sp->txlen == 0) { - RTE_LOG(ERR, USER1, "invalid arg at line %u: txlen=%u " - "exceeds allowed values: (0, %u]\n", - sp->line, sp->txlen, RTE_MBUF_DEFAULT_DATAROOM); - return -EINVAL; - } else if (is_addr_wc(&sp->sprm.prm.remote_addr)) { - RTE_LOG(ERR, USER1, "invalid arg at line %u: " - "raddr=%s are not allowed for op=%s;\n", - sp->line, - format_addr(&sp->sprm.prm.remote_addr, - buf, sizeof(buf)), - format_feop(sp->op)); - return -EINVAL; - } - } else if (sp->op == FWD) { - if (sp->fprm.prm.local_addr.ss_family != - sp->fprm.prm.remote_addr.ss_family) { - RTE_LOG(ERR, USER1, "invalid arg at line %u: " - "fwladdr and fwraddr for different protocols\n", - sp->line); - return -EINVAL; - } else if (is_addr_wc(&sp->fprm.prm.remote_addr)) { - RTE_LOG(ERR, USER1, "invalid arg at line %u: " - "fwaddr=%s are not allowed for op=%s;\n", - sp->line, - format_addr(&sp->fprm.prm.remote_addr, - buf, sizeof(buf)), - format_feop(sp->op)); - return -EINVAL; - } - } - - return 0; -} - -int -netfe_parse_cfg(const char *fname, struct netfe_lcore_prm *lp) -{ - uint32_t i, ln, n, num; - int32_t rc; - size_t sz; - char *s; - FILE *f; - struct netfe_stream_prm *sp; - char line[LINE_MAX]; - - f = fopen(fname, "r"); - if (f == NULL) { - RTE_LOG(ERR, USER1, "%s failed to open file \"%s\"\n", - __func__, fname); - return -EINVAL; - } - - n = 0; - num = 0; - sp = NULL; - - for (ln = 0; fgets(line, sizeof(line), f) != NULL; ln++) { - - /* skip spaces at the start. */ - for (s = line; isspace(s[0]); s++) - ; - - /* skip comment line. */ - if (s[0] == '#' || s[0] == 0) - continue; - - /* skip spaces at the end. */ - for (i = strlen(s); i-- != 0 && isspace(s[i]); s[i] = 0) - ; - - if (n == lp->max_streams) { - RTE_LOG(ERR, USER1, - "%s(%s) number of entries exceed max streams " - "value: %u\n", - __func__, fname, n); - rc = -EINVAL; - break; - } - - if (n == num) { - num += DEF_LINE_NUM; - sz = sizeof(sp[0]) * num; - sp = realloc(sp, sizeof(sp[0]) * num); - if (sp == NULL) { - RTE_LOG(ERR, USER1, - "%s(%s) allocation of %zu bytes " - "failed\n", - __func__, fname, sz); - rc = -ENOMEM; - break; - } - memset(&sp[n], 0, sizeof(sp[0]) * (num - n)); - } - - sp[n].line = ln + 1; - if ((rc = parse_netfe_arg(sp + n, s)) != 0 || - (rc = check_netfe_arg(sp + n)) != 0) { - RTE_LOG(ERR, USER1, "%s(%s) failed to parse line %u\n", - __func__, fname, sp[n].line); - break; - } - n++; - } - - fclose(f); - - if (rc != 0) { - free(sp); - sp = NULL; - n = 0; - } - - lp->stream = sp; - lp->nb_streams = n; - return rc; -} |