28 #include "ipv4_packet.h" 36 #define foreach_cnat_ipv4_tcp_inside_input_error \ 37 _(TCP_NAT_IN, "packets received") \ 38 _(TCP_NAT, "packets NATed") \ 39 _(TCP_EXCEPTION, "packets to exception") \ 40 _(TCP_TTL_GEN, "Generated TTL Expiry ICMP packet") \ 41 _(TCP_TTL_DROP, "Could not generate TTL Expiry ICMP packet") \ 42 _(TCP_SESSION_DROP, "Could not generate session") \ 43 _(TCP_FRAG_DROP, "Non-first Fragment received") 46 #define _(sym,str) sym, 53 #define _(sym,string) string, 59 typedef struct cnat_v4_tcp_in2out_pipeline_data_ {
60 spp_node_main_vector_t *nmv;
65 } cnat_v4_tcp_in2out_pipeline_data_t;
67 static cnat_v4_tcp_in2out_pipeline_data_t pctx_data[SPP_MAXDISPATCH];
69 #define EXTRA_PIPELINE_ARGS_PROTO , cnat_v4_tcp_in2out_pipeline_data_t *pctx 70 #define EXTRA_PIPELINE_ARGS , pctx 82 SPP_PREFETCH_CTX(ctx);
88 u8 *disp_used EXTRA_PIPELINE_ARGS_PROTO))
92 SPP_PREFETCH_CTX_DATA(ctx, 1*CACHE_DATA_QUANTUM);
98 u8 *disp_used EXTRA_PIPELINE_ARGS_PROTO))
103 cnat_feature_data_t *fd = (cnat_feature_data_t *)ctx->feature_data;
113 ctx->application_start = (ip->version_hdr_len_words & 0xf) << 2;
117 fd->dbl.k.k.ipv4 = spp_net_to_host_byte_order_32(&ip->src_addr);
124 u16 *feature_data_ports = (
u16 *)&ctx->feature_data[2];
125 pctx[index].src_port = fd->dbl.k.k.port = *feature_data_ports;
126 feature_data_ports++;
127 pctx[index].dst_port = *feature_data_ports;
129 fd->dbl.k.k.port = spp_net_to_host_byte_order_16(&tcp->src_port);
130 pctx[index].dst_port =
131 spp_net_to_host_byte_order_16(&tcp->dest_port);
137 spp_net_to_host_byte_order_32(&ip->dest_addr) : 0;
144 pctx[index].bucket = bucket;
147 SPP_PREFETCH(prefetch_target, 0, LOAD);
154 u8 *disp_used EXTRA_PIPELINE_ARGS_PROTO))
158 uword prefetch_target0, prefetch_target1;
160 bucket = pctx[index].bucket;
174 SPP_PREFETCH(prefetch_target0, 0, LOAD);
178 prefetch_target1 = prefetch_target0 +
186 SPP_PREFETCH(prefetch_target1, 0, LOAD);
194 u8 *disp_used EXTRA_PIPELINE_ARGS_PROTO)
197 u32 db_index = pctx[index].bucket;
199 cnat_feature_data_t *fd;
209 fd = (cnat_feature_data_t *)ctx->feature_data;
223 }
while (db_index !=
EMPTY);
228 pctx[index].bucket = db_index;
233 stage5(
spp_ctx_t **ctxs,
int index, spp_node_t *np,
237 u32 db_index = pctx[index].bucket;
238 cnat_feature_data_t *fd = (cnat_feature_data_t *)ctx->feature_data;
259 (ctx, ip, ctx->ru.rx.uidb_index)) {
265 disposition = CNAT_DROP;
276 spp_net_to_host_byte_order_16(&(ip->frag_flags_offset));
279 disposition = CNAT_DROP;
283 disposition = CNAT_V4_TCP_IE;
287 disposition = CNAT_V4_TCP_IE;
295 dest_info.
k.
port = pctx[index].dst_port;
296 dest_info.
k.
ipv4 = spp_net_to_host_byte_order_32(&(ip->dest_addr));
301 db->dst_ipv4 = dest_info.
k.
ipv4;
302 db->dst_port = dest_info.
k.
port;
307 db->dst_port != dest_info.
k.
port)) {
317 dest_info.
k.
vrf = db->in2out_key.k.vrf;
320 disposition = CNAT_DROP;
325 dest_info.
k.
vrf = db->in2out_key.k.vrf;
334 disposition = CNAT_DROP;
341 window = (
u32)spp_net_to_host_byte_order_16(
343 window = window << session_db->
scale;
346 session_db->
scale = scale;
347 session_db->
window = window;
351 session_db->
window = window;
355 session_db->
tcp_seq_num = spp_net_to_host_byte_order_32(
357 session_db->
ack_no = spp_net_to_host_byte_order_32(
361 " ack no = %u, window = %u\n",
372 window = (
u32)spp_net_to_host_byte_order_16(
374 window = window << db->scale;
378 db->proto_data.tcp_seq_chk.seq_no =
379 spp_net_to_host_byte_order_32(
381 db->proto_data.tcp_seq_chk.ack_no =
382 spp_net_to_host_byte_order_32(
387 db->diff_window = window;
392 db->proto_data.tcp_seq_chk.seq_no,
393 db->proto_data.tcp_seq_chk.ack_no);
415 spp_net_to_host_byte_order_16(&(ip->frag_flags_offset));
420 goto handle_ttl_n_checksum;
424 spp_net_to_host_byte_order_16(&tcp->src_port),
425 spp_net_to_host_byte_order_16(&tcp->dest_port))
429 (spp_net_to_host_byte_order_16(&tcp->src_port) == 21 ||
430 spp_net_to_host_byte_order_16(&tcp->dest_port) == 21))) {
436 goto handle_ttl_n_checksum;
455 || ((!session_db) && (db->alg.delta != 0)))) {
477 seq1 = seq > db->proto_data.seq_pcp.tcp_seq_num ?
478 (seq + db->alg.alg_dlt[1]):
479 (seq + db->alg.alg_dlt[0]);
501 rc =
cnat_ftp_alg((
u8*) ip, &delta, db, dslite_entry_ptr, ipv6_hdr);
529 "cnat_ftp_alg seq_num 0x%x, dlt0 0x%x, dlt1 0x%x",
535 db->proto_data.seq_pcp.tcp_seq_num =
net2host32(&tcp->seq_num);
536 db->alg.alg_dlt[0] = db->alg.alg_dlt[1];
539 db->alg.alg_dlt[1] += delta;
542 "cnat_ftp_alg seq_num 0x%x, dlt0 0x%x, dlt1 0x%x",
543 db->proto_data.seq_pcp.tcp_seq_num,
547 ctx->current_length += delta;
567 #define RTSP_ALG_DELTA_MASK 0xFF 577 (seq + db->alg.alg_dlt[1]):
578 (seq + db->alg.alg_dlt[0]);
580 seq1 = seq > db->proto_data.seq_pcp.tcp_seq_num ?
581 (seq + db->alg.alg_dlt[1]):
582 (seq + db->alg.alg_dlt[0]);
604 if ((session_db && (!session_db->
alg.
il)) ||
605 ((!session_db) && (!db->alg.il))) {
606 cnat_rtsp_alg((
u8*) ip,
614 handle_ttl_n_checksum:
624 db->out2in_key.k.ipv4,
625 db->out2in_key.k.port,
630 (spp_net_to_host_byte_order_16(&tcp->dest_port) ==
635 PPTP_DBG(3,
"PPTP mgmt/ctrl msg recieved");
637 ret = cnat_handle_pptp_msg(ctx, db , tcp,
PPTP_PNS );
640 PPTP_DBG(3,
"PPTP mgmt/ctrl msg drop");
641 disposition = CNAT_DROP;
672 fd->dbl.db_index = db_index;
676 DISP_PUSH_CTX(np, ctx, disposition, disp_used, last_disposition, last_contexts_ptr, last_nused_ptr);
#define ALG_ENABLED_DB(db)
cnat_main_db_entry_t * cnat_main_db
cnat_session_entry_t * cnat_create_session_db_entry(cnat_key_t *ko, cnat_main_db_entry_t *bdb, u8 log)
void ipv4_decr_ttl_n_calc_csum(ipv4_header *ipv4)
#define CNAT_DB_FLAG_PPTP_TUNNEL_INIT
#define foreach_cnat_ipv4_tcp_inside_input_error
#define V4_TCP_UPDATE_SESSION_FLAG(db, tcp)
void tcp_in2out_nat_mss_n_checksum(ipv4_header *ip, tcp_hdr_type *tcp, u32 ipv4_addr, u16 port, cnat_main_db_entry_t *db)
#define EXTRA_PIPELINE_ARGS_PROTO
#define CNAT_DB_FLAG_ALG_CTRL_FLOW
u8 address_dependent_filtering
#define STRUCT_OFFSET_OF(t, f)
index_slist_t in2out_hash
cnat_session_entry_t * cnat_handle_1to2_session(cnat_main_db_entry_t *mdb, cnat_key_t *dest_info)
int cnat_ftp_alg(u8 *pkt, i8 *delta, cnat_main_db_entry_t *db, dslite_table_entry_t *dslite_entry_ptr, ipv6_header_t *ipv6_hdr)
index_slist_t * cnat_in2out_hash
#define CNAT_DB_TIMEOUT_RST(db)
union cnat_session_entry_t::@215 alg
static void stage1(vlib_main_t *vm, vlib_node_runtime_t *node, u32 bi)
#define FTP_ALG_DEBUG_PRINTF(...)
#define RTSP_ALG_DELTA_MASK
#define CNAT_UPDATE_TCP_SEQ_ACK_CHECKSUM(old_val32, new_val32)
int icmpv4_generate_with_throttling(spp_ctx_t *ctx, ipv4_header *ipv4, u16 rx_uidb_index)
void calculate_window_scale(tcp_hdr_type *tcp_header, u8 *scale)
#define CNAT_DB_FLAG_PPTP_TUNNEL_ACTIVE
#define CNAT_DEBUG_GLOBAL_ALL
#define PPTP_DBG(debug,...)
void cnat_add_dest_n_log(cnat_main_db_entry_t *mdb, cnat_key_t *dest_info)
#define INCREMENT_NODE_COUNTER(c)
cnat_ipv4_tcp_inside_input_t
#define CNAT_MAIN_HASH_MASK
struct _spp_ctx spp_ctx_t
u32 in2out_forwarding_count
#define CNAT_V4_GET_HASH(key64, hash, mask)
#define V4_TCP_UPDATE_SESSION_DB_FLAG(sdb, tcp)