FD.io VPP  v17.01-9-ge7dcee4
Vector Packet Processing
cnat_ipv4_udp_inside_input_exceptions.c
Go to the documentation of this file.
1 /*
2  *---------------------------------------------------------------------------
3  * cnat_ipv4_udp_inside_input_exception_stages.c - cnat_ipv4_udp_inside_input_exception node pipeline stage functions
4  *
5  *
6  * Copyright (c) 2008-2014 Cisco and/or its affiliates.
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at:
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *---------------------------------------------------------------------------
19  */
20 
21 #include <vlib/vlib.h>
22 #include <vnet/vnet.h>
23 #include <vppinfra/error.h>
24 #include <vnet/buffer.h>
25 
26 #include "cnat_global.h"
27 #include "cnat_db.h"
28 #include "cnat_ipv4_udp.h"
29 
30 /*
31  * Dump these counters via the "show error" CLI command
32  */
33 
34 #define foreach_cnat_ipv4_udp_inside_input_exc_error \
35 _(CNAT_V4_UDP_I2O_T_PKT, "v4 udp i2o transmit") \
36 _(CNAT_V4_UDP_I2O_D_PKT, "v4 udp i2o drop") \
37 _(CNAT_V4_ICMP_G_I2O_T_PKT, "v4 udp i2o icmp msg gen") \
38 _(CNAT_V4_UDP_I2O_DC_PKT, "v4 udp i2o (no config) drop") \
39 _(CNAT_V4_UDP_I2O_DR_PKT, "v4 udp i2o (not in run state) drop") \
40 _(CNAT_V4_UDP_I2O_DD_PKT, "v4 udp i2o (no direct port) drop") \
41 _(CNAT_V4_UDP_I2O_DA_PKT, "v4 udp i2o (no any port) drop") \
42 _(CNAT_V4_UDP_I2O_DO_PKT, "v4 udp i2o (out of port limit) drop") \
43 _(CNAT_V4_UDP_I2O_DI_PKT, "v4 udp i2o (invalid packet) drop") \
44 _(CNAT_V4_UDP_I2O_DS_PKT, "v4 udp i2o (no sessoon db) drop")
45 
46 typedef enum {
47 #define _(sym,str) sym,
49 #undef _
52 
53 
55 #define _(sym,string) string,
57 #undef _
58 };
59 
60 typedef struct {
62  /* $$$$ add data here */
63 
64  /* convenience variables */
68 
69 typedef enum {
75 
78 
79 #define NSTAGES 2
80 
81 /*
82  * Use the generic buffer metadata + first line of packet data prefetch
83  * stage function from <api/pipeline.h>. This is usually a Good Idea.
84  */
85 #define stage0 generic_stage0
86 
87 static inline u32 last_stage (vlib_main_t *vm, vlib_node_runtime_t *node,
88  u32 bi)
89 {
90  vlib_buffer_t *b0 = vlib_get_buffer (vm, bi);
91  vlib_node_t *n =
93  u32 node_counter_base_index = n->error_heap_index;
94  vlib_error_main_t * em = &vm->error_main;
95 
96  cnat_gen_icmp_info info;
98  spp_ctx_t *ctx __attribute__((unused))
99  = (spp_ctx_t *) &vnet_buffer(b0)->vcgn_uii;
102  u8 ipv4_hdr_len = (ip->version_hdr_len_words & 0xf) << 2;
103  udp_hdr_type_t *udp = (udp_hdr_type_t *)((u8*)ip + ipv4_hdr_len);
104  int disposition = CNAT_V4_UDP_I2O_T;
105  int counter = CNAT_V4_UDP_I2O_T_PKT;
106 
107  cnat_key_t dest_info;
108 
109  PLATFORM_CNAT_SET_RX_VRF(vnet_buffer(b0)->sw_if_index[VLIB_RX],
110  vnet_buffer(b0)->vcgn_uii.key.k.vrf,
111  CNAT_UDP)
112 
113  vnet_buffer(b0)->vcgn_uii.key.k.ipv4 = clib_net_to_host_u32(ip->src_addr);
114 
115  PLATFORM_CNAT_SET_RX_VRF(vnet_buffer(b0)->sw_if_index[VLIB_RX],
116  ki.k.k.vrf, CNAT_UDP)
117 
118  ki.k.k.ipv4 = clib_net_to_host_u32(ip->src_addr);
119 
120 
121  /* MUST REVISIT: commentting frag check. Unconditional destination port
122  * update. DONOT remove this #if 0 */
123  ki.k.k.port =
124  clib_net_to_host_u16(udp->src_port);
125  dest_info.k.port =
126  clib_net_to_host_u16(udp->dest_port);
127 #if 0
128  if(PREDICT_FALSE(ctx->ru.rx.frag)) {
129 #ifdef TOBE_PORTED
130  /* Must have routed through cnat_v4_frag_in2out node */
131  u16 *feature_data_ports = (u16 *)&ctx->feature_data[2];
132  ki.k.k.port = *feature_data_ports;
133  feature_data_ports++;
134  dest_info.k.port = *feature_data_ports;
135 #endif
136  } else {
137  ki.k.k.port =
138  clib_net_to_host_u16(udp->src_port);
139  dest_info.k.port =
140  clib_net_to_host_u16(udp->dest_port);
141  }
142 #endif /* if 0 */
143 
144  dest_info.k.ipv4 = clib_net_to_host_u32(ip->dest_addr);
145  PLATFORM_CNAT_SET_RX_VRF(vnet_buffer(b0)->sw_if_index[VLIB_RX],
146  dest_info.k.vrf, CNAT_UDP)
147 
148  if (PREDICT_TRUE(ki.k.k.port)) {
149  if (ki.k.k.port & 0x1) {
151  &info, &dest_info);
152  } else {
154  &info, &dest_info);
155  }
156  } else {
157  /*
158  * No UDP port value of 0 - drop it
159  */
160  db = NULL;
162  }
163 
164  if (PREDICT_TRUE((u64)db)) {
165 
167  /*
168  * Decrement TTL and update IPv4 checksum
169  */
171  }
172 
173  /*
174  * step 6 do nat before fwd pkt
175  */
176  swap_ip_src_udp_port(ip, udp, db);
177  /*
178  * update db for this pkt
179  */
181 
182  /* Check timeout db if there is config for this */
183  (void) query_and_update_db_timeout((void *)db, MAIN_DB_TYPE);
184 
185 /* Temporarily keeping it commented */
186  //PLATFORM_CNAT_SET_TX_VRF(vnet_buffer(b0)->sw_if_index[VLIB_TX],
187  // db->out2in_key.k.vrf)
189 
190  } else {
191  switch (info.error) {
192  case (CNAT_NO_VRF_RUN):
193  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DR_PKT] += 1;
194  break;
195  case (CNAT_OUT_LIMIT):
196  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DO_PKT] += 1;
197  break;
198  case (CNAT_NO_PORT_ANY):
199  case (CNAT_NO_POOL_ANY):
200  case (CNAT_BAD_INUSE_ANY):
201  case (CNAT_NOT_FOUND_ANY):
202  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DA_PKT] += 1;
203  break;
204  case (CNAT_INV_PORT_DIRECT):
205  case (CNAT_DEL_PORT_DIRECT):
206  case (CNAT_BAD_INUSE_DIRECT):
207  case (CNAT_NOT_FOUND_DIRECT):
208  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DD_PKT] += 1;
209  break;
211  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DI_PKT] += 1;
212  break;
213  case (CNAT_ERR_NO_SESSION_DB):
214  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DS_PKT] += 1;
215  break;
216  default:
217  em->counters[node_counter_base_index + CNAT_V4_UDP_I2O_DC_PKT] += 1;
218  break;
219  }
220  /*
221  * send to icmp msg generate node
222  */
223  if (info.gen_icmp_msg == CNAT_ICMP_MSG) {
224 #ifdef TOBE_PORTED
225  u32 *fd = (u32*)ctx->feature_data;
226  fd[0] = info.svi_addr;
228 #endif
229  disposition = CNAT_V4_ICMP_G_I2O_T;
230  counter = CNAT_V4_ICMP_G_I2O_T_PKT;
231  } else {
232  disposition = CNAT_V4_UDP_I2O_D;
233  counter = CNAT_V4_UDP_I2O_D_PKT;
234  }
236  }
237 
238  em->counters[node_counter_base_index + counter] += 1;
239 
240  return disposition;
241 }
242 
243 
244 #include <vnet/pipeline.h>
245 
247  vlib_node_runtime_t * node,
248  vlib_frame_t * frame)
249 {
250  return dispatch_pipeline (vm, node, frame);
251 }
252 
255  .name = "vcgn-v4-udp-i2o-e",
256  .vector_size = sizeof (u32),
258 
261 
262  .n_next_nodes = CNAT_V4_UDP_INSIDE_INPUT_EXC_N_NEXT,
263 
264  /* edit / add dispositions here */
265  .next_nodes = {
266  [CNAT_V4_UDP_I2O_T] = "ip4-input",
267  [CNAT_V4_UDP_I2O_D] = "error-drop",
268  },
269 };
270 
271 
273 {
275 
276  mp->vlib_main = vm;
277  mp->vnet_main = vnet_get_main();
278 
279  return 0;
280 }
281 
283 
u32 error_heap_index
Definition: node.h:278
u16 query_and_update_db_timeout(void *db, u8 db_type)
Definition: cnat_db_v2.c:2325
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define PREDICT_TRUE(x)
Definition: clib.h:98
void ipv4_decr_ttl_n_calc_csum(ipv4_header *ipv4)
#define NULL
Definition: clib.h:55
Definition: cnat_db.h:153
struct _vlib_node_registration vlib_node_registration_t
vlib_node_registration_t cnat_ipv4_udp_inside_input_exc_node
(constructor) VLIB_REGISTER_NODE (cnat_ipv4_udp_inside_input_exc_node)
#define MAIN_DB_TYPE
Definition: cnat_db.h:626
clib_error_t * cnat_ipv4_udp_inside_input_exc_init(vlib_main_t *vm)
cnat_errno_t error
Definition: cnat_db.h:528
#define CNAT_DB_UPDATE_IN2OUT_TIMER
Definition: cnat_db.h:557
static char * cnat_ipv4_udp_inside_input_exc_error_strings[]
cnat_ipv4_udp_inside_input_exc_main_t cnat_ipv4_udp_inside_input_exc_main
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
cnat_main_db_entry_t * cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki, port_pair_t port_pair_type, port_type_t port_type, cnat_gen_icmp_info *info, cnat_key_t *dest_info)
Definition: cnat_db_v2.c:1647
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:194
cnat_key_t k
Definition: cnat_db.h:113
unsigned long u64
Definition: types.h:89
#define PLATFORM_CNAT_SET_RX_VRF(ctx, rx_vrf, proto)
vlib_error_main_t error_main
Definition: main.h:124
#define PREDICT_FALSE(x)
Definition: clib.h:97
#define CNAT_UDP
Definition: cnat_db.h:93
u64 * counters
Definition: error.h:78
#define ARRAY_LEN(x)
Definition: clib.h:59
cnat_db_key_t k
Definition: cnat_db.h:108
#define DEBUG_I2O_DROP(debug_flag)
Definition: cnat_db.h:565
#define foreach_cnat_ipv4_udp_inside_input_exc_error
unsigned int u32
Definition: types.h:88
#define vnet_buffer(b)
Definition: buffer.h:361
u64 uword
Definition: types.h:112
#define CNAT_DEBUG_DROP_UDP
Definition: cnat_cli.h:88
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
struct _spp_ctx spp_ctx_t
#define CNAT_ICMP_DEST_UNREACHABLE
u32 in2out_forwarding_count
void swap_ip_src_udp_port(ipv4_header *ip, udp_hdr_type_t *udp, cnat_main_db_entry_t *db)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
#define PLATFORM_HANDLE_TTL_DECREMENT
static u32 last_stage(vlib_main_t *vm, vlib_node_runtime_t *node, u32 bi)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
static uword cnat_ipv4_udp_inside_input_exc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: defs.h:46
cnat_icmp_msg_t gen_icmp_msg
Definition: cnat_db.h:529