Line data Source code
1 : /* 2 : * det44.h - deterministic NAT definitions 3 : * 4 : * Copyright (c) 2020 Cisco and/or its affiliates. 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at: 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : /** 19 : * @file 20 : * @brief Deterministic NAT (CGN) inlines 21 : */ 22 : 23 : #ifndef __included_det44_inlines_h__ 24 : #define __included_det44_inlines_h__ 25 : 26 : static_always_inline int 27 2 : det44_is_interface_addr (vlib_node_runtime_t * node, 28 : u32 sw_if_index0, u32 ip4_addr) 29 : { 30 2 : det44_runtime_t *rt = (det44_runtime_t *) node->runtime_data; 31 2 : det44_main_t *dm = &det44_main; 32 : ip4_address_t *first_int_addr; 33 : 34 2 : if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0)) 35 : { 36 1 : first_int_addr = ip4_interface_first_address (dm->ip4_main, 37 : sw_if_index0, 0); 38 1 : rt->cached_sw_if_index = sw_if_index0; 39 1 : if (first_int_addr) 40 1 : rt->cached_ip4_address = first_int_addr->as_u32; 41 : else 42 0 : rt->cached_ip4_address = 0; 43 : } 44 2 : if (PREDICT_FALSE (rt->cached_ip4_address == ip4_addr)) 45 0 : return 0; 46 2 : return 1; 47 : } 48 : 49 : /** 50 : * @brief Check if packet should be translated 51 : * 52 : * Packets aimed at outside interface and external address with active session 53 : * should be translated. 54 : * 55 : * @param node NAT runtime data 56 : * @param sw_if_index0 index of the inside interface 57 : * @param ip0 IPv4 header 58 : * @param proto0 NAT protocol 59 : * @param rx_fib_index0 RX FIB index 60 : * 61 : * @returns 0 if packet should be translated otherwise 1 62 : */ 63 : static_always_inline int 64 2 : det44_translate (vlib_node_runtime_t * node, u32 sw_if_index0, 65 : ip4_header_t * ip0, u32 proto0, u32 rx_fib_index0) 66 : { 67 2 : det44_main_t *dm = &det44_main; 68 2 : fib_node_index_t fei = FIB_NODE_INDEX_INVALID; 69 : det44_fib_t *outside_fib; 70 2 : fib_prefix_t pfx = { 71 : .fp_proto = FIB_PROTOCOL_IP4, 72 : .fp_len = 32, 73 : .fp_addr = { 74 2 : .ip4.as_u32 = ip0->dst_address.as_u32, 75 : } 76 : , 77 : }; 78 : 79 : /* Don't NAT packet aimed at the interface address */ 80 2 : if (PREDICT_FALSE (!det44_is_interface_addr (node, sw_if_index0, 81 : ip0->dst_address.as_u32))) 82 : { 83 0 : return 1; 84 : } 85 : 86 : /* find out if there is outside feature enabled for this destination */ 87 2 : fei = fib_table_lookup (rx_fib_index0, &pfx); 88 2 : if (FIB_NODE_INDEX_INVALID != fei) 89 : { 90 2 : u32 sw_if_index = fib_entry_get_resolving_interface (fei); 91 2 : if (sw_if_index == ~0) 92 : { 93 : // TODO: go over use cases 94 : /* *INDENT-OFF* */ 95 0 : vec_foreach (outside_fib, dm->outside_fibs) 96 : { 97 0 : fei = fib_table_lookup (outside_fib->fib_index, &pfx); 98 0 : if (FIB_NODE_INDEX_INVALID != fei) 99 : { 100 0 : sw_if_index = fib_entry_get_resolving_interface (fei); 101 0 : if (sw_if_index != ~0) 102 0 : break; 103 : } 104 : } 105 : /* *INDENT-ON* */ 106 : } 107 2 : if (sw_if_index != ~0) 108 : { 109 : det44_interface_t *i; 110 : /* *INDENT-OFF* */ 111 4 : pool_foreach (i, dm->interfaces) { 112 : /* NAT packet aimed at outside interface */ 113 4 : if ((det44_interface_is_outside (i)) && (sw_if_index == i->sw_if_index)) 114 2 : return 0; 115 : } 116 : /* *INDENT-ON* */ 117 : } 118 : } 119 0 : return 1; 120 : } 121 : 122 : #endif /* __included_det44_inlines_h__ */ 123 : 124 : /* 125 : * fd.io coding-style-patch-verification: ON 126 : * 127 : * Local Variables: 128 : * eval: (c-set-style "gnu") 129 : * End: 130 : */