examples/ipsec-secgw: allow to specify neighbour MAC address
In some cases it is useful to allow user to specify destination ether address for outgoing packets. This patch adds such ability by introducing new 'neigh' config file option. Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com> Acked-by: Radu Nicolau <radu.nicolau@intel.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
This commit is contained in:
parent
03128be4cd
commit
7622291b64
@ -217,7 +217,7 @@ Configurations
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
The following sections provide the syntax of configurations to initialize
|
The following sections provide the syntax of configurations to initialize
|
||||||
your SP, SA and Routing tables.
|
your SP, SA, Routing and Neighbour tables.
|
||||||
Configurations shall be specified in the configuration file to be passed to
|
Configurations shall be specified in the configuration file to be passed to
|
||||||
the application. The file is then parsed by the application. The successful
|
the application. The file is then parsed by the application. The successful
|
||||||
parsing will result in the appropriate rules being applied to the tables
|
parsing will result in the appropriate rules being applied to the tables
|
||||||
@ -238,8 +238,8 @@ General rule syntax
|
|||||||
|
|
||||||
The parse treats one line in the configuration file as one configuration
|
The parse treats one line in the configuration file as one configuration
|
||||||
item (unless the line concatenation symbol exists). Every configuration
|
item (unless the line concatenation symbol exists). Every configuration
|
||||||
item shall follow the syntax of either SP, SA, or Routing rules specified
|
item shall follow the syntax of either SP, SA, Routing or Neighbour
|
||||||
below.
|
rules specified below.
|
||||||
|
|
||||||
The configuration parser supports the following special symbols:
|
The configuration parser supports the following special symbols:
|
||||||
|
|
||||||
@ -631,3 +631,39 @@ Example SP rules:
|
|||||||
rt ipv4 dst 172.16.1.5/32 port 0
|
rt ipv4 dst 172.16.1.5/32 port 0
|
||||||
|
|
||||||
rt ipv6 dst 1111:1111:1111:1111:1111:1111:1111:5555/116 port 0
|
rt ipv6 dst 1111:1111:1111:1111:1111:1111:1111:5555/116 port 0
|
||||||
|
|
||||||
|
Neighbour rule syntax
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The Neighbour rule syntax is shown as follows:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
neigh <port> <dst_mac>
|
||||||
|
|
||||||
|
|
||||||
|
where each options means:
|
||||||
|
|
||||||
|
``<port>``
|
||||||
|
|
||||||
|
* The output port id
|
||||||
|
|
||||||
|
* Optional: No
|
||||||
|
|
||||||
|
* Syntax: *port X*
|
||||||
|
|
||||||
|
``<dst_mac>``
|
||||||
|
|
||||||
|
* The destination ethernet address to use for that port
|
||||||
|
|
||||||
|
* Optional: No
|
||||||
|
|
||||||
|
* Syntax:
|
||||||
|
|
||||||
|
* XX:XX:XX:XX:XX:XX
|
||||||
|
|
||||||
|
Example Neighbour rules:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
neigh port 0 DE:AD:BE:EF:01:02
|
||||||
|
@ -104,9 +104,9 @@ static uint16_t nb_txd = IPSEC_SECGW_TX_DESC_DEFAULT;
|
|||||||
#define ETHADDR(a, b, c, d, e, f) (__BYTES_TO_UINT64(a, b, c, d, e, f, 0, 0))
|
#define ETHADDR(a, b, c, d, e, f) (__BYTES_TO_UINT64(a, b, c, d, e, f, 0, 0))
|
||||||
|
|
||||||
#define ETHADDR_TO_UINT64(addr) __BYTES_TO_UINT64( \
|
#define ETHADDR_TO_UINT64(addr) __BYTES_TO_UINT64( \
|
||||||
addr.addr_bytes[0], addr.addr_bytes[1], \
|
(addr)->addr_bytes[0], (addr)->addr_bytes[1], \
|
||||||
addr.addr_bytes[2], addr.addr_bytes[3], \
|
(addr)->addr_bytes[2], (addr)->addr_bytes[3], \
|
||||||
addr.addr_bytes[4], addr.addr_bytes[5], \
|
(addr)->addr_bytes[4], (addr)->addr_bytes[5], \
|
||||||
0, 0)
|
0, 0)
|
||||||
|
|
||||||
/* port/source ethernet addr and destination ethernet addr */
|
/* port/source ethernet addr and destination ethernet addr */
|
||||||
@ -1246,6 +1246,19 @@ print_ethaddr(const char *name, const struct ether_addr *eth_addr)
|
|||||||
printf("%s%s", name, buf);
|
printf("%s%s", name, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update destination ethaddr for the port.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
add_dst_ethaddr(uint16_t port, const struct ether_addr *addr)
|
||||||
|
{
|
||||||
|
if (port > RTE_DIM(ethaddr_tbl))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ethaddr_tbl[port].dst = ETHADDR_TO_UINT64(addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the link status of all ports in up to 9s, and print them finally */
|
/* Check the link status of all ports in up to 9s, and print them finally */
|
||||||
static void
|
static void
|
||||||
check_all_ports_link_status(uint32_t port_mask)
|
check_all_ports_link_status(uint32_t port_mask)
|
||||||
@ -1645,7 +1658,7 @@ port_init(uint16_t portid, uint64_t req_rx_offloads, uint64_t req_tx_offloads)
|
|||||||
printf("Configuring device port %u:\n", portid);
|
printf("Configuring device port %u:\n", portid);
|
||||||
|
|
||||||
rte_eth_macaddr_get(portid, ðaddr);
|
rte_eth_macaddr_get(portid, ðaddr);
|
||||||
ethaddr_tbl[portid].src = ETHADDR_TO_UINT64(ethaddr);
|
ethaddr_tbl[portid].src = ETHADDR_TO_UINT64(ðaddr);
|
||||||
print_ethaddr("Address: ", ðaddr);
|
print_ethaddr("Address: ", ðaddr);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
@ -247,4 +247,7 @@ int
|
|||||||
sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
|
sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
|
||||||
uint64_t *tx_offloads);
|
uint64_t *tx_offloads);
|
||||||
|
|
||||||
|
int
|
||||||
|
add_dst_ethaddr(uint16_t port, const struct ether_addr *addr);
|
||||||
|
|
||||||
#endif /* __IPSEC_H__ */
|
#endif /* __IPSEC_H__ */
|
||||||
|
@ -306,6 +306,46 @@ parse_range(const char *token, uint16_t *low, uint16_t *high)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper function for parse_mac, parse one section of the ether addr.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
parse_uint8x16(const char *s, uint8_t *v, uint8_t ls)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
unsigned long t;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
t = strtoul(s, &end, 16);
|
||||||
|
if (errno != 0 || end[0] != ls || t > UINT8_MAX)
|
||||||
|
return NULL;
|
||||||
|
v[0] = t;
|
||||||
|
return end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_mac(const char *str, struct ether_addr *addr)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
static const uint8_t stop_sym[RTE_DIM(addr->addr_bytes)] = {
|
||||||
|
[0] = ':',
|
||||||
|
[1] = ':',
|
||||||
|
[2] = ':',
|
||||||
|
[3] = ':',
|
||||||
|
[4] = ':',
|
||||||
|
[5] = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i != RTE_DIM(addr->addr_bytes); i++) {
|
||||||
|
str = parse_uint8x16(str, addr->addr_bytes + i, stop_sym[i]);
|
||||||
|
if (str == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** sp add parse */
|
/** sp add parse */
|
||||||
struct cfg_sp_add_cfg_item {
|
struct cfg_sp_add_cfg_item {
|
||||||
cmdline_fixed_string_t sp_keyword;
|
cmdline_fixed_string_t sp_keyword;
|
||||||
@ -444,11 +484,61 @@ cmdline_parse_inst_t cfg_rt_add_rule = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* neigh add parse */
|
||||||
|
struct cfg_neigh_add_item {
|
||||||
|
cmdline_fixed_string_t neigh;
|
||||||
|
cmdline_fixed_string_t pstr;
|
||||||
|
uint16_t port;
|
||||||
|
cmdline_fixed_string_t mac;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cfg_parse_neigh(void *parsed_result, __rte_unused struct cmdline *cl,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int32_t rc;
|
||||||
|
struct cfg_neigh_add_item *res;
|
||||||
|
struct parse_status *st;
|
||||||
|
struct ether_addr mac;
|
||||||
|
|
||||||
|
st = data;
|
||||||
|
res = parsed_result;
|
||||||
|
rc = parse_mac(res->mac, &mac);
|
||||||
|
APP_CHECK(rc == 0, st, "invalid ether addr:%s", res->mac);
|
||||||
|
rc = add_dst_ethaddr(res->port, &mac);
|
||||||
|
APP_CHECK(rc == 0, st, "invalid port numer:%hu", res->port);
|
||||||
|
if (st->status < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdline_parse_token_string_t cfg_add_neigh_start =
|
||||||
|
TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, neigh, "neigh");
|
||||||
|
cmdline_parse_token_string_t cfg_add_neigh_pstr =
|
||||||
|
TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, pstr, "port");
|
||||||
|
cmdline_parse_token_num_t cfg_add_neigh_port =
|
||||||
|
TOKEN_NUM_INITIALIZER(struct cfg_neigh_add_item, port, UINT16);
|
||||||
|
cmdline_parse_token_string_t cfg_add_neigh_mac =
|
||||||
|
TOKEN_STRING_INITIALIZER(struct cfg_neigh_add_item, mac, NULL);
|
||||||
|
|
||||||
|
cmdline_parse_inst_t cfg_neigh_add_rule = {
|
||||||
|
.f = cfg_parse_neigh,
|
||||||
|
.data = NULL,
|
||||||
|
.help_str = "",
|
||||||
|
.tokens = {
|
||||||
|
(void *)&cfg_add_neigh_start,
|
||||||
|
(void *)&cfg_add_neigh_pstr,
|
||||||
|
(void *)&cfg_add_neigh_port,
|
||||||
|
(void *)&cfg_add_neigh_mac,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/** set of cfg items */
|
/** set of cfg items */
|
||||||
cmdline_parse_ctx_t ipsec_ctx[] = {
|
cmdline_parse_ctx_t ipsec_ctx[] = {
|
||||||
(cmdline_parse_inst_t *)&cfg_sp_add_rule,
|
(cmdline_parse_inst_t *)&cfg_sp_add_rule,
|
||||||
(cmdline_parse_inst_t *)&cfg_sa_add_rule,
|
(cmdline_parse_inst_t *)&cfg_sa_add_rule,
|
||||||
(cmdline_parse_inst_t *)&cfg_rt_add_rule,
|
(cmdline_parse_inst_t *)&cfg_rt_add_rule,
|
||||||
|
(cmdline_parse_inst_t *)&cfg_neigh_add_rule,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -474,6 +564,7 @@ parse_cfg_file(const char *cfg_filename)
|
|||||||
cfg_sp_add_rule.data = &status;
|
cfg_sp_add_rule.data = &status;
|
||||||
cfg_sa_add_rule.data = &status;
|
cfg_sa_add_rule.data = &status;
|
||||||
cfg_rt_add_rule.data = &status;
|
cfg_rt_add_rule.data = &status;
|
||||||
|
cfg_neigh_add_rule.data = &status;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char oneline[1024];
|
char oneline[1024];
|
||||||
|
@ -14,14 +14,14 @@ struct parse_status {
|
|||||||
char parse_msg[256];
|
char parse_msg[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define APP_CHECK(exp, status, fmt, ...) \
|
#define APP_CHECK(exp, st, fmt, ...) \
|
||||||
do { \
|
do { \
|
||||||
if (!(exp)) { \
|
if (!(exp)) { \
|
||||||
sprintf(status->parse_msg, fmt "\n", \
|
sprintf((st)->parse_msg, fmt "\n", \
|
||||||
## __VA_ARGS__); \
|
## __VA_ARGS__); \
|
||||||
status->status = -1; \
|
(st)->status = -1; \
|
||||||
} else \
|
} else \
|
||||||
status->status = 0; \
|
(st)->status = 0; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define APP_CHECK_PRESENCE(val, str, status) \
|
#define APP_CHECK_PRESENCE(val, str, status) \
|
||||||
|
Loading…
Reference in New Issue
Block a user