Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-UPF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-UPF
Commits
68b73303
Commit
68b73303
authored
Aug 03, 2021
by
Raphael Defosseux
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'flexcn_traffic_steering' into 'develop'
traffic steering See merge request oai/cn5g/oai-cn5g-upf-vpp!3
parents
72acfc6d
4b855d93
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
704 additions
and
4 deletions
+704
-4
docker/Dockerfile.upf-vpp.rhel7
docker/Dockerfile.upf-vpp.rhel7
+1
-1
docker/Dockerfile.upf-vpp.ubuntu18
docker/Dockerfile.upf-vpp.ubuntu18
+1
-1
docs/BUILD_IMAGE.md
docs/BUILD_IMAGE.md
+2
-2
scripts/patches/forwarding_policy_lbo_for_flexcn.patch
scripts/patches/forwarding_policy_lbo_for_flexcn.patch
+700
-0
No files found.
docker/Dockerfile.upf-vpp.rhel7
View file @
68b73303
...
...
@@ -67,7 +67,7 @@ RUN git clone -b stable/2101 https://github.com/fdio/vpp.git && \
git clone https://github.com/travelping/upg-vpp.git && \
# For the moment let us fix a given commit
cd upg-vpp && \
git checkout -f
4d32e1721c1e9a1bd7ea861658f502a64f9b4073
&& \
git checkout -f
1f047425c5c99db44c2e599ad1dfd767d426cce8
&& \
cd .. && \
mv upg-vpp/upf/ vpp/src/plugins/ && \
mv upg-vpp/vpp-patches/* scripts/patches/ && \
...
...
docker/Dockerfile.upf-vpp.ubuntu18
View file @
68b73303
...
...
@@ -60,7 +60,7 @@ RUN git clone -b stable/2101 https://github.com/fdio/vpp.git && \
git clone https://github.com/travelping/upg-vpp.git && \
# For the moment let us fix a given commit
cd upg-vpp && \
git checkout -f
4d32e1721c1e9a1bd7ea861658f502a64f9b4073
&& \
git checkout -f
1f047425c5c99db44c2e599ad1dfd767d426cce8
&& \
cd .. && \
mv upg-vpp/upf/ vpp/src/plugins/ && \
mv upg-vpp/vpp-patches/* scripts/patches/ && \
...
...
docs/BUILD_IMAGE.md
View file @
68b73303
...
...
@@ -19,7 +19,7 @@ Here in our network configuration, we need to pass the "GIT PROXY" configuration
## 3.1 On a Ubuntu 18.04 Host ##
```
bash
$
docker build
--target
vpp-upg
--tag
vpp-upg:develop
\
$
docker build
--target
oai-upf-vpp
--tag
vpp-upg:develop
\
--file
docker/Dockerfile.upf-vpp.ubuntu18
\
--build-arg
NEEDED_GIT_PROXY
=
"http://proxy.eurecom.fr:8080"
.
```
...
...
@@ -27,7 +27,7 @@ $ docker build --target vpp-upg --tag vpp-upg:develop \
## 3.2 On a RHEL 7 Host ##
```
bash
$
docker build
--target
vpp-upg
--tag
vpp-upg:develop
\
$
docker build
--target
oai-upf-vpp
--tag
vpp-upg:develop
\
--file
docker/Dockerfile.upf-vpp.rhel7
\
--build-arg
NEEDED_GIT_PROXY
=
"http://proxy.eurecom.fr:8080"
.
```
scripts/patches/forwarding_policy_lbo_for_flexcn.patch
0 → 100644
View file @
68b73303
--- a/src/plugins/upf/upf.c 2021-06-09 09:57:56.063303427 +0200
+++ b/src/plugins/upf/upf.c 2021-06-08 23:42:50.517451466 +0200
@@ -48,6 +48,9 @@
#include <vppinfra/tw_timer_1t_3w_1024sl_ov.h>
+#include <vnet/fib/fib_path_list.h>
+#include <vnet/fib/fib_walk.h>
+
static fib_source_t upf_fib_source;
int
@@ -334,6 +337,8 @@
sm->nwi_index_by_name =
hash_create_vec ( /* initial length */ 32, sizeof (u8), sizeof (uword));
mhash_init (&sm->upip_res_index, sizeof (uword), sizeof (upf_upip_res_t));
+ sm->forwarding_policy_by_id =
+ hash_create_vec ( /* initial length */ 32, sizeof (u8), sizeof (uword)); // forwarding policy hash
/* initialize the IP/TEID hash's */
clib_bihash_init_8_8 (&sm->v4_tunnel_by_key,
@@ -433,6 +438,17 @@
return s;
}
+void
+upf_fpath_stack_dpo (upf_forwarding_policy_t * p)
+{
+ dpo_id_t dpo = DPO_INVALID;
+ fib_path_list_contribute_forwarding(p->fib_pl,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ FIB_PATH_LIST_FWD_FLAG_COLLAPSE, &dpo);
+ dpo_stack_from_node (p->forward_index, &p->dpo, &dpo);
+ dpo_reset (&dpo);
+}
+
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () =
{
--- a/src/plugins/upf/upf_cli.c 2021-06-09 09:57:56.063303427 +0200
+++ b/src/plugins/upf/upf_cli.c 2021-06-09 00:07:50.999668963 +0200
@@ -34,6 +34,12 @@
/* Action function shared between message handler and debug CLI */
#include <upf/flowtable.h>
#include <upf/upf_app_db.h>
+#include <vnet/fib/fib_path_list.h>
+#include <vnet/fib/fib_walk.h>
+/**
+ * FIB node type the attachment is registered
+ */
+fib_node_type_t upf_policy_fib_node_type; // The types of nodes in a FIB graph
static clib_error_t *
upf_pfcp_endpoint_ip_add_del_command_fn (vlib_main_t * vm,
@@ -1346,6 +1352,337 @@
};
/* *INDENT-ON* */
+// #################### dpo restacking vft ####################
+static void
+upf_policy_destroy (upf_forwarding_policy_t * fp_entry)
+{
+ upf_main_t *gtm = &upf_main;
+ /*
+ * this upf_fp should not be a sibling on the path list, since
+ * that was removed when the API config went
+ */
+ ASSERT (fp_entry->fib_sibling == ~0);
+ ASSERT (fp_entry->fib_pl == FIB_NODE_INDEX_INVALID);
+
+ hash_unset_mem (gtm->forwarding_policy_by_id, fp_entry->policy_id);
+ pool_put (gtm->upf_forwarding_policies, fp_entry);
+}
+
+static upf_forwarding_policy_t *
+upf_policy_get_from_fib_node (fib_node_t * node)
+{
+ return ((upf_forwarding_policy_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (upf_forwarding_policy_t, fib_node)));
+}
+/**
+ * Function definition to get a FIB node from its index
+ */
+static fib_node_t *
+ upf_policy_fib_node_get (fib_node_index_t index)
+{
+ upf_main_t *gtm = &upf_main;
+ upf_forwarding_policy_t *p;
+
+ p = pool_elt_at_index (gtm->upf_forwarding_policies, index);
+ return (&p->fib_node);
+}
+
+/**
+ * Function definition to inform the FIB node that its last lock has gone.
+ */
+static void
+upf_policy_last_lock_gone (fib_node_t * node)
+{
+ upf_policy_destroy(upf_policy_get_from_fib_node (node));
+}
+
+/**
+ * Function definition to backwalk a FIB node -
+ * Here we will restack the new dpo to forward node.
+ */
+static fib_node_back_walk_rc_t
+upf_policy_back_walk (fib_node_t * node, fib_node_back_walk_ctx_t * ctx)
+{
+ upf_fpath_stack_dpo (upf_policy_get_from_fib_node (node));
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+}
+
+const fib_node_vft_t upf_fp_vft = {
+ .fnv_get = upf_policy_fib_node_get,
+ .fnv_last_lock = upf_policy_last_lock_gone,
+ .fnv_back_walk = upf_policy_back_walk,
+};
+
+static clib_error_t *
+upf_policy_init (vlib_main_t * vm)
+{
+ upf_policy_fib_node_type = fib_node_register_new_type (&upf_fp_vft);
+ return (NULL);
+}
+VLIB_INIT_FUNCTION (upf_policy_init);
+
+// #################### new commands ####################
+
+static u8 *
+format_upf_policy (u8 * s, va_list * args)
+{
+ upf_main_t *gtm = &upf_main;
+ upf_forwarding_policy_t *fp_entry = va_arg (*args, upf_forwarding_policy_t *);
+
+ s = format (s, "upf:[%d]: policy:%v",
+ fp_entry - gtm->upf_forwarding_policies, fp_entry->policy_id);
+ s = format (s, "\n ");
+ if (FIB_NODE_INDEX_INVALID == fp_entry->fib_pl)
+ {
+ s = format (s, "no forwarding");
+ }
+ else
+ {
+ s = fib_path_list_format (fp_entry->fib_pl, s);
+ }
+ return (s);
+}
+
+// Quick show method
+void
+show_policy (vlib_main_t * vm, u8 * policy_id)
+{
+ upf_main_t *gtm = &upf_main;
+ upf_forwarding_policy_t *fp_entry;
+ uword *hash_ptr;
+
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id) ;
+ if (hash_ptr)
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ vlib_cli_output(vm, "%U", format_upf_policy, fp_entry);
+ }
+}
+static void
+fib_path_list_create_and_child_add (upf_forwarding_policy_t * fp_entry, fib_route_path_t *rpaths)
+{
+ upf_main_t *gtm = &upf_main;
+ fp_entry->fib_pl = fib_path_list_create ((FIB_PATH_LIST_FLAG_SHARED |
+ FIB_PATH_LIST_FLAG_NO_URPF), rpaths);
+ // Keep rpath for update path lists later
+ clib_memcpy(fp_entry->rpaths, rpaths, sizeof(fp_entry->rpaths));
+ /*
+ * become a child of the path list so we get poked when
+ * the forwarding changes.
+ */
+ fp_entry->fib_sibling = fib_path_list_child_add(fp_entry->fib_pl,
+ upf_policy_fib_node_type,
+ fp_entry - gtm->upf_forwarding_policies );
+}
+
+static clib_error_t *
+upf_show_policy_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ upf_main_t *gtm = &upf_main;
+ upf_forwarding_policy_t *fp_entry;
+ uword *hash_ptr;
+ u8 *policy_id = NULL;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%_%v%_", &policy_id))
+ ;
+ else
+ return (clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, input));
+ }
+ if (NULL == policy_id)
+ {
+ pool_foreach(fp_entry, gtm->upf_forwarding_policies);
+ }
+ else
+ {
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id) ;
+ if (hash_ptr)
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ vlib_cli_output(vm, "%U", format_upf_policy, fp_entry);
+ }
+ else
+ clib_warning("###### Policy with id %v does not exist ######", policy_id);
+ }
+ return (NULL);
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (upf_show_policy_command, static) =
+{
+ .path = "show upf policy",
+ .short_help = "show upf policy",
+ .function = upf_show_policy_command_fn,
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
+upf_policy_command_fn (vlib_main_t * vm,
+ unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ fib_route_path_t *rpaths = NULL, rpath;
+ upf_main_t *gtm = &upf_main;
+ upf_forwarding_policy_t *fp_entry;
+ dpo_proto_t payload_proto;
+ fib_node_index_t old_pl;
+
+ u8 * policy_id;
+ uword *hash_ptr;
+ u32 is_del = 0;
+
+ if (unformat_user (main_input, unformat_line_input, line_input))
+ {
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat(line_input, "id %_%v%_", &policy_id))
+ ;
+ else if (unformat (line_input, "del"))
+ is_del = 1;
+ else if (unformat (line_input, "add"))
+ is_del = 0;
+ else if (unformat (line_input, "via %U",
+ unformat_fib_route_path, &rpath, &payload_proto))
+ vec_add1 (rpaths, rpath);
+ else
+ return (clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input));
+ }
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id);
+ if (!hash_ptr) // Add policy as not preconfigured previously
+ {
+ if (is_del == 0) // Add policy
+ {
+ pool_get(gtm->upf_forwarding_policies, fp_entry);
+ fib_node_init (&fp_entry->fib_node, upf_policy_fib_node_type);
+ fp_entry->policy_id = policy_id;
+ fp_entry->rpaths = clib_mem_alloc(sizeof(fp_entry->rpaths));
+
+ fib_path_list_create_and_child_add(fp_entry, rpaths);
+ hash_set_mem(gtm->forwarding_policy_by_id, fp_entry->policy_id,
+ fp_entry - gtm->upf_forwarding_policies);
+ upf_fpath_stack_dpo (fp_entry);
+ fib_node_lock (&fp_entry->fib_node);
+ clib_warning("###### Policy created ######");
+ show_policy(vm, policy_id);
+ }
+ else
+ clib_warning("###### Policy doesn't exist ######");
+ }
+ else // Delete policy as preconfigured previously
+ {
+ if (is_del != 0) // Delete policy
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ if (fp_entry->ref_cnt!=0)
+ {
+ clib_warning("###### Policy %v can not be removed as it is referred by %d FARs ######", policy_id, fp_entry->ref_cnt);
+ }
+ else
+ {
+ old_pl = fp_entry->fib_pl;
+ fib_path_list_lock (old_pl);
+ fp_entry->fib_pl = fib_path_list_copy_and_path_remove (fp_entry->fib_pl,
+ (FIB_PATH_LIST_FLAG_SHARED |
+ FIB_PATH_LIST_FLAG_NO_URPF), rpaths);
+ fib_path_list_child_remove (old_pl, fp_entry->fib_sibling);
+ fp_entry->fib_sibling = ~0;
+ fib_node_unlock (&fp_entry->fib_node);
+ clib_mem_free(fp_entry->rpaths);
+ fib_path_list_unlock (old_pl);
+
+ clib_warning("###### Fpath list removed ######");
+ show_policy(vm, policy_id);
+ clib_warning("###### Policy removed ######");
+ }
+ }
+ else
+ clib_warning("###### Policy already exist ######");
+ }
+ }
+ unformat_free (line_input);
+ return (NULL);
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (upf_add_policy_command, static) =
+{
+ .path = "upf policy",
+ .short_help = "upf policy [add|del] id <policy_id> via <next_hop> <interface>",
+ .function = upf_policy_command_fn,
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
+upf_update_policy_command_fn (vlib_main_t * vm,
+ unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ upf_main_t *gtm = &upf_main;
+ fib_route_path_t *rpaths = NULL, rpath;
+ dpo_proto_t payload_proto;
+ upf_forwarding_policy_t *fp_entry;
+ fib_node_index_t old_pl;
+
+ u8 * policy_id;
+ uword *hash_ptr;
+
+ if (unformat_user (main_input, unformat_line_input, line_input))
+ {
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat(line_input, "id %_%v%_", &policy_id))
+ ;
+ else if (unformat (line_input, "via %U",
+ unformat_fib_route_path, &rpath, &payload_proto))
+ vec_add1 (rpaths, rpath);
+ else
+ return (clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input));
+ }
+
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id);
+ if (hash_ptr)
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ old_pl = fp_entry->fib_pl;
+ fib_path_list_lock (old_pl);
+ fp_entry->fib_pl = fib_path_list_copy_and_path_remove (fp_entry->fib_pl,
+ (FIB_PATH_LIST_FLAG_SHARED |
+ FIB_PATH_LIST_FLAG_NO_URPF), fp_entry->rpaths);
+ fib_path_list_child_remove (old_pl, fp_entry->fib_sibling);
+ fp_entry->fib_sibling = ~0;
+ fib_path_list_unlock (old_pl);
+ clib_warning("###### Old fpath list removed ######");
+
+ fib_path_list_create_and_child_add(fp_entry, rpaths);
+ hash_set_mem(gtm->forwarding_policy_by_id, fp_entry->policy_id,
+ fp_entry - gtm->upf_forwarding_policies);
+ upf_fpath_stack_dpo(fp_entry);
+ show_policy(vm, policy_id);
+ clib_warning("###### Policy updated ######");
+ }
+ else
+ clib_warning("###### Policy doesn't exist ######");
+ }
+ unformat_free (line_input);
+ return (NULL);
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (upf_update_policy_command, static) =
+{
+ .path = "upf policy update",
+ .short_help = "upf policy update id <policy_id> via <next_hop> <interface>",
+ .function = upf_update_policy_command_fn,
+};
+
/*
* fd.io coding-style-patch-verification: ON
*
--- a/src/plugins/upf/upf_forward.c 2021-06-09 09:57:56.063303427 +0200
+++ b/src/plugins/upf/upf_forward.c 2021-06-09 00:14:24.430311474 +0200
@@ -30,6 +30,8 @@
#include <upf/upf_pfcp.h>
#include <upf/upf_proxy.h>
+#include <vnet/fib/fib_path_list.h>
+
#if CLIB_DEBUG > 1
#define upf_debug clib_warning
#else
@@ -105,6 +107,8 @@
u32 len;
struct rules *active;
+ upf_forwarding_policy_t *fp_entry;
+
next_index = node->cached_next_index;
stats_sw_if_index = node->runtime_data[0];
stats_n_packets = stats_n_bytes = 0;
@@ -194,6 +198,17 @@
goto trace;
}
}
+ else if (far->forward.flags & FAR_F_FORWARDING_POLICY) // forwarding policy check
+ {
+ b->flags &= ~(VNET_BUFFER_F_OFFLOAD_TCP_CKSUM |
+ VNET_BUFFER_F_OFFLOAD_UDP_CKSUM |
+ VNET_BUFFER_F_OFFLOAD_IP_CKSUM);
+ // Getting dpio_index
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, far->forward.fp_pool_index);
+ vnet_buffer (b)->ip.adj_index[VLIB_TX] = fp_entry->dpo.dpoi_index;
+ next = UPF_FORWARD_NEXT_IP_REWRITE;
+ clib_warning("###### Forwarding policy with id %v is applied ######", far->forward.forwarding_policy.identifier);
+ }
else
{
if (is_ip4)
@@ -319,7 +334,8 @@
[UPF_FORWARD_NEXT_DROP] = "error-drop",
[UPF_FORWARD_NEXT_GTP_IP4_ENCAP] = "upf4-encap",
[UPF_FORWARD_NEXT_GTP_IP6_ENCAP] = "upf6-encap",
- [UPF_FORWARD_NEXT_IP_INPUT] = "ip4-input"
+ [UPF_FORWARD_NEXT_IP_INPUT] = "ip4-input",
+ [UPF_FORWARD_NEXT_IP_REWRITE] = "ip4-rewrite"
},
};
/* *INDENT-ON* */
@@ -337,7 +353,8 @@
[UPF_FORWARD_NEXT_DROP] = "error-drop",
[UPF_FORWARD_NEXT_GTP_IP4_ENCAP] = "upf4-encap",
[UPF_FORWARD_NEXT_GTP_IP6_ENCAP] = "upf6-encap",
- [UPF_FORWARD_NEXT_IP_INPUT] = "ip6-input"
+ [UPF_FORWARD_NEXT_IP_INPUT] = "ip6-input",
+ [UPF_FORWARD_NEXT_IP_REWRITE] = "ip6-rewrite",
},
};
/* *INDENT-ON* */
--- a/src/plugins/upf/upf.h 2021-06-09 09:58:07.743494454 +0200
+++ b/src/plugins/upf/upf.h 2021-06-09 00:11:42.043580712 +0200
@@ -431,6 +431,7 @@
u16 flags;
#define FAR_F_REDIRECT_INFORMATION BIT(0)
#define FAR_F_OUTER_HEADER_CREATION BIT(1)
+#define FAR_F_FORWARDING_POLICY BIT(2) // forwarding policy bit
pfcp_destination_interface_t dst_intf;
u32 dst_sw_if_index;
@@ -438,11 +439,52 @@
pfcp_redirect_information_t redirect_information;
pfcp_outer_header_creation_t outer_header_creation;
+ pfcp_forwarding_policy_t forwarding_policy; // forwarding policy struct init
+ uword fp_pool_index;
u32 peer_idx;
u8 *rewrite;
} upf_far_forward_t;
+/*Forwarding policy table*/
+typedef struct
+{
+ /**
+ * Counter for FAR reference
+ */
+ uword ref_cnt;
+ /**
+ * Linkage into the FIB graph
+ */
+ fib_node_t fib_node;
+ /**
+ * The path-list describing how to forward in case of a match
+ */
+ fib_node_index_t fib_pl;
+ /**
+ * Sibling index on the path-list
+ */
+ u32 fib_sibling;
+ /**
+ * The forwarding policy ID - as configured by the client
+ */
+ u8 * policy_id;
+ /**
+ * The Data-path objects through which this path resolves for IP.
+ */
+ dpo_id_t dpo;
+ /**
+ * A representation of a path as described by a route producer.
+ * We maintain this path as we need to remove old path while policy update
+ */
+ fib_route_path_t *rpaths;
+ /**
+ * Next node index (ip4-rewrite here)
+ *
+ */
+ u32 forward_index;
+} upf_forwarding_policy_t;
+
/* Forward Action Rules */
typedef struct
{
@@ -816,6 +858,9 @@
upf_nwi_t *nwis;
uword *nwi_index_by_name;
+ upf_forwarding_policy_t *upf_forwarding_policies;
+ uword *forwarding_policy_by_id;
+
/* Free vlib hw_if_indices */
u32 *free_nwi_hw_if_indices;
@@ -888,12 +933,15 @@
} upf_main_t;
extern const fib_node_vft_t upf_vft;
+extern const fib_node_vft_t upf_fp_vft;
extern upf_main_t upf_main;
extern vlib_node_registration_t upf_gtpu4_input_node;
extern vlib_node_registration_t upf_gtpu6_input_node;
extern vlib_node_registration_t upf4_encap_node;
extern vlib_node_registration_t upf6_encap_node;
+extern vlib_node_registration_t upf_ip4_forward_node;
+extern vlib_node_registration_t upf_ip6_forward_node;
typedef enum
{
@@ -901,6 +949,7 @@
UPF_FORWARD_NEXT_GTP_IP4_ENCAP,
UPF_FORWARD_NEXT_GTP_IP6_ENCAP,
UPF_FORWARD_NEXT_IP_INPUT,
+ UPF_FORWARD_NEXT_IP_REWRITE,
UPF_FORWARD_N_NEXT,
} upf_forward_next_t;
@@ -948,6 +997,8 @@
void upf_proxy_init (vlib_main_t * vm);
+void upf_fpath_stack_dpo (upf_forwarding_policy_t * p);
+
#endif /* __included_upf_h__ */
/*
--- a/src/plugins/upf/upf_pfcp_api.c 2021-06-09 09:57:56.063303427 +0200
+++ b/src/plugins/upf/upf_pfcp_api.c 2021-06-09 00:27:38.031691029 +0200
@@ -45,6 +45,8 @@
#include "upf_app_db.h"
#include "upf_ipfilter.h"
+#include <vnet/fib/fib_path_list.h>
+
#if CLIB_DEBUG > 1
#define upf_debug clib_warning
#else
@@ -1301,6 +1303,10 @@
pfcp_create_far_t *far;
struct rules *rules;
+ u8 *policy_id = NULL;
+ uword *hash_ptr;
+ upf_forwarding_policy_t *fp_entry;
+
if (pfcp_make_pending_far (sx) != 0)
{
tp_session_error_report (response, "no resources available");
@@ -1390,9 +1396,34 @@
ip_udp_gtpu_rewrite (&create->forward, fib_index, is_ip4);
}
- //TODO: transport_level_marking
- //TODO: forwarding_policy
- //TODO: header_enrichment
+// TODO: transport_level_marking
+// forwarding_policy >> oln: Implementation
+ if (ISSET_BIT (far->forwarding_parameters.grp.fields,
+ FORWARDING_PARAMETERS_FORWARDING_POLICY))
+ {
+ policy_id = far->forwarding_parameters.forwarding_policy.identifier;
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id);
+ if (hash_ptr) // validate if policy is preconfigured
+ {
+ if (rules->pdr->pdi.src_intf == SRC_INTF_ACCESS) // validate if source interface is access
+ { // set forwarding policy identifier
+ create->forward.flags |= FAR_F_FORWARDING_POLICY;
+ create->forward.forwarding_policy.identifier = far->forwarding_parameters.forwarding_policy.identifier;
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ create->forward.fp_pool_index = hash_ptr[0];
+ fp_entry->ref_cnt++;
+ }
+ else
+ {
+ clib_warning("###### Forwarding policy can not be applied as source interface is not Access ######");
+ }
+ }
+ else
+ {
+ clib_warning("###### Forwarding policy id %v is not preconfigured at UPF ######", far->forwarding_parameters.forwarding_policy.identifier);
+ create->forward.fp_pool_index = ~0;
+ }
+ } //TODO: header_enrichment
}
}
@@ -1415,6 +1446,11 @@
upf_main_t *gtm = &upf_main;
pfcp_update_far_t *far;
+ u8 *policy_id = NULL;
+ uword *hash_ptr;
+ upf_forwarding_policy_t *fp_entry;
+
+
if (pfcp_make_pending_far (sx) != 0)
{
tp_session_error_report (response, "no resources available");
@@ -1517,7 +1553,35 @@
ip_udp_gtpu_rewrite (&update->forward, fib_index, is_ip4);
}
//TODO: transport_level_marking
- //TODO: forwarding_policy
+ //forwarding_policy >> oln: Implementation
+ if (ISSET_BIT (far->update_forwarding_parameters.grp.fields,
+ UPDATE_FORWARDING_PARAMETERS_FORWARDING_POLICY))
+ {
+ policy_id = far->update_forwarding_parameters.forwarding_policy.identifier;
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id);
+ if (hash_ptr)
+ {
+ if(update->forward.fp_pool_index!= ~0) // old policy is preconfigured
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, update->forward.fp_pool_index); // old policy
+ fp_entry->ref_cnt--; // decrement FAR reference counter in old policy table
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]); // new policy
+ update->forward.forwarding_policy.identifier = far->update_forwarding_parameters.forwarding_policy.identifier;
+ update->forward.fp_pool_index = hash_ptr[0]; // update with new pool index
+ fp_entry->ref_cnt++; // increment FAR reference counter in new policy table
+ }
+ else // old policy was not preconfigured somehow but we still update to new policy
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]); // new policy
+ update->forward.flags |= FAR_F_FORWARDING_POLICY;
+ update->forward.forwarding_policy.identifier = far->update_forwarding_parameters.forwarding_policy.identifier;
+ update->forward.fp_pool_index = hash_ptr[0]; // set pool index
+ fp_entry->ref_cnt++; // increment FAR reference counter in new policy table
+ }
+ }
+ else
+ clib_warning("###### Forwarding policy id %v is not preconfigured at UPF ######", far->update_forwarding_parameters.forwarding_policy.identifier);
+ }
//TODO: header_enrichment
}
}
@@ -2566,6 +2630,12 @@
upf_session_t *sess;
int r = 0;
+ upf_main_t *gtm = &upf_main;
+ upf_far_t *far;
+ upf_forwarding_policy_t *fp_entry;
+ u8 *policy_id = NULL;
+ uword *hash_ptr;
+
memset (resp, 0, sizeof (*resp));
SET_BIT (resp->grp.fields, SESSION_PROCEDURE_RESPONSE_CAUSE);
resp->cause = PFCP_CAUSE_REQUEST_REJECTED;
@@ -2606,6 +2676,16 @@
out_send_resp:
if (r == 0)
{
+ vec_foreach (far, active->far)
+ {
+ policy_id = active->far->forward.forwarding_policy.identifier;
+ hash_ptr = hash_get_mem (gtm->forwarding_policy_by_id, policy_id);
+ if (hash_ptr)
+ {
+ fp_entry = pool_elt_at_index (gtm->upf_forwarding_policies, hash_ptr[0]);
+ fp_entry->ref_cnt--; // dec ref_cnt for forwarding policy
+ }
+ }
pfcp_free_session (sess);
resp->cause = PFCP_CAUSE_REQUEST_ACCEPTED;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment