Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2017 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 15 | #include <vnet/plugin/plugin.h> |
| 16 | #include <nat/dslite/dslite.h> |
| 17 | #include <nat/dslite/dslite_dpo.h> |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 18 | #include <vnet/fib/fib_table.h> |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 19 | #include <vpp/app/version.h> |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 20 | |
| 21 | dslite_main_t dslite_main; |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 22 | fib_source_t nat_fib_src_hi; |
| 23 | |
| 24 | clib_error_t *dslite_api_hookup (vlib_main_t * vm); |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 25 | |
| 26 | void |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 27 | add_del_dslite_pool_addr_cb (ip4_address_t addr, u8 is_add, void *opaque); |
| 28 | |
| 29 | static clib_error_t * |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 30 | dslite_init (vlib_main_t * vm) |
| 31 | { |
| 32 | dslite_main_t *dm = &dslite_main; |
| 33 | vlib_thread_registration_t *tr; |
| 34 | vlib_thread_main_t *tm = vlib_get_thread_main (); |
| 35 | uword *p; |
Filip Varga | e69e423 | 2019-02-13 01:42:59 -0800 | [diff] [blame] | 36 | vlib_node_t *node; |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 37 | dslite_per_thread_data_t *td; |
| 38 | u32 translation_buckets = 1024; |
| 39 | u32 translation_memory_size = 128 << 20; |
| 40 | u32 b4_buckets = 128; |
| 41 | u32 b4_memory_size = 64 << 20; |
| 42 | |
Filip Varga | e69e423 | 2019-02-13 01:42:59 -0800 | [diff] [blame] | 43 | node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out"); |
| 44 | dm->dslite_in2out_node_index = node->index; |
| 45 | |
| 46 | node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out-slowpath"); |
| 47 | dm->dslite_in2out_slowpath_node_index = node->index; |
| 48 | |
| 49 | node = vlib_get_node_by_name (vm, (u8 *) "dslite-out2in"); |
| 50 | dm->dslite_out2in_node_index = node->index; |
| 51 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 52 | dm->first_worker_index = 0; |
| 53 | dm->num_workers = 0; |
| 54 | |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 55 | // init nat address pool |
| 56 | dm->pool.add_del_pool_addr_cb = add_del_dslite_pool_addr_cb; |
| 57 | dm->pool.alloc_addr_and_port_cb = nat_alloc_ip4_addr_and_port_cb_default; |
| 58 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 59 | p = hash_get_mem (tm->thread_registrations_by_name, "workers"); |
| 60 | if (p) |
| 61 | { |
| 62 | tr = (vlib_thread_registration_t *) p[0]; |
| 63 | if (tr) |
| 64 | { |
| 65 | dm->num_workers = tr->count; |
| 66 | dm->first_worker_index = tr->first_index; |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | if (dm->num_workers) |
| 71 | dm->port_per_thread = (0xffff - 1024) / dm->num_workers; |
| 72 | else |
| 73 | dm->port_per_thread = 0xffff - 1024; |
| 74 | |
| 75 | vec_validate (dm->per_thread_data, tm->n_vlib_mains - 1); |
| 76 | |
| 77 | /* *INDENT-OFF* */ |
| 78 | vec_foreach (td, dm->per_thread_data) |
| 79 | { |
| 80 | clib_bihash_init_24_8 (&td->in2out, "in2out", translation_buckets, |
| 81 | translation_memory_size); |
| 82 | |
| 83 | clib_bihash_init_8_8 (&td->out2in, "out2in", translation_buckets, |
| 84 | translation_memory_size); |
| 85 | |
| 86 | clib_bihash_init_16_8 (&td->b4_hash, "b4s", b4_buckets, b4_memory_size); |
| 87 | } |
| 88 | /* *INDENT-ON* */ |
| 89 | |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 90 | dm->is_ce = 0; |
| 91 | |
Matus Fabian | fd0d508 | 2018-12-18 01:08:51 -0800 | [diff] [blame] | 92 | /* Init counters */ |
| 93 | dm->total_b4s.name = "total-b4s"; |
| 94 | dm->total_b4s.stat_segment_name = "/dslite/total-b4s"; |
| 95 | vlib_validate_simple_counter (&dm->total_b4s, 0); |
| 96 | vlib_zero_simple_counter (&dm->total_b4s, 0); |
| 97 | dm->total_sessions.name = "total-sessions"; |
| 98 | dm->total_sessions.stat_segment_name = "/dslite/total-sessions"; |
| 99 | vlib_validate_simple_counter (&dm->total_sessions, 0); |
| 100 | vlib_zero_simple_counter (&dm->total_sessions, 0); |
| 101 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 102 | dslite_dpo_module_init (); |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 103 | |
| 104 | nat_fib_src_hi = fib_source_allocate ("dslite-hi", |
| 105 | FIB_SOURCE_PRIORITY_HI, |
| 106 | FIB_SOURCE_BH_SIMPLE); |
| 107 | |
| 108 | return dslite_api_hookup (vm); |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 109 | } |
| 110 | |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 111 | void |
| 112 | dslite_set_ce (dslite_main_t * dm, u8 set) |
| 113 | { |
| 114 | dm->is_ce = (set != 0); |
| 115 | } |
| 116 | |
Vladimir Ratnikov | 958919f | 2020-04-13 06:36:19 -0400 | [diff] [blame] | 117 | static clib_error_t * |
| 118 | dslite_config (vlib_main_t * vm, unformat_input_t * input) |
| 119 | { |
| 120 | dslite_main_t *dm = &dslite_main; |
| 121 | |
| 122 | while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) |
| 123 | { |
| 124 | if (unformat (input, "ce")) |
| 125 | dslite_set_ce (dm, 1); |
| 126 | } |
| 127 | return 0; |
| 128 | } |
| 129 | |
| 130 | VLIB_CONFIG_FUNCTION (dslite_config, "dslite"); |
| 131 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 132 | int |
| 133 | dslite_set_aftr_ip6_addr (dslite_main_t * dm, ip6_address_t * addr) |
| 134 | { |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 135 | dpo_id_t dpo = DPO_INVALID; |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 136 | |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 137 | if (dm->is_ce) |
| 138 | { |
| 139 | dslite_ce_dpo_create (DPO_PROTO_IP4, 0, &dpo); |
| 140 | fib_prefix_t pfx = { |
| 141 | .fp_proto = FIB_PROTOCOL_IP4, |
| 142 | .fp_len = 0, |
| 143 | .fp_addr.ip4.as_u32 = 0, |
| 144 | }; |
Neale Ranns | 3bab8f9 | 2019-12-04 06:11:00 +0000 | [diff] [blame] | 145 | fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi, |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 146 | FIB_ENTRY_FLAG_EXCLUSIVE, &dpo); |
| 147 | } |
| 148 | else |
| 149 | { |
| 150 | dslite_dpo_create (DPO_PROTO_IP6, 0, &dpo); |
| 151 | fib_prefix_t pfx = { |
| 152 | .fp_proto = FIB_PROTOCOL_IP6, |
| 153 | .fp_len = 128, |
| 154 | .fp_addr.ip6.as_u64[0] = addr->as_u64[0], |
| 155 | .fp_addr.ip6.as_u64[1] = addr->as_u64[1], |
| 156 | }; |
Neale Ranns | 3bab8f9 | 2019-12-04 06:11:00 +0000 | [diff] [blame] | 157 | fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi, |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 158 | FIB_ENTRY_FLAG_EXCLUSIVE, &dpo); |
| 159 | } |
| 160 | |
| 161 | dpo_reset (&dpo); |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 162 | |
| 163 | dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0]; |
| 164 | dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1]; |
| 165 | return 0; |
| 166 | } |
| 167 | |
| 168 | int |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 169 | dslite_set_aftr_ip4_addr (dslite_main_t * dm, ip4_address_t * addr) |
| 170 | { |
| 171 | dm->aftr_ip4_addr.as_u32 = addr->as_u32; |
| 172 | return 0; |
| 173 | } |
| 174 | |
| 175 | int |
| 176 | dslite_set_b4_ip6_addr (dslite_main_t * dm, ip6_address_t * addr) |
| 177 | { |
| 178 | if (dm->is_ce) |
| 179 | { |
| 180 | dpo_id_t dpo = DPO_INVALID; |
| 181 | |
| 182 | dslite_ce_dpo_create (DPO_PROTO_IP6, 0, &dpo); |
| 183 | fib_prefix_t pfx = { |
| 184 | .fp_proto = FIB_PROTOCOL_IP6, |
| 185 | .fp_len = 128, |
| 186 | .fp_addr.ip6.as_u64[0] = addr->as_u64[0], |
| 187 | .fp_addr.ip6.as_u64[1] = addr->as_u64[1], |
| 188 | }; |
Neale Ranns | 3bab8f9 | 2019-12-04 06:11:00 +0000 | [diff] [blame] | 189 | fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi, |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 190 | FIB_ENTRY_FLAG_EXCLUSIVE, &dpo); |
| 191 | |
| 192 | dpo_reset (&dpo); |
| 193 | |
| 194 | dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0]; |
| 195 | dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1]; |
| 196 | } |
| 197 | else |
| 198 | { |
| 199 | return VNET_API_ERROR_FEATURE_DISABLED; |
| 200 | } |
| 201 | |
| 202 | return 0; |
| 203 | } |
| 204 | |
| 205 | int |
| 206 | dslite_set_b4_ip4_addr (dslite_main_t * dm, ip4_address_t * addr) |
| 207 | { |
| 208 | if (dm->is_ce) |
| 209 | { |
| 210 | dm->b4_ip4_addr.as_u32 = addr->as_u32; |
| 211 | } |
| 212 | else |
| 213 | { |
| 214 | return VNET_API_ERROR_FEATURE_DISABLED; |
| 215 | } |
| 216 | |
| 217 | return 0; |
| 218 | } |
| 219 | |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 220 | void |
| 221 | add_del_dslite_pool_addr_cb (ip4_address_t addr, u8 is_add, void *opaque) |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 222 | { |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 223 | dpo_id_t dpo_v4 = DPO_INVALID; |
| 224 | fib_prefix_t pfx = { |
| 225 | .fp_proto = FIB_PROTOCOL_IP4, |
| 226 | .fp_len = 32, |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 227 | .fp_addr.ip4.as_u32 = addr.as_u32, |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 228 | }; |
| 229 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 230 | if (is_add) |
| 231 | { |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 232 | dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4); |
Neale Ranns | 3bab8f9 | 2019-12-04 06:11:00 +0000 | [diff] [blame] | 233 | fib_table_entry_special_dpo_add (0, &pfx, nat_fib_src_hi, |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 234 | FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4); |
| 235 | dpo_reset (&dpo_v4); |
| 236 | } |
| 237 | else |
| 238 | { |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 239 | fib_table_entry_special_remove (0, &pfx, nat_fib_src_hi); |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 240 | } |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 241 | } |
| 242 | |
| 243 | u8 * |
| 244 | format_dslite_trace (u8 * s, va_list * args) |
| 245 | { |
| 246 | CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); |
| 247 | CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); |
| 248 | dslite_trace_t *t = va_arg (*args, dslite_trace_t *); |
| 249 | |
| 250 | s = |
| 251 | format (s, "next index %d, session %d", t->next_index, t->session_index); |
| 252 | |
| 253 | return s; |
| 254 | } |
| 255 | |
Juraj Sloboda | c5c6a33 | 2018-01-09 16:08:32 +0100 | [diff] [blame] | 256 | u8 * |
| 257 | format_dslite_ce_trace (u8 * s, va_list * args) |
| 258 | { |
| 259 | CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); |
| 260 | CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); |
| 261 | dslite_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *); |
| 262 | |
| 263 | s = format (s, "next index %d", t->next_index); |
| 264 | |
| 265 | return s; |
| 266 | } |
| 267 | |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 268 | VLIB_INIT_FUNCTION (dslite_init); |
| 269 | |
Filip Varga | 603e754 | 2020-07-21 10:27:39 +0200 | [diff] [blame^] | 270 | /* *INDENT-OFF* */ |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 271 | VLIB_PLUGIN_REGISTER () = |
| 272 | { |
Filip Varga | 603e754 | 2020-07-21 10:27:39 +0200 | [diff] [blame^] | 273 | .version = VPP_BUILD_VER, |
| 274 | .description = "Dual-Stack Lite", |
| 275 | }; |
| 276 | /* *INDENT-ON* */ |
Ole Troan | 2c6639c | 2019-12-19 11:55:54 +0100 | [diff] [blame] | 277 | |
Matus Fabian | 8ebe625 | 2017-11-06 05:04:53 -0800 | [diff] [blame] | 278 | /* |
| 279 | * fd.io coding-style-patch-verification: ON |
| 280 | * |
| 281 | * Local Variables: |
| 282 | * eval: (c-set-style "gnu") |
| 283 | * End: |
| 284 | */ |