Fix semantic error in packet filter [#338]

<DOWNLINK>
RX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>

<UPLINK>
RX : permit in from <UE_IP> <UE_PORT> to <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
This commit is contained in:
Sukchan Lee 2020-09-20 23:35:10 -04:00
parent cc873269a4
commit f5601a95f7
18 changed files with 527 additions and 291 deletions

View File

@ -106,52 +106,52 @@ int ogs_ipfw_compile_rule(ogs_ipfw_rule_t *ipfw_rule, char *flow_description)
case O_IP_SRC: case O_IP_SRC:
case O_IP_SRC_MASK: case O_IP_SRC_MASK:
a = ((ipfw_insn_u32 *)cmd)->d; a = ((ipfw_insn_u32 *)cmd)->d;
ipfw_rule->ipv4_local = 1; ipfw_rule->ipv4_src = 1;
ipfw_rule->ip.local.addr[0] = a[0]; ipfw_rule->ip.src.addr[0] = a[0];
if (cmd->opcode == O_IP_SRC_MASK) if (cmd->opcode == O_IP_SRC_MASK)
ipfw_rule->ip.local.mask[0] = a[1]; ipfw_rule->ip.src.mask[0] = a[1];
else else
ipfw_rule->ip.local.mask[0] = 0xffffffff; ipfw_rule->ip.src.mask[0] = 0xffffffff;
break; break;
case O_IP_DST: case O_IP_DST:
case O_IP_DST_MASK: case O_IP_DST_MASK:
a = ((ipfw_insn_u32 *)cmd)->d; a = ((ipfw_insn_u32 *)cmd)->d;
ipfw_rule->ipv4_remote = 1; ipfw_rule->ipv4_dst = 1;
ipfw_rule->ip.remote.addr[0] = a[0]; ipfw_rule->ip.dst.addr[0] = a[0];
if (cmd->opcode == O_IP_DST_MASK) if (cmd->opcode == O_IP_DST_MASK)
ipfw_rule->ip.remote.mask[0] = a[1]; ipfw_rule->ip.dst.mask[0] = a[1];
else else
ipfw_rule->ip.remote.mask[0] = 0xffffffff; ipfw_rule->ip.dst.mask[0] = 0xffffffff;
break; break;
case O_IP6_SRC: case O_IP6_SRC:
case O_IP6_SRC_MASK: case O_IP6_SRC_MASK:
a = ((ipfw_insn_u32 *)cmd)->d; a = ((ipfw_insn_u32 *)cmd)->d;
ipfw_rule->ipv6_local = 1; ipfw_rule->ipv6_src = 1;
memcpy(ipfw_rule->ip.local.addr, a, OGS_IPV6_LEN); memcpy(ipfw_rule->ip.src.addr, a, OGS_IPV6_LEN);
if (cmd->opcode == O_IP6_SRC_MASK) if (cmd->opcode == O_IP6_SRC_MASK)
memcpy(ipfw_rule->ip.local.mask, a+4, OGS_IPV6_LEN); memcpy(ipfw_rule->ip.src.mask, a+4, OGS_IPV6_LEN);
else else
n2mask((struct in6_addr *)ipfw_rule->ip.local.mask, 128); n2mask((struct in6_addr *)ipfw_rule->ip.src.mask, 128);
break; break;
case O_IP6_DST: case O_IP6_DST:
case O_IP6_DST_MASK: case O_IP6_DST_MASK:
a = ((ipfw_insn_u32 *)cmd)->d; a = ((ipfw_insn_u32 *)cmd)->d;
ipfw_rule->ipv6_remote = 1; ipfw_rule->ipv6_dst = 1;
memcpy(ipfw_rule->ip.remote.addr, a, OGS_IPV6_LEN); memcpy(ipfw_rule->ip.dst.addr, a, OGS_IPV6_LEN);
if (cmd->opcode == O_IP6_DST_MASK) if (cmd->opcode == O_IP6_DST_MASK)
memcpy(ipfw_rule->ip.remote.mask, a+4, OGS_IPV6_LEN); memcpy(ipfw_rule->ip.dst.mask, a+4, OGS_IPV6_LEN);
else else
n2mask((struct in6_addr *)ipfw_rule->ip.remote.mask, 128); n2mask((struct in6_addr *)ipfw_rule->ip.dst.mask, 128);
break; break;
case O_IP_SRCPORT: case O_IP_SRCPORT:
p = ((ipfw_insn_u16 *)cmd)->ports; p = ((ipfw_insn_u16 *)cmd)->ports;
ipfw_rule->port.local.low = p[0]; ipfw_rule->port.src.low = p[0];
ipfw_rule->port.local.high = p[1]; ipfw_rule->port.src.high = p[1];
break; break;
case O_IP_DSTPORT: case O_IP_DSTPORT:
p = ((ipfw_insn_u16 *)cmd)->ports; p = ((ipfw_insn_u16 *)cmd)->ports;
ipfw_rule->port.remote.low = p[0]; ipfw_rule->port.dst.low = p[0];
ipfw_rule->port.remote.high = p[1]; ipfw_rule->port.dst.high = p[1];
break; break;
} }
} }
@ -174,15 +174,34 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
char buf[OGS_ADDRSTRLEN]; char buf[OGS_ADDRSTRLEN];
ogs_sockaddr_t sa; ogs_sockaddr_t sa;
int prefixlen = 0; int prefixlen = 0;
ogs_ipfw_rule_t permit_out_rule;
p = flow_description; p = flow_description;
last = flow_description + OGS_HUGE_LEN; last = flow_description + OGS_HUGE_LEN;
ogs_assert(ipfw_rule); ogs_assert(ipfw_rule);
/*
* Issue #338
*
* <DOWNLINK>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
* -->
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
*
* <UPLINK>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
*/
ogs_ipfw_copy_and_swap(&permit_out_rule, ipfw_rule);
p = ogs_slprintf(p, last, "permit out"); p = ogs_slprintf(p, last, "permit out");
if (ipfw_rule->proto) { if (permit_out_rule.proto) {
p = ogs_slprintf(p, last, " %d", ipfw_rule->proto); p = ogs_slprintf(p, last, " %d", permit_out_rule.proto);
} else { } else {
p = ogs_slprintf(p, last, " ip"); p = ogs_slprintf(p, last, " ip");
} }
@ -193,21 +212,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
p = ogs_slprintf(p, last, " from"); p = ogs_slprintf(p, last, " from");
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
if (ipfw_rule->ipv4_local) { if (permit_out_rule.ipv4_src) {
sa.ogs_sa_family = AF_INET; sa.ogs_sa_family = AF_INET;
memcpy(&sa.sin.sin_addr, memcpy(&sa.sin.sin_addr,
ipfw_rule->ip.local.addr, sizeof(struct in_addr)); permit_out_rule.ip.src.addr, sizeof(struct in_addr));
OGS_ADDR(&sa, buf); OGS_ADDR(&sa, buf);
prefixlen = contigmask( prefixlen = contigmask(
(uint8_t *)ipfw_rule->ip.local.mask, IPV4_BITLEN); (uint8_t *)permit_out_rule.ip.src.mask, IPV4_BITLEN);
if (prefixlen < 0) { if (prefixlen < 0) {
ogs_error("Invalid mask[%x:%x:%x:%x]", ogs_error("Invalid mask[%x:%x:%x:%x]",
ipfw_rule->ip.local.mask[0], permit_out_rule.ip.src.mask[0],
ipfw_rule->ip.local.mask[1], permit_out_rule.ip.src.mask[1],
ipfw_rule->ip.local.mask[2], permit_out_rule.ip.src.mask[2],
ipfw_rule->ip.local.mask[3]); permit_out_rule.ip.src.mask[3]);
return NULL; return NULL;
} else if (prefixlen == 0) { } else if (prefixlen == 0) {
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
@ -220,21 +239,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
ogs_assert_if_reached(); ogs_assert_if_reached();
} }
} else if (ipfw_rule->ipv6_local) { } else if (permit_out_rule.ipv6_src) {
sa.ogs_sa_family = AF_INET6; sa.ogs_sa_family = AF_INET6;
memcpy(&sa.sin6.sin6_addr, memcpy(&sa.sin6.sin6_addr,
ipfw_rule->ip.local.addr, sizeof(struct in6_addr)); permit_out_rule.ip.src.addr, sizeof(struct in6_addr));
OGS_ADDR(&sa, buf); OGS_ADDR(&sa, buf);
prefixlen = contigmask( prefixlen = contigmask(
(uint8_t *)ipfw_rule->ip.local.mask, IPV6_BITLEN); (uint8_t *)permit_out_rule.ip.src.mask, IPV6_BITLEN);
if (prefixlen < 0) { if (prefixlen < 0) {
ogs_error("Invalid mask[%x:%x:%x:%x]", ogs_error("Invalid mask[%x:%x:%x:%x]",
ipfw_rule->ip.local.mask[0], permit_out_rule.ip.src.mask[0],
ipfw_rule->ip.local.mask[1], permit_out_rule.ip.src.mask[1],
ipfw_rule->ip.local.mask[2], permit_out_rule.ip.src.mask[2],
ipfw_rule->ip.local.mask[3]); permit_out_rule.ip.src.mask[3]);
return NULL; return NULL;
} else if (prefixlen == 0) { } else if (prefixlen == 0) {
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
@ -249,35 +268,35 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
} else } else
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
if (ipfw_rule->port.local.low == ipfw_rule->port.local.high) { if (permit_out_rule.port.src.low == permit_out_rule.port.src.high) {
if (ipfw_rule->port.local.low == 0) { if (permit_out_rule.port.src.low == 0) {
/* Nothing */ /* Nothing */
} else { } else {
p = ogs_slprintf(p, last, " %d", ipfw_rule->port.local.low); p = ogs_slprintf(p, last, " %d", permit_out_rule.port.src.low);
} }
} else { } else {
p = ogs_slprintf(p, last, " %d-%d", p = ogs_slprintf(p, last, " %d-%d",
ipfw_rule->port.local.low, ipfw_rule->port.local.high); permit_out_rule.port.src.low, permit_out_rule.port.src.high);
} }
p = ogs_slprintf(p, last, " to"); p = ogs_slprintf(p, last, " to");
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
if (ipfw_rule->ipv4_remote) { if (permit_out_rule.ipv4_dst) {
sa.ogs_sa_family = AF_INET; sa.ogs_sa_family = AF_INET;
memcpy(&sa.sin.sin_addr, memcpy(&sa.sin.sin_addr,
ipfw_rule->ip.remote.addr, sizeof(struct in_addr)); permit_out_rule.ip.dst.addr, sizeof(struct in_addr));
OGS_ADDR(&sa, buf); OGS_ADDR(&sa, buf);
prefixlen = contigmask( prefixlen = contigmask(
(uint8_t *)ipfw_rule->ip.remote.mask, IPV4_BITLEN); (uint8_t *)permit_out_rule.ip.dst.mask, IPV4_BITLEN);
if (prefixlen < 0) { if (prefixlen < 0) {
ogs_error("Invalid mask[%x:%x:%x:%x]", ogs_error("Invalid mask[%x:%x:%x:%x]",
ipfw_rule->ip.remote.mask[0], permit_out_rule.ip.dst.mask[0],
ipfw_rule->ip.remote.mask[1], permit_out_rule.ip.dst.mask[1],
ipfw_rule->ip.remote.mask[2], permit_out_rule.ip.dst.mask[2],
ipfw_rule->ip.remote.mask[3]); permit_out_rule.ip.dst.mask[3]);
return NULL; return NULL;
} else if (prefixlen == 0) { } else if (prefixlen == 0) {
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
@ -290,21 +309,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
ogs_assert_if_reached(); ogs_assert_if_reached();
} }
} else if (ipfw_rule->ipv6_remote) { } else if (permit_out_rule.ipv6_dst) {
sa.ogs_sa_family = AF_INET6; sa.ogs_sa_family = AF_INET6;
memcpy(&sa.sin6.sin6_addr, memcpy(&sa.sin6.sin6_addr,
ipfw_rule->ip.remote.addr, sizeof(struct in6_addr)); permit_out_rule.ip.dst.addr, sizeof(struct in6_addr));
OGS_ADDR(&sa, buf); OGS_ADDR(&sa, buf);
prefixlen = contigmask( prefixlen = contigmask(
(uint8_t *)ipfw_rule->ip.remote.mask, IPV6_BITLEN); (uint8_t *)permit_out_rule.ip.dst.mask, IPV6_BITLEN);
if (prefixlen < 0) { if (prefixlen < 0) {
ogs_error("Invalid mask[%x:%x:%x:%x]", ogs_error("Invalid mask[%x:%x:%x:%x]",
ipfw_rule->ip.remote.mask[0], permit_out_rule.ip.dst.mask[0],
ipfw_rule->ip.remote.mask[1], permit_out_rule.ip.dst.mask[1],
ipfw_rule->ip.remote.mask[2], permit_out_rule.ip.dst.mask[2],
ipfw_rule->ip.remote.mask[3]); permit_out_rule.ip.dst.mask[3]);
return NULL; return NULL;
} else if (prefixlen == 0) { } else if (prefixlen == 0) {
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
@ -319,16 +338,48 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule)
} else } else
p = ogs_slprintf(p, last, " any"); p = ogs_slprintf(p, last, " any");
if (ipfw_rule->port.remote.low == ipfw_rule->port.remote.high) { if (permit_out_rule.port.dst.low == permit_out_rule.port.dst.high) {
if (ipfw_rule->port.remote.low == 0) { if (permit_out_rule.port.dst.low == 0) {
/* Nothing */ /* Nothing */
} else { } else {
p = ogs_slprintf(p, last, " %d", ipfw_rule->port.remote.low); p = ogs_slprintf(p, last, " %d", permit_out_rule.port.dst.low);
} }
} else { } else {
p = ogs_slprintf(p, last, " %d-%d", p = ogs_slprintf(p, last, " %d-%d",
ipfw_rule->port.remote.low, ipfw_rule->port.remote.high); permit_out_rule.port.dst.low, permit_out_rule.port.dst.high);
} }
return ogs_strdup(flow_description); return ogs_strdup(flow_description);
} }
ogs_ipfw_rule_t *ogs_ipfw_copy_and_swap(
ogs_ipfw_rule_t *dst, ogs_ipfw_rule_t *src)
{
ogs_assert(src);
ogs_assert(dst);
ogs_assert(src != dst);
memcpy(dst, src, sizeof(ogs_ipfw_rule_t));
dst->ipv4_src = src->ipv4_dst;
dst->ipv4_dst = src->ipv4_src;
dst->ipv6_src = src->ipv6_dst;
dst->ipv6_dst = src->ipv6_src;
memcpy(&dst->ip.src, &src->ip.dst, sizeof(dst->ip.src));
memcpy(&dst->ip.dst, &src->ip.src, sizeof(dst->ip.dst));
memcpy(&dst->port.src, &src->port.dst, sizeof(dst->port.src));
memcpy(&dst->port.dst, &src->port.src, sizeof(dst->port.dst));
return dst;
}
void ogs_ipfw_rule_swap(ogs_ipfw_rule_t *ipfw_rule)
{
ogs_ipfw_rule_t dst;
ogs_assert(ipfw_rule);
ogs_ipfw_copy_and_swap(&dst, ipfw_rule);
memcpy(ipfw_rule, &dst, sizeof(ogs_ipfw_rule_t));
}

View File

@ -29,30 +29,30 @@ extern "C" {
typedef struct ogs_ipfw_rule_s { typedef struct ogs_ipfw_rule_s {
uint8_t proto; uint8_t proto;
uint8_t ipv4_local; uint8_t ipv4_src;
uint8_t ipv4_remote; uint8_t ipv4_dst;
uint8_t ipv6_local; uint8_t ipv6_src;
uint8_t ipv6_remote; uint8_t ipv6_dst;
struct { struct {
struct { struct {
uint32_t addr[4]; uint32_t addr[4];
uint32_t mask[4]; uint32_t mask[4];
} local; } src;
struct { struct {
uint32_t addr[4]; uint32_t addr[4];
uint32_t mask[4]; uint32_t mask[4];
} remote; } dst;
} ip; } ip;
struct { struct {
struct { struct {
uint16_t low; uint16_t low;
uint16_t high; uint16_t high;
} local; } src;
struct { struct {
uint16_t low; uint16_t low;
uint16_t high; uint16_t high;
} remote; } dst;
} port; } port;
uint16_t tos_traffic_class; uint16_t tos_traffic_class;
@ -64,6 +64,28 @@ typedef struct ogs_ipfw_rule_s {
int ogs_ipfw_compile_rule(ogs_ipfw_rule_t *ipfw_rule, char *flow_description); int ogs_ipfw_compile_rule(ogs_ipfw_rule_t *ipfw_rule, char *flow_description);
char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule); char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule);
/*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* RX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*
* <UPLINK>
* RX : permit in from <UE_IP> <UE_PORT> to <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
ogs_ipfw_rule_t *ogs_ipfw_copy_and_swap(
ogs_ipfw_rule_t *dst, ogs_ipfw_rule_t *src);
void ogs_ipfw_rule_swap(ogs_ipfw_rule_t *ipfw_rule);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -789,10 +789,17 @@ void ogs_pfcp_gtpu_resource_remove_all(ogs_list_t *list)
ogs_pfcp_gtpu_resource_remove(list, resource); ogs_pfcp_gtpu_resource_remove(list, resource);
} }
ogs_pfcp_pdr_t *ogs_pfcp_sess_default_pdr(ogs_pfcp_sess_t *sess) ogs_pfcp_pdr_t *ogs_pfcp_sess_default_pdr(
ogs_pfcp_sess_t *sess, ogs_pfcp_interface_t src_if)
{ {
ogs_pfcp_pdr_t *pdr = NULL;
ogs_assert(sess); ogs_assert(sess);
return sess->default_pdr;
for (pdr = ogs_list_last(&sess->pdr_list); pdr; pdr = ogs_list_prev(pdr))
if (pdr->src_if == src_if) return pdr;
return NULL;
} }
void ogs_pfcp_sess_clear(ogs_pfcp_sess_t *sess) void ogs_pfcp_sess_clear(ogs_pfcp_sess_t *sess)

View File

@ -231,9 +231,6 @@ typedef struct ogs_pfcp_sess_s {
OGS_POOL(urr_id_pool, uint8_t); OGS_POOL(urr_id_pool, uint8_t);
OGS_POOL(qer_id_pool, uint8_t); OGS_POOL(qer_id_pool, uint8_t);
OGS_POOL(bar_id_pool, uint8_t); OGS_POOL(bar_id_pool, uint8_t);
/* Related Context */
ogs_pfcp_pdr_t *default_pdr; /* Used by UPF */
} ogs_pfcp_sess_t; } ogs_pfcp_sess_t;
typedef struct ogs_pfcp_subnet_s ogs_pfcp_subnet_t; typedef struct ogs_pfcp_subnet_s ogs_pfcp_subnet_t;
@ -308,14 +305,12 @@ void ogs_pfcp_gtpu_resource_remove(ogs_list_t *list,
ogs_pfcp_gtpu_resource_t *resource); ogs_pfcp_gtpu_resource_t *resource);
void ogs_pfcp_gtpu_resource_remove_all(ogs_list_t *list); void ogs_pfcp_gtpu_resource_remove_all(ogs_list_t *list);
#define OGS_SETUP_DEFAULT_PDR(__sESS, __pDR) \ #define OGS_DEFAULT_DL_PDR(__sESS) \
do { \ ogs_pfcp_sess_default_pdr(__sESS, OGS_PFCP_INTERFACE_CORE)
ogs_assert((__sESS)); \ #define OGS_DEFAULT_UL_PDR(__sESS) \
ogs_assert((__pDR)); \ ogs_pfcp_sess_default_pdr(__sESS, OGS_PFCP_INTERFACE_ACCESS)
(__sESS)->default_pdr = __pDR; \ ogs_pfcp_pdr_t *ogs_pfcp_sess_default_pdr(
ogs_assert((__sESS)->default_pdr); \ ogs_pfcp_sess_t *sess, ogs_pfcp_interface_t src_if);
} while(0)
ogs_pfcp_pdr_t *ogs_pfcp_sess_default_pdr(ogs_pfcp_sess_t *sess);
void ogs_pfcp_sess_clear(ogs_pfcp_sess_t *sess); void ogs_pfcp_sess_clear(ogs_pfcp_sess_t *sess);
ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess); ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess);

View File

@ -241,9 +241,45 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
rule = ogs_pfcp_rule_add(pdr); rule = ogs_pfcp_rule_add(pdr);
ogs_assert(rule); ogs_assert(rule);
rv = ogs_ipfw_compile_rule(&rule->ipfw, flow_description); rv = ogs_ipfw_compile_rule(&rule->ipfw, flow_description);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
/*
*
* TS29.244 Ch 5.2.1A.2A
*
* The UP function shall apply the SDF filter based on the Source Interface
* of the PDR as follows (see also clause 8.2.5):
*
* - when the Source Interface is CORE, this indicates that the filter is
* for downlink data flow, so the UP function shall apply
* the Flow Description as is;
*
* - when the Source Interface is ACCESS, this indicates that the filter is
* for uplink data flow, so the UP function shall swap the source and
* destination address/port in the Flow Description;
*
* - when the Source Interface is CP-function or SGi-LAN,
* the UP function shall use the Flow Description as is.
*
*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
/* Uplink data flow */
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS)
ogs_ipfw_rule_swap(&rule->ipfw);
ogs_free(flow_description); ogs_free(flow_description);
} }
} }
@ -368,6 +404,41 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess,
rv = ogs_ipfw_compile_rule(&rule->ipfw, flow_description); rv = ogs_ipfw_compile_rule(&rule->ipfw, flow_description);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
/*
*
* TS29.244 Ch 5.2.1A.2A
*
* The UP function shall apply the SDF filter based on the Source Interface
* of the PDR as follows (see also clause 8.2.5):
*
* - when the Source Interface is CORE, this indicates that the filter is
* for downlink data flow, so the UP function shall apply
* the Flow Description as is;
*
* - when the Source Interface is ACCESS, this indicates that the filter is
* for uplink data flow, so the UP function shall swap the source and
* destination address/port in the Flow Description;
*
* - when the Source Interface is CP-function or SGi-LAN,
* the UP function shall use the Flow Description as is.
*
*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
/* Uplink data flow */
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS)
ogs_ipfw_rule_swap(&rule->ipfw);
ogs_free(flow_description); ogs_free(flow_description);
} }

View File

@ -1338,6 +1338,7 @@ static int encode_pcc_rule_definition(
static int flow_rx_to_gx(ogs_flow_t *rx_flow, ogs_flow_t *gx_flow) static int flow_rx_to_gx(ogs_flow_t *rx_flow, ogs_flow_t *gx_flow)
{ {
int len; int len;
char *from_str, *to_str;
ogs_assert(rx_flow); ogs_assert(rx_flow);
ogs_assert(gx_flow); ogs_assert(gx_flow);
@ -1358,8 +1359,19 @@ static int flow_rx_to_gx(ogs_flow_t *rx_flow, ogs_flow_t *gx_flow)
len = strlen(rx_flow->description)+2; len = strlen(rx_flow->description)+2;
gx_flow->description = ogs_malloc(len); gx_flow->description = ogs_malloc(len);
strcpy(gx_flow->description, "permit out"); strcpy(gx_flow->description, "permit out");
strcat(gx_flow->description, from_str = strstr(&rx_flow->description[strlen("permit in")], "from");
&rx_flow->description[strlen("permit in")]); ogs_assert(from_str);
to_str = strstr(&rx_flow->description[strlen("permit in")], "to");
ogs_assert(to_str);
strncat(gx_flow->description,
&rx_flow->description[strlen("permit in")],
strlen(rx_flow->description) -
strlen("permit in") - strlen(from_str));
strcat(gx_flow->description, "from");
strcat(gx_flow->description, &to_str[strlen("to")]);
strcat(gx_flow->description, " to");
strncat(gx_flow->description, &from_str[strlen("from")],
strlen(from_str) - strlen(to_str) - strlen("from") - 1);
ogs_assert(len == strlen(gx_flow->description)+1); ogs_assert(len == strlen(gx_flow->description)+1);
} else { } else {
ogs_error("Invalid Flow Descripton : [%s]", rx_flow->description); ogs_error("Invalid Flow Descripton : [%s]", rx_flow->description);

View File

@ -362,8 +362,8 @@ int sgwu_context_parse_config(void)
return OGS_OK; return OGS_OK;
} }
sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *cp_f_seid, sgwu_sess_t *sgwu_sess_add(
const char *apn, uint8_t pdn_type, ogs_pfcp_pdr_id_t default_pdr_id) ogs_pfcp_f_seid_t *cp_f_seid, const char *apn, uint8_t pdn_type)
{ {
sgwu_sess_t *sess = NULL; sgwu_sess_t *sess = NULL;
@ -449,7 +449,6 @@ sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message)
ogs_pfcp_f_seid_t *f_seid = NULL; ogs_pfcp_f_seid_t *f_seid = NULL;
char apn[OGS_MAX_APN_LEN]; char apn[OGS_MAX_APN_LEN];
ogs_pfcp_pdr_id_t default_pdr_id = 0;
ogs_pfcp_session_establishment_request_t *req = ogs_pfcp_session_establishment_request_t *req =
&message->pfcp_session_establishment_request;; &message->pfcp_session_establishment_request;;
@ -497,8 +496,7 @@ sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message)
sess = sgwu_sess_find_by_cp_seid(f_seid->seid); sess = sgwu_sess_find_by_cp_seid(f_seid->seid);
if (!sess) { if (!sess) {
sess = sgwu_sess_add( sess = sgwu_sess_add(f_seid, apn, req->pdn_type.u8);
f_seid, apn, req->pdn_type.u8, default_pdr_id);
if (!sess) return NULL; if (!sess) return NULL;
} }
ogs_assert(sess); ogs_assert(sess);

View File

@ -72,8 +72,8 @@ int sgwu_context_parse_config(void);
sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message); sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message);
sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *f_seid, sgwu_sess_t *sgwu_sess_add(
const char *apn, uint8_t pdn_type, ogs_pfcp_pdr_id_t default_pdr_id); ogs_pfcp_f_seid_t *f_seid, const char *apn, uint8_t pdn_type);
int sgwu_sess_remove(sgwu_sess_t *sess); int sgwu_sess_remove(sgwu_sess_t *sess);
void sgwu_sess_remove_all(void); void sgwu_sess_remove_all(void);
sgwu_sess_t *sgwu_sess_find(uint32_t index); sgwu_sess_t *sgwu_sess_find(uint32_t index);

View File

@ -35,6 +35,17 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
"Message-Type[%d]", sess->sgw_s5c_teid, sess->smf_n4_teid, type); "Message-Type[%d]", sess->sgw_s5c_teid, sess->smf_n4_teid, type);
} }
/*
* Issue #338
*
* <DOWNLINK>
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*
* <UPLINK>
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
static void encode_traffic_flow_template( static void encode_traffic_flow_template(
ogs_gtp_tft_t *tft, smf_bearer_t *bearer) ogs_gtp_tft_t *tft, smf_bearer_t *bearer)
{ {
@ -62,76 +73,107 @@ static void encode_traffic_flow_template(
j++; len += 2; j++; len += 2;
} }
if (pf->ipfw_rule.ipv4_local) { if (pf->ipfw_rule.ipv4_src) {
tft->pf[i].component[j].type = if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE;
tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.local.addr[0];
tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.local.mask[0];
j++; len += 9;
}
if (pf->ipfw_rule.ipv4_remote) {
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE;
tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.remote.addr[0];
tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.remote.mask[0];
j++; len += 9;
}
if (pf->ipfw_rule.ipv6_local) {
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE;
memcpy(tft->pf[i].component[j].ipv6.addr,
pf->ipfw_rule.ip.local.addr,
sizeof pf->ipfw_rule.ip.local.addr);
tft->pf[i].component[j].ipv6.prefixlen =
contigmask((uint8_t *)pf->ipfw_rule.ip.local.mask, 128);
j++; len += 18;
}
if (pf->ipfw_rule.ipv6_remote) {
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE;
memcpy(tft->pf[i].component[j].ipv6.addr,
pf->ipfw_rule.ip.remote.addr,
sizeof pf->ipfw_rule.ip.remote.addr);
tft->pf[i].component[j].ipv6.prefixlen =
contigmask((uint8_t *)pf->ipfw_rule.ip.remote.mask, 128);
j++; len += 18;
}
if (pf->ipfw_rule.port.local.low) {
if (pf->ipfw_rule.port.local.low == pf->ipfw_rule.port.local.high)
{
tft->pf[i].component[j].type = tft->pf[i].component[j].type =
GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE;
tft->pf[i].component[j].port.low = pf->ipfw_rule.port.local.low; else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE;
tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.src.addr[0];
tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.src.mask[0];
j++; len += 9;
}
if (pf->ipfw_rule.ipv4_dst) {
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE;
tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.dst.addr[0];
tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.dst.mask[0];
j++; len += 9;
}
if (pf->ipfw_rule.ipv6_src) {
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE;
memcpy(tft->pf[i].component[j].ipv6.addr,
pf->ipfw_rule.ip.src.addr,
sizeof pf->ipfw_rule.ip.src.addr);
tft->pf[i].component[j].ipv6.prefixlen =
contigmask((uint8_t *)pf->ipfw_rule.ip.src.mask, 128);
j++; len += 18;
}
if (pf->ipfw_rule.ipv6_dst) {
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE;
memcpy(tft->pf[i].component[j].ipv6.addr,
pf->ipfw_rule.ip.dst.addr,
sizeof pf->ipfw_rule.ip.dst.addr);
tft->pf[i].component[j].ipv6.prefixlen =
contigmask((uint8_t *)pf->ipfw_rule.ip.dst.mask, 128);
j++; len += 18;
}
if (pf->ipfw_rule.port.src.low) {
if (pf->ipfw_rule.port.src.low == pf->ipfw_rule.port.src.high) {
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE;
tft->pf[i].component[j].port.low = pf->ipfw_rule.port.src.low;
j++; len += 3; j++; len += 3;
} else { } else {
tft->pf[i].component[j].type = if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE; tft->pf[i].component[j].type =
tft->pf[i].component[j].port.low = pf->ipfw_rule.port.local.low; GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE;
tft->pf[i].component[j].port.low = pf->ipfw_rule.port.src.low;
tft->pf[i].component[j].port.high = tft->pf[i].component[j].port.high =
pf->ipfw_rule.port.local.high; pf->ipfw_rule.port.src.high;
j++; len += 5; j++; len += 5;
} }
} }
if (pf->ipfw_rule.port.remote.low) { if (pf->ipfw_rule.port.dst.low) {
if (pf->ipfw_rule.port.remote.low == if (pf->ipfw_rule.port.dst.low == pf->ipfw_rule.port.dst.high) {
pf->ipfw_rule.port.remote.high) { if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
tft->pf[i].component[j].type = tft->pf[i].component[j].type =
GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE;
tft->pf[i].component[j].port.low = tft->pf[i].component[j].port.low =
pf->ipfw_rule.port.remote.low; pf->ipfw_rule.port.dst.low;
j++; len += 3; j++; len += 3;
} else { } else {
tft->pf[i].component[j].type = if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE; tft->pf[i].component[j].type =
GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE;
else
tft->pf[i].component[j].type =
GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE;
tft->pf[i].component[j].port.low = tft->pf[i].component[j].port.low =
pf->ipfw_rule.port.remote.low; pf->ipfw_rule.port.dst.low;
tft->pf[i].component[j].port.high = tft->pf[i].component[j].port.high =
pf->ipfw_rule.port.remote.high; pf->ipfw_rule.port.dst.high;
j++; len += 5; j++; len += 5;
} }
} }
@ -264,8 +306,26 @@ void smf_bearer_binding(smf_sess_t *sess)
pf->direction = flow->direction; pf->direction = flow->direction;
pf->flow_description = ogs_strdup(flow->description); pf->flow_description = ogs_strdup(flow->description);
rv = ogs_ipfw_compile_rule( rv = ogs_ipfw_compile_rule(
&pf->ipfw_rule, pf->flow_description); &pf->ipfw_rule, pf->flow_description);
/*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* -->
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
* -->
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
if (flow->direction == OGS_FLOW_UPLINK_ONLY)
ogs_ipfw_rule_swap(&pf->ipfw_rule);
if (rv != OGS_OK) { if (rv != OGS_OK) {
ogs_error("Invalid Flow-Description[%s]", ogs_error("Invalid Flow-Description[%s]",
pf->flow_description); pf->flow_description);

View File

@ -535,71 +535,75 @@ static int reconfigure_packet_filter(smf_pf_t *pf, ogs_gtp_tft_t *tft, int i)
{ {
int j; int j;
ogs_assert(pf);
ogs_assert(tft);
memset(&pf->ipfw_rule, 0, sizeof(ogs_ipfw_rule_t)); memset(&pf->ipfw_rule, 0, sizeof(ogs_ipfw_rule_t));
pf->direction = tft->pf[i].direction;
for (j = 0; j < tft->pf[i].num_of_component; j++) { for (j = 0; j < tft->pf[i].num_of_component; j++) {
switch(tft->pf[i].component[j].type) { switch(tft->pf[i].component[j].type) {
case GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: case GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE:
pf->ipfw_rule.proto = tft->pf[i].component[j].proto; pf->ipfw_rule.proto = tft->pf[i].component[j].proto;
break; break;
case GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: case GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE:
pf->ipfw_rule.ipv4_remote = 1; pf->ipfw_rule.ipv4_dst = 1;
pf->ipfw_rule.ip.remote.addr[0] = tft->pf[i].component[j].ipv4.addr; pf->ipfw_rule.ip.dst.addr[0] = tft->pf[i].component[j].ipv4.addr;
pf->ipfw_rule.ip.remote.mask[0] = tft->pf[i].component[j].ipv4.mask; pf->ipfw_rule.ip.dst.mask[0] = tft->pf[i].component[j].ipv4.mask;
break; break;
case GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: case GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE:
pf->ipfw_rule.ipv4_local = 1; pf->ipfw_rule.ipv4_src = 1;
pf->ipfw_rule.ip.local.addr[0] = tft->pf[i].component[j].ipv4.addr; pf->ipfw_rule.ip.src.addr[0] = tft->pf[i].component[j].ipv4.addr;
pf->ipfw_rule.ip.local.mask[0] = tft->pf[i].component[j].ipv4.mask; pf->ipfw_rule.ip.src.mask[0] = tft->pf[i].component[j].ipv4.mask;
break; break;
case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE:
pf->ipfw_rule.ipv6_remote = 1; pf->ipfw_rule.ipv6_dst = 1;
memcpy(pf->ipfw_rule.ip.remote.addr, memcpy(pf->ipfw_rule.ip.dst.addr,
tft->pf[i].component[j].ipv6_mask.addr, tft->pf[i].component[j].ipv6_mask.addr,
sizeof(pf->ipfw_rule.ip.remote.addr)); sizeof(pf->ipfw_rule.ip.dst.addr));
memcpy(pf->ipfw_rule.ip.remote.mask, memcpy(pf->ipfw_rule.ip.dst.mask,
tft->pf[i].component[j].ipv6_mask.mask, tft->pf[i].component[j].ipv6_mask.mask,
sizeof(pf->ipfw_rule.ip.remote.mask)); sizeof(pf->ipfw_rule.ip.dst.mask));
break; break;
case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE:
pf->ipfw_rule.ipv6_remote = 1; pf->ipfw_rule.ipv6_dst = 1;
memcpy(pf->ipfw_rule.ip.remote.addr, memcpy(pf->ipfw_rule.ip.dst.addr,
tft->pf[i].component[j].ipv6_mask.addr, tft->pf[i].component[j].ipv6_mask.addr,
sizeof(pf->ipfw_rule.ip.remote.addr)); sizeof(pf->ipfw_rule.ip.dst.addr));
n2mask((struct in6_addr *)pf->ipfw_rule.ip.remote.mask, n2mask((struct in6_addr *)pf->ipfw_rule.ip.dst.mask,
tft->pf[i].component[j].ipv6.prefixlen); tft->pf[i].component[j].ipv6.prefixlen);
break; break;
case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE:
pf->ipfw_rule.ipv6_local = 1; pf->ipfw_rule.ipv6_src = 1;
memcpy(pf->ipfw_rule.ip.local.addr, memcpy(pf->ipfw_rule.ip.src.addr,
tft->pf[i].component[j].ipv6_mask.addr, tft->pf[i].component[j].ipv6_mask.addr,
sizeof(pf->ipfw_rule.ip.local.addr)); sizeof(pf->ipfw_rule.ip.src.addr));
memcpy(pf->ipfw_rule.ip.local.mask, memcpy(pf->ipfw_rule.ip.src.mask,
tft->pf[i].component[j].ipv6_mask.mask, tft->pf[i].component[j].ipv6_mask.mask,
sizeof(pf->ipfw_rule.ip.local.mask)); sizeof(pf->ipfw_rule.ip.src.mask));
break; break;
case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE:
pf->ipfw_rule.ipv6_local = 1; pf->ipfw_rule.ipv6_src = 1;
memcpy(pf->ipfw_rule.ip.local.addr, memcpy(pf->ipfw_rule.ip.src.addr,
tft->pf[i].component[j].ipv6_mask.addr, tft->pf[i].component[j].ipv6_mask.addr,
sizeof(pf->ipfw_rule.ip.local.addr)); sizeof(pf->ipfw_rule.ip.src.addr));
n2mask((struct in6_addr *)pf->ipfw_rule.ip.local.mask, n2mask((struct in6_addr *)pf->ipfw_rule.ip.src.mask,
tft->pf[i].component[j].ipv6.prefixlen); tft->pf[i].component[j].ipv6.prefixlen);
break; break;
case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE:
pf->ipfw_rule.port.local.low = pf->ipfw_rule.port.local.high = pf->ipfw_rule.port.src.low = pf->ipfw_rule.port.src.high =
tft->pf[i].component[j].port.low; tft->pf[i].component[j].port.low;
break; break;
case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE:
pf->ipfw_rule.port.remote.low = pf->ipfw_rule.port.remote.high = pf->ipfw_rule.port.dst.low = pf->ipfw_rule.port.dst.high =
tft->pf[i].component[j].port.low; tft->pf[i].component[j].port.low;
break; break;
case GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: case GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE:
pf->ipfw_rule.port.local.low = tft->pf[i].component[j].port.low; pf->ipfw_rule.port.src.low = tft->pf[i].component[j].port.low;
pf->ipfw_rule.port.local.high = tft->pf[i].component[j].port.high; pf->ipfw_rule.port.src.high = tft->pf[i].component[j].port.high;
break; break;
case GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: case GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE:
pf->ipfw_rule.port.remote.low = tft->pf[i].component[j].port.low; pf->ipfw_rule.port.dst.low = tft->pf[i].component[j].port.low;
pf->ipfw_rule.port.remote.high = tft->pf[i].component[j].port.high; pf->ipfw_rule.port.dst.high = tft->pf[i].component[j].port.high;
break; break;
default: default:
ogs_error("Unknown Packet Filter Type(%d)", ogs_error("Unknown Packet Filter Type(%d)",
@ -692,12 +696,27 @@ void smf_s5c_handle_bearer_resource_command(
OGS_GTP_CAUSE_SEMANTIC_ERROR_IN_THE_TAD_OPERATION); OGS_GTP_CAUSE_SEMANTIC_ERROR_IN_THE_TAD_OPERATION);
return; return;
} }
/*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
ogs_ipfw_rule_swap(&pf->ipfw_rule);
if (pf->flow_description) if (pf->flow_description)
ogs_free(pf->flow_description); ogs_free(pf->flow_description);
pf->flow_description = pf->flow_description =
ogs_ipfw_encode_flow_description(&pf->ipfw_rule); ogs_ipfw_encode_flow_description(&pf->ipfw_rule);
pf->direction = tft.pf[i].direction;
} }
tft_update = 1; tft_update = 1;
@ -721,12 +740,27 @@ void smf_s5c_handle_bearer_resource_command(
OGS_GTP_CAUSE_SEMANTIC_ERROR_IN_THE_TAD_OPERATION); OGS_GTP_CAUSE_SEMANTIC_ERROR_IN_THE_TAD_OPERATION);
return; return;
} }
/*
* Refer to lib/ipfw/ogs-ipfw.h
* Issue #338
*
* <DOWNLINK>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
*
* <UPLINK>
* TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
* -->
* RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
*/
if (pf->direction == OGS_FLOW_DOWNLINK_ONLY)
ogs_ipfw_rule_swap(&pf->ipfw_rule);
if (pf->flow_description) if (pf->flow_description)
ogs_free(pf->flow_description); ogs_free(pf->flow_description);
pf->flow_description = pf->flow_description =
ogs_ipfw_encode_flow_description(&pf->ipfw_rule); ogs_ipfw_encode_flow_description(&pf->ipfw_rule);
pf->direction = tft.pf[i].direction;
tft_update = 1; tft_update = 1;
} }

View File

@ -373,8 +373,7 @@ int upf_context_parse_config(void)
} }
upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid, upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid,
const char *apn, uint8_t pdn_type, ogs_pfcp_ue_ip_addr_t *ue_ip, const char *apn, uint8_t pdn_type, ogs_pfcp_ue_ip_addr_t *ue_ip)
ogs_pfcp_pdr_id_t default_pdr_id)
{ {
char buf1[OGS_ADDRSTRLEN]; char buf1[OGS_ADDRSTRLEN];
char buf2[OGS_ADDRSTRLEN]; char buf2[OGS_ADDRSTRLEN];
@ -442,17 +441,12 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid,
goto cleanup; goto cleanup;
} }
/* Set Default PDR */
OGS_SETUP_DEFAULT_PDR(&sess->pfcp,
ogs_pfcp_pdr_find_or_add(&sess->pfcp, default_pdr_id));
ogs_info("UE F-SEID[CP:0x%lx,UP:0x%lx] " ogs_info("UE F-SEID[CP:0x%lx,UP:0x%lx] "
"APN[%s] PDN-Type[%d] IPv4[%s] IPv6[%s], Default PDR ID[%d]", "APN[%s] PDN-Type[%d] IPv4[%s] IPv6[%s]",
(long)sess->upf_n4_seid, (long)sess->smf_n4_seid, (long)sess->upf_n4_seid, (long)sess->smf_n4_seid,
apn, pdn_type, apn, pdn_type,
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "", sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "", sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
sess->pfcp.default_pdr->id);
ogs_list_add(&self.sess_list, sess); ogs_list_add(&self.sess_list, sess);
@ -541,7 +535,6 @@ upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message)
char apn[OGS_MAX_APN_LEN]; char apn[OGS_MAX_APN_LEN];
ogs_pfcp_ue_ip_addr_t *addr = NULL; ogs_pfcp_ue_ip_addr_t *addr = NULL;
bool default_pdr_found = false; bool default_pdr_found = false;
ogs_pfcp_pdr_id_t default_pdr_id;
ogs_pfcp_session_establishment_request_t *req = ogs_pfcp_session_establishment_request_t *req =
&message->pfcp_session_establishment_request;; &message->pfcp_session_establishment_request;;
@ -587,7 +580,6 @@ upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message)
if (message->pdi.source_interface.u8 != OGS_PFCP_INTERFACE_CORE) if (message->pdi.source_interface.u8 != OGS_PFCP_INTERFACE_CORE)
continue; continue;
default_pdr_id = message->pdr_id.u16;
ogs_fqdn_parse(apn, ogs_fqdn_parse(apn,
message->pdi.network_instance.data, message->pdi.network_instance.data,
message->pdi.network_instance.len); message->pdi.network_instance.len);
@ -614,8 +606,7 @@ upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message)
sess = upf_sess_find_by_cp_seid(f_seid->seid); sess = upf_sess_find_by_cp_seid(f_seid->seid);
if (!sess) { if (!sess) {
sess = upf_sess_add( sess = upf_sess_add(f_seid, apn, req->pdn_type.u8, addr);
f_seid, apn, req->pdn_type.u8, addr, default_pdr_id);
if (!sess) return NULL; if (!sess) return NULL;
} }
ogs_assert(sess); ogs_assert(sess);

View File

@ -89,8 +89,7 @@ int upf_context_parse_config(void);
upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message); upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message);
upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *f_seid, upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *f_seid,
const char *apn, uint8_t pdn_type, ogs_pfcp_ue_ip_addr_t *ue_ip, const char *apn, uint8_t pdn_type, ogs_pfcp_ue_ip_addr_t *ue_ip);
ogs_pfcp_pdr_id_t default_pdr_id);
int upf_sess_remove(upf_sess_t *sess); int upf_sess_remove(upf_sess_t *sess);
void upf_sess_remove_all(void); void upf_sess_remove_all(void);
upf_sess_t *upf_sess_find(uint32_t index); upf_sess_t *upf_sess_find(uint32_t index);

View File

@ -372,7 +372,7 @@ static void upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf)
/* PDN IPv6 is avaiable */ /* PDN IPv6 is avaiable */
ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_pdr_t *pdr = NULL;
pdr = ogs_pfcp_sess_default_pdr(&sess->pfcp); pdr = OGS_DEFAULT_DL_PDR(&sess->pfcp);
ogs_assert(pdr); ogs_assert(pdr);
ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report); ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report);
@ -434,7 +434,7 @@ static int upf_gtp_send_router_advertisement(
struct nd_opt_prefix_info *prefix = NULL; struct nd_opt_prefix_info *prefix = NULL;
ogs_assert(sess); ogs_assert(sess);
pdr = ogs_pfcp_sess_default_pdr(&sess->pfcp); pdr = OGS_DEFAULT_DL_PDR(&sess->pfcp);
ogs_assert(pdr); ogs_assert(pdr);
far = pdr->far; far = pdr->far;
ogs_assert(far); ogs_assert(far);

View File

@ -153,7 +153,7 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
if (sess) { if (sess) {
ogs_pfcp_pdr_t *default_pdr = NULL; ogs_pfcp_pdr_t *fallback_pdr = NULL;
ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_far_t *far = NULL; ogs_pfcp_far_t *far = NULL;
ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *rule = NULL;
@ -163,79 +163,71 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
if (ip6_h && sess->ipv6) if (ip6_h && sess->ipv6)
ogs_debug("PAA IPv6:%s", OGS_INET6_NTOP(&sess->ipv6->addr, buf)); ogs_debug("PAA IPv6:%s", OGS_INET6_NTOP(&sess->ipv6->addr, buf));
/* Save the default PDR */
default_pdr = ogs_pfcp_sess_default_pdr(&sess->pfcp);
ogs_assert(default_pdr);
/* Found */ /* Found */
ogs_debug("Found Session : Default PDR-ID[%d]", default_pdr->id);
ogs_list_for_each(&sess->pfcp.pdr_list, pdr) { ogs_list_for_each(&sess->pfcp.pdr_list, pdr) {
far = pdr->far;
ogs_assert(far);
/* Check if PDR is Downlink */
if (pdr->src_if != OGS_PFCP_INTERFACE_CORE)
continue;
/* Check if FAR is Downlink */
if (far->dst_if != OGS_PFCP_INTERFACE_ACCESS)
continue;
/* Save the Fallback PDR : Lowest precedence downlink PDR */
fallback_pdr = pdr;
/* Check if Outer header creation */
if (far->outer_header_creation.teid == 0)
continue;
ogs_list_for_each(&pdr->rule_list, rule) { ogs_list_for_each(&pdr->rule_list, rule) {
int k; int k;
uint32_t src_mask[4]; uint32_t src_mask[4];
uint32_t dst_mask[4]; uint32_t dst_mask[4];
ogs_ipfw_rule_t *ipfw = NULL; ogs_ipfw_rule_t *ipfw = NULL;
pdr = rule->pdr;
ogs_assert(pdr);
far = pdr->far;
ogs_assert(far);
ipfw = &rule->ipfw; ipfw = &rule->ipfw;
ogs_assert(ipfw); ogs_assert(ipfw);
/* Skip if PDR is default */
if (pdr->id == default_pdr->id)
continue;
/* Check if PDR is Downlink */
if (pdr->src_if != OGS_PFCP_INTERFACE_CORE)
continue;
/* Check if FAR is Downlink */
if (far->dst_if != OGS_PFCP_INTERFACE_ACCESS)
continue;
/* Check if Outer header creation */
if (far->outer_header_creation.teid == 0)
continue;
ogs_debug("PROTO:%d SRC:%d-%d DST:%d-%d", ogs_debug("PROTO:%d SRC:%d-%d DST:%d-%d",
ipfw->proto, ipfw->proto,
ipfw->port.local.low, ipfw->port.src.low,
ipfw->port.local.high, ipfw->port.src.high,
ipfw->port.remote.low, ipfw->port.dst.low,
ipfw->port.remote.high); ipfw->port.dst.high);
ogs_debug("SRC:%08x %08x %08x %08x/%08x %08x %08x %08x", ogs_debug("SRC:%08x %08x %08x %08x/%08x %08x %08x %08x",
be32toh(ipfw->ip.local.addr[0]), be32toh(ipfw->ip.src.addr[0]),
be32toh(ipfw->ip.local.addr[1]), be32toh(ipfw->ip.src.addr[1]),
be32toh(ipfw->ip.local.addr[2]), be32toh(ipfw->ip.src.addr[2]),
be32toh(ipfw->ip.local.addr[3]), be32toh(ipfw->ip.src.addr[3]),
be32toh(ipfw->ip.local.mask[0]), be32toh(ipfw->ip.src.mask[0]),
be32toh(ipfw->ip.local.mask[1]), be32toh(ipfw->ip.src.mask[1]),
be32toh(ipfw->ip.local.mask[2]), be32toh(ipfw->ip.src.mask[2]),
be32toh(ipfw->ip.local.mask[3])); be32toh(ipfw->ip.src.mask[3]));
ogs_debug("DST:%08x %08x %08x %08x/%08x %08x %08x %08x", ogs_debug("DST:%08x %08x %08x %08x/%08x %08x %08x %08x",
be32toh(ipfw->ip.remote.addr[0]), be32toh(ipfw->ip.dst.addr[0]),
be32toh(ipfw->ip.remote.addr[1]), be32toh(ipfw->ip.dst.addr[1]),
be32toh(ipfw->ip.remote.addr[2]), be32toh(ipfw->ip.dst.addr[2]),
be32toh(ipfw->ip.remote.addr[3]), be32toh(ipfw->ip.dst.addr[3]),
be32toh(ipfw->ip.remote.mask[0]), be32toh(ipfw->ip.dst.mask[0]),
be32toh(ipfw->ip.remote.mask[1]), be32toh(ipfw->ip.dst.mask[1]),
be32toh(ipfw->ip.remote.mask[2]), be32toh(ipfw->ip.dst.mask[2]),
be32toh(ipfw->ip.remote.mask[3])); be32toh(ipfw->ip.dst.mask[3]));
for (k = 0; k < 4; k++) { for (k = 0; k < 4; k++) {
src_mask[k] = src_addr[k] & ipfw->ip.local.mask[k]; src_mask[k] = src_addr[k] & ipfw->ip.src.mask[k];
dst_mask[k] = dst_addr[k] & ipfw->ip.remote.mask[k]; dst_mask[k] = dst_addr[k] & ipfw->ip.dst.mask[k];
} }
if (memcmp(src_mask, ipfw->ip.local.addr, addr_len) == 0 && if (memcmp(src_mask, ipfw->ip.src.addr, addr_len) == 0 &&
memcmp(dst_mask, ipfw->ip.remote.addr, addr_len) == 0) { memcmp(dst_mask, ipfw->ip.dst.addr, addr_len) == 0) {
/* Protocol match */ /* Protocol match */
if (ipfw->proto == 0) { /* IP */ if (ipfw->proto == 0) { /* IP */
/* No need to match port */ /* No need to match port */
break; goto found;
} }
if (ipfw->proto == proto) { if (ipfw->proto == proto) {
@ -244,80 +236,84 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
(struct tcphdr *)((char *)pkt->data + ip_hlen); (struct tcphdr *)((char *)pkt->data + ip_hlen);
/* Source port */ /* Source port */
if (ipfw->port.local.low && if (ipfw->port.src.low &&
be16toh(tcph->th_sport) < be16toh(tcph->th_sport) <
ipfw->port.local.low) { ipfw->port.src.low) {
continue; continue;
} }
if (ipfw->port.local.high && if (ipfw->port.src.high &&
be16toh(tcph->th_sport) > be16toh(tcph->th_sport) >
ipfw->port.local.high) { ipfw->port.src.high) {
continue; continue;
} }
/* Dst Port*/ /* Dst Port*/
if (ipfw->port.remote.low && if (ipfw->port.dst.low &&
be16toh(tcph->th_dport) < be16toh(tcph->th_dport) <
ipfw->port.remote.low) { ipfw->port.dst.low) {
continue; continue;
} }
if (ipfw->port.remote.high && if (ipfw->port.dst.high &&
be16toh(tcph->th_dport) > be16toh(tcph->th_dport) >
ipfw->port.remote.high) { ipfw->port.dst.high) {
continue; continue;
} }
/* Matched */ /* Matched */
break; goto found;
} else if (ipfw->proto == IPPROTO_UDP) { } else if (ipfw->proto == IPPROTO_UDP) {
struct udphdr *udph = struct udphdr *udph =
(struct udphdr *)((char *)pkt->data + ip_hlen); (struct udphdr *)((char *)pkt->data + ip_hlen);
/* Source port */ /* Source port */
if (ipfw->port.local.low && if (ipfw->port.src.low &&
be16toh(udph->uh_sport) < be16toh(udph->uh_sport) <
ipfw->port.local.low) { ipfw->port.src.low) {
continue; continue;
} }
if (ipfw->port.local.high && if (ipfw->port.src.high &&
be16toh(udph->uh_sport) > be16toh(udph->uh_sport) >
ipfw->port.local.high) { ipfw->port.src.high) {
continue; continue;
} }
/* Dst Port*/ /* Dst Port*/
if (ipfw->port.remote.low && if (ipfw->port.dst.low &&
be16toh(udph->uh_dport) < be16toh(udph->uh_dport) <
ipfw->port.remote.low) { ipfw->port.dst.low) {
continue; continue;
} }
if (ipfw->port.remote.high && if (ipfw->port.dst.high &&
be16toh(udph->uh_dport) > be16toh(udph->uh_dport) >
ipfw->port.remote.high) { ipfw->port.dst.high) {
continue; continue;
} }
/* Matched */ /* Matched */
break; goto found;
} else { } else {
/* No need to match port */ /* No need to match port */
break; goto found;
} }
} }
} }
} }
} }
found:
if (rule) { if (rule) {
ogs_debug("Found Dedicated PDR : PDR ID[%d]", pdr->id); ogs_fatal("Found Dedicated PDR : PDR ID[%d]", pdr->id);
return pdr; return pdr;
} }
return default_pdr; ogs_assert(fallback_pdr);
ogs_debug("Found Session : Fallback PDR-ID[%d]", fallback_pdr->id);
return fallback_pdr;
} else { } else {
ogs_debug("No Session"); ogs_debug("No Session");
} }

View File

@ -72,16 +72,16 @@ static void test1_func(abts_case *tc, void *data)
"}," "},"
"\"flow\" : [" "\"flow\" : ["
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23454\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23454 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50020 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50020\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } },"
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23455\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23455 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50021 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50021\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }" "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }"
"]" "]"
"}" "}"

View File

@ -377,7 +377,7 @@ void pcscf_rx_send_aar(uint8_t **rx_sid,
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC1 \ #define TEST_OGS_DIAM_RX_FLOW_DESC1 \
"permit out 17 from 172.20.166.84 to 172.18.128.20 20001" "permit out 17 from 172.20.166.84 to 10.45.0.2 20001"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC1; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC1;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC1); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC1);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -388,7 +388,7 @@ void pcscf_rx_send_aar(uint8_t **rx_sid,
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC2 \ #define TEST_OGS_DIAM_RX_FLOW_DESC2 \
"permit in 17 from 172.18.128.20 to 172.20.166.84 20360" "permit in 17 from 10.45.0.2 to 172.20.166.84 20360"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC2; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC2;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC2); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC2);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -421,7 +421,7 @@ void pcscf_rx_send_aar(uint8_t **rx_sid,
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC3 \ #define TEST_OGS_DIAM_RX_FLOW_DESC3 \
"permit out 17 from 172.20.166.84 to 172.18.128.20 20002" "permit out 17 from 172.20.166.84 to 10.45.0.2 20002"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC3; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC3;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC3); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC3);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -432,7 +432,7 @@ void pcscf_rx_send_aar(uint8_t **rx_sid,
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC4 \ #define TEST_OGS_DIAM_RX_FLOW_DESC4 \
"permit in 17 from 172.18.128.20 to 172.20.166.84 20361" "permit in 17 from 10.45.0.2 to 172.20.166.84 20361"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC4; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC4;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC4); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC4);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -670,7 +670,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC5 \ #define TEST_OGS_DIAM_RX_FLOW_DESC5 \
"permit out 17 from 45.45.0.3 50022 to 45.45.0.5 50026" "permit out 17 from 45.45.0.5 50026 to 45.45.0.3 50022"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC5; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC5;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC5); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC5);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -681,7 +681,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC6 \ #define TEST_OGS_DIAM_RX_FLOW_DESC6 \
"permit in 17 from 45.45.0.5 50026 to 45.45.0.3 50022" "permit in 17 from 45.45.0.3 50022 to 45.45.0.5 50026"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC6; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC6;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC6); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC6);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -692,7 +692,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC7 \ #define TEST_OGS_DIAM_RX_FLOW_DESC7 \
"permit out 17 from 45.45.0.3 50023 to 45.45.0.5 50027" "permit out 17 from 45.45.0.5 50027 to 45.45.0.3 50023"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC7; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC7;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC7); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC7);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -703,7 +703,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC8 \ #define TEST_OGS_DIAM_RX_FLOW_DESC8 \
"permit in 17 from 45.45.0.5 50027 to 45.45.0.3 50023" "permit in 17 from 45.45.0.3 50023 to 45.45.0.5 50027"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC8; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC8;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC8); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC8);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -854,7 +854,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC9 \ #define TEST_OGS_DIAM_RX_FLOW_DESC9 \
"permit out 17 from 45.45.0.3 60010 to 45.45.0.5 60010" "permit out 17 from 45.45.0.5 60010 to 45.45.0.3 60010"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC9; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC9;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC9); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC9);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -865,7 +865,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC10 \ #define TEST_OGS_DIAM_RX_FLOW_DESC10 \
"permit in 17 from 45.45.0.5 60010 to 45.45.0.3 60010" "permit in 17 from 45.45.0.3 60010 to 45.45.0.5 60010"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC10; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC10;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC10); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC10);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -876,7 +876,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC11 \ #define TEST_OGS_DIAM_RX_FLOW_DESC11 \
"permit out 17 from 45.45.0.3 60011 to 45.45.0.5 60011" "permit out 17 from 45.45.0.5 60011 to 45.45.0.3 60011"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC11; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC11;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC11); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC11);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);
@ -887,7 +887,7 @@ void pcscf_rx_send_aar2(uint8_t **rx_sid, test_sess_t *sess, int id_type)
ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2);
ogs_assert(ret == 0); ogs_assert(ret == 0);
#define TEST_OGS_DIAM_RX_FLOW_DESC12 \ #define TEST_OGS_DIAM_RX_FLOW_DESC12 \
"permit in 17 from 45.45.0.5 60011 to 45.45.0.3 60011" "permit in 17 from 45.45.0.3 60011 to 45.45.0.5 60011"
val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC12; val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC12;
val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC12); val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC12);
ret = fd_msg_avp_setvalue (avpch2, &val); ret = fd_msg_avp_setvalue (avpch2, &val);

View File

@ -695,16 +695,16 @@ static void test2_func(abts_case *tc, void *data)
"}," "},"
"\"flow\" : [" "\"flow\" : ["
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23454\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23454 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50020 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50020\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } },"
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23455\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23455 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50021 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50021\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }" "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }"
"]" "]"
"}" "}"

View File

@ -85,16 +85,16 @@ static void test1_func(abts_case *tc, void *data)
"}," "},"
"\"flow\" : [" "\"flow\" : ["
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23454\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23454 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50020 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50020\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } },"
"{ \"direction\" : 2," "{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23455\"," "\"description\" : \"permit out udp from 10.200.136.98/32 23455 to any 1-65535\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } },"
"{ \"direction\" : 1," "{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50021 to 10.200.136.98/32 1-65535\"," "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to any 50021\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }" "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }"
"]" "]"
"}" "}"