Skip to content

Commit

Permalink
wip: test node
Browse files Browse the repository at this point in the history
  • Loading branch information
demo-exe committed Feb 2, 2024
1 parent 8c35b2a commit 5e79eea
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 145 deletions.
327 changes: 183 additions & 144 deletions upf/upf_nat.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* Copyright (c) 2017-2019 Travelping GmbH
* Copyright (c) 2019 Travelping GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -14,146 +14,185 @@
* limitations under the License.
*/

#include <math.h>
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <inttypes.h>
#include <vppinfra/clib.h>
#include <vppinfra/mem.h>
#include <vppinfra/pool.h>
#include <vppinfra/sparse_vec.h>
#include <vppinfra/error.h>
#include <vppinfra/hash.h>
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/format.h>
#include <vnet/ip/ip6_hop_by_hop.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/fib_entry_track.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/tcp/tcp_packet.h>
#include <vnet/udp/udp_packet.h>
#include <search.h>
#include <netinet/ip.h>
#include <vlib/unix/plugin.h>

#include "pfcp.h"
#include "upf.h"
#include "upf_app_db.h"
#include "upf_pfcp.h"
#include "upf_pfcp_api.h"
#include "upf_pfcp_server.h"
#include "upf_ipfilter.h"
#include "upf_ipfix.h"

// static_always_inline nat_translation_error_e
// nat_6t_flow_buf_translate (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t
// *b,
// ip4_header_t *ip, nat_6t_flow_t *f,
// ip_protocol_t proto, int is_output_feature,
// int is_i2o)
// {
// if (!is_output_feature && f->ops & NAT_FLOW_OP_TXFIB_REWRITE)
// {
// vnet_buffer (b)->sw_if_index[VLIB_TX] = f->rewrite.fib_index;
// }
//
// if (IP_PROTOCOL_ICMP == proto)
// {
// if (ip->src_address.as_u32 != f->rewrite.saddr.as_u32)
// {
// // packet is returned from a router, not from destination
// // skip source address rewrite if in o2i path
// nat_6t_flow_ip4_translate (sm, b, ip, f, proto,
// 0 /* is_icmp_inner_ip4 */,
// !is_i2o /* skip_saddr_rewrite */);
// }
// else
// {
// nat_6t_flow_ip4_translate (sm, b, ip, f, proto,
// 0 /* is_icmp_inner_ip4 */,
// 0 /* skip_saddr_rewrite */);
// }
// return nat_6t_flow_icmp_translate (vm, sm, b, ip, f);
// }
//
// nat_6t_flow_ip4_translate (sm, b, ip, f, proto, 0 /* is_icmp_inner_ip4 */,
// 0 /* skip_saddr_rewrite */);
//
// return NAT_ED_TRNSL_ERR_SUCCESS;
// }
//
// void
// nat_6t_l3_l4_csum_calc (nat_6t_flow_t *f)
// {
// f->l3_csum_delta = 0;
// f->l4_csum_delta = 0;
// if (f->ops & NAT_FLOW_OP_SADDR_REWRITE &&
// f->rewrite.saddr.as_u32 != f->match.saddr.as_u32)
// {
// f->l3_csum_delta =
// ip_csum_add_even (f->l3_csum_delta, f->rewrite.saddr.as_u32);
// f->l3_csum_delta =
// ip_csum_sub_even (f->l3_csum_delta, f->match.saddr.as_u32);
// }
// else
// {
// f->rewrite.saddr.as_u32 = f->match.saddr.as_u32;
// }
// if (f->ops & NAT_FLOW_OP_DADDR_REWRITE &&
// f->rewrite.daddr.as_u32 != f->match.daddr.as_u32)
// {
// f->l3_csum_delta =
// ip_csum_add_even (f->l3_csum_delta, f->rewrite.daddr.as_u32);
// f->l3_csum_delta =
// ip_csum_sub_even (f->l3_csum_delta, f->match.daddr.as_u32);
// }
// else
// {
// f->rewrite.daddr.as_u32 = f->match.daddr.as_u32;
// }
// if (f->ops & NAT_FLOW_OP_SPORT_REWRITE && f->rewrite.sport !=
// f->match.sport)
// {
// f->l4_csum_delta = ip_csum_add_even (f->l4_csum_delta,
// f->rewrite.sport); f->l4_csum_delta = ip_csum_sub_even
// (f->l4_csum_delta, f->match.sport);
// }
// else
// {
// f->rewrite.sport = f->match.sport;
// }
// if (f->ops & NAT_FLOW_OP_DPORT_REWRITE && f->rewrite.dport !=
// f->match.dport)
// {
// f->l4_csum_delta = ip_csum_add_even (f->l4_csum_delta,
// f->rewrite.dport); f->l4_csum_delta = ip_csum_sub_even
// (f->l4_csum_delta, f->match.dport);
// }
// else
// {
// f->rewrite.dport = f->match.dport;
// }
// if (f->ops & NAT_FLOW_OP_ICMP_ID_REWRITE &&
// f->rewrite.icmp_id != f->match.sport)
// {
// f->l4_csum_delta =
// ip_csum_add_even (f->l4_csum_delta, f->rewrite.icmp_id);
// f->l4_csum_delta = ip_csum_sub_even (f->l4_csum_delta,
// f->match.sport);
// }
// else
// {
// f->rewrite.icmp_id = f->match.sport;
// }
// if (f->ops & NAT_FLOW_OP_TXFIB_REWRITE)
// {
// }
// else
// {
// f->rewrite.fib_index = f->match.fib_index;
// }
// }
//
//
//
#include <vnet/ethernet/ethernet.h>
#include <vnet/dpo/drop_dpo.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/interface_output.h>

#include <upf/upf.h>
#include <upf/upf_pfcp.h>

#if CLIB_DEBUG > 2
#define upf_debug clib_warning
#else
#define upf_debug(...) \
do \
{ \
} \
while (0)
#endif

#ifndef CLIB_MARCH_VARIANT



const static char *const upf_session_dpo_ip4_nodes[] = {
"upf-ip4-session-dpo",
NULL,
};

const static char *const upf_session_dpo_ip6_nodes[] = {
"upf-ip6-session-dpo",
NULL,
};

const static char *const *const upf_session_dpo_nodes[DPO_PROTO_NUM] = {
[DPO_PROTO_IP4] = upf_session_dpo_ip4_nodes,
[DPO_PROTO_IP6] = upf_session_dpo_ip6_nodes,
};

#endif /* CLIB_MARCH_VARIANT */

/* Statistics (not all errors) */
#define foreach_upf_session_dpo_error \
_ (SESSION_DPO, "good packets session_dpo") \
_ (PROXY_LOOP, "proxy output loop detected")

static char *upf_session_dpo_error_strings[] = {
#define _(sym, string) string,
foreach_upf_session_dpo_error
#undef _
};

typedef enum
{
#define _(sym, str) UPF_NAT_ERROR_##sym,
foreach_upf_session_dpo_error
#undef _
UPF_SESSION_DPO_N_ERROR,
} upf_session_dpo_error_t;

typedef enum
{
UPF_NAT_NEXT_DROP,
UPF_NAT_NEXT_ICMP_ERROR,
UPF_NAT_NEXT_FLOW_PROCESS,
UPF_NAT_N_NEXT,
} upf_session_dpo_next_t;

typedef struct
{
u32 session_index;
u64 up_seid;
u8 packet_data[64 - 1 * sizeof (u32)];
} upf_session_dpo_trace_t;

static u8 *
format_upf_session_dpo_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
upf_session_dpo_trace_t *t = va_arg (*args, upf_session_dpo_trace_t *);
u32 indent = format_get_indent (s);

s = format (s, "upf_session%d seid %d \n%U%U", t->session_index, t->up_seid,
format_white_space, indent, format_ip4_header, t->packet_data,
sizeof (t->packet_data));
return s;
}

VLIB_NODE_FN (upf_nat_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
{
vlib_node_runtime_t *error_node =
vlib_node_get_runtime (vm, ip4_input_node.index);
u32 n_left_from, next_index, *from, *to_next;
upf_main_t *gtm = &upf_main;

from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;

u16 next = 0;
u32 sidx = 0;

next_index = node->cached_next_index;

while (n_left_from > 0)
{
u32 n_left_to_next;
vlib_buffer_t *b;
u32 bi;

vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

/* TODO: dual and maybe quad loop */
while (n_left_from > 0 && n_left_to_next > 0)
{
ip4_header_t *ip0;
u32 error0;

bi = from[0];
to_next[0] = bi;
from += 1;
to_next += 1;
n_left_from -= 1;
n_left_to_next -= 1;

b = vlib_get_buffer (vm, bi);

sidx = vnet_buffer (b)->ip.adj_index[VLIB_TX];
upf_debug ("Session %d (0x%08x)", sidx, sidx);

// UPF_ENTER_SUBGRAPH (b, sidx, 1);
error0 = IP4_ERROR_NONE;
next = UPF_NAT_NEXT_FLOW_PROCESS;
upf_debug ("IP hdr: %U", format_ip4_header, ip0, b->current_length);

// ip4_ttl_and_checksum_check (b, ip0, &next, &error0);
// vnet_calc_checksums_inline (vm, b, 1 /* is_ip4 */, 0 /* is_ip6 */);

trace:
b->error = error_node->errors[error0];
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
upf_session_t *sess = pool_elt_at_index (gtm->sessions, sidx);
upf_session_dpo_trace_t *tr =
vlib_add_trace (vm, node, b, sizeof (*tr));
tr->session_index = sidx;
tr->up_seid = sess->up_seid;
clib_memcpy (tr->packet_data, vlib_buffer_get_current (b),
sizeof (tr->packet_data));
}

vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, bi, next);
}

vlib_put_next_frame (vm, node, next_index, n_left_to_next);
}

return from_frame->n_vectors;
}

/* clang-format off */
VLIB_REGISTER_NODE (upf_nat_node) = {
.name = "upf-nat-test",
.vector_size = sizeof (u32),
.format_trace = format_upf_session_dpo_trace,
.type = VLIB_NODE_TYPE_INTERNAL,

.n_errors = ARRAY_LEN(upf_session_dpo_error_strings),
.error_strings = upf_session_dpo_error_strings,

.n_next_nodes = UPF_NAT_N_NEXT,
.next_nodes = {
[UPF_NAT_NEXT_DROP] = "error-drop",
[UPF_NAT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
[UPF_NAT_NEXT_FLOW_PROCESS] = "upf-ip4-flow-process",
},
};
2 changes: 1 addition & 1 deletion upf/upf_session_dpo.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ VLIB_REGISTER_NODE (upf_ip4_session_dpo_node) = {
.next_nodes = {
[UPF_SESSION_DPO_NEXT_DROP] = "error-drop",
[UPF_SESSION_DPO_NEXT_ICMP_ERROR] = "ip4-icmp-error",
[UPF_SESSION_DPO_NEXT_FLOW_PROCESS] = "upf-ip4-flow-process",
[UPF_SESSION_DPO_NEXT_FLOW_PROCESS] = "upf-nat-test",
},
};

Expand Down

0 comments on commit 5e79eea

Please sign in to comment.