mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-upf.git
				synced 2025-11-03 21:43:34 +00:00 
			
		
		
		
	Introduce hashtable to look up gtp_tundev by local TEID
Use this hashtable while looking up for tunend based on <access.local.teid, access.remote.teid, access.remote.addr>. This kind of look up is used every time a session is added or removed, which means potentially thousands of tunend sessions were being iterated linerarly every time. For simplification (easier/quicker hashtable key generation), reduce the whole key presented above to a more general one based on "access.local.teid". This is usually enough since we are anyways allocating local TEIDs globally per tunnel without caring about remote address. Change-Id: Ib12ecc8ce87175071c52c0ed2217a29d901f0f05
This commit is contained in:
		@@ -24,6 +24,7 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <osmocom/core/linuxlist.h>
 | 
					#include <osmocom/core/linuxlist.h>
 | 
				
			||||||
 | 
					#include <osmocom/core/hashtable.h>
 | 
				
			||||||
#include <osmocom/core/select.h>
 | 
					#include <osmocom/core/select.h>
 | 
				
			||||||
#include <osmocom/core/logging.h>
 | 
					#include <osmocom/core/logging.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,6 +56,8 @@ struct upf_gtp_dev {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* list of struct upf_gtp_tunend */
 | 
						/* list of struct upf_gtp_tunend */
 | 
				
			||||||
	struct llist_head tunnels;
 | 
						struct llist_head tunnels;
 | 
				
			||||||
 | 
						/* hashtable of (struct upf_gtp_tunen) with key desc.access.local.teid */
 | 
				
			||||||
 | 
						DECLARE_HASHTABLE(tunnels_by_local_f_teid, 10);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Description of a GTP encapsulation / decapsulation.
 | 
					/* Description of a GTP encapsulation / decapsulation.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -134,6 +134,7 @@ static struct upf_gtp_dev *upf_gtp_dev_alloc(const char *name, const char *local
 | 
				
			|||||||
		.gtpv1.ofd.fd = -1,
 | 
							.gtpv1.ofd.fd = -1,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	INIT_LLIST_HEAD(&dev->tunnels);
 | 
						INIT_LLIST_HEAD(&dev->tunnels);
 | 
				
			||||||
 | 
						hash_init(dev->tunnels_by_local_f_teid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	osmo_sockaddr_str_from_str(&addr_conv, local_addr, PORT_GTP0_U);
 | 
						osmo_sockaddr_str_from_str(&addr_conv, local_addr, PORT_GTP0_U);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -318,7 +319,8 @@ int upf_gtp_genl_ensure_open()
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct upf_gtp_tunend {
 | 
					struct upf_gtp_tunend {
 | 
				
			||||||
	struct llist_head entry;
 | 
						struct llist_head entry; /* item in (struct upf_gtp_dev)->tunnels */
 | 
				
			||||||
 | 
						struct hlist_node node_by_local_f_teid; /* item in g_upf->gtp.pdrs_by_local_f_teid */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct upf_gtp_dev *dev;
 | 
						struct upf_gtp_dev *dev;
 | 
				
			||||||
	struct upf_tunend desc;
 | 
						struct upf_tunend desc;
 | 
				
			||||||
@@ -349,6 +351,7 @@ static int upf_gtp_tunend_destruct(struct upf_gtp_tunend *tun)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (tun->active)
 | 
						if (tun->active)
 | 
				
			||||||
		upf_gtp_tunend_deactivate(tun);
 | 
							upf_gtp_tunend_deactivate(tun);
 | 
				
			||||||
 | 
						hash_del(&tun->node_by_local_f_teid);
 | 
				
			||||||
	llist_del(&tun->entry);
 | 
						llist_del(&tun->entry);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -369,6 +372,7 @@ static struct upf_gtp_tunend *upf_gtp_tunend_alloc(struct upf_gtp_dev *dev, cons
 | 
				
			|||||||
		.dev = dev,
 | 
							.dev = dev,
 | 
				
			||||||
		.desc = *desc,
 | 
							.desc = *desc,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
						hash_add(dev->tunnels_by_local_f_teid, &tun->node_by_local_f_teid, tun->desc.access.local.teid);
 | 
				
			||||||
	llist_add(&tun->entry, &dev->tunnels);
 | 
						llist_add(&tun->entry, &dev->tunnels);
 | 
				
			||||||
	talloc_set_destructor(tun, upf_gtp_tunend_destruct);
 | 
						talloc_set_destructor(tun, upf_gtp_tunend_destruct);
 | 
				
			||||||
	return tun;
 | 
						return tun;
 | 
				
			||||||
@@ -425,7 +429,8 @@ static struct upf_gtp_tunend *upf_gtp_dev_tunend_find(struct upf_gtp_dev *dev, c
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct upf_gtp_tunend *tun;
 | 
						struct upf_gtp_tunend *tun;
 | 
				
			||||||
	tunend_validate(tunend);
 | 
						tunend_validate(tunend);
 | 
				
			||||||
	llist_for_each_entry(tun, &dev->tunnels, entry) {
 | 
					
 | 
				
			||||||
 | 
						hash_for_each_possible(dev->tunnels_by_local_f_teid, tun, node_by_local_f_teid, tunend->access.local.teid) {
 | 
				
			||||||
		if (upf_gtp_tunend_cmp(tunend, &tun->desc))
 | 
							if (upf_gtp_tunend_cmp(tunend, &tun->desc))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		return tun;
 | 
							return tun;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user