diff --git a/lib/ipfw/ogs-ipfw.c b/lib/ipfw/ogs-ipfw.c index 87db15f8b..23e0a981c 100644 --- a/lib/ipfw/ogs-ipfw.c +++ b/lib/ipfw/ogs-ipfw.c @@ -174,34 +174,16 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) char buf[OGS_ADDRSTRLEN]; ogs_sockaddr_t sa; int prefixlen = 0; - ogs_ipfw_rule_t permit_out_rule; p = flow_description; last = flow_description + OGS_HUGE_LEN; ogs_assert(ipfw_rule); -/* - * Issue #338 - * - * - * RULE : Source Destination - * --> - * GX : permit out from to - * PFCP : permit out from to - * - * - * RULE : Source Destination - * --> - * GX : permit out from to - * PFCP : permit out from to - */ - ogs_ipfw_copy_and_swap(&permit_out_rule, ipfw_rule); - p = ogs_slprintf(p, last, "permit out"); - if (permit_out_rule.proto) { - p = ogs_slprintf(p, last, " %d", permit_out_rule.proto); + if (ipfw_rule->proto) { + p = ogs_slprintf(p, last, " %d", ipfw_rule->proto); } else { p = ogs_slprintf(p, last, " ip"); } @@ -212,21 +194,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) p = ogs_slprintf(p, last, " from"); memset(&sa, 0, sizeof(sa)); - if (permit_out_rule.ipv4_src) { + if (ipfw_rule->ipv4_src) { sa.ogs_sa_family = AF_INET; memcpy(&sa.sin.sin_addr, - permit_out_rule.ip.src.addr, sizeof(struct in_addr)); + ipfw_rule->ip.src.addr, sizeof(struct in_addr)); OGS_ADDR(&sa, buf); prefixlen = contigmask( - (uint8_t *)permit_out_rule.ip.src.mask, IPV4_BITLEN); + (uint8_t *)ipfw_rule->ip.src.mask, IPV4_BITLEN); if (prefixlen < 0) { ogs_error("Invalid mask[%x:%x:%x:%x]", - permit_out_rule.ip.src.mask[0], - permit_out_rule.ip.src.mask[1], - permit_out_rule.ip.src.mask[2], - permit_out_rule.ip.src.mask[3]); + ipfw_rule->ip.src.mask[0], + ipfw_rule->ip.src.mask[1], + ipfw_rule->ip.src.mask[2], + ipfw_rule->ip.src.mask[3]); return NULL; } else if (prefixlen == 0) { p = ogs_slprintf(p, last, " any"); @@ -239,21 +221,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) ogs_assert_if_reached(); } - } else if (permit_out_rule.ipv6_src) { + } else if (ipfw_rule->ipv6_src) { sa.ogs_sa_family = AF_INET6; memcpy(&sa.sin6.sin6_addr, - permit_out_rule.ip.src.addr, sizeof(struct in6_addr)); + ipfw_rule->ip.src.addr, sizeof(struct in6_addr)); OGS_ADDR(&sa, buf); prefixlen = contigmask( - (uint8_t *)permit_out_rule.ip.src.mask, IPV6_BITLEN); + (uint8_t *)ipfw_rule->ip.src.mask, IPV6_BITLEN); if (prefixlen < 0) { ogs_error("Invalid mask[%x:%x:%x:%x]", - permit_out_rule.ip.src.mask[0], - permit_out_rule.ip.src.mask[1], - permit_out_rule.ip.src.mask[2], - permit_out_rule.ip.src.mask[3]); + ipfw_rule->ip.src.mask[0], + ipfw_rule->ip.src.mask[1], + ipfw_rule->ip.src.mask[2], + ipfw_rule->ip.src.mask[3]); return NULL; } else if (prefixlen == 0) { p = ogs_slprintf(p, last, " any"); @@ -268,35 +250,35 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) } else p = ogs_slprintf(p, last, " any"); - if (permit_out_rule.port.src.low == permit_out_rule.port.src.high) { - if (permit_out_rule.port.src.low == 0) { + if (ipfw_rule->port.src.low == ipfw_rule->port.src.high) { + if (ipfw_rule->port.src.low == 0) { /* Nothing */ } else { - p = ogs_slprintf(p, last, " %d", permit_out_rule.port.src.low); + p = ogs_slprintf(p, last, " %d", ipfw_rule->port.src.low); } } else { p = ogs_slprintf(p, last, " %d-%d", - permit_out_rule.port.src.low, permit_out_rule.port.src.high); + ipfw_rule->port.src.low, ipfw_rule->port.src.high); } p = ogs_slprintf(p, last, " to"); memset(&sa, 0, sizeof(sa)); - if (permit_out_rule.ipv4_dst) { + if (ipfw_rule->ipv4_dst) { sa.ogs_sa_family = AF_INET; memcpy(&sa.sin.sin_addr, - permit_out_rule.ip.dst.addr, sizeof(struct in_addr)); + ipfw_rule->ip.dst.addr, sizeof(struct in_addr)); OGS_ADDR(&sa, buf); prefixlen = contigmask( - (uint8_t *)permit_out_rule.ip.dst.mask, IPV4_BITLEN); + (uint8_t *)ipfw_rule->ip.dst.mask, IPV4_BITLEN); if (prefixlen < 0) { ogs_error("Invalid mask[%x:%x:%x:%x]", - permit_out_rule.ip.dst.mask[0], - permit_out_rule.ip.dst.mask[1], - permit_out_rule.ip.dst.mask[2], - permit_out_rule.ip.dst.mask[3]); + ipfw_rule->ip.dst.mask[0], + ipfw_rule->ip.dst.mask[1], + ipfw_rule->ip.dst.mask[2], + ipfw_rule->ip.dst.mask[3]); return NULL; } else if (prefixlen == 0) { p = ogs_slprintf(p, last, " any"); @@ -309,21 +291,21 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) ogs_assert_if_reached(); } - } else if (permit_out_rule.ipv6_dst) { + } else if (ipfw_rule->ipv6_dst) { sa.ogs_sa_family = AF_INET6; memcpy(&sa.sin6.sin6_addr, - permit_out_rule.ip.dst.addr, sizeof(struct in6_addr)); + ipfw_rule->ip.dst.addr, sizeof(struct in6_addr)); OGS_ADDR(&sa, buf); prefixlen = contigmask( - (uint8_t *)permit_out_rule.ip.dst.mask, IPV6_BITLEN); + (uint8_t *)ipfw_rule->ip.dst.mask, IPV6_BITLEN); if (prefixlen < 0) { ogs_error("Invalid mask[%x:%x:%x:%x]", - permit_out_rule.ip.dst.mask[0], - permit_out_rule.ip.dst.mask[1], - permit_out_rule.ip.dst.mask[2], - permit_out_rule.ip.dst.mask[3]); + ipfw_rule->ip.dst.mask[0], + ipfw_rule->ip.dst.mask[1], + ipfw_rule->ip.dst.mask[2], + ipfw_rule->ip.dst.mask[3]); return NULL; } else if (prefixlen == 0) { p = ogs_slprintf(p, last, " any"); @@ -338,15 +320,15 @@ char *ogs_ipfw_encode_flow_description(ogs_ipfw_rule_t *ipfw_rule) } else p = ogs_slprintf(p, last, " any"); - if (permit_out_rule.port.dst.low == permit_out_rule.port.dst.high) { - if (permit_out_rule.port.dst.low == 0) { + if (ipfw_rule->port.dst.low == ipfw_rule->port.dst.high) { + if (ipfw_rule->port.dst.low == 0) { /* Nothing */ } else { - p = ogs_slprintf(p, last, " %d", permit_out_rule.port.dst.low); + p = ogs_slprintf(p, last, " %d", ipfw_rule->port.dst.low); } } else { p = ogs_slprintf(p, last, " %d-%d", - permit_out_rule.port.dst.low, permit_out_rule.port.dst.high); + ipfw_rule->port.dst.low, ipfw_rule->port.dst.high); } return ogs_strdup(flow_description); diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 3ed8920f1..3d7e712d5 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -715,8 +715,30 @@ void smf_s5c_handle_bearer_resource_command( if (pf->flow_description) ogs_free(pf->flow_description); - pf->flow_description = - ogs_ipfw_encode_flow_description(&pf->ipfw_rule); +/* + * Issue #338 + * + * + * RULE : Source Destination + * --> + * GX : permit out from to + * PFCP : permit out from to + * + * + * RULE : Source Destination + * --> + * GX : permit out from to + * PFCP : permit out from to + */ + if (pf->direction == OGS_FLOW_UPLINK_ONLY) { + ogs_ipfw_rule_t tmp; + ogs_ipfw_copy_and_swap(&tmp, &pf->ipfw_rule); + pf->flow_description = + ogs_ipfw_encode_flow_description(&tmp); + } else { + pf->flow_description = + ogs_ipfw_encode_flow_description(&pf->ipfw_rule); + } } tft_update = 1; @@ -759,8 +781,31 @@ void smf_s5c_handle_bearer_resource_command( if (pf->flow_description) ogs_free(pf->flow_description); - pf->flow_description = - ogs_ipfw_encode_flow_description(&pf->ipfw_rule); + +/* + * Issue #338 + * + * + * RULE : Source Destination + * --> + * GX : permit out from to + * PFCP : permit out from to + * + * + * RULE : Source Destination + * --> + * GX : permit out from to + * PFCP : permit out from to + */ + if (pf->direction == OGS_FLOW_UPLINK_ONLY) { + ogs_ipfw_rule_t tmp; + ogs_ipfw_copy_and_swap(&tmp, &pf->ipfw_rule); + pf->flow_description = + ogs_ipfw_encode_flow_description(&tmp); + } else { + pf->flow_description = + ogs_ipfw_encode_flow_description(&pf->ipfw_rule); + } tft_update = 1; } diff --git a/tests/common/esm-build.c b/tests/common/esm-build.c index 5bc9af177..a2be7dce1 100644 --- a/tests/common/esm-build.c +++ b/tests/common/esm-build.c @@ -424,7 +424,7 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( } else if (tft.code == OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT) { tft.num_of_packet_filter = 1; - tft.pf[0].direction = 1; + tft.pf[0].direction = 2; tft.pf[0].identifier = 4; tft.pf[0].precedence = 0x0f; @@ -433,14 +433,14 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( #if 1 tft.pf[0].length = 18; tft.pf[0].component[0].type = - GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE; + GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; memcpy(tft.pf[0].component[0].ipv6.addr, ipsubnet.sub, sizeof(tft.pf[0].component[0].ipv6.addr)); tft.pf[0].component[0].ipv6.prefixlen = 120; #else tft.pf[0].length = 33; tft.pf[0].component[0].type = - GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE; + GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE; memcpy(tft.pf[0].component[0].ipv6_mask.addr, ipsubnet.sub, sizeof(tft.pf[0].component[0].ipv6_mask.addr)); memcpy(tft.pf[0].component[0].ipv6_mask.mask, ipsubnet.mask,