nat: 1:1 policy NAT
[vpp.git] / src / plugins / nat / pnat / pnat_node.c
1 /*
2  * Copyright (c) 2021 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  */
15
16 /*
17  * Policy NAT.
18  * Match packet against rule in a hash and translate according to given
19  * instructions. Rules are kept in a flow-cache bihash. Instructions in a pool
20  * of translation entries.
21  *
22  * All rules for a given interface/direction must use the same lookup pattern.
23  * E.g. SA+SP.
24  *
25  * A dynamic NAT would punt to slow path on a miss in the flow cache, in this
26  * case the miss behaviour is configurable. Default behaviour is pass packet
27  * along unchanged.
28  *
29  * The data structures are shared and assuming that updates to the tables are
30  * rare. Data-structures are protected depending on the API/CLI barriers.
31  */
32
33 #include <stdbool.h>
34 #include <vlib/vlib.h>
35 #include <pnat/pnat.api_enum.h> /* For error counters */
36 #include "pnat_node.h"          /* Graph nodes */
37
38 VLIB_NODE_FN(pnat_input_node)
39 (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) {
40     return pnat_node_inline(vm, node, frame, PNAT_IP4_INPUT, VLIB_RX);
41 }
42 VLIB_NODE_FN(pnat_output_node)
43 (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) {
44     return pnat_node_inline(vm, node, frame, PNAT_IP4_OUTPUT, VLIB_TX);
45 }
46
47 VLIB_REGISTER_NODE(pnat_input_node) = {
48     .name = "pnat-input",
49     .vector_size = sizeof(u32),
50     .format_trace = format_pnat_trace,
51     .type = VLIB_NODE_TYPE_INTERNAL,
52     .n_errors = PNAT_N_ERROR,
53     .error_counters = pnat_error_counters,
54     .n_next_nodes = PNAT_N_NEXT,
55     .next_nodes =
56         {
57             [PNAT_NEXT_DROP] = "error-drop",
58         },
59 };
60
61 VLIB_REGISTER_NODE(pnat_output_node) = {
62     .name = "pnat-output",
63     .vector_size = sizeof(u32),
64     .format_trace = format_pnat_trace,
65     .type = VLIB_NODE_TYPE_INTERNAL,
66     .n_errors = PNAT_N_ERROR,
67     .error_counters = pnat_error_counters,
68     .sibling_of = "pnat-input",
69 };
70
71 /* Hook up features */
72 VNET_FEATURE_INIT(pnat_input, static) = {
73     .arc_name = "ip4-unicast",
74     .node_name = "pnat-input",
75     .runs_after = VNET_FEATURES("acl-plugin-in-ip4-fa",
76                                 "ip4-sv-reassembly-feature"),
77 };
78 VNET_FEATURE_INIT(pnat_output, static) = {
79     .arc_name = "ip4-output",
80     .node_name = "pnat-output",
81     .runs_after = VNET_FEATURES("acl-plugin-out-ip4-fa",
82                                 "ip4-sv-reassembly-output-feature"),
83 };