aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/sgsn/gb_proxy.h
blob: ac03a11344022fea9051cd5eda938723db15cd91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef _GB_PROXY_H
#define _GB_PROXY_H


#include <osmocom/core/msgb.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/hashtable.h>
#include <osmocom/gsm/gsm23003.h>

#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/vty/command.h>

#include <sys/types.h>
#include <regex.h>
#include <stdbool.h>

#define GBPROXY_INIT_VU_GEN_TX 256

/* BVCI uses 16 bits */
#define BVC_LOG_CTX_FLAG (1<<17)

struct rate_ctr_group;
struct gprs_gb_parse_context;
struct tlv_parsed;

enum gbproxy_global_ctr {
	GBPROX_GLOB_CTR_INV_BVCI,
	GBPROX_GLOB_CTR_INV_LAI,
	GBPROX_GLOB_CTR_INV_RAI,
	GBPROX_GLOB_CTR_INV_NSEI,
	GBPROX_GLOB_CTR_PROTO_ERR_BSS,
	GBPROX_GLOB_CTR_PROTO_ERR_SGSN,
	GBPROX_GLOB_CTR_NOT_SUPPORTED_BSS,
	GBPROX_GLOB_CTR_NOT_SUPPORTED_SGSN,
	GBPROX_GLOB_CTR_RESTART_RESET_SGSN,
	GBPROX_GLOB_CTR_TX_ERR_SGSN,
	GBPROX_GLOB_CTR_OTHER_ERR,
};

enum gbproxy_bvc_ctr {
	GBPROX_PEER_CTR_BLOCKED,
	GBPROX_PEER_CTR_UNBLOCKED,
	GBPROX_PEER_CTR_DROPPED,
	GBPROX_PEER_CTR_INV_NSEI,
	GBPROX_PEER_CTR_TX_ERR,
	GBPROX_PEER_CTR_LAST,
};

/* global gb-proxy configuration */
struct gbproxy_config {
	/* parsed from config file */
	uint16_t nsip_sgsn_nsei;

	/* NS instance of libosmogb */
	struct gprs_ns2_inst *nsi;

	/* Linked list of all BSS side Gb peers */
	DECLARE_HASHTABLE(bss_nses, 8);

	/* Counter */
	struct rate_ctr_group *ctrg;
};

/* One BVC inside an NSE */
struct gbproxy_bvc {
	/* linked to gbproxy_nse.bvcs */
	struct hlist_node list;

	/* The NSE this BVC belongs to */
	struct gbproxy_nse *nse;

	/* PTP BVCI of this BVC */
	uint16_t bvci;

	/* Routing Area that this BVC is part of (raw 04.08 encoding) */
	uint8_t ra[6];

	/* true if this BVC is blocked */
	bool blocked;

	/* Counter */
	struct rate_ctr_group *ctrg;
};

/* one NS Entity that we interact with (BSS/PCU) */
struct gbproxy_nse {
	/* linked to gbproxy_config.bss_nses */
	struct hlist_node list;

	/* point back to the config */
	struct gbproxy_config *cfg;

	/* NSEI of the NSE */
	uint16_t nsei;

	/* List of all BVCs in this NSE */
	DECLARE_HASHTABLE(bvcs, 10);
};

/* Convenience logging macros for NSE/BVC */
#define LOGPNSE_CAT(NSE, SUBSYS, LEVEL, FMT, ARGS...) \
	LOGP(SUBSYS, LEVEL, "NSE(%05u/BSS) " FMT, (NSE)->nsei, ## ARGS)
#define LOGPNSE(NSE, LEVEL, FMT, ARGS...) \
	LOGPNSE_CAT(NSE, DGPRS, LEVEL, FMT, ## ARGS)

#define LOGPBVC_CAT(BVC, SUBSYS, LEVEL, FMT, ARGS...) \
	LOGP(SUBSYS, LEVEL, "NSE(%05u/BSS)-BVC(%05u/%s) " FMT, (BVC)->nse->nsei, (BVC)->bvci, \
		(BVC)->blocked ? "BLOCKED" : "UNBLOCKED", ## ARGS)
#define LOGPBVC(BVC, LEVEL, FMT, ARGS...) \
	LOGPBVC_CAT(BVC, DGPRS, LEVEL, FMT, ## ARGS)

/* gb_proxy_vty .c */

int gbproxy_vty_init(void);
int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);

/* gb_proxy_ctrl.c */
int gb_ctrl_cmds_install(void);


/* gb_proxy.c */
int gbproxy_init_config(struct gbproxy_config *cfg);

/* Main input function for Gb proxy */
int gbprox_rcvmsg(void *ctx, struct msgb *msg);

int gbprox_signal(unsigned int subsys, unsigned int signal,
		  void *handler_data, void *signal_data);


int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx);

void gbprox_reset(struct gbproxy_config *cfg);

/* Peer handling */
struct gbproxy_bvc *gbproxy_bvc_by_bvci(
	struct gbproxy_config *cfg, uint16_t bvci);
struct gbproxy_bvc *gbproxy_bvc_by_nsei(
	struct gbproxy_config *cfg, uint16_t nsei);
struct gbproxy_bvc *gbproxy_bvc_by_rai(
	struct gbproxy_config *cfg, const uint8_t *ra);
struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci);
void gbproxy_bvc_free(struct gbproxy_bvc *bvc);
void gbproxy_bvc_move(struct gbproxy_bvc *bvc, struct gbproxy_nse *nse);
int gbproxy_cleanup_bvcs(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci);

/* NSE handling */
struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei);
void gbproxy_nse_free(struct gbproxy_nse *nse);
struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint16_t nsei);

#endif