forked from acouzens/open5gs
[UPF] Handle framed routes
This commit is contained in:
parent
3e980e006f
commit
990abbab2c
|
@ -1004,6 +1004,8 @@ void ogs_pfcp_pdr_associate_qer(ogs_pfcp_pdr_t *pdr, ogs_pfcp_qer_t *qer)
|
|||
|
||||
void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr)
|
||||
{
|
||||
int i;
|
||||
|
||||
ogs_assert(pdr);
|
||||
ogs_assert(pdr->sess);
|
||||
|
||||
|
@ -1033,6 +1035,24 @@ void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr)
|
|||
if (pdr->id_node)
|
||||
ogs_pool_free(&pdr->sess->pdr_id_pool, pdr->id_node);
|
||||
|
||||
if (pdr->ipv4_framed_routes) {
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!pdr->ipv4_framed_routes[i])
|
||||
break;
|
||||
ogs_free(pdr->ipv4_framed_routes[i]);
|
||||
}
|
||||
ogs_free(pdr->ipv4_framed_routes);
|
||||
}
|
||||
|
||||
if (pdr->ipv6_framed_routes) {
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!pdr->ipv6_framed_routes[i])
|
||||
break;
|
||||
ogs_free(pdr->ipv6_framed_routes[i]);
|
||||
}
|
||||
ogs_free(pdr->ipv6_framed_routes);
|
||||
}
|
||||
|
||||
ogs_pool_free(&ogs_pfcp_pdr_pool, pdr);
|
||||
}
|
||||
|
||||
|
|
|
@ -160,6 +160,9 @@ typedef struct ogs_pfcp_pdr_s {
|
|||
ogs_pfcp_ue_ip_addr_t ue_ip_addr;
|
||||
int ue_ip_addr_len;
|
||||
|
||||
char **ipv4_framed_routes;
|
||||
char **ipv6_framed_routes;
|
||||
|
||||
ogs_pfcp_f_teid_t f_teid;
|
||||
int f_teid_len;
|
||||
|
||||
|
|
|
@ -478,6 +478,58 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
|
|||
pdr->ue_ip_addr_len);
|
||||
}
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!pdr->ipv4_framed_routes || !pdr->ipv4_framed_routes[i])
|
||||
break;
|
||||
ogs_free(pdr->ipv4_framed_routes[i]);
|
||||
pdr->ipv4_framed_routes[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!pdr->ipv6_framed_routes || !pdr->ipv6_framed_routes[i])
|
||||
break;
|
||||
ogs_free(pdr->ipv6_framed_routes[i]);
|
||||
pdr->ipv6_framed_routes[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
char *route;
|
||||
|
||||
if (!message->pdi.framed_route[i].presence)
|
||||
break;
|
||||
|
||||
if (!pdr->ipv4_framed_routes) {
|
||||
pdr->ipv4_framed_routes = ogs_calloc(
|
||||
OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI, sizeof(pdr->ipv4_framed_routes[0]));
|
||||
ogs_assert(pdr->ipv4_framed_routes);
|
||||
}
|
||||
route = ogs_malloc(message->pdi.framed_route[i].len + 1);
|
||||
ogs_assert(route);
|
||||
memcpy(route, message->pdi.framed_route[i].data,
|
||||
message->pdi.framed_route[i].len);
|
||||
route[message->pdi.framed_route[i].len] = '\0';
|
||||
pdr->ipv4_framed_routes[i] = route;
|
||||
}
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
char *route;
|
||||
|
||||
if (!message->pdi.framed_ipv6_route[i].presence)
|
||||
break;
|
||||
|
||||
if (!pdr->ipv6_framed_routes) {
|
||||
pdr->ipv6_framed_routes = ogs_calloc(
|
||||
OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI, sizeof(ogs_ipsubnet_t));
|
||||
ogs_assert(pdr->ipv6_framed_routes);
|
||||
}
|
||||
route = ogs_malloc(message->pdi.framed_ipv6_route[i].len + 1);
|
||||
ogs_assert(route);
|
||||
memcpy(route, message->pdi.framed_ipv6_route[i].data,
|
||||
message->pdi.framed_ipv6_route[i].len);
|
||||
route[message->pdi.framed_ipv6_route[i].len] = '\0';
|
||||
pdr->ipv6_framed_routes[i] = route;
|
||||
}
|
||||
|
||||
memset(&pdr->outer_header_removal, 0, sizeof(pdr->outer_header_removal));
|
||||
pdr->outer_header_removal_len = 0;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ void upf_context_init(void)
|
|||
ogs_pfcp_self()->up_function_features.empu = 1;
|
||||
ogs_pfcp_self()->up_function_features.mnop = 1;
|
||||
ogs_pfcp_self()->up_function_features.vtime = 1;
|
||||
ogs_pfcp_self()->up_function_features.frrt = 1;
|
||||
ogs_pfcp_self()->up_function_features_len = 4;
|
||||
|
||||
ogs_list_init(&self.sess_list);
|
||||
|
@ -61,6 +62,15 @@ void upf_context_init(void)
|
|||
context_initialized = 1;
|
||||
}
|
||||
|
||||
static void free_upf_route_trie_node(struct upf_route_trie_node *node)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
free_upf_route_trie_node(node->left);
|
||||
free_upf_route_trie_node(node->right);
|
||||
ogs_free(node);
|
||||
}
|
||||
|
||||
void upf_context_final(void)
|
||||
{
|
||||
ogs_assert(context_initialized == 1);
|
||||
|
@ -76,6 +86,9 @@ void upf_context_final(void)
|
|||
ogs_assert(self.ipv6_hash);
|
||||
ogs_hash_destroy(self.ipv6_hash);
|
||||
|
||||
free_upf_route_trie_node(self.ipv4_framed_routes);
|
||||
free_upf_route_trie_node(self.ipv6_framed_routes);
|
||||
|
||||
ogs_pool_final(&upf_sess_pool);
|
||||
|
||||
context_initialized = 0;
|
||||
|
@ -208,6 +221,9 @@ int upf_sess_remove(upf_sess_t *sess)
|
|||
ogs_pfcp_ue_ip_free(sess->ipv6);
|
||||
}
|
||||
|
||||
upf_sess_set_ue_ipv4_framed_routes(sess, NULL);
|
||||
upf_sess_set_ue_ipv6_framed_routes(sess, NULL);
|
||||
|
||||
ogs_pfcp_pool_final(&sess->pfcp);
|
||||
|
||||
ogs_pool_free(&upf_sess_pool, sess);
|
||||
|
@ -259,16 +275,66 @@ upf_sess_t *upf_sess_find_by_upf_n4_seid(uint64_t seid)
|
|||
|
||||
upf_sess_t *upf_sess_find_by_ipv4(uint32_t addr)
|
||||
{
|
||||
upf_sess_t *ret;
|
||||
struct upf_route_trie_node *trie = self.ipv4_framed_routes;
|
||||
const int nbits = sizeof(addr) << 3;
|
||||
int i;
|
||||
|
||||
ogs_assert(self.ipv4_hash);
|
||||
return (upf_sess_t *)ogs_hash_get(self.ipv4_hash, &addr, OGS_IPV4_LEN);
|
||||
|
||||
ret = ogs_hash_get(self.ipv4_hash, &addr, OGS_IPV4_LEN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i <= nbits; i++) {
|
||||
int bit = nbits - i - 1;
|
||||
|
||||
if (!trie)
|
||||
break;
|
||||
if (trie->sess)
|
||||
ret = trie->sess;
|
||||
if (i == nbits)
|
||||
break;
|
||||
|
||||
if ((1 << bit) & be32toh(addr))
|
||||
trie = trie->right;
|
||||
else
|
||||
trie = trie->left;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
upf_sess_t *upf_sess_find_by_ipv6(uint32_t *addr6)
|
||||
{
|
||||
upf_sess_t *ret = NULL;
|
||||
struct upf_route_trie_node *trie = self.ipv6_framed_routes;
|
||||
int i;
|
||||
const int chunk_size = sizeof(*addr6) << 3;
|
||||
|
||||
ogs_assert(self.ipv6_hash);
|
||||
ogs_assert(addr6);
|
||||
return (upf_sess_t *)ogs_hash_get(
|
||||
ret = ogs_hash_get(
|
||||
self.ipv6_hash, addr6, OGS_IPV6_DEFAULT_PREFIX_LEN >> 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i <= OGS_IPV6_128_PREFIX_LEN; i++) {
|
||||
int part = i / chunk_size;
|
||||
int bit = (OGS_IPV6_128_PREFIX_LEN - i - 1) % chunk_size;
|
||||
|
||||
if (!trie)
|
||||
break;
|
||||
if (trie->sess)
|
||||
ret = trie->sess;
|
||||
if (i == OGS_IPV6_128_PREFIX_LEN)
|
||||
break;
|
||||
|
||||
if ((1 << bit) & be32toh(addr6[part]))
|
||||
trie = trie->right;
|
||||
else
|
||||
trie = trie->left;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message)
|
||||
|
@ -408,6 +474,184 @@ uint8_t upf_sess_set_ue_ip(upf_sess_t *sess,
|
|||
return cause_value;
|
||||
}
|
||||
|
||||
/* Remove amd free framed ROUTE from TRIE. It isn't an error if the framed
|
||||
route doesn't exist in TRIE. */
|
||||
static void free_framed_route_from_trie(ogs_ipsubnet_t *route)
|
||||
{
|
||||
const int chunk_size = sizeof(route->sub[0]) << 3;
|
||||
const int is_ipv4 = route->family == AF_INET;
|
||||
const int nbits = is_ipv4 ? chunk_size : OGS_IPV6_128_PREFIX_LEN;
|
||||
struct upf_route_trie_node **trie =
|
||||
is_ipv4 ? &self.ipv4_framed_routes : &self.ipv6_framed_routes;
|
||||
|
||||
struct upf_route_trie_node **to_free_tries[OGS_IPV6_128_PREFIX_LEN + 1];
|
||||
int free_from = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i <= nbits; i++) {
|
||||
int part = i / chunk_size;
|
||||
int bit = (nbits - i - 1) % chunk_size;
|
||||
|
||||
if (!*trie)
|
||||
break;
|
||||
to_free_tries[i] = trie;
|
||||
|
||||
if (i == nbits ||
|
||||
((1 << bit) & be32toh(route->mask[part])) == 0) {
|
||||
(*trie)->sess = NULL;
|
||||
if ((*trie)->left || (*trie)->right)
|
||||
free_from = i + 1;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((1 << bit) & be32toh(route->sub[part])) {
|
||||
if ((*trie)->left || (*trie)->sess)
|
||||
free_from = i + 1;
|
||||
trie = &(*trie)->right;
|
||||
} else {
|
||||
if ((*trie)->right || (*trie)->sess)
|
||||
free_from = i + 1;
|
||||
trie = &(*trie)->left;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = i - 1; i >= free_from; i--) {
|
||||
trie = to_free_tries[i];
|
||||
ogs_free(*trie);
|
||||
*trie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_framed_route_to_trie(ogs_ipsubnet_t *route, upf_sess_t *sess)
|
||||
{
|
||||
const int chunk_size = sizeof(route->sub[0]) << 3;
|
||||
const int is_ipv4 = route->family == AF_INET;
|
||||
const int nbits = is_ipv4 ? chunk_size : OGS_IPV6_128_PREFIX_LEN;
|
||||
struct upf_route_trie_node **trie =
|
||||
is_ipv4 ? &self.ipv4_framed_routes : &self.ipv6_framed_routes;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i <= nbits; i++) {
|
||||
int part = i / chunk_size;
|
||||
int bit = (- i - 1) % chunk_size;
|
||||
|
||||
if (!*trie)
|
||||
*trie = ogs_calloc(1, sizeof(**trie));
|
||||
|
||||
if (i == nbits ||
|
||||
((1 << bit) & be32toh(route->mask[part])) == 0) {
|
||||
(*trie)->sess = sess;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((1 << bit) & be32toh(route->sub[part])) {
|
||||
trie = &(*trie)->right;
|
||||
} else {
|
||||
trie = &(*trie)->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_framed_route(ogs_ipsubnet_t *subnet, const char *framed_route)
|
||||
{
|
||||
char *mask = ogs_strdup(framed_route);
|
||||
char *addr = strsep(&mask, "/");
|
||||
int rv;
|
||||
|
||||
rv = ogs_ipsubnet(subnet, addr, mask);
|
||||
ogs_free(addr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t upf_sess_set_ue_ipv4_framed_routes(upf_sess_t *sess,
|
||||
char *framed_routes[])
|
||||
{
|
||||
int i = 0, j = 0, rv;
|
||||
uint8_t cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!sess->ipv4_framed_routes || !sess->ipv4_framed_routes[i].family)
|
||||
break;
|
||||
free_framed_route_from_trie(&sess->ipv4_framed_routes[i]);
|
||||
memset(&sess->ipv4_framed_routes[i], 0,
|
||||
sizeof(sess->ipv4_framed_routes[i]));
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!framed_routes || !framed_routes[i])
|
||||
break;
|
||||
|
||||
if (sess->ipv4_framed_routes == NULL) {
|
||||
sess->ipv4_framed_routes = ogs_calloc(
|
||||
OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI, sizeof(ogs_ipsubnet_t));
|
||||
ogs_assert(sess->ipv4_framed_routes);
|
||||
}
|
||||
|
||||
rv = parse_framed_route(&sess->ipv4_framed_routes[j], framed_routes[i]);
|
||||
|
||||
if (rv != OGS_OK) {
|
||||
ogs_warn("Ignoring invalid framed route %s", framed_routes[i]);
|
||||
memset(&sess->ipv4_framed_routes[j], 0,
|
||||
sizeof(sess->ipv4_framed_routes[j]));
|
||||
continue;
|
||||
}
|
||||
add_framed_route_to_trie(&sess->ipv4_framed_routes[j], sess);
|
||||
j++;
|
||||
}
|
||||
if (j == 0 && sess->ipv4_framed_routes) {
|
||||
ogs_free(sess->ipv4_framed_routes);
|
||||
sess->ipv4_framed_routes = NULL;
|
||||
}
|
||||
|
||||
return cause_value;
|
||||
}
|
||||
|
||||
uint8_t upf_sess_set_ue_ipv6_framed_routes(upf_sess_t *sess,
|
||||
char *framed_routes[])
|
||||
{
|
||||
int i = 0, j = 0, rv;
|
||||
uint8_t cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!sess->ipv6_framed_routes || !sess->ipv6_framed_routes[i].family)
|
||||
break;
|
||||
free_framed_route_from_trie(&sess->ipv6_framed_routes[i]);
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
if (!framed_routes || !framed_routes[i])
|
||||
break;
|
||||
|
||||
if (sess->ipv6_framed_routes == NULL) {
|
||||
sess->ipv6_framed_routes = ogs_calloc(
|
||||
OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI, sizeof(ogs_ipsubnet_t));
|
||||
ogs_assert(sess->ipv6_framed_routes);
|
||||
}
|
||||
|
||||
rv = parse_framed_route(&sess->ipv6_framed_routes[j], framed_routes[i]);
|
||||
|
||||
if (rv != OGS_OK) {
|
||||
ogs_warn("Ignoring invalid framed route %s", framed_routes[i]);
|
||||
memset(&sess->ipv6_framed_routes[j], 0,
|
||||
sizeof(sess->ipv6_framed_routes[j]));
|
||||
continue;
|
||||
}
|
||||
add_framed_route_to_trie(&sess->ipv6_framed_routes[j], sess);
|
||||
j++;
|
||||
}
|
||||
if (j == 0 && sess->ipv6_framed_routes) {
|
||||
ogs_free(sess->ipv6_framed_routes);
|
||||
sess->ipv6_framed_routes = NULL;
|
||||
}
|
||||
|
||||
return cause_value;
|
||||
}
|
||||
|
||||
void upf_sess_urr_acc_add(upf_sess_t *sess, ogs_pfcp_urr_t *urr, size_t size, bool is_uplink)
|
||||
{
|
||||
upf_sess_urr_acc_t *urr_acc = &sess->urr_acc[urr->id];
|
||||
|
|
|
@ -45,15 +45,26 @@ extern int __upf_log_domain;
|
|||
#undef OGS_LOG_DOMAIN
|
||||
#define OGS_LOG_DOMAIN __upf_log_domain
|
||||
|
||||
typedef struct upf_context_s {
|
||||
ogs_hash_t *seid_hash; /* hash table (SEID) */
|
||||
ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */
|
||||
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
|
||||
ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */
|
||||
struct upf_route_trie_node;
|
||||
|
||||
ogs_list_t sess_list;
|
||||
typedef struct upf_context_s {
|
||||
ogs_hash_t *seid_hash; /* hash table (SEID) */
|
||||
ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */
|
||||
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
|
||||
ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */
|
||||
struct upf_route_trie_node *ipv4_framed_routes; /* IPv4 framed routes trie */
|
||||
struct upf_route_trie_node *ipv6_framed_routes; /* IPv6 framed routes trie */
|
||||
|
||||
ogs_list_t sess_list;
|
||||
} upf_context_t;
|
||||
|
||||
/* trie mapping from IP framed routes to session. */
|
||||
struct upf_route_trie_node {
|
||||
struct upf_route_trie_node *left;
|
||||
struct upf_route_trie_node *right;
|
||||
upf_sess_t *sess;
|
||||
};
|
||||
|
||||
/* Accounting: */
|
||||
typedef struct upf_sess_urr_acc_s {
|
||||
bool reporting_enabled;
|
||||
|
@ -99,6 +110,9 @@ typedef struct upf_sess_s {
|
|||
ogs_pfcp_ue_ip_t *ipv4;
|
||||
ogs_pfcp_ue_ip_t *ipv6;
|
||||
|
||||
ogs_ipsubnet_t *ipv4_framed_routes;
|
||||
ogs_ipsubnet_t *ipv6_framed_routes;
|
||||
|
||||
char *gx_sid; /* Gx Session ID */
|
||||
ogs_pfcp_node_t *pfcp_node;
|
||||
|
||||
|
@ -126,6 +140,10 @@ upf_sess_t *upf_sess_find_by_ipv6(uint32_t *addr6);
|
|||
|
||||
uint8_t upf_sess_set_ue_ip(upf_sess_t *sess,
|
||||
uint8_t session_type, ogs_pfcp_pdr_t *pdr);
|
||||
uint8_t upf_sess_set_ue_ipv4_framed_routes(upf_sess_t *sess,
|
||||
char *framed_routes[]);
|
||||
uint8_t upf_sess_set_ue_ipv6_framed_routes(upf_sess_t *sess,
|
||||
char *framed_routes[]);
|
||||
|
||||
void upf_sess_urr_acc_add(upf_sess_t *sess, ogs_pfcp_urr_t *urr, size_t size, bool is_uplink);
|
||||
void upf_sess_urr_acc_fill_usage_report(upf_sess_t *sess, const ogs_pfcp_urr_t *urr,
|
||||
|
|
|
@ -61,6 +61,36 @@ static ogs_pkbuf_pool_t *packet_pool = NULL;
|
|||
|
||||
static void upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf);
|
||||
|
||||
static int check_framed_routes(upf_sess_t *sess, int family, uint32_t *addr)
|
||||
{
|
||||
int i = 0;
|
||||
ogs_ipsubnet_t *routes = family == AF_INET ?
|
||||
sess->ipv4_framed_routes : sess->ipv6_framed_routes;
|
||||
|
||||
if (!routes)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI; i++) {
|
||||
uint32_t *sub = routes[i].sub;
|
||||
uint32_t *mask = routes[i].mask;
|
||||
|
||||
if (!routes[i].family)
|
||||
break;
|
||||
|
||||
if (family == AF_INET) {
|
||||
if (sub[0] == (addr[0] & mask[0]))
|
||||
return true;
|
||||
} else {
|
||||
if (sub[0] == (addr[0] & mask[0]) &&
|
||||
sub[1] == (addr[1] & mask[1]) &&
|
||||
sub[2] == (addr[2] & mask[2]) &&
|
||||
sub[3] == (addr[3] & mask[3]))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t _get_eth_type(uint8_t *data, uint len) {
|
||||
if (len > ETHER_HDR_LEN) {
|
||||
struct ether_header *hdr = (struct ether_header*)data;
|
||||
|
@ -443,6 +473,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
|
||||
if (src_addr[0] == sess->ipv4->addr[0]) {
|
||||
/* Source IP address should be matched in uplink */
|
||||
} else if (check_framed_routes(sess, AF_INET, src_addr)) {
|
||||
/* Or source IP address should match a framed route */
|
||||
} else {
|
||||
ogs_error("[DROP] Source IP-%d Spoofing APN:%s SrcIf:%d DstIf:%d TEID:0x%x",
|
||||
ip_h->ip_v, pdr->dnn, pdr->src_if, far->dst_if, teid);
|
||||
|
@ -519,6 +551,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
* If Global address
|
||||
* 64 bit prefix should be matched
|
||||
*/
|
||||
} else if (check_framed_routes(sess, AF_INET6, src_addr)) {
|
||||
/* Or source IP address should match a framed route */
|
||||
} else {
|
||||
ogs_error("[DROP] Source IP-%d Spoofing APN:%s SrcIf:%d DstIf:%d TEID:0x%x",
|
||||
ip_h->ip_v, pdr->dnn, pdr->src_if, far->dst_if, teid);
|
||||
|
|
|
@ -138,6 +138,22 @@ void upf_n4_handle_session_establishment_request(
|
|||
}
|
||||
}
|
||||
|
||||
if (pdr->ipv4_framed_routes) {
|
||||
cause_value =
|
||||
upf_sess_set_ue_ipv4_framed_routes(sess,
|
||||
pdr->ipv4_framed_routes);
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pdr->ipv6_framed_routes) {
|
||||
cause_value =
|
||||
upf_sess_set_ue_ipv6_framed_routes(sess,
|
||||
pdr->ipv6_framed_routes);
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Setup UPF-N3-TEID & QFI Hash */
|
||||
if (pdr->f_teid_len) {
|
||||
ogs_pfcp_object_type_e type = OGS_PFCP_OBJ_SESS_TYPE;
|
||||
|
|
Loading…
Reference in New Issue