epdg: Make sure PCO is forwarded from strongswan to PGW and back
Related: OS#6369 Change-Id: Ie01d6e88b3ccc55fecc97c2ba75bb31bba5b9ef7
This commit is contained in:
parent
cacd707fbf
commit
f29258602e
|
@ -46,6 +46,10 @@ modulepar {
|
|||
integer mp_s2b_local_port := GTP2C_PORT;
|
||||
charstring mp_s2b_remote_ip := "127.0.0.1";
|
||||
integer mp_s2b_remote_port := GTP2C_PORT;
|
||||
charstring mp_s2b_dns_ipv4 := "1.2.3.4";
|
||||
charstring mp_s2b_dns_ipv6 := "::1";
|
||||
charstring mp_s2b_pcscf_ipv4 := "5.6.7.8";
|
||||
charstring mp_s2b_pcscf_ipv6 := "::2";
|
||||
|
||||
charstring mp_diam_realm := "localdomain";
|
||||
integer mp_diam_watchdog_initial_wait_sec := 6*3;
|
||||
|
@ -433,6 +437,45 @@ private function f_S6b_ST_success() runs on EPDG_ConnHdlr {
|
|||
}
|
||||
}
|
||||
|
||||
private function f_exp_tr_GTP2C_APCO_in_CreateSessionReq()
|
||||
runs on EPDG_ConnHdlr return template (present) APCO {
|
||||
var template ProtocolIDs_and_ContainerIDs protos, protosV4, protosV6, protosV46;
|
||||
protosV4 := {tr_GTP2C_PCO_P_DNS_IPv4(''O), tr_GTP2C_PCO_P_PCSCF_IPv4(''O)};
|
||||
protosV6 := {tr_GTP2C_PCO_P_DNS_IPv6(''O), tr_GTP2C_PCO_P_PCSCF_IPv6(''O)};
|
||||
protosV46 := {tr_GTP2C_PCO_P_DNS_IPv4(''O), tr_GTP2C_PCO_P_PCSCF_IPv4(''O),
|
||||
tr_GTP2C_PCO_P_DNS_IPv6(''O), tr_GTP2C_PCO_P_PCSCF_IPv6(''O)}
|
||||
/* TODO: pick proto based on req_type v4, v6 or v4v6 */
|
||||
protos := protosV4;
|
||||
return tr_GTP2C_APCO('0000'B, protos);
|
||||
}
|
||||
|
||||
private function f_GTPv2C_gen_APCO_response(APCO apco_req) runs on EPDG_ConnHdlr return template (value) APCO {
|
||||
var ProtocolIDs_and_ContainerIDs proto_list_resp := {};
|
||||
|
||||
for (var integer i := 0; i < lengthof(apco_req.protocolIDs_and_ContainerIDs); i := i + 1) {
|
||||
var ProtocolID_or_ContainerID proto_req := apco_req.protocolIDs_and_ContainerIDs[i];
|
||||
select (proto_req.protocolID_or_ContainerID) {
|
||||
case (PCO_P_to_OCT2(PCO_P_DNS_IPv4_ADDR)) {
|
||||
proto_list_resp := proto_list_resp & { valueof(ts_GTP2C_PCO_P_DNS_IPv4(f_inet_addr(mp_s2b_dns_ipv4))) };
|
||||
}
|
||||
case (PCO_P_to_OCT2(PCO_P_DNS_IPv6_ADDR)) {
|
||||
proto_list_resp := proto_list_resp & { valueof(ts_GTP2C_PCO_P_DNS_IPv6(f_inet_addr(mp_s2b_dns_ipv6))) };
|
||||
}
|
||||
case (PCO_P_to_OCT2(PCO_P_PCSCF_IPv4_ADDR)) {
|
||||
proto_list_resp := proto_list_resp & { valueof(ts_GTP2C_PCO_P_PCSCF_IPv4(f_inet_addr(mp_s2b_pcscf_ipv4))) };
|
||||
}
|
||||
case (PCO_P_to_OCT2(PCO_P_PCSCF_ADDR)) {
|
||||
proto_list_resp := proto_list_resp & { valueof(ts_GTP2C_PCO_P_PCSCF_IPv6(f_inet_addr(mp_s2b_pcscf_ipv6))) };
|
||||
}
|
||||
case else {
|
||||
log("Ignoring unknown PCO Protocol ID: ", proto_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ts_GTP2C_APCO(apco_req.instance, proto_list_resp);
|
||||
}
|
||||
|
||||
/* ePDG Creates session at the PGW. PGW sends Diameter s6b AAR + AAA. */
|
||||
private altstep as_GTP2C_CreateSession_success() runs on EPDG_ConnHdlr {
|
||||
var PDU_GTPCv2 rx_msg;
|
||||
|
@ -441,7 +484,7 @@ private altstep as_GTP2C_CreateSession_success() runs on EPDG_ConnHdlr {
|
|||
var template (value) PDN_AddressAllocation paa;
|
||||
var template (value) BearerContextIEs bctx_ies;
|
||||
|
||||
[] GTP2.receive(tr_GTP2C_CreateSessionReq(g_pars.imsi)) -> value rx_msg {
|
||||
[] GTP2.receive(tr_GTP2C_CreateSessionReq(g_pars.imsi, apco := f_exp_tr_GTP2C_APCO_in_CreateSessionReq())) -> value rx_msg {
|
||||
/* Parse TEIC and Bearer EBI and TEID and store it in g_pars */
|
||||
g_pars.teic_remote := rx_msg.gtpcv2_pdu.createSessionRequest.fullyQualifiedTEID[0].tEID_GRE_Key;
|
||||
rx_bctx_ies := rx_msg.gtpcv2_pdu.createSessionRequest.bearerContextGrouped[0].bearerContextIEs;
|
||||
|
@ -466,7 +509,8 @@ private altstep as_GTP2C_CreateSession_success() runs on EPDG_ConnHdlr {
|
|||
charging_id := ts_GTP2C_ChargingID(g_pars.teic_local));
|
||||
GTP2.send(ts_GTP2C_CreateSessionResp(g_pars.teic_remote, rx_msg.sequenceNumber,
|
||||
{ fteid_c_ie }, paa,
|
||||
{ ts_GTP2C_BcGrouped(bctx_ies) } ));
|
||||
{ ts_GTP2C_BcGrouped(bctx_ies) },
|
||||
f_GTPv2C_gen_APCO_response(rx_msg.gtpcv2_pdu.createSessionRequest.aPCO) ));
|
||||
setverdict(pass);
|
||||
}
|
||||
[] GTP2.receive(PDU_GTPCv2:?) -> value rx_msg {
|
||||
|
@ -605,15 +649,20 @@ private function f_GSUP_EPDGTunnel_success() runs on EPDG_ConnHdlr {
|
|||
GSUP.send(ts_GSUP_EPDGTunnel_REQ(g_pars.imsi, pco));
|
||||
as_GTP2C_CreateSession_success();
|
||||
/* Expect a positive response back to the translator; */
|
||||
var template (present) GSUP_IEs pdp_info := {
|
||||
var template (present) GSUP_IEs exp_pdp_info := {
|
||||
tr_GSUP_IE_PDP_CONTEXT_ID(?),
|
||||
tr_GSUP_IE_PDP_ADDRESS(tr_GSUP_PDP_Address_IPv4(f_inet_addr(g_pars.ue_ip))),
|
||||
tr_GSUP_IE_APN(f_enc_dns_hostname(g_pars.apn)),
|
||||
tr_GSUP_IE_PDP_QOS(?),
|
||||
tr_GSUP_IE_Charging_Characteristics(?)
|
||||
};
|
||||
var template (present) PCO_DATA exp_pco := tr_PCO({
|
||||
tr_PCO_P_DNS_IPv4(f_inet_addr(mp_s2b_dns_ipv4)),
|
||||
tr_PCO_P_PCSCF_IPv4(f_inet_addr(mp_s2b_pcscf_ipv4))
|
||||
});
|
||||
/* TODO: check for v6 and v4v6 types ^ */
|
||||
alt {
|
||||
[] GSUP.receive(tr_GSUP_EPDGTunnel_RES(g_pars.imsi, pdp_info));
|
||||
[] GSUP.receive(tr_GSUP_EPDGTunnel_RES(g_pars.imsi, exp_pdp_info));
|
||||
[] GSUP.receive(GSUP_PDU:?) -> value rx_gsup {
|
||||
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected GSUP msg rx: ", rx_gsup));
|
||||
}
|
||||
|
|
|
@ -301,6 +301,14 @@ template (value) GSUP_IE ts_GSUP_IE_PCO(template (value) PCO_DATA pco) := {
|
|||
}
|
||||
}
|
||||
|
||||
template (present) GSUP_IE tr_GSUP_IE_PCO(template (present) PCO_DATA pco := ?) := {
|
||||
tag := OSMO_GSUP_PCO_IE,
|
||||
len := ?,
|
||||
val := {
|
||||
pco := pco
|
||||
}
|
||||
}
|
||||
|
||||
template GSUP_PDU tr_GSUP(template GSUP_MessageType msgt := ?, template GSUP_IEs ies := *) := {
|
||||
msg_type := msgt,
|
||||
ies := ies
|
||||
|
@ -536,6 +544,7 @@ template (value) GSUP_PDU ts_GSUP_EPDGTunnel_RES(hexstring imsi,
|
|||
|
||||
template (present) GSUP_PDU tr_GSUP_EPDGTunnel_RES(template (present) hexstring imsi,
|
||||
template (present) GSUP_IEs pdp_info,
|
||||
template (present) PCO_DATA pco := ?,
|
||||
template (present) GSUP_Message_Class message_class := OSMO_GSUP_MESSAGE_CLASS_IPSEC_EPDG,
|
||||
template octetstring destination_name := omit) :=
|
||||
tr_GSUP(OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT,
|
||||
|
@ -543,6 +552,7 @@ template (present) GSUP_PDU tr_GSUP_EPDGTunnel_RES(template (present) hexstring
|
|||
pdp_info_compl := true,
|
||||
pdp_info := pdp_info,
|
||||
message_class := message_class,
|
||||
pco := pco,
|
||||
destination_name := destination_name));
|
||||
|
||||
template (value) GSUP_PDU ts_GSUP_EPDGTunnel_ERR(hexstring imsi,
|
||||
|
@ -1229,6 +1239,7 @@ private function f_gen_tr_ies(template hexstring imsi,
|
|||
template GSUP_CancelType cancel_type := omit,
|
||||
template hexstring msisdn := omit,
|
||||
template GSUP_IMEIResult imei_result := omit,
|
||||
template PCO_DATA pco := omit,
|
||||
template GSUP_CnDomain cn_domain := omit,
|
||||
template octetstring source_name := omit,
|
||||
template octetstring destination_name := omit
|
||||
|
@ -1278,6 +1289,11 @@ private function f_gen_tr_ies(template hexstring imsi,
|
|||
idx := idx + 1;
|
||||
}
|
||||
|
||||
if (not istemplatekind(pco, "omit")) {
|
||||
ies[idx] := tr_GSUP_IE_PCO(pco);
|
||||
idx := idx + 1;
|
||||
}
|
||||
|
||||
if (not istemplatekind(source_name, "omit")) {
|
||||
ies[idx] := tr_GSUP_IE_Source_Name(source_name);
|
||||
idx := idx + 1;
|
||||
|
|
|
@ -48,6 +48,10 @@ type enumerated PCO_P {
|
|||
} with { variant "FIELDLENGTH(16)";
|
||||
variant "BYTEORDER(last)" };
|
||||
|
||||
function PCO_P_to_OCT2(PCO_P p) return OCT2 {
|
||||
return int2oct(enum2int(p), 2);
|
||||
}
|
||||
|
||||
/* RFC 1332 IP Control Protocol options, extensions in RFC 1877 */
|
||||
type enumerated IPCP_OPT {
|
||||
IPCP_OPT_IPADDR (3), /* RFC 1332 3.3 */
|
||||
|
@ -108,15 +112,23 @@ template (present) ProtocolElement tr_PCO_P_OCTSTR(template (present) PCO_P prot
|
|||
|
||||
template (value) ProtocolElement ts_PCO_P_DNS_IPv4(template (value) octetstring dns4 := ''O) :=
|
||||
ts_PCO_P_OCTSTR(PCO_P_DNS_IPv4_ADDR, protoIDContents := dns4);
|
||||
template (present) ProtocolElement tr_PCO_P_DNS_IPv4(template (present) octetstring dns4 := ?) :=
|
||||
tr_PCO_P_OCTSTR(PCO_P_DNS_IPv4_ADDR, protoIDContents := dns4);
|
||||
|
||||
template (value) ProtocolElement ts_PCO_P_DNS_IPv6(template (value) octetstring dns6 := ''O) :=
|
||||
ts_PCO_P_OCTSTR(PCO_P_DNS_IPv6_ADDR, protoIDContents := dns6);
|
||||
template (present) ProtocolElement tr_PCO_P_DNS_IPv6(template (present) octetstring dns6 := ?) :=
|
||||
tr_PCO_P_OCTSTR(PCO_P_DNS_IPv6_ADDR, protoIDContents := dns6);
|
||||
|
||||
template (value) ProtocolElement ts_PCO_P_PCSCF_IPv4(template (value) octetstring pcscf4 := ''O) :=
|
||||
ts_PCO_P_OCTSTR(PCO_P_PCSCF_IPv4_ADDR, protoIDContents := pcscf4);
|
||||
template (present) ProtocolElement tr_PCO_P_PCSCF_IPv4(template (present) octetstring pcscf4 := ?) :=
|
||||
tr_PCO_P_OCTSTR(PCO_P_PCSCF_IPv4_ADDR, protoIDContents := pcscf4);
|
||||
|
||||
template (value) ProtocolElement ts_PCO_P_PCSCF_IPv6(template (value) octetstring pcscf6 := ''O) :=
|
||||
ts_PCO_P_OCTSTR(PCO_P_PCSCF_ADDR, protoIDContents := pcscf6);
|
||||
template (present) ProtocolElement tr_PCO_P_PCSCF_IPv6(template (present) octetstring pcscf6 := ?) :=
|
||||
tr_PCO_P_OCTSTR(PCO_P_PCSCF_ADDR, protoIDContents := pcscf6);
|
||||
|
||||
/* PCO send base template */
|
||||
template (value) PCO_DATA ts_PCO(template (value) ProtocolIDList protocols := {}) := {
|
||||
|
|
Loading…
Reference in New Issue