Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CENNSO-617][wip] Don't allow UE-UE access #323

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
[wip] Don't allow UE-UE access
  • Loading branch information
Sergey Matov committed Mar 27, 2023
commit eaa8cda558068e6aa964cf918ddc02dbfe609b4b
31 changes: 31 additions & 0 deletions test/e2e/upg_e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,37 @@ var _ = ginkgo.Describe("UPG Binary API", func() {
})
})

var _ = ginkgo.Describe("Accessing SGi interface", func() {
ginkgo.Context("from UE", func() {
f := framework.NewDefaultFramework(framework.UPGModeTDF, framework.UPGIPModeV4)
ginkgo.It("ping should be ignored", func() {
sessionCfg := &framework.SessionConfig{
IdBase: 1,
UEIP: f.UEIP(),
Mode: f.Mode,
}
anotherSessionCfg := &framework.SessionConfig{
IdBase: 2,
UEIP: net.ParseIP("10.0.1.2"),
Mode: f.Mode,
}
_, err := f.PFCP.EstablishSession(f.Context, 0, sessionCfg.SessionIEs()...)
framework.ExpectNoError(err)
_, err = f.PFCP.EstablishSession(f.Context, 0, anotherSessionCfg.SessionIEs()...)
framework.ExpectNoError(err)
tg, clientNS, serverNS := newTrafficGen(f, &traffic.ICMPPingConfig{
//ServerIP: sgiAddress,
ServerIP: net.ParseIP("10.0.1.2"),
PacketCount: 10, // 10s
Retry: true,
Delay: 100 * time.Millisecond,
}, &traffic.SimpleTrafficRec{})
tg.Start(f.Context, clientNS, serverNS)
// Expect no crash here
})
})
})

var _ = ginkgo.Describe("Clearing message queue", func() {
ginkgo.Context("during session deletion", func() {
f := framework.NewDefaultFramework(framework.UPGModeTDF, framework.UPGIPModeV4)
Expand Down
24 changes: 1 addition & 23 deletions upf/upf.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,38 +78,16 @@ STATIC_ASSERT (sizeof (upf_buffer_opaque_t) <=
((upf_buffer_opaque_t *)((u8 *)((b)->opaque2) + \
STRUCT_OFFSET_OF (vnet_buffer_opaque_t, unused)))

#if CLIB_DEBUG > 0

/*
* For debug builds, we add a flag to each buffer when we initialize
* GTPU metadata when the buffer is processed by one of the UPF
* entry nodes (upf-gtpu[46]-input, upf-ip[46]-session-dpo,
* upf-ip[46]-proxy-server-output)
*/
#define UPF_BUFFER_F_GTPU_INITIALIZED VNET_BUFFER_F_AVAIL1
#define UPF_ENTER_SUBGRAPH(b, sidx, is_ip4) \
do { \
ASSERT (!((b)->flags & UPF_BUFFER_F_GTPU_INITIALIZED)); \
clib_memset(upf_buffer_opaque (b), 0, sizeof(upf_buffer_opaque_t)); \
b->flags |= UPF_BUFFER_F_GTPU_INITIALIZED; \
upf_buffer_opaque (b)->gtpu.session_index = sidx; \
upf_buffer_opaque (b)->gtpu.flags = \
is_ip4 ? BUFFER_GTP_UDP_IP4 : BUFFER_GTP_UDP_IP6; \
} while (0)
#define UPF_CHECK_INNER_NODE(b) ASSERT (b->flags & UPF_BUFFER_F_GTPU_INITIALIZED)

#else

#define UPF_ENTER_SUBGRAPH(b, sidx, is_ip4) \
do { \
clib_memset(upf_buffer_opaque (b), 0, sizeof(upf_buffer_opaque_t)); \
upf_buffer_opaque (b)->gtpu.session_index = sidx; \
upf_buffer_opaque (b)->gtpu.flags = \
is_ip4 ? BUFFER_GTP_UDP_IP4 : BUFFER_GTP_UDP_IP6; \
} while (0)
#define UPF_CHECK_INNER_NODE(b)

#endif
#define UPF_CHECK_INNER_NODE(b) (b->flags & UPF_BUFFER_F_GTPU_INITIALIZED)

#define BUFFER_FAR_ONLY (1<<3) /* don't include in QER/URR processing */
#define BUFFER_HAS_GTP_HDR (1<<4)
Expand Down
31 changes: 29 additions & 2 deletions upf/upf_session_dpo.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,9 @@ VLIB_INIT_FUNCTION (upf_session_dpo_module_init);
#endif /* CLIB_MARCH_VARIANT */

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

static char *upf_session_dpo_error_strings[] = {
Expand Down Expand Up @@ -423,6 +424,19 @@ VLIB_NODE_FN (upf_ip4_session_dpo_node) (vlib_main_t * vm,
goto trace;
}

/* Traffic hits UPF Subgraph for second time. This might happen if
* packet was originated from UE to another UE or local SGi interface
* and hit DPO of SGi table. By security reasons this is not allowed.
*/
if (UPF_CHECK_INNER_NODE (b))
{
upf_debug ("UPF Subgraph re-entered: %U", format_ip4_header,
ip0, b->current_length);
error0 = UPF_SESSION_DPO_ERROR_SUBGRAPH_ENTRY;
next = UPF_SESSION_DPO_NEXT_DROP;
goto trace;
}

UPF_ENTER_SUBGRAPH (b, sidx, 1);
error0 = IP4_ERROR_NONE;
next = UPF_SESSION_DPO_NEXT_FLOW_PROCESS;
Expand Down Expand Up @@ -556,6 +570,19 @@ VLIB_NODE_FN (upf_ip6_session_dpo_node) (vlib_main_t * vm,
goto trace;
}

/* Traffic hits UPF Subgraph for second time. This might happen if
* packet was originated from UE to another UE or local SGi interface
* and hit DPO of SGi table. By security reasons this is not allowed.
*/
if (UPF_CHECK_INNER_NODE (b))
{
upf_debug ("UPF Subgraph re-entered: %U", format_ip4_header,
ip0, b->current_length);
error0 = UPF_SESSION_DPO_ERROR_SUBGRAPH_ENTRY;
next = UPF_SESSION_DPO_NEXT_DROP;
goto trace;
}

UPF_ENTER_SUBGRAPH (b, sidx, 0);
error0 = IP6_ERROR_NONE;
next = UPF_SESSION_DPO_NEXT_FLOW_PROCESS;
Expand Down