1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2016 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Routing Table (RT) 36 */ 37 #include <sys/types.h> 38 #include <rte_lpm.h> 39 #include <rte_lpm6.h> 40 #include <rte_errno.h> 41 #include <rte_ip.h> 42 43 #include "ipsec.h" 44 45 #define RT_IPV4_MAX_RULES 1024 46 #define RT_IPV6_MAX_RULES 1024 47 48 struct ip4_route { 49 uint32_t ip; 50 uint8_t depth; 51 uint8_t if_out; 52 }; 53 54 struct ip6_route { 55 uint8_t ip[16]; 56 uint8_t depth; 57 uint8_t if_out; 58 }; 59 60 static struct ip4_route rt_ip4_ep0[] = { 61 /* Outbound */ 62 /* Tunnels */ 63 { IPv4(172, 16, 2, 5), 32, 0 }, 64 { IPv4(172, 16, 2, 6), 32, 1 }, 65 /* Transport */ 66 { IPv4(192, 168, 175, 0), 24, 0 }, 67 { IPv4(192, 168, 176, 0), 24, 1 }, 68 /* Bypass */ 69 { IPv4(192, 168, 240, 0), 24, 0 }, 70 { IPv4(192, 168, 241, 0), 24, 1 }, 71 72 /* Inbound */ 73 /* Tunnels */ 74 { IPv4(192, 168, 115, 0), 24, 2 }, 75 { IPv4(192, 168, 116, 0), 24, 3 }, 76 { IPv4(192, 168, 65, 0), 24, 2 }, 77 { IPv4(192, 168, 66, 0), 24, 3 }, 78 /* Transport */ 79 { IPv4(192, 168, 185, 0), 24, 2 }, 80 { IPv4(192, 168, 186, 0), 24, 3 }, 81 /* NULL */ 82 { IPv4(192, 168, 210, 0), 24, 2 }, 83 { IPv4(192, 168, 211, 0), 24, 3 }, 84 /* Bypass */ 85 { IPv4(192, 168, 245, 0), 24, 2 }, 86 { IPv4(192, 168, 246, 0), 24, 3 }, 87 }; 88 89 static struct ip6_route rt_ip6_ep0[] = { 90 /* Outbound */ 91 /* Tunnels */ 92 { { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 93 0x22, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55 }, 116, 0 }, 94 { { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 95 0x22, 0x22, 0x22, 0x22, 0x22, 0x66, 0x66 }, 116, 1 }, 96 /* Transport */ 97 { { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 0 }, 99 { { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 100 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 1 }, 101 /* Inbound */ 102 /* Tunnels */ 103 { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 104 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 105 { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 106 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 107 { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 108 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 109 { { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 110 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 111 /* Transport */ 112 { { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 114 { { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 115 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 116 }; 117 118 static struct ip4_route rt_ip4_ep1[] = { 119 /* Outbound */ 120 /* Tunnels */ 121 { IPv4(172, 16, 1, 5), 32, 0 }, 122 { IPv4(172, 16, 1, 6), 32, 1 }, 123 /* Transport */ 124 { IPv4(192, 168, 185, 0), 24, 0 }, 125 { IPv4(192, 168, 186, 0), 24, 1 }, 126 /* Bypass */ 127 { IPv4(192, 168, 245, 0), 24, 0 }, 128 { IPv4(192, 168, 246, 0), 24, 1 }, 129 130 /* Inbound */ 131 /* Tunnels */ 132 { IPv4(192, 168, 105, 0), 24, 2 }, 133 { IPv4(192, 168, 106, 0), 24, 3 }, 134 { IPv4(192, 168, 55, 0), 24, 2 }, 135 { IPv4(192, 168, 56, 0), 24, 3 }, 136 /* Transport */ 137 { IPv4(192, 168, 175, 0), 24, 2 }, 138 { IPv4(192, 168, 176, 0), 24, 3 }, 139 /* NULL */ 140 { IPv4(192, 168, 200, 0), 24, 2 }, 141 { IPv4(192, 168, 201, 0), 24, 3 }, 142 /* Bypass */ 143 { IPv4(192, 168, 240, 0), 24, 2 }, 144 { IPv4(192, 168, 241, 0), 24, 3 }, 145 }; 146 147 static struct ip6_route rt_ip6_ep1[] = { 148 /* Outbound */ 149 /* Tunnels */ 150 { { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 151 0x11, 0x11, 0x11, 0x11, 0x11, 0x55, 0x55 }, 116, 0 }, 152 { { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 153 0x11, 0x11, 0x11, 0x11, 0x11, 0x66, 0x66 }, 116, 1 }, 154 /* Transport */ 155 { { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 0 }, 157 { { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 158 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 1 }, 159 160 /* Inbound */ 161 /* Tunnels */ 162 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 163 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 164 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 165 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 166 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 167 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 168 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 169 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 170 /* Transport */ 171 { { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 2 }, 173 { { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 174 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 3 }, 175 }; 176 177 void 178 rt_init(struct socket_ctx *ctx, int32_t socket_id, uint32_t ep) 179 { 180 char name[PATH_MAX]; 181 uint32_t i; 182 int32_t ret; 183 struct rte_lpm *lpm; 184 struct rte_lpm6 *lpm6; 185 struct ip4_route *rt; 186 struct ip6_route *rt6; 187 char a, b, c, d; 188 uint32_t nb_routes, nb_routes6; 189 struct rte_lpm_config conf = { 0 }; 190 struct rte_lpm6_config conf6 = { 0 }; 191 192 if (ctx == NULL) 193 rte_exit(EXIT_FAILURE, "NULL context.\n"); 194 195 if (ctx->rt_ip4 != NULL) 196 rte_exit(EXIT_FAILURE, "IPv4 Routing Table for socket %u " 197 "already initialized\n", socket_id); 198 199 if (ctx->rt_ip6 != NULL) 200 rte_exit(EXIT_FAILURE, "IPv6 Routing Table for socket %u " 201 "already initialized\n", socket_id); 202 203 printf("Creating IPv4 Routing Table (RT) context with %u max routes\n", 204 RT_IPV4_MAX_RULES); 205 206 if (ep == 0) { 207 rt = rt_ip4_ep0; 208 nb_routes = RTE_DIM(rt_ip4_ep0); 209 rt6 = rt_ip6_ep0; 210 nb_routes6 = RTE_DIM(rt_ip6_ep0); 211 } else if (ep == 1) { 212 rt = rt_ip4_ep1; 213 nb_routes = RTE_DIM(rt_ip4_ep1); 214 rt6 = rt_ip6_ep1; 215 nb_routes6 = RTE_DIM(rt_ip6_ep1); 216 } else 217 rte_exit(EXIT_FAILURE, "Invalid EP value %u. Only 0 or 1 " 218 "supported.\n", ep); 219 220 /* create the LPM table */ 221 snprintf(name, sizeof(name), "%s_%u", "rt_ip4", socket_id); 222 conf.max_rules = RT_IPV4_MAX_RULES; 223 conf.number_tbl8s = RTE_LPM_TBL8_NUM_ENTRIES; 224 lpm = rte_lpm_create(name, socket_id, &conf); 225 if (lpm == NULL) 226 rte_exit(EXIT_FAILURE, "Unable to create %s LPM table " 227 "on socket %d\n", name, socket_id); 228 229 /* populate the LPM table */ 230 for (i = 0; i < nb_routes; i++) { 231 ret = rte_lpm_add(lpm, rt[i].ip, rt[i].depth, rt[i].if_out); 232 if (ret < 0) 233 rte_exit(EXIT_FAILURE, "Fail to add entry num %u to %s " 234 "LPM table on socket %d\n", i, name, socket_id); 235 236 uint32_t_to_char(rt[i].ip, &a, &b, &c, &d); 237 printf("LPM: Adding route %hhu.%hhu.%hhu.%hhu/%hhu (%hhu)\n", 238 a, b, c, d, rt[i].depth, rt[i].if_out); 239 } 240 241 snprintf(name, sizeof(name), "%s_%u", "rt_ip6", socket_id); 242 conf6.max_rules = RT_IPV6_MAX_RULES; 243 conf6.number_tbl8s = RTE_LPM_TBL8_NUM_ENTRIES; 244 lpm6 = rte_lpm6_create(name, socket_id, &conf6); 245 if (lpm6 == NULL) 246 rte_exit(EXIT_FAILURE, "Unable to create %s LPM table " 247 "on socket %d\n", name, socket_id); 248 249 /* populate the LPM table */ 250 for (i = 0; i < nb_routes6; i++) { 251 ret = rte_lpm6_add(lpm6, rt6[i].ip, rt6[i].depth, 252 rt6[i].if_out); 253 if (ret < 0) 254 rte_exit(EXIT_FAILURE, "Fail to add entry num %u to %s " 255 "LPM table on socket %d\n", i, name, socket_id); 256 257 printf("LPM6: Adding route " 258 " %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%hhx (%hhx)\n", 259 (uint16_t)((rt6[i].ip[0] << 8) | rt6[i].ip[1]), 260 (uint16_t)((rt6[i].ip[2] << 8) | rt6[i].ip[3]), 261 (uint16_t)((rt6[i].ip[4] << 8) | rt6[i].ip[5]), 262 (uint16_t)((rt6[i].ip[6] << 8) | rt6[i].ip[7]), 263 (uint16_t)((rt6[i].ip[8] << 8) | rt6[i].ip[9]), 264 (uint16_t)((rt6[i].ip[10] << 8) | rt6[i].ip[11]), 265 (uint16_t)((rt6[i].ip[12] << 8) | rt6[i].ip[13]), 266 (uint16_t)((rt6[i].ip[14] << 8) | rt6[i].ip[15]), 267 rt6[i].depth, rt6[i].if_out); 268 } 269 270 ctx->rt_ip4 = (struct rt_ctx *)lpm; 271 ctx->rt_ip6 = (struct rt_ctx *)lpm6; 272 } 273