nat: move deterministic nat to det44 sub feature
[vpp.git] / src / plugins / nat / det44 / det44_inlines.h
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 det44_is_interface_addr (vlib_node_runtime_t * node,
28                          u32 sw_if_index0, u32 ip4_addr)
29 {
30   det44_runtime_t *rt = (det44_runtime_t *) node->runtime_data;
31   det44_main_t *dm = &det44_main;
32   ip4_address_t *first_int_addr;
33
34   if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
35     {
36       first_int_addr = ip4_interface_first_address (dm->ip4_main,
37                                                     sw_if_index0, 0);
38       rt->cached_sw_if_index = sw_if_index0;
39       if (first_int_addr)
40         rt->cached_ip4_address = first_int_addr->as_u32;
41       else
42         rt->cached_ip4_address = 0;
43     }
44   if (PREDICT_FALSE (rt->cached_ip4_address == ip4_addr))
45     return 0;
46   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 det44_translate (vlib_node_runtime_t * node, u32 sw_if_index0,
65                  ip4_header_t * ip0, u32 proto0, u32 rx_fib_index0)
66 {
67   det44_main_t *dm = &det44_main;
68   fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
69   det44_fib_t *outside_fib;
70   fib_prefix_t pfx = {
71     .fp_proto = FIB_PROTOCOL_IP4,
72     .fp_len = 32,
73     .fp_addr = {
74                 .ip4.as_u32 = ip0->dst_address.as_u32,
75                 }
76     ,
77   };
78
79   /* Don't NAT packet aimed at the interface address */
80   if (PREDICT_FALSE (!det44_is_interface_addr (node, sw_if_index0,
81                                                ip0->dst_address.as_u32)))
82     {
83       return 1;
84     }
85
86   /* find out if there is outside feature enabled for this destination */
87   fei = fib_table_lookup (rx_fib_index0, &pfx);
88   if (FIB_NODE_INDEX_INVALID != fei)
89     {
90       u32 sw_if_index = fib_entry_get_resolving_interface (fei);
91       if (sw_if_index == ~0)
92         {
93           // TODO: go over use cases
94           /* *INDENT-OFF* */
95           vec_foreach (outside_fib, dm->outside_fibs)
96             {
97               fei = fib_table_lookup (outside_fib->fib_index, &pfx);
98               if (FIB_NODE_INDEX_INVALID != fei)
99                 {
100                   sw_if_index = fib_entry_get_resolving_interface (fei);
101                   if (sw_if_index != ~0)
102                     break;
103                 }
104             }
105           /* *INDENT-ON* */
106         }
107       if (sw_if_index != ~0)
108         {
109           det44_interface_t *i;
110           /* *INDENT-OFF* */
111           pool_foreach (i, dm->interfaces, ({
112             /* NAT packet aimed at outside interface */
113             if ((det44_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
114               return 0;
115           }));
116           /* *INDENT-ON* */
117         }
118     }
119   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  */