1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2022 Intel Corporation
8 #include <sys/socket.h>
11 #include "l3fwd_route.h"
19 struct lpm_route_rule *route_base_v4;
20 struct lpm_route_rule *route_base_v6;
24 /* Bypass comment and empty lines */
26 is_bypass_line(const char *buff)
31 if (buff[0] == COMMENT_LEAD_CHAR)
34 while (buff[i] != '\0') {
35 if (!isspace(buff[i]))
43 parse_ipv6_addr_mask(char *token, uint32_t *ipv6, uint8_t *mask)
46 const char *dlm = "/";
49 sa = strtok_r(token, dlm, &sv);
52 sm = strtok_r(NULL, dlm, &sv);
56 if (inet_pton(AF_INET6, sa, ipv6) != 1)
59 GET_CB_FIELD(sm, *mask, 0, 128, 0);
64 parse_ipv4_addr_mask(char *token, uint32_t *ipv4, uint8_t *mask)
67 const char *dlm = "/";
70 sa = strtok_r(token, dlm, &sv);
73 sm = strtok_r(NULL, dlm, &sv);
77 if (inet_pton(AF_INET, sa, ipv4) != 1)
80 GET_CB_FIELD(sm, *mask, 0, 32, 0);
86 lpm_parse_v6_net(char *in, uint32_t *v, uint8_t *mask_len)
91 rc = parse_ipv6_addr_mask(in, v, mask_len);
97 lpm_parse_v6_rule(char *str, struct lpm_route_rule *v)
100 char *s, *sp, *in[CB_FLD_MAX];
101 static const char *dlm = " \t\n";
102 int dim = CB_FLD_MAX;
105 for (i = 0; i != dim; i++, s = NULL) {
106 in[i] = strtok_r(s, dlm, &sp);
111 rc = lpm_parse_v6_net(in[CB_FLD_DST_ADDR], v->ip_32, &v->depth);
113 GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
119 lpm_parse_v4_rule(char *str, struct lpm_route_rule *v)
122 char *s, *sp, *in[CB_FLD_MAX];
123 static const char *dlm = " \t\n";
124 int dim = CB_FLD_MAX;
127 for (i = 0; i != dim; i++, s = NULL) {
128 in[i] = strtok_r(s, dlm, &sp);
133 rc = parse_ipv4_addr_mask(in[CB_FLD_DST_ADDR], &v->ip, &v->depth);
135 GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
141 lpm_add_default_v4_rules(void)
143 /* populate the LPM IPv4 table */
144 unsigned int i, rule_size = sizeof(*route_base_v4);
145 route_num_v4 = RTE_DIM(ipv4_l3fwd_route_array);
147 route_base_v4 = calloc(route_num_v4, rule_size);
149 for (i = 0; i < (unsigned int)route_num_v4; i++) {
150 route_base_v4[i].ip = ipv4_l3fwd_route_array[i].ip;
151 route_base_v4[i].depth = ipv4_l3fwd_route_array[i].depth;
152 route_base_v4[i].if_out = ipv4_l3fwd_route_array[i].if_out;
158 lpm_add_default_v6_rules(void)
160 /* populate the LPM IPv6 table */
161 unsigned int i, rule_size = sizeof(*route_base_v6);
162 route_num_v6 = RTE_DIM(ipv6_l3fwd_route_array);
164 route_base_v6 = calloc(route_num_v6, rule_size);
166 for (i = 0; i < (unsigned int)route_num_v6; i++) {
167 memcpy(route_base_v6[i].ip_8, ipv6_l3fwd_route_array[i].ip,
168 sizeof(route_base_v6[i].ip_8));
169 route_base_v6[i].depth = ipv6_l3fwd_route_array[i].depth;
170 route_base_v6[i].if_out = ipv6_l3fwd_route_array[i].if_out;
176 lpm_add_rules(const char *rule_path,
177 struct lpm_route_rule **proute_base,
178 int (*parser)(char *, struct lpm_route_rule *))
180 struct lpm_route_rule *route_rules;
181 struct lpm_route_rule *next;
182 unsigned int route_num = 0;
183 unsigned int route_cnt = 0;
186 unsigned int i = 0, rule_size = sizeof(*next);
190 fh = fopen(rule_path, "rb");
194 while ((fgets(buff, LINE_MAX, fh) != NULL)) {
195 if (buff[0] == ROUTE_LEAD_CHAR)
199 if (route_num == 0) {
204 val = fseek(fh, 0, SEEK_SET);
210 route_rules = calloc(route_num, rule_size);
212 if (route_rules == NULL) {
218 while (fgets(buff, LINE_MAX, fh) != NULL) {
220 if (is_bypass_line(buff))
226 if (s == ROUTE_LEAD_CHAR)
227 next = &route_rules[route_cnt];
232 "%s Line %u: should start with leading "
234 rule_path, i, ROUTE_LEAD_CHAR);
240 if (parser(buff + 1, next) != 0) {
242 "%s Line %u: parse rules error\n",
254 *proute_base = route_rules;
260 lpm_free_routes(void)
264 route_base_v4 = NULL;
265 route_base_v6 = NULL;
270 /* Load rules from the input file */
272 read_config_files_lpm(void)
274 if (parm_config.rule_ipv4_name != NULL &&
275 parm_config.rule_ipv6_name != NULL) {
277 route_num_v4 = lpm_add_rules(parm_config.rule_ipv4_name,
278 &route_base_v4, &lpm_parse_v4_rule);
279 if (route_num_v4 < 0) {
281 rte_exit(EXIT_FAILURE, "Failed to add IPv4 rules\n");
285 route_num_v6 = lpm_add_rules(parm_config.rule_ipv6_name,
286 &route_base_v6, &lpm_parse_v6_rule);
287 if (route_num_v6 < 0) {
289 rte_exit(EXIT_FAILURE, "Failed to add IPv6 rules\n");
292 RTE_LOG(INFO, L3FWD, "Missing 1 or more rule files, using default instead\n");
293 if (lpm_add_default_v4_rules() < 0) {
295 rte_exit(EXIT_FAILURE, "Failed to add default IPv4 rules\n");
297 if (lpm_add_default_v6_rules() < 0) {
299 rte_exit(EXIT_FAILURE, "Failed to add default IPv6 rules\n");