gtphub: implement sgsn_use_sender for NAT.
If an SGSN is behind NAT, we cannot rely on the default ports. Specifically, if a GGSN sends a message, the forwarding to the SGSN should go to whichever port the SGSN last sent from (whether sequence nr is known or not). Add sgsn_use_sender config and VTY command, and store the sender instead of the GSN Address IE and default port if set. Sponsored-by: On-Waves ehi
This commit is contained in:
parent
d53c6046bc
commit
ca2361c237
|
@ -361,6 +361,7 @@ struct gtphub_cfg_bind {
|
|||
struct gtphub_cfg {
|
||||
struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */
|
||||
};
|
||||
|
||||
|
||||
|
@ -454,6 +455,8 @@ struct gtphub {
|
|||
struct expiry expire_slowly;
|
||||
|
||||
uint8_t restart_counter;
|
||||
|
||||
int sgsn_use_sender;
|
||||
};
|
||||
|
||||
struct gtp_packet_desc;
|
||||
|
|
|
@ -1502,9 +1502,27 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
|
|||
tei_from_ie = ntoh32(p->ie[ie_idx]->tv4.v);
|
||||
|
||||
/* Make sure an entry for this peer address with default port
|
||||
* exists. */
|
||||
* exists.
|
||||
*
|
||||
* Exception: if sgsn_use_sender is set, instead use the
|
||||
* sender's address and port for Ctrl -- the User port is not
|
||||
* known until the first User packet arrives.
|
||||
*
|
||||
* Note: doing this here is just an optimization, because
|
||||
* gtphub_handle_buf() has code to replace the tunnel
|
||||
* endpoints' addresses with the sender (needed for User
|
||||
* plane). We could just ignore sgsn_use_sender here. But if we
|
||||
* set up a default port here and replace it in
|
||||
* gtphub_handle_buf(), we'd be creating a peer port just to
|
||||
* expire it right away. */
|
||||
if (hub->sgsn_use_sender && (side_idx == GTPH_SIDE_SGSN)) {
|
||||
gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa);
|
||||
} else {
|
||||
use_port = gtphub_plane_idx_default_port[plane_idx];
|
||||
|
||||
}
|
||||
|
||||
struct gtphub_peer_port *peer_from_ie;
|
||||
use_port = gtphub_plane_idx_default_port[plane_idx];
|
||||
peer_from_ie = gtphub_port_have(hub,
|
||||
&hub->to_gsns[side_idx][plane_idx],
|
||||
&use_addr, use_port);
|
||||
|
@ -2417,6 +2435,7 @@ int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg,
|
|||
gtphub_init(hub);
|
||||
|
||||
hub->restart_counter = restart_counter;
|
||||
hub->sgsn_use_sender = cfg->sgsn_use_sender? 1 : 0;
|
||||
|
||||
/* If a Ctrl plane proxy is configured, ares will never be used. */
|
||||
if (!cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) {
|
||||
|
|
|
@ -87,6 +87,10 @@ static int config_write_gtphub(struct vty *vty)
|
|||
&g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].bind,
|
||||
&g_cfg->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].bind);
|
||||
|
||||
if (g_cfg->sgsn_use_sender) {
|
||||
vty_out(vty, "sgsn-use-sender%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].addr_str) {
|
||||
write_addrs(vty, "sgsn-proxy",
|
||||
&g_cfg->proxy[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL],
|
||||
|
@ -237,6 +241,28 @@ DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd,
|
|||
}
|
||||
|
||||
|
||||
#define SGSN_USE_SENDER_STR \
|
||||
"Ignore SGSN's Address IEs, use sender address and port (useful over NAT)\n"
|
||||
|
||||
DEFUN(cfg_gtphub_sgsn_use_sender,
|
||||
cfg_gtphub_sgsn_use_sender_cmd,
|
||||
"sgsn-use-sender",
|
||||
SGSN_USE_SENDER_STR)
|
||||
{
|
||||
g_cfg->sgsn_use_sender = 1;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_gtphub_no_sgsn_use_sender,
|
||||
cfg_gtphub_no_sgsn_use_sender_cmd,
|
||||
"no sgsn-use-sender",
|
||||
NO_STR SGSN_USE_SENDER_STR)
|
||||
{
|
||||
g_cfg->sgsn_use_sender = 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Copied from sgsn_vty.h */
|
||||
DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd,
|
||||
"grx-dns-add A.B.C.D",
|
||||
|
@ -425,6 +451,8 @@ int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg)
|
|||
install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_cmd);
|
||||
install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_short_cmd);
|
||||
install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_cmd);
|
||||
install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_use_sender_cmd);
|
||||
install_element(GTPHUB_NODE, &cfg_gtphub_no_sgsn_use_sender_cmd);
|
||||
install_element(GTPHUB_NODE, &cfg_grx_ggsn_cmd);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue