TFT rule for IPv6 is added

This commit is contained in:
Sukchan Lee 2017-12-15 20:53:53 +09:00
parent 08b88eba73
commit d0530877c2
6 changed files with 106 additions and 5 deletions

View File

@ -183,7 +183,45 @@ c_int16_t gtp_build_tft(
sizeof(target.pf[i].component[j].ipv4.mask));
size += sizeof(target.pf[i].component[j].ipv4.mask);
break;
case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE:
case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE:
d_assert(size +
sizeof(target.pf[i].component[j].ipv6.addr)
<= data_len,
return -1, "encode error");
memcpy(octet->data + size,
&target.pf[i].component[j].ipv6.addr,
sizeof(target.pf[i].component[j].ipv6.addr));
size += sizeof(target.pf[i].component[j].ipv6.addr);
d_assert(size +
sizeof(target.pf[i].component[j].ipv6.prefixlen)
<= data_len,
return -1, "encode error");
memcpy(octet->data + size,
&target.pf[i].component[j].ipv6.prefixlen,
sizeof(target.pf[i].component[j].ipv6.prefixlen));
size += sizeof(target.pf[i].component[j].ipv6.prefixlen);
break;
case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE:
d_assert(size +
sizeof(target.pf[i].component[j].ipv6_mask.addr)
<= data_len,
return -1, "encode error");
memcpy(octet->data + size,
&target.pf[i].component[j].ipv6_mask.addr,
sizeof(target.pf[i].component[j].ipv6_mask.addr));
size += sizeof(target.pf[i].component[j].ipv6_mask.addr);
d_assert(size +
sizeof(target.pf[i].component[j].ipv6_mask.mask)
<= data_len,
return -1, "encode error");
memcpy(octet->data + size,
&target.pf[i].component[j].ipv6_mask.mask,
sizeof(target.pf[i].component[j].ipv6_mask.mask));
size += sizeof(target.pf[i].component[j].ipv6_mask.mask);
break;
case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE:
case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE:
d_assert(size +

View File

@ -224,6 +224,7 @@ ED3(c_uint8_t code:3;,
#define GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE 17
#define GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE 32
#define GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE 33
#define GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE 34
#define GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE 35
#define GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE 64
#define GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE 65
@ -240,6 +241,14 @@ ED3(c_uint8_t code:3;,
c_uint32_t addr;
c_uint32_t mask;
} ipv4;
struct {
c_uint32_t addr[4];
c_uint8_t prefixlen;
} ipv6;
struct {
c_uint32_t addr[4];
c_uint32_t mask[4];
} ipv6_mask;
struct {
c_uint16_t low;
c_uint16_t high;

View File

@ -129,6 +129,11 @@ typedef struct _pgw_bearer_t {
typedef struct _pgw_rule_t {
c_uint8_t proto;
ED5(c_uint8_t ipv4_local:1;,
c_uint8_t ipv4_remote:1;,
c_uint8_t ipv6_local:1;,
c_uint8_t ipv6_remote:1;,
c_uint8_t reserved:4;)
struct {
struct {
c_uint32_t addr[4];

View File

@ -78,18 +78,19 @@ status_t pgw_compile_packet_filter(pgw_rule_t *pgw_rule, c_int8_t *description)
case O_IP_SRC_MASK:
{
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
pgw_rule->ipv4_local = 1;
pgw_rule->ip.local.addr[0] = a[0];
if (cmd->opcode == O_IP_SRC_MASK)
pgw_rule->ip.local.mask[0] = a[1];
else
pgw_rule->ip.local.mask[0] = 0xffffffff;
break;
}
case O_IP_DST:
case O_IP_DST_MASK:
{
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
pgw_rule->ipv4_remote = 1;
pgw_rule->ip.remote.addr[0] = a[0];
if (cmd->opcode == O_IP_DST_MASK)
pgw_rule->ip.remote.mask[0] = a[1];
@ -97,6 +98,30 @@ status_t pgw_compile_packet_filter(pgw_rule_t *pgw_rule, c_int8_t *description)
pgw_rule->ip.remote.mask[0] = 0xffffffff;
break;
}
case O_IP6_SRC:
case O_IP6_SRC_MASK:
{
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
pgw_rule->ipv6_local = 1;
memcpy(pgw_rule->ip.local.addr, a, IPV6_LEN);
if (cmd->opcode == O_IP6_SRC_MASK)
memcpy(pgw_rule->ip.local.mask, a+4, IPV6_LEN);
else
n2mask((struct in6_addr *)pgw_rule->ip.local.mask, 128);
break;
}
case O_IP6_DST:
case O_IP6_DST_MASK:
{
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
pgw_rule->ipv6_remote = 1;
memcpy(pgw_rule->ip.remote.addr, a, IPV6_LEN);
if (cmd->opcode == O_IP6_DST_MASK)
memcpy(pgw_rule->ip.remote.mask, a+4, IPV6_LEN);
else
n2mask((struct in6_addr *)pgw_rule->ip.remote.mask, 128);
break;
}
case O_IP_SRCPORT:
{
uint16_t *p = ((ipfw_insn_u16 *)cmd)->ports;

View File

@ -8,6 +8,8 @@
#include "gtp_message.h"
#include "gx_message.h"
#include "ipfw2.h"
#include "pgw_context.h"
static c_int16_t pgw_pco_build(c_uint8_t *pco_buf, tlv_pco_t *tlv_pco);
@ -248,7 +250,7 @@ status_t pgw_s5c_build_create_bearer_request(
j++; len += 2;
}
if (pf->rule.ip.local.addr[0])
if (pf->rule.ipv4_local)
{
tft.pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE;
@ -257,7 +259,7 @@ status_t pgw_s5c_build_create_bearer_request(
j++; len += 9;
}
if (pf->rule.ip.remote.addr)
if (pf->rule.ipv4_remote)
{
tft.pf[i].component[j].type =
GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE;
@ -266,6 +268,28 @@ status_t pgw_s5c_build_create_bearer_request(
j++; len += 9;
}
if (pf->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->rule.ip.local.addr,
sizeof pf->rule.ip.local.addr);
tft.pf[i].component[j].ipv6.prefixlen =
contigmask((c_uint8_t *)pf->rule.ip.local.mask, 128);
j++; len += 18;
}
if (pf->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->rule.ip.remote.addr,
sizeof pf->rule.ip.remote.addr);
tft.pf[i].component[j].ipv6.prefixlen =
contigmask((c_uint8_t *)pf->rule.ip.remote.mask, 128);
j++; len += 18;
}
if (pf->rule.port.local.low)
{
if (pf->rule.port.local.low == pf->rule.port.local.high)

View File

@ -374,10 +374,10 @@ static void volte_test2(abts_case *tc, void *data)
"\"description\" : \"permit out ip from 45.45.0.1 to any\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } },"
"{ \"direction\" : 2,"
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23455\","
"\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/24 23455\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } },"
"{ \"direction\" : 1,"
"\"description\" : \"permit out udp from any 50021 to 10.200.136.98/32 1-65535\","
"\"description\" : \"permit out ip from cafe::1 to any\","
"\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } } ]"
"} ],"
"\"ambr\" : {"