From 94c2c6ca7d3a23996d110a9f5eafbcbc941e2659 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Fri, 15 Dec 2017 09:41:54 +0900 Subject: [PATCH] message format creation bug is fixed related prefixlen --- lib/core/include/3gpp_types.h | 4 ++-- lib/nas/nas_types.h | 4 ++-- src/mme/esm_build.c | 4 ++-- src/pgw/pgw_context.c | 39 ++++++++++++++++++++++++++--------- src/pgw/pgw_context.h | 1 + src/pgw/pgw_fd_path.c | 28 ++++++++++++++++--------- src/pgw/pgw_s5c_build.c | 15 -------------- 7 files changed, 54 insertions(+), 41 deletions(-) diff --git a/lib/core/include/3gpp_types.h b/lib/core/include/3gpp_types.h index c007e4cca..204c205b4 100644 --- a/lib/core/include/3gpp_types.h +++ b/lib/core/include/3gpp_types.h @@ -137,12 +137,12 @@ ED2(c_uint8_t spare:5;, /* GTP_PDN_TYPE_BOTH */ struct { - c_uint32_t addr; struct { c_uint8_t len; c_uint8_t addr6[IPV6_LEN]; }; - } both; + c_uint32_t addr; + } __attribute__ ((packed)) both; }; } __attribute__ ((packed)) paa_t; diff --git a/lib/nas/nas_types.h b/lib/nas/nas_types.h index 294aa2784..717d2bca9 100644 --- a/lib/nas/nas_types.h +++ b/lib/nas/nas_types.h @@ -1162,10 +1162,10 @@ ED2(c_uint8_t reserved:5;, union { c_uint32_t addr; struct { - c_uint8_t addr6[IPV6_LEN/2]; /* Interface Identifer Only */ + c_uint8_t addr6[IPV6_LEN>>1]; /* Interface Identifer Only */ }; struct { - c_uint8_t addr6[IPV6_LEN/2]; /* Interface Identifer Only */ + c_uint8_t addr6[IPV6_LEN>>1]; /* Interface Identifer Only */ c_uint32_t addr; } both; }; diff --git a/src/mme/esm_build.c b/src/mme/esm_build.c index 590b9d58e..41b58ec72 100644 --- a/src/mme/esm_build.c +++ b/src/mme/esm_build.c @@ -140,14 +140,14 @@ status_t esm_build_activate_default_bearer_context_request( } else if (pdn_address->pdn_type == GTP_PDN_TYPE_IPV6) { - memcpy(pdn_address->addr6, pdn->paa.addr6+IPV6_LEN/2, IPV6_LEN/2); + memcpy(pdn_address->addr6, pdn->paa.addr6+(IPV6_LEN>>1), IPV6_LEN>>1); pdn_address->length = NAS_PDN_ADDRESS_IPV6_LEN; } else if (pdn_address->pdn_type == GTP_PDN_TYPE_IPV4V6) { pdn_address->both.addr = pdn->paa.both.addr; memcpy(pdn_address->both.addr6, - pdn->paa.both.addr6+IPV6_LEN/2, IPV6_LEN/2); + pdn->paa.both.addr6+(IPV6_LEN>>1), IPV6_LEN>>1); pdn_address->length = NAS_PDN_ADDRESS_IPV4V6_LEN; } else diff --git a/src/pgw/pgw_context.c b/src/pgw/pgw_context.c index 5d259f3d8..121538639 100644 --- a/src/pgw/pgw_context.c +++ b/src/pgw/pgw_context.c @@ -755,17 +755,22 @@ pgw_sess_t *pgw_sess_add( "Can't add default bearer context"); bearer->ebi = ebi; + sess->pdn.paa.pdn_type = pdn_type; if (pdn_type == GTP_PDN_TYPE_IPV4) { sess->ipv4 = pgw_ue_ip_alloc(AF_INET, apn); d_assert(sess->ipv4, pgw_sess_remove(sess); return NULL, "Can't allocate IPv4 Pool"); + sess->pdn.paa.addr = sess->ipv4->addr[0]; } else if (pdn_type == GTP_PDN_TYPE_IPV6) { sess->ipv6 = pgw_ue_ip_alloc(AF_INET6, apn); d_assert(sess->ipv6, pgw_sess_remove(sess); return NULL, "Can't allocate IPv6 Pool"); + + sess->pdn.paa.len = pgw_ue_ip_prefixlen(sess->ipv6); + memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, IPV6_LEN); } else if (pdn_type == GTP_PDN_TYPE_IPV4V6) { @@ -775,10 +780,13 @@ pgw_sess_t *pgw_sess_add( sess->ipv6 = pgw_ue_ip_alloc(AF_INET6, apn); d_assert(sess->ipv6, pgw_sess_remove(sess); return NULL, "Can't allocate IPv6 Pool"); + + sess->pdn.paa.both.addr = sess->ipv4->addr[0]; + sess->pdn.paa.both.len = pgw_ue_ip_prefixlen(sess->ipv6); + memcpy(sess->pdn.paa.both.addr6, sess->ipv6->addr, IPV6_LEN); } else d_assert(0, return NULL, "Unsupported PDN Type(%d)", pdn_type); - sess->pdn.pdn_type = pdn_type; /* Generate Hash Key : IMSI + APN */ sess_hash_keygen(sess->hash_keybuf, &sess->hash_keylen, @@ -1381,7 +1389,7 @@ status_t pgw_ue_pool_generate() { int index = 0; ipsubnet_t ipaddr, ipsub; - c_uint32_t bits; + c_uint32_t prefixlen; c_uint32_t mask_count; c_uint32_t broadcast[4]; @@ -1393,23 +1401,23 @@ status_t pgw_ue_pool_generate() d_assert(rv == CORE_OK, return CORE_ERROR,); d_assert(self.ue_pool[i].mask_or_numbits, return CORE_ERROR,); - bits = atoi(self.ue_pool[i].mask_or_numbits); + prefixlen = atoi(self.ue_pool[i].mask_or_numbits); if (ipsub.family == AF_INET) { - if (bits == 32) + if (prefixlen == 32) mask_count = 1; - else if (bits < 32) - mask_count = (0xffffffff >> bits) + 1; + else if (prefixlen < 32) + mask_count = (0xffffffff >> prefixlen) + 1; else d_assert(0, return CORE_ERROR,); } else if (ipsub.family == AF_INET6) { - if (bits == 128) + if (prefixlen == 128) mask_count = 1; - else if (bits > 96 && bits < 128) - mask_count = (0xffffffff >> (bits - 96)) + 1; - else if (bits <= 96) + else if (prefixlen > 96 && prefixlen < 128) + mask_count = (0xffffffff >> (prefixlen - 96)) + 1; + else if (prefixlen <= 96) mask_count = 0xffffffff; else d_assert(0, return CORE_ERROR,); @@ -1542,3 +1550,14 @@ status_t pgw_ue_ip_free(pgw_ue_ip_t *ue_ip) return CORE_OK; } + +c_uint8_t pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip) +{ + d_assert(ue_ip, return CORE_ERROR,); + + c_uint8_t index = ue_ip->index; + d_assert(index < MAX_NUM_OF_UE_POOL, return CORE_ERROR,); + d_assert(pgw_self()->ue_pool[index].mask_or_numbits, + return CORE_ERROR,); + return atoi(pgw_self()->ue_pool[index].mask_or_numbits); +} diff --git a/src/pgw/pgw_context.h b/src/pgw/pgw_context.h index 18fc51130..243360b17 100644 --- a/src/pgw/pgw_context.h +++ b/src/pgw/pgw_context.h @@ -213,6 +213,7 @@ CORE_DECLARE(pgw_pf_t*) pgw_pf_next(pgw_pf_t *pf); CORE_DECLARE(status_t ) pgw_ue_pool_generate(); CORE_DECLARE(pgw_ue_ip_t *) pgw_ue_ip_alloc(int family, const char *apn); CORE_DECLARE(status_t) pgw_ue_ip_free(pgw_ue_ip_t *ip); +CORE_DECLARE(c_uint8_t) pgw_ue_ip_prefixlen(pgw_ue_ip_t *ue_ip); #ifdef __cplusplus } diff --git a/src/pgw/pgw_fd_path.c b/src/pgw/pgw_fd_path.c index 4855e8335..b78a8ff47 100644 --- a/src/pgw/pgw_fd_path.c +++ b/src/pgw/pgw_fd_path.c @@ -136,20 +136,28 @@ void pgw_gx_send_ccr(gtp_xact_t *xact, pgw_sess_t *sess, CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); /* Set Framed-IP-Address */ - CHECK_FCT_DO( fd_msg_avp_new(gx_framed_ip_address, 0, &avp), - goto out ); - if (sess->ipv6) - { - val.os.data = (c_uint8_t*)&sess->ipv6->addr; - val.os.len = 16; - } - else + if (sess->ipv4) { + CHECK_FCT_DO( fd_msg_avp_new(gx_framed_ip_address, 0, &avp), + goto out ); val.os.data = (c_uint8_t*)&sess->ipv4->addr; val.os.len = 4; + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), + goto out ); + } + + /* Set Framed-IP-Address-Prefix */ + if (sess->ipv6) + { + CHECK_FCT_DO( fd_msg_avp_new(gx_framed_ipv6_prefix, 0, &avp), + goto out ); + val.os.data = (c_uint8_t*)&sess->pdn.paa; + val.os.len = PAA_IPV6_LEN; + CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); + CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), + goto out ); } - CHECK_FCT_DO( fd_msg_avp_setvalue(avp, &val), goto out ); - CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out ); /* Set IP-Can-Type */ CHECK_FCT_DO( fd_msg_avp_new(gx_ip_can_type, 0, &avp), diff --git a/src/pgw/pgw_s5c_build.c b/src/pgw/pgw_s5c_build.c index 51979f1ea..23e0dfd43 100644 --- a/src/pgw/pgw_s5c_build.c +++ b/src/pgw/pgw_s5c_build.c @@ -61,26 +61,11 @@ status_t pgw_s5c_build_create_session_response( /* PDN Address Allocation */ rsp->pdn_address_allocation.data = &sess->pdn.paa; if (sess->ipv4 && sess->ipv6) - { - sess->pdn.paa.pdn_type = GTP_PDN_TYPE_IPV4V6; - sess->pdn.paa.both.addr = sess->ipv4->addr[0]; - sess->pdn.paa.both.len = IPV6_LEN; - memcpy(sess->pdn.paa.both.addr6, sess->ipv6->addr, IPV6_LEN); rsp->pdn_address_allocation.len = PAA_IPV4V6_LEN; - } else if (sess->ipv4) - { - sess->pdn.paa.pdn_type = GTP_PDN_TYPE_IPV4; - sess->pdn.paa.addr = sess->ipv4->addr[0]; rsp->pdn_address_allocation.len = PAA_IPV4_LEN; - } else if (sess->ipv6) - { - sess->pdn.paa.pdn_type = GTP_PDN_TYPE_IPV6; - sess->pdn.paa.len = IPV6_LEN; - memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, IPV6_LEN); rsp->pdn_address_allocation.len = PAA_IPV6_LEN; - } else d_assert(0, return CORE_ERROR, "No IP Pool"); rsp->pdn_address_allocation.presence = 1;