1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2022 Intel Corporation
8 #include <sys/socket.h>
11 #include "l3fwd_route.h"
13 static struct em_rule *em_route_base_v4;
14 static struct em_rule *em_route_base_v6;
27 em_parse_v6_net(const char *in, uint8_t *v)
32 rc = inet_pton(AF_INET6, in, v);
40 em_parse_v6_rule(char *str, struct em_rule *v)
43 char *s, *sp, *in[CB_FLD_MAX];
44 static const char *dlm = " \t\n";
48 for (i = 0; i != dim; i++, s = NULL) {
49 in[i] = strtok_r(s, dlm, &sp);
54 rc = em_parse_v6_net(in[CB_FLD_DST_ADDR], v->v6_key.ip_dst);
57 rc = em_parse_v6_net(in[CB_FLD_SRC_ADDR], v->v6_key.ip_src);
62 GET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v6_key.port_src, 0, UINT16_MAX, 0);
63 /* destination port. */
64 GET_CB_FIELD(in[CB_FLD_DST_PORT], v->v6_key.port_dst, 0, UINT16_MAX, 0);
66 GET_CB_FIELD(in[CB_FLD_PROTO], v->v6_key.proto, 0, UINT8_MAX, 0);
68 GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
74 em_parse_v4_rule(char *str, struct em_rule *v)
77 char *s, *sp, *in[CB_FLD_MAX];
78 static const char *dlm = " \t\n";
82 for (i = 0; i != dim; i++, s = NULL) {
83 in[i] = strtok_r(s, dlm, &sp);
88 rc = inet_pton(AF_INET, in[CB_FLD_DST_ADDR], &(v->v4_key.ip_dst));
89 v->v4_key.ip_dst = ntohl(v->v4_key.ip_dst);
93 rc = inet_pton(AF_INET, in[CB_FLD_SRC_ADDR], &(v->v4_key.ip_src));
94 v->v4_key.ip_src = ntohl(v->v4_key.ip_src);
99 GET_CB_FIELD(in[CB_FLD_SRC_PORT], v->v4_key.port_src, 0, UINT16_MAX, 0);
100 /* destination port. */
101 GET_CB_FIELD(in[CB_FLD_DST_PORT], v->v4_key.port_dst, 0, UINT16_MAX, 0);
103 GET_CB_FIELD(in[CB_FLD_PROTO], v->v4_key.proto, 0, UINT8_MAX, 0);
105 GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
111 em_add_rules(const char *rule_path,
112 struct em_rule **proute_base,
113 int (*parser)(char *, struct em_rule *))
115 struct em_rule *route_rules;
116 struct em_rule *next;
117 unsigned int route_num = 0;
118 unsigned int route_cnt = 0;
121 unsigned int i = 0, rule_size = sizeof(*next);
125 fh = fopen(rule_path, "rb");
129 while ((fgets(buff, LINE_MAX, fh) != NULL)) {
130 if (buff[0] == ROUTE_LEAD_CHAR)
134 if (route_num == 0) {
139 val = fseek(fh, 0, SEEK_SET);
145 route_rules = calloc(route_num, rule_size);
147 if (route_rules == NULL) {
153 while (fgets(buff, LINE_MAX, fh) != NULL) {
155 if (is_bypass_line(buff))
161 if (s == ROUTE_LEAD_CHAR)
162 next = &route_rules[route_cnt];
167 "%s Line %u: should start with leading "
169 rule_path, i, ROUTE_LEAD_CHAR);
175 if (parser(buff + 1, next) != 0) {
177 "%s Line %u: parse rules error\n",
189 *proute_base = route_rules;
195 em_add_default_v4_rules(void)
197 /* populate the LPM IPv4 table */
198 unsigned int i, rule_size = sizeof(*em_route_base_v4);
199 route_num_v4 = RTE_DIM(ipv4_l3fwd_em_route_array);
201 em_route_base_v4 = calloc(route_num_v4, rule_size);
203 for (i = 0; i < (unsigned int)route_num_v4; i++) {
204 em_route_base_v4[i].v4_key.ip_dst = ipv4_l3fwd_em_route_array[i].key.ip_dst;
205 em_route_base_v4[i].v4_key.ip_src = ipv4_l3fwd_em_route_array[i].key.ip_src;
206 em_route_base_v4[i].v4_key.port_dst = ipv4_l3fwd_em_route_array[i].key.port_dst;
207 em_route_base_v4[i].v4_key.port_src = ipv4_l3fwd_em_route_array[i].key.port_src;
208 em_route_base_v4[i].v4_key.proto = ipv4_l3fwd_em_route_array[i].key.proto;
209 em_route_base_v4[i].if_out = ipv4_l3fwd_em_route_array[i].if_out;
215 em_add_default_v6_rules(void)
217 /* populate the LPM IPv6 table */
218 unsigned int i, rule_size = sizeof(*em_route_base_v6);
219 route_num_v6 = RTE_DIM(ipv6_l3fwd_em_route_array);
221 em_route_base_v6 = calloc(route_num_v6, rule_size);
223 for (i = 0; i < (unsigned int)route_num_v6; i++) {
224 memcpy(em_route_base_v6[i].v6_key.ip_dst, ipv6_l3fwd_em_route_array[i].key.ip_dst,
225 sizeof(em_route_base_v6[i].v6_key.ip_dst));
226 memcpy(em_route_base_v6[i].v6_key.ip_src, ipv6_l3fwd_em_route_array[i].key.ip_src,
227 sizeof(em_route_base_v6[i].v6_key.ip_src));
228 em_route_base_v6[i].v6_key.port_dst = ipv6_l3fwd_em_route_array[i].key.port_dst;
229 em_route_base_v6[i].v6_key.port_src = ipv6_l3fwd_em_route_array[i].key.port_src;
230 em_route_base_v6[i].v6_key.proto = ipv6_l3fwd_em_route_array[i].key.proto;
231 em_route_base_v6[i].if_out = ipv6_l3fwd_em_route_array[i].if_out;
239 free(em_route_base_v4);
240 free(em_route_base_v6);
241 em_route_base_v4 = NULL;
242 em_route_base_v6 = NULL;
247 /* Load rules from the input file */
249 read_config_files_em(void)
252 if (parm_config.rule_ipv4_name != NULL &&
253 parm_config.rule_ipv6_name != NULL) {
255 route_num_v4 = em_add_rules(parm_config.rule_ipv4_name,
256 &em_route_base_v4, &em_parse_v4_rule);
257 if (route_num_v4 < 0) {
259 rte_exit(EXIT_FAILURE, "Failed to add EM IPv4 rules\n");
263 route_num_v6 = em_add_rules(parm_config.rule_ipv6_name,
264 &em_route_base_v6, &em_parse_v6_rule);
265 if (route_num_v6 < 0) {
267 rte_exit(EXIT_FAILURE, "Failed to add EM IPv6 rules\n");
270 RTE_LOG(INFO, L3FWD, "Missing 1 or more rule files, using default instead\n");
271 if (em_add_default_v4_rules() < 0) {
273 rte_exit(EXIT_FAILURE, "Failed to add default IPv4 rules\n");
275 if (em_add_default_v6_rules() < 0) {
277 rte_exit(EXIT_FAILURE, "Failed to add default IPv6 rules\n");