13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2016 Intel Corporation 3906257e9SSergio Gonzalez Monroy */ 4906257e9SSergio Gonzalez Monroy 5906257e9SSergio Gonzalez Monroy /* 6906257e9SSergio Gonzalez Monroy * Security Policies 7906257e9SSergio Gonzalez Monroy */ 8906257e9SSergio Gonzalez Monroy #include <sys/types.h> 9906257e9SSergio Gonzalez Monroy #include <netinet/in.h> 10906257e9SSergio Gonzalez Monroy #include <netinet/ip.h> 11906257e9SSergio Gonzalez Monroy 12906257e9SSergio Gonzalez Monroy #include <rte_acl.h> 13906257e9SSergio Gonzalez Monroy #include <rte_ip.h> 14906257e9SSergio Gonzalez Monroy 15906257e9SSergio Gonzalez Monroy #include "ipsec.h" 160d547ed0SFan Zhang #include "parser.h" 17906257e9SSergio Gonzalez Monroy 180d547ed0SFan Zhang #define MAX_ACL_RULE_NUM 1024 19906257e9SSergio Gonzalez Monroy 20906257e9SSergio Gonzalez Monroy /* 21906257e9SSergio Gonzalez Monroy * Rule and trace formats definitions. 22906257e9SSergio Gonzalez Monroy */ 23906257e9SSergio Gonzalez Monroy enum { 24906257e9SSergio Gonzalez Monroy PROTO_FIELD_IPV4, 25906257e9SSergio Gonzalez Monroy SRC_FIELD_IPV4, 26906257e9SSergio Gonzalez Monroy DST_FIELD_IPV4, 27906257e9SSergio Gonzalez Monroy SRCP_FIELD_IPV4, 28906257e9SSergio Gonzalez Monroy DSTP_FIELD_IPV4, 29906257e9SSergio Gonzalez Monroy NUM_FIELDS_IPV4 30906257e9SSergio Gonzalez Monroy }; 31906257e9SSergio Gonzalez Monroy 32906257e9SSergio Gonzalez Monroy /* 33906257e9SSergio Gonzalez Monroy * That effectively defines order of IPV4 classifications: 34906257e9SSergio Gonzalez Monroy * - PROTO 35906257e9SSergio Gonzalez Monroy * - SRC IP ADDRESS 36906257e9SSergio Gonzalez Monroy * - DST IP ADDRESS 37906257e9SSergio Gonzalez Monroy * - PORTS (SRC and DST) 38906257e9SSergio Gonzalez Monroy */ 39906257e9SSergio Gonzalez Monroy enum { 40906257e9SSergio Gonzalez Monroy RTE_ACL_IPV4_PROTO, 41906257e9SSergio Gonzalez Monroy RTE_ACL_IPV4_SRC, 42906257e9SSergio Gonzalez Monroy RTE_ACL_IPV4_DST, 43906257e9SSergio Gonzalez Monroy RTE_ACL_IPV4_PORTS, 44906257e9SSergio Gonzalez Monroy RTE_ACL_IPV4_NUM 45906257e9SSergio Gonzalez Monroy }; 46906257e9SSergio Gonzalez Monroy 47*d92fc70eSKonstantin Ananyev static struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = { 48906257e9SSergio Gonzalez Monroy { 49906257e9SSergio Gonzalez Monroy .type = RTE_ACL_FIELD_TYPE_BITMASK, 50906257e9SSergio Gonzalez Monroy .size = sizeof(uint8_t), 51906257e9SSergio Gonzalez Monroy .field_index = PROTO_FIELD_IPV4, 52906257e9SSergio Gonzalez Monroy .input_index = RTE_ACL_IPV4_PROTO, 53906257e9SSergio Gonzalez Monroy .offset = 0, 54906257e9SSergio Gonzalez Monroy }, 55906257e9SSergio Gonzalez Monroy { 56906257e9SSergio Gonzalez Monroy .type = RTE_ACL_FIELD_TYPE_MASK, 57906257e9SSergio Gonzalez Monroy .size = sizeof(uint32_t), 58906257e9SSergio Gonzalez Monroy .field_index = SRC_FIELD_IPV4, 59906257e9SSergio Gonzalez Monroy .input_index = RTE_ACL_IPV4_SRC, 60906257e9SSergio Gonzalez Monroy .offset = offsetof(struct ip, ip_src) - offsetof(struct ip, ip_p) 61906257e9SSergio Gonzalez Monroy }, 62906257e9SSergio Gonzalez Monroy { 63906257e9SSergio Gonzalez Monroy .type = RTE_ACL_FIELD_TYPE_MASK, 64906257e9SSergio Gonzalez Monroy .size = sizeof(uint32_t), 65906257e9SSergio Gonzalez Monroy .field_index = DST_FIELD_IPV4, 66906257e9SSergio Gonzalez Monroy .input_index = RTE_ACL_IPV4_DST, 67906257e9SSergio Gonzalez Monroy .offset = offsetof(struct ip, ip_dst) - offsetof(struct ip, ip_p) 68906257e9SSergio Gonzalez Monroy }, 69906257e9SSergio Gonzalez Monroy { 70906257e9SSergio Gonzalez Monroy .type = RTE_ACL_FIELD_TYPE_RANGE, 71906257e9SSergio Gonzalez Monroy .size = sizeof(uint16_t), 72906257e9SSergio Gonzalez Monroy .field_index = SRCP_FIELD_IPV4, 73906257e9SSergio Gonzalez Monroy .input_index = RTE_ACL_IPV4_PORTS, 74906257e9SSergio Gonzalez Monroy .offset = sizeof(struct ip) - offsetof(struct ip, ip_p) 75906257e9SSergio Gonzalez Monroy }, 76906257e9SSergio Gonzalez Monroy { 77906257e9SSergio Gonzalez Monroy .type = RTE_ACL_FIELD_TYPE_RANGE, 78906257e9SSergio Gonzalez Monroy .size = sizeof(uint16_t), 79906257e9SSergio Gonzalez Monroy .field_index = DSTP_FIELD_IPV4, 80906257e9SSergio Gonzalez Monroy .input_index = RTE_ACL_IPV4_PORTS, 81906257e9SSergio Gonzalez Monroy .offset = sizeof(struct ip) - offsetof(struct ip, ip_p) + 82906257e9SSergio Gonzalez Monroy sizeof(uint16_t) 83906257e9SSergio Gonzalez Monroy }, 84906257e9SSergio Gonzalez Monroy }; 85906257e9SSergio Gonzalez Monroy 86906257e9SSergio Gonzalez Monroy RTE_ACL_RULE_DEF(acl4_rules, RTE_DIM(ip4_defs)); 87906257e9SSergio Gonzalez Monroy 88*d92fc70eSKonstantin Ananyev static struct acl4_rules acl4_rules_out[MAX_ACL_RULE_NUM]; 89*d92fc70eSKonstantin Ananyev static uint32_t nb_acl4_rules_out; 90906257e9SSergio Gonzalez Monroy 91*d92fc70eSKonstantin Ananyev static struct acl4_rules acl4_rules_in[MAX_ACL_RULE_NUM]; 92*d92fc70eSKonstantin Ananyev static uint32_t nb_acl4_rules_in; 930d547ed0SFan Zhang 940d547ed0SFan Zhang void 950d547ed0SFan Zhang parse_sp4_tokens(char **tokens, uint32_t n_tokens, 960d547ed0SFan Zhang struct parse_status *status) 97906257e9SSergio Gonzalez Monroy { 980d547ed0SFan Zhang struct acl4_rules *rule_ipv4 = NULL; 990d547ed0SFan Zhang 1000d547ed0SFan Zhang uint32_t *ri = NULL; /* rule index */ 1010d547ed0SFan Zhang uint32_t ti = 0; /* token index */ 1020d547ed0SFan Zhang 1030d547ed0SFan Zhang uint32_t esp_p = 0; 1040d547ed0SFan Zhang uint32_t protect_p = 0; 1050d547ed0SFan Zhang uint32_t bypass_p = 0; 1060d547ed0SFan Zhang uint32_t discard_p = 0; 1070d547ed0SFan Zhang uint32_t pri_p = 0; 1080d547ed0SFan Zhang uint32_t src_p = 0; 1090d547ed0SFan Zhang uint32_t dst_p = 0; 1100d547ed0SFan Zhang uint32_t proto_p = 0; 1110d547ed0SFan Zhang uint32_t sport_p = 0; 1120d547ed0SFan Zhang uint32_t dport_p = 0; 1130d547ed0SFan Zhang 1140d547ed0SFan Zhang if (strcmp(tokens[1], "in") == 0) { 1150d547ed0SFan Zhang ri = &nb_acl4_rules_in; 1160d547ed0SFan Zhang 1170d547ed0SFan Zhang APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, 1180d547ed0SFan Zhang "too many sp rules, abort insertion\n"); 1190d547ed0SFan Zhang if (status->status < 0) 1200d547ed0SFan Zhang return; 1210d547ed0SFan Zhang 1220d547ed0SFan Zhang rule_ipv4 = &acl4_rules_in[*ri]; 1230d547ed0SFan Zhang 1240d547ed0SFan Zhang } else if (strcmp(tokens[1], "out") == 0) { 1250d547ed0SFan Zhang ri = &nb_acl4_rules_out; 1260d547ed0SFan Zhang 1270d547ed0SFan Zhang APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, 1280d547ed0SFan Zhang "too many sp rules, abort insertion\n"); 1290d547ed0SFan Zhang if (status->status < 0) 1300d547ed0SFan Zhang return; 1310d547ed0SFan Zhang 1320d547ed0SFan Zhang rule_ipv4 = &acl4_rules_out[*ri]; 1330d547ed0SFan Zhang } else { 1340d547ed0SFan Zhang APP_CHECK(0, status, "unrecognized input \"%s\", expect" 1350d547ed0SFan Zhang " \"in\" or \"out\"\n", tokens[ti]); 1360d547ed0SFan Zhang return; 137906257e9SSergio Gonzalez Monroy } 1380d547ed0SFan Zhang 1390d547ed0SFan Zhang rule_ipv4->data.category_mask = 1; 1400d547ed0SFan Zhang 1410d547ed0SFan Zhang for (ti = 2; ti < n_tokens; ti++) { 1420d547ed0SFan Zhang if (strcmp(tokens[ti], "esp") == 0) { 1430d547ed0SFan Zhang /* currently do nothing */ 1440d547ed0SFan Zhang APP_CHECK_PRESENCE(esp_p, tokens[ti], status); 1450d547ed0SFan Zhang if (status->status < 0) 1460d547ed0SFan Zhang return; 1470d547ed0SFan Zhang esp_p = 1; 1480d547ed0SFan Zhang continue; 1490d547ed0SFan Zhang } 1500d547ed0SFan Zhang 1510d547ed0SFan Zhang if (strcmp(tokens[ti], "protect") == 0) { 1520d547ed0SFan Zhang APP_CHECK_PRESENCE(protect_p, tokens[ti], status); 1530d547ed0SFan Zhang if (status->status < 0) 1540d547ed0SFan Zhang return; 1550d547ed0SFan Zhang APP_CHECK(bypass_p == 0, status, "conflict item " 1560d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 1570d547ed0SFan Zhang "bypass"); 1580d547ed0SFan Zhang if (status->status < 0) 1590d547ed0SFan Zhang return; 1600d547ed0SFan Zhang APP_CHECK(discard_p == 0, status, "conflict item " 1610d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 1620d547ed0SFan Zhang "discard"); 1630d547ed0SFan Zhang if (status->status < 0) 1640d547ed0SFan Zhang return; 1650d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 1660d547ed0SFan Zhang if (status->status < 0) 1670d547ed0SFan Zhang return; 1680d547ed0SFan Zhang APP_CHECK_TOKEN_IS_NUM(tokens, ti, status); 1690d547ed0SFan Zhang if (status->status < 0) 1700d547ed0SFan Zhang return; 1710d547ed0SFan Zhang 1720d547ed0SFan Zhang rule_ipv4->data.userdata = 1730d547ed0SFan Zhang PROTECT(atoi(tokens[ti])); 1740d547ed0SFan Zhang 1750d547ed0SFan Zhang protect_p = 1; 1760d547ed0SFan Zhang continue; 1770d547ed0SFan Zhang } 1780d547ed0SFan Zhang 1790d547ed0SFan Zhang if (strcmp(tokens[ti], "bypass") == 0) { 1800d547ed0SFan Zhang APP_CHECK_PRESENCE(bypass_p, tokens[ti], status); 1810d547ed0SFan Zhang if (status->status < 0) 1820d547ed0SFan Zhang return; 1830d547ed0SFan Zhang APP_CHECK(protect_p == 0, status, "conflict item " 1840d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 1850d547ed0SFan Zhang "protect"); 1860d547ed0SFan Zhang if (status->status < 0) 1870d547ed0SFan Zhang return; 1880d547ed0SFan Zhang APP_CHECK(discard_p == 0, status, "conflict item " 1890d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 1900d547ed0SFan Zhang "discard"); 1910d547ed0SFan Zhang if (status->status < 0) 1920d547ed0SFan Zhang return; 1930d547ed0SFan Zhang 1940d547ed0SFan Zhang rule_ipv4->data.userdata = BYPASS; 1950d547ed0SFan Zhang 1960d547ed0SFan Zhang bypass_p = 1; 1970d547ed0SFan Zhang continue; 1980d547ed0SFan Zhang } 1990d547ed0SFan Zhang 2000d547ed0SFan Zhang if (strcmp(tokens[ti], "discard") == 0) { 2010d547ed0SFan Zhang APP_CHECK_PRESENCE(discard_p, tokens[ti], status); 2020d547ed0SFan Zhang if (status->status < 0) 2030d547ed0SFan Zhang return; 2040d547ed0SFan Zhang APP_CHECK(protect_p == 0, status, "conflict item " 2050d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 2060d547ed0SFan Zhang "protect"); 2070d547ed0SFan Zhang if (status->status < 0) 2080d547ed0SFan Zhang return; 2090d547ed0SFan Zhang APP_CHECK(bypass_p == 0, status, "conflict item " 2100d547ed0SFan Zhang "between \"%s\" and \"%s\"", tokens[ti], 2110d547ed0SFan Zhang "discard"); 2120d547ed0SFan Zhang if (status->status < 0) 2130d547ed0SFan Zhang return; 2140d547ed0SFan Zhang 2150d547ed0SFan Zhang rule_ipv4->data.userdata = DISCARD; 2160d547ed0SFan Zhang 2170d547ed0SFan Zhang discard_p = 1; 2180d547ed0SFan Zhang continue; 2190d547ed0SFan Zhang } 2200d547ed0SFan Zhang 2210d547ed0SFan Zhang if (strcmp(tokens[ti], "pri") == 0) { 2220d547ed0SFan Zhang APP_CHECK_PRESENCE(pri_p, tokens[ti], status); 2230d547ed0SFan Zhang if (status->status < 0) 2240d547ed0SFan Zhang return; 2250d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 2260d547ed0SFan Zhang if (status->status < 0) 2270d547ed0SFan Zhang return; 2280d547ed0SFan Zhang APP_CHECK_TOKEN_IS_NUM(tokens, ti, status); 2290d547ed0SFan Zhang if (status->status < 0) 2300d547ed0SFan Zhang return; 2310d547ed0SFan Zhang 2320d547ed0SFan Zhang rule_ipv4->data.priority = atoi(tokens[ti]); 2330d547ed0SFan Zhang 2340d547ed0SFan Zhang pri_p = 1; 2350d547ed0SFan Zhang continue; 2360d547ed0SFan Zhang } 2370d547ed0SFan Zhang 2380d547ed0SFan Zhang if (strcmp(tokens[ti], "src") == 0) { 2390d547ed0SFan Zhang struct in_addr ip; 2400d547ed0SFan Zhang uint32_t depth; 2410d547ed0SFan Zhang 2420d547ed0SFan Zhang APP_CHECK_PRESENCE(src_p, tokens[ti], status); 2430d547ed0SFan Zhang if (status->status < 0) 2440d547ed0SFan Zhang return; 2450d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 2460d547ed0SFan Zhang if (status->status < 0) 2470d547ed0SFan Zhang return; 2480d547ed0SFan Zhang 2490d547ed0SFan Zhang APP_CHECK(parse_ipv4_addr(tokens[ti], &ip, 2500d547ed0SFan Zhang &depth) == 0, status, "unrecognized " 2510d547ed0SFan Zhang "input \"%s\", expect valid ipv4 addr", 2520d547ed0SFan Zhang tokens[ti]); 2530d547ed0SFan Zhang if (status->status < 0) 2540d547ed0SFan Zhang return; 2550d547ed0SFan Zhang 2560d547ed0SFan Zhang rule_ipv4->field[1].value.u32 = 2570d547ed0SFan Zhang rte_bswap32(ip.s_addr); 2580d547ed0SFan Zhang rule_ipv4->field[1].mask_range.u32 = 2590d547ed0SFan Zhang depth; 2600d547ed0SFan Zhang 2610d547ed0SFan Zhang src_p = 1; 2620d547ed0SFan Zhang continue; 2630d547ed0SFan Zhang } 2640d547ed0SFan Zhang 2650d547ed0SFan Zhang if (strcmp(tokens[ti], "dst") == 0) { 2660d547ed0SFan Zhang struct in_addr ip; 2670d547ed0SFan Zhang uint32_t depth; 2680d547ed0SFan Zhang 2690d547ed0SFan Zhang APP_CHECK_PRESENCE(dst_p, tokens[ti], status); 2700d547ed0SFan Zhang if (status->status < 0) 2710d547ed0SFan Zhang return; 2720d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 2730d547ed0SFan Zhang if (status->status < 0) 2740d547ed0SFan Zhang return; 2750d547ed0SFan Zhang APP_CHECK(parse_ipv4_addr(tokens[ti], &ip, 2760d547ed0SFan Zhang &depth) == 0, status, "unrecognized " 2770d547ed0SFan Zhang "input \"%s\", expect valid ipv4 addr", 2780d547ed0SFan Zhang tokens[ti]); 2790d547ed0SFan Zhang if (status->status < 0) 2800d547ed0SFan Zhang return; 2810d547ed0SFan Zhang 2820d547ed0SFan Zhang rule_ipv4->field[2].value.u32 = 2830d547ed0SFan Zhang rte_bswap32(ip.s_addr); 2840d547ed0SFan Zhang rule_ipv4->field[2].mask_range.u32 = 2850d547ed0SFan Zhang depth; 2860d547ed0SFan Zhang 2870d547ed0SFan Zhang dst_p = 1; 2880d547ed0SFan Zhang continue; 2890d547ed0SFan Zhang } 2900d547ed0SFan Zhang 2910d547ed0SFan Zhang if (strcmp(tokens[ti], "proto") == 0) { 2920d547ed0SFan Zhang uint16_t low, high; 2930d547ed0SFan Zhang 2940d547ed0SFan Zhang APP_CHECK_PRESENCE(proto_p, tokens[ti], status); 2950d547ed0SFan Zhang if (status->status < 0) 2960d547ed0SFan Zhang return; 2970d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 2980d547ed0SFan Zhang if (status->status < 0) 2990d547ed0SFan Zhang return; 3000d547ed0SFan Zhang 3010d547ed0SFan Zhang APP_CHECK(parse_range(tokens[ti], &low, &high) 3020d547ed0SFan Zhang == 0, status, "unrecognized input \"%s\"" 3030d547ed0SFan Zhang ", expect \"from:to\"", tokens[ti]); 3040d547ed0SFan Zhang if (status->status < 0) 3050d547ed0SFan Zhang return; 3060d547ed0SFan Zhang APP_CHECK(low <= 0xff, status, "proto low " 3070d547ed0SFan Zhang "over-limit"); 3080d547ed0SFan Zhang if (status->status < 0) 3090d547ed0SFan Zhang return; 3100d547ed0SFan Zhang APP_CHECK(high <= 0xff, status, "proto high " 3110d547ed0SFan Zhang "over-limit"); 3120d547ed0SFan Zhang if (status->status < 0) 3130d547ed0SFan Zhang return; 3140d547ed0SFan Zhang 3150d547ed0SFan Zhang rule_ipv4->field[0].value.u8 = (uint8_t)low; 3160d547ed0SFan Zhang rule_ipv4->field[0].mask_range.u8 = (uint8_t)high; 3170d547ed0SFan Zhang 3180d547ed0SFan Zhang proto_p = 1; 3190d547ed0SFan Zhang continue; 3200d547ed0SFan Zhang } 3210d547ed0SFan Zhang 3220d547ed0SFan Zhang if (strcmp(tokens[ti], "sport") == 0) { 3230d547ed0SFan Zhang uint16_t port_low, port_high; 3240d547ed0SFan Zhang 3250d547ed0SFan Zhang APP_CHECK_PRESENCE(sport_p, tokens[ti], status); 3260d547ed0SFan Zhang if (status->status < 0) 3270d547ed0SFan Zhang return; 3280d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 3290d547ed0SFan Zhang if (status->status < 0) 3300d547ed0SFan Zhang return; 3310d547ed0SFan Zhang 3320d547ed0SFan Zhang APP_CHECK(parse_range(tokens[ti], &port_low, 3330d547ed0SFan Zhang &port_high) == 0, status, "unrecognized " 3340d547ed0SFan Zhang "input \"%s\", expect \"port_from:" 3350d547ed0SFan Zhang "port_to\"", tokens[ti]); 3360d547ed0SFan Zhang if (status->status < 0) 3370d547ed0SFan Zhang return; 3380d547ed0SFan Zhang 3390d547ed0SFan Zhang rule_ipv4->field[3].value.u16 = port_low; 3400d547ed0SFan Zhang rule_ipv4->field[3].mask_range.u16 = port_high; 3410d547ed0SFan Zhang 3420d547ed0SFan Zhang sport_p = 1; 3430d547ed0SFan Zhang continue; 3440d547ed0SFan Zhang } 3450d547ed0SFan Zhang 3460d547ed0SFan Zhang if (strcmp(tokens[ti], "dport") == 0) { 3470d547ed0SFan Zhang uint16_t port_low, port_high; 3480d547ed0SFan Zhang 3490d547ed0SFan Zhang APP_CHECK_PRESENCE(dport_p, tokens[ti], status); 3500d547ed0SFan Zhang if (status->status < 0) 3510d547ed0SFan Zhang return; 3520d547ed0SFan Zhang INCREMENT_TOKEN_INDEX(ti, n_tokens, status); 3530d547ed0SFan Zhang if (status->status < 0) 3540d547ed0SFan Zhang return; 3550d547ed0SFan Zhang 3560d547ed0SFan Zhang APP_CHECK(parse_range(tokens[ti], &port_low, 3570d547ed0SFan Zhang &port_high) == 0, status, "unrecognized " 3580d547ed0SFan Zhang "input \"%s\", expect \"port_from:" 3590d547ed0SFan Zhang "port_to\"", tokens[ti]); 3600d547ed0SFan Zhang if (status->status < 0) 3610d547ed0SFan Zhang return; 3620d547ed0SFan Zhang 3630d547ed0SFan Zhang rule_ipv4->field[4].value.u16 = port_low; 3640d547ed0SFan Zhang rule_ipv4->field[4].mask_range.u16 = port_high; 3650d547ed0SFan Zhang 3660d547ed0SFan Zhang dport_p = 1; 3670d547ed0SFan Zhang continue; 3680d547ed0SFan Zhang } 3690d547ed0SFan Zhang 3700d547ed0SFan Zhang /* unrecognizeable input */ 3710d547ed0SFan Zhang APP_CHECK(0, status, "unrecognized input \"%s\"", 3720d547ed0SFan Zhang tokens[ti]); 3730d547ed0SFan Zhang return; 3740d547ed0SFan Zhang } 3750d547ed0SFan Zhang 3760d547ed0SFan Zhang /* check if argument(s) are missing */ 3770d547ed0SFan Zhang APP_CHECK(esp_p == 1, status, "missing argument \"esp\""); 3780d547ed0SFan Zhang if (status->status < 0) 3790d547ed0SFan Zhang return; 3800d547ed0SFan Zhang 3810d547ed0SFan Zhang APP_CHECK(protect_p | bypass_p | discard_p, status, "missing " 3820d547ed0SFan Zhang "argument \"protect\", \"bypass\", or \"discard\""); 3830d547ed0SFan Zhang if (status->status < 0) 3840d547ed0SFan Zhang return; 3850d547ed0SFan Zhang 3860d547ed0SFan Zhang *ri = *ri + 1; 3870d547ed0SFan Zhang } 388906257e9SSergio Gonzalez Monroy 389906257e9SSergio Gonzalez Monroy static void 390906257e9SSergio Gonzalez Monroy print_one_ip4_rule(const struct acl4_rules *rule, int32_t extra) 391906257e9SSergio Gonzalez Monroy { 392906257e9SSergio Gonzalez Monroy uint8_t a, b, c, d; 393906257e9SSergio Gonzalez Monroy 394906257e9SSergio Gonzalez Monroy uint32_t_to_char(rule->field[SRC_FIELD_IPV4].value.u32, 395906257e9SSergio Gonzalez Monroy &a, &b, &c, &d); 396906257e9SSergio Gonzalez Monroy printf("%hhu.%hhu.%hhu.%hhu/%u ", a, b, c, d, 397906257e9SSergio Gonzalez Monroy rule->field[SRC_FIELD_IPV4].mask_range.u32); 398906257e9SSergio Gonzalez Monroy uint32_t_to_char(rule->field[DST_FIELD_IPV4].value.u32, 399906257e9SSergio Gonzalez Monroy &a, &b, &c, &d); 400906257e9SSergio Gonzalez Monroy printf("%hhu.%hhu.%hhu.%hhu/%u ", a, b, c, d, 401906257e9SSergio Gonzalez Monroy rule->field[DST_FIELD_IPV4].mask_range.u32); 402906257e9SSergio Gonzalez Monroy printf("%hu : %hu %hu : %hu 0x%hhx/0x%hhx ", 403906257e9SSergio Gonzalez Monroy rule->field[SRCP_FIELD_IPV4].value.u16, 404906257e9SSergio Gonzalez Monroy rule->field[SRCP_FIELD_IPV4].mask_range.u16, 405906257e9SSergio Gonzalez Monroy rule->field[DSTP_FIELD_IPV4].value.u16, 406906257e9SSergio Gonzalez Monroy rule->field[DSTP_FIELD_IPV4].mask_range.u16, 407906257e9SSergio Gonzalez Monroy rule->field[PROTO_FIELD_IPV4].value.u8, 408906257e9SSergio Gonzalez Monroy rule->field[PROTO_FIELD_IPV4].mask_range.u8); 409906257e9SSergio Gonzalez Monroy if (extra) 410906257e9SSergio Gonzalez Monroy printf("0x%x-0x%x-0x%x ", 411906257e9SSergio Gonzalez Monroy rule->data.category_mask, 412906257e9SSergio Gonzalez Monroy rule->data.priority, 413906257e9SSergio Gonzalez Monroy rule->data.userdata); 414906257e9SSergio Gonzalez Monroy } 415906257e9SSergio Gonzalez Monroy 416906257e9SSergio Gonzalez Monroy static inline void 417906257e9SSergio Gonzalez Monroy dump_ip4_rules(const struct acl4_rules *rule, int32_t num, int32_t extra) 418906257e9SSergio Gonzalez Monroy { 419906257e9SSergio Gonzalez Monroy int32_t i; 420906257e9SSergio Gonzalez Monroy 421906257e9SSergio Gonzalez Monroy for (i = 0; i < num; i++, rule++) { 422906257e9SSergio Gonzalez Monroy printf("\t%d:", i + 1); 423906257e9SSergio Gonzalez Monroy print_one_ip4_rule(rule, extra); 424906257e9SSergio Gonzalez Monroy printf("\n"); 425906257e9SSergio Gonzalez Monroy } 426906257e9SSergio Gonzalez Monroy } 427906257e9SSergio Gonzalez Monroy 428906257e9SSergio Gonzalez Monroy static struct rte_acl_ctx * 429906257e9SSergio Gonzalez Monroy acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, 430906257e9SSergio Gonzalez Monroy uint32_t rules_nb) 431906257e9SSergio Gonzalez Monroy { 432906257e9SSergio Gonzalez Monroy char s[PATH_MAX]; 433906257e9SSergio Gonzalez Monroy struct rte_acl_param acl_param; 434906257e9SSergio Gonzalez Monroy struct rte_acl_config acl_build_param; 435906257e9SSergio Gonzalez Monroy struct rte_acl_ctx *ctx; 436906257e9SSergio Gonzalez Monroy 437906257e9SSergio Gonzalez Monroy printf("Creating SP context with %u max rules\n", MAX_ACL_RULE_NUM); 438906257e9SSergio Gonzalez Monroy 439906257e9SSergio Gonzalez Monroy memset(&acl_param, 0, sizeof(acl_param)); 440906257e9SSergio Gonzalez Monroy 441906257e9SSergio Gonzalez Monroy /* Create ACL contexts */ 442906257e9SSergio Gonzalez Monroy snprintf(s, sizeof(s), "%s_%d", name, socketid); 443906257e9SSergio Gonzalez Monroy 444906257e9SSergio Gonzalez Monroy printf("IPv4 %s entries [%u]:\n", s, rules_nb); 445906257e9SSergio Gonzalez Monroy dump_ip4_rules(rules, rules_nb, 1); 446906257e9SSergio Gonzalez Monroy 447906257e9SSergio Gonzalez Monroy acl_param.name = s; 448906257e9SSergio Gonzalez Monroy acl_param.socket_id = socketid; 449906257e9SSergio Gonzalez Monroy acl_param.rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ip4_defs)); 450906257e9SSergio Gonzalez Monroy acl_param.max_rule_num = MAX_ACL_RULE_NUM; 451906257e9SSergio Gonzalez Monroy 452906257e9SSergio Gonzalez Monroy ctx = rte_acl_create(&acl_param); 453906257e9SSergio Gonzalez Monroy if (ctx == NULL) 454906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "Failed to create ACL context\n"); 455906257e9SSergio Gonzalez Monroy 456906257e9SSergio Gonzalez Monroy if (rte_acl_add_rules(ctx, (const struct rte_acl_rule *)rules, 457906257e9SSergio Gonzalez Monroy rules_nb) < 0) 458906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "add rules failed\n"); 459906257e9SSergio Gonzalez Monroy 460906257e9SSergio Gonzalez Monroy /* Perform builds */ 461906257e9SSergio Gonzalez Monroy memset(&acl_build_param, 0, sizeof(acl_build_param)); 462906257e9SSergio Gonzalez Monroy 463906257e9SSergio Gonzalez Monroy acl_build_param.num_categories = DEFAULT_MAX_CATEGORIES; 464906257e9SSergio Gonzalez Monroy acl_build_param.num_fields = RTE_DIM(ip4_defs); 465906257e9SSergio Gonzalez Monroy memcpy(&acl_build_param.defs, ip4_defs, sizeof(ip4_defs)); 466906257e9SSergio Gonzalez Monroy 467906257e9SSergio Gonzalez Monroy if (rte_acl_build(ctx, &acl_build_param) != 0) 468906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "Failed to build ACL trie\n"); 469906257e9SSergio Gonzalez Monroy 470906257e9SSergio Gonzalez Monroy rte_acl_dump(ctx); 471906257e9SSergio Gonzalez Monroy 472906257e9SSergio Gonzalez Monroy return ctx; 473906257e9SSergio Gonzalez Monroy } 474906257e9SSergio Gonzalez Monroy 475906257e9SSergio Gonzalez Monroy void 4760d547ed0SFan Zhang sp4_init(struct socket_ctx *ctx, int32_t socket_id) 477906257e9SSergio Gonzalez Monroy { 478906257e9SSergio Gonzalez Monroy const char *name; 479906257e9SSergio Gonzalez Monroy 480906257e9SSergio Gonzalez Monroy if (ctx == NULL) 481906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "NULL context.\n"); 482906257e9SSergio Gonzalez Monroy 483906257e9SSergio Gonzalez Monroy if (ctx->sp_ip4_in != NULL) 484906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "Inbound SP DB for socket %u already " 485906257e9SSergio Gonzalez Monroy "initialized\n", socket_id); 486906257e9SSergio Gonzalez Monroy 487906257e9SSergio Gonzalez Monroy if (ctx->sp_ip4_out != NULL) 488906257e9SSergio Gonzalez Monroy rte_exit(EXIT_FAILURE, "Outbound SP DB for socket %u already " 489906257e9SSergio Gonzalez Monroy "initialized\n", socket_id); 490906257e9SSergio Gonzalez Monroy 4910d547ed0SFan Zhang if (nb_acl4_rules_in > 0) { 492906257e9SSergio Gonzalez Monroy name = "sp_ip4_in"; 4930d547ed0SFan Zhang ctx->sp_ip4_in = (struct sp_ctx *)acl4_init(name, 4940d547ed0SFan Zhang socket_id, acl4_rules_in, nb_acl4_rules_in); 4950d547ed0SFan Zhang } else 4960d547ed0SFan Zhang RTE_LOG(WARNING, IPSEC, "No IPv4 SP Inbound rule " 4970d547ed0SFan Zhang "specified\n"); 498906257e9SSergio Gonzalez Monroy 4990d547ed0SFan Zhang if (nb_acl4_rules_out > 0) { 500906257e9SSergio Gonzalez Monroy name = "sp_ip4_out"; 5010d547ed0SFan Zhang ctx->sp_ip4_out = (struct sp_ctx *)acl4_init(name, 5020d547ed0SFan Zhang socket_id, acl4_rules_out, nb_acl4_rules_out); 5030d547ed0SFan Zhang } else 5040d547ed0SFan Zhang RTE_LOG(WARNING, IPSEC, "No IPv4 SP Outbound rule " 5050d547ed0SFan Zhang "specified\n"); 506906257e9SSergio Gonzalez Monroy } 507