message format creation bug is fixed related prefixlen

This commit is contained in:
Sukchan Lee 2017-12-15 09:41:54 +09:00
parent ae57423eab
commit 94c2c6ca7d
7 changed files with 54 additions and 41 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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);
}

View File

@ -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
}

View File

@ -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),

View File

@ -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;