[dpdk-dev] [PATCH v3 8/9] examples/ipsec-secgw: transport mode support

Sergio Gonzalez Monroy sergio.gonzalez.monroy at intel.com
Thu Jun 9 10:42:49 CEST 2016


IPSec transport mode support.

Signed-off-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy at intel.com>
---
 examples/ipsec-secgw/esp.c   | 124 ++++++++++++++++++++++++++++++-------------
 examples/ipsec-secgw/ipsec.h |   1 +
 examples/ipsec-secgw/rt.c    |  32 +++++++++++
 examples/ipsec-secgw/sa.c    |  39 ++++++++++++++
 examples/ipsec-secgw/sp4.c   |  40 ++++++++++++++
 examples/ipsec-secgw/sp6.c   |  48 +++++++++++++++++
 6 files changed, 248 insertions(+), 36 deletions(-)

diff --git a/examples/ipsec-secgw/esp.c b/examples/ipsec-secgw/esp.c
index e1fde36..05caa77 100644
--- a/examples/ipsec-secgw/esp.c
+++ b/examples/ipsec-secgw/esp.c
@@ -42,7 +42,6 @@
 #include <unistd.h>
 
 #include <rte_common.h>
-#include <rte_memcpy.h>
 #include <rte_crypto.h>
 #include <rte_cryptodev.h>
 #include <rte_random.h>
@@ -70,21 +69,24 @@ int
 esp_inbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 		struct rte_crypto_op *cop)
 {
-	int32_t payload_len, ip_hdr_len;
+	struct ip *ip4;
 	struct rte_crypto_sym_op *sym_cop;
+	int32_t payload_len, ip_hdr_len;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	ip_hdr_len = 0;
-	switch (sa->flags) {
-	case IP4_TUNNEL:
-		ip_hdr_len = sizeof(struct ip);
-		break;
-	case IP6_TUNNEL:
+	ip4 = rte_pktmbuf_mtod(m, struct ip *);
+	if (likely(ip4->ip_v == IPVERSION))
+		ip_hdr_len = ip4->ip_hl * 4;
+	else if (ip4->ip_v == IP6_VERSION)
+		/* XXX No option headers supported */
 		ip_hdr_len = sizeof(struct ip6_hdr);
-		break;
+	else {
+		RTE_LOG(ERR, IPSEC_ESP, "invalid IP packet type %d\n",
+				ip4->ip_v);
+		return -EINVAL;
 	}
 
 	payload_len = rte_pktmbuf_pkt_len(m) - ip_hdr_len -
@@ -126,6 +128,8 @@ int
 esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 		struct rte_crypto_op *cop)
 {
+	struct ip *ip4, *ip;
+	struct ip6_hdr *ip6;
 	uint8_t *nexthdr, *pad_len;
 	uint8_t *padding;
 	uint16_t i;
@@ -135,7 +139,7 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	RTE_ASSERT(cop != NULL);
 
 	if (cop->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
-		RTE_LOG(ERR, IPSEC_ESP, "Failed crypto op\n");
+		RTE_LOG(ERR, IPSEC_ESP, "failed crypto op\n");
 		return -1;
 	}
 
@@ -146,7 +150,7 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 	padding = pad_len - *pad_len;
 	for (i = 0; i < *pad_len; i++) {
 		if (padding[i] != i + 1) {
-			RTE_LOG(ERR, IPSEC_ESP, "invalid pad_len field\n");
+			RTE_LOG(ERR, IPSEC_ESP, "invalid padding\n");
 			return -EINVAL;
 		}
 	}
@@ -157,7 +161,23 @@ esp_inbound_post(struct rte_mbuf *m, struct ipsec_sa *sa,
 		return -EINVAL;
 	}
 
-	ipip_inbound(m, sizeof(struct esp_hdr) + sa->iv_len);
+	if (unlikely(sa->flags == TRANSPORT)) {
+		ip = rte_pktmbuf_mtod(m, struct ip *);
+		ip4 = (struct ip *)rte_pktmbuf_adj(m,
+				sizeof(struct esp_hdr) + sa->iv_len);
+		if (likely(ip->ip_v == IPVERSION)) {
+			memmove(ip4, ip, ip->ip_hl * 4);
+			ip4->ip_p = *nexthdr;
+			ip4->ip_len = htons(rte_pktmbuf_data_len(m));
+		} else {
+			ip6 = (struct ip6_hdr *)ip4;
+			/* XXX No option headers supported */
+			memmove(ip6, ip, sizeof(struct ip6_hdr));
+			ip6->ip6_nxt = *nexthdr;
+			ip6->ip6_plen = htons(rte_pktmbuf_data_len(m));
+		}
+	} else
+		ipip_inbound(m, sizeof(struct esp_hdr) + sa->iv_len);
 
 	return 0;
 }
@@ -166,31 +186,57 @@ int
 esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 		struct rte_crypto_op *cop)
 {
-	uint16_t pad_payload_len, pad_len, ip_hdr_len;
 	struct ip *ip4;
 	struct ip6_hdr *ip6;
-	struct esp_hdr *esp;
-	int32_t i;
-	char *padding;
+	struct esp_hdr *esp = NULL;
+	uint8_t *padding, *new_ip, nlp;
 	struct rte_crypto_sym_op *sym_cop;
+	int32_t i;
+	uint16_t pad_payload_len, pad_len, ip_hdr_len;
 
 	RTE_ASSERT(m != NULL);
 	RTE_ASSERT(sa != NULL);
 	RTE_ASSERT(cop != NULL);
 
-	/* Payload length */
-	pad_payload_len = RTE_ALIGN_CEIL(rte_pktmbuf_pkt_len(m) + 2,
-			sa->block_size);
-	pad_len = pad_payload_len - rte_pktmbuf_pkt_len(m);
-
 	ip_hdr_len = 0;
-	switch (sa->flags) {
-	case IP4_TUNNEL:
+
+	ip4 = rte_pktmbuf_mtod(m, struct ip *);
+	if (likely(ip4->ip_v == IPVERSION)) {
+		if (unlikely(sa->flags == TRANSPORT)) {
+			ip_hdr_len = ip4->ip_hl * 4;
+			nlp = ip4->ip_p;
+		} else
+			nlp = IPPROTO_IPIP;
+	} else if (ip4->ip_v == IP6_VERSION) {
+		if (unlikely(sa->flags == TRANSPORT)) {
+			/* XXX No option headers supported */
+			ip_hdr_len = sizeof(struct ip6_hdr);
+			ip6 = (struct ip6_hdr *)ip4;
+			nlp = ip6->ip6_nxt;
+		} else
+			nlp = IPPROTO_IPV6;
+	} else {
+		RTE_LOG(ERR, IPSEC_ESP, "invalid IP packet type %d\n",
+				ip4->ip_v);
+		return -EINVAL;
+	}
+
+	/* Padded payload length */
+	pad_payload_len = RTE_ALIGN_CEIL(rte_pktmbuf_pkt_len(m) -
+			ip_hdr_len + 2, sa->block_size);
+	pad_len = pad_payload_len + ip_hdr_len - rte_pktmbuf_pkt_len(m);
+
+	RTE_ASSERT(sa->flags == IP4_TUNNEL || sa->flags == IP6_TUNNEL ||
+			sa->flags == TRANSPORT);
+
+	if (likely(sa->flags == IP4_TUNNEL))
 		ip_hdr_len = sizeof(struct ip);
-		break;
-	case IP6_TUNNEL:
+	else if (sa->flags == IP6_TUNNEL)
 		ip_hdr_len = sizeof(struct ip6_hdr);
-		break;
+	else if (sa->flags != TRANSPORT) {
+		RTE_LOG(ERR, IPSEC_ESP, "Unsupported SA flags: 0x%x\n",
+				sa->flags);
+		return -EINVAL;
 	}
 
 	/* Check maximum packet size */
@@ -200,7 +246,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 		return -EINVAL;
 	}
 
-	padding = rte_pktmbuf_append(m, pad_len + sa->digest_len);
+	padding = (uint8_t *)rte_pktmbuf_append(m, pad_len + sa->digest_len);
 	if (unlikely(padding == NULL)) {
 		RTE_LOG(ERR, IPSEC_ESP, "not enough mbuf trailing space\n");
 		return -ENOSPC;
@@ -218,10 +264,20 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 				&sa->src, &sa->dst);
 		esp = (struct esp_hdr *)(ip6 + 1);
 		break;
-	default:
-		RTE_LOG(ERR, IPSEC_ESP, "Unsupported SA flags: 0x%x\n",
-				sa->flags);
-		return -EINVAL;
+	case TRANSPORT:
+		new_ip = (uint8_t *)rte_pktmbuf_prepend(m,
+				sizeof(struct esp_hdr) + sa->iv_len);
+		memmove(new_ip, ip4, ip_hdr_len);
+		esp = (struct esp_hdr *)(new_ip + ip_hdr_len);
+		if (likely(ip4->ip_v == IPVERSION)) {
+			ip4 = (struct ip *)new_ip;
+			ip4->ip_p = IPPROTO_ESP;
+			ip4->ip_len = htons(rte_pktmbuf_data_len(m));
+		} else {
+			ip6 = (struct ip6_hdr *)new_ip;
+			ip6->ip6_nxt = IPPROTO_ESP;
+			ip6->ip6_plen = htons(rte_pktmbuf_data_len(m));
+		}
 	}
 
 	sa->seq++;
@@ -235,11 +291,7 @@ esp_outbound(struct rte_mbuf *m, struct ipsec_sa *sa,
 	for (i = 0; i < pad_len - 2; i++)
 		padding[i] = i + 1;
 	padding[pad_len - 2] = pad_len - 2;
-
-	if (RTE_ETH_IS_IPV4_HDR(m->packet_type))
-		padding[pad_len - 1] = IPPROTO_IPIP;
-	else
-		padding[pad_len - 1] = IPPROTO_IPV6;
+	padding[pad_len - 1] = nlp;
 
 	sym_cop = (struct rte_crypto_sym_op *)(cop + 1);
 
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 83d7b1c..0d2ee25 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -103,6 +103,7 @@ struct ipsec_sa {
 	uint16_t flags;
 #define IP4_TUNNEL (1 << 0)
 #define IP6_TUNNEL (1 << 1)
+#define TRANSPORT  (1 << 2)
 	struct ip_addr src;
 	struct ip_addr dst;
 	struct rte_crypto_sym_xform *xforms;
diff --git a/examples/ipsec-secgw/rt.c b/examples/ipsec-secgw/rt.c
index d46df49..fa5f042 100644
--- a/examples/ipsec-secgw/rt.c
+++ b/examples/ipsec-secgw/rt.c
@@ -62,6 +62,9 @@ static struct ip4_route rt_ip4_ep0[] = {
 	/* Tunnels */
 	{ IPv4(172, 16, 2, 5), 32, 0 },
 	{ IPv4(172, 16, 2, 6), 32, 1 },
+	/* Transport */
+	{ IPv4(192, 168, 175, 0), 24, 0 },
+	{ IPv4(192, 168, 176, 0), 24, 1 },
 	/* Bypass */
 	{ IPv4(192, 168, 240, 0), 24, 0 },
 	{ IPv4(192, 168, 241, 0), 24, 1 },
@@ -72,6 +75,9 @@ static struct ip4_route rt_ip4_ep0[] = {
 	{ IPv4(192, 168, 116, 0), 24, 3 },
 	{ IPv4(192, 168, 65, 0), 24, 2 },
 	{ IPv4(192, 168, 66, 0), 24, 3 },
+	/* Transport */
+	{ IPv4(192, 168, 185, 0), 24, 2 },
+	{ IPv4(192, 168, 186, 0), 24, 3 },
 	/* NULL */
 	{ IPv4(192, 168, 210, 0), 24, 2 },
 	{ IPv4(192, 168, 211, 0), 24, 3 },
@@ -87,6 +93,11 @@ static struct ip6_route rt_ip6_ep0[] = {
 		  0x22, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55 }, 116, 0 },
 	{ { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 		  0x22, 0x22, 0x22, 0x22, 0x22, 0x66, 0x66 }, 116, 1 },
+	/* Transport */
+	{ { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 0 },
+	{ { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11,
+		  0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 1 },
 	/* Inbound */
 	/* Tunnels */
 	{ { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
@@ -97,6 +108,11 @@ static struct ip6_route rt_ip6_ep0[] = {
 		  0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00 }, 116, 2 },
 	{ { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
 		  0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, 116, 3 },
+	/* Transport */
+	{ { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 2 },
+	{ { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11,
+		  0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 3 },
 };
 
 static struct ip4_route rt_ip4_ep1[] = {
@@ -104,6 +120,9 @@ static struct ip4_route rt_ip4_ep1[] = {
 	/* Tunnels */
 	{ IPv4(172, 16, 1, 5), 32, 0 },
 	{ IPv4(172, 16, 1, 6), 32, 1 },
+	/* Transport */
+	{ IPv4(192, 168, 185, 0), 24, 0 },
+	{ IPv4(192, 168, 186, 0), 24, 1 },
 	/* Bypass */
 	{ IPv4(192, 168, 245, 0), 24, 0 },
 	{ IPv4(192, 168, 246, 0), 24, 1 },
@@ -114,6 +133,9 @@ static struct ip4_route rt_ip4_ep1[] = {
 	{ IPv4(192, 168, 106, 0), 24, 3 },
 	{ IPv4(192, 168, 55, 0), 24, 2 },
 	{ IPv4(192, 168, 56, 0), 24, 3 },
+	/* Transport */
+	{ IPv4(192, 168, 175, 0), 24, 2 },
+	{ IPv4(192, 168, 176, 0), 24, 3 },
 	/* NULL */
 	{ IPv4(192, 168, 200, 0), 24, 2 },
 	{ IPv4(192, 168, 201, 0), 24, 3 },
@@ -129,6 +151,11 @@ static struct ip6_route rt_ip6_ep1[] = {
 		  0x11, 0x11, 0x11, 0x11, 0x11, 0x55, 0x55 }, 116, 0 },
 	{ { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 		  0x11, 0x11, 0x11, 0x11, 0x11, 0x66, 0x66 }, 116, 1 },
+	/* Transport */
+	{ { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 0 },
+	{ { 0xff, 0xff, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11,
+		  0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 1 },
 
 	/* Inbound */
 	/* Tunnels */
@@ -140,6 +167,11 @@ static struct ip6_route rt_ip6_ep1[] = {
 		  0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00 }, 116, 2 },
 	{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
 		  0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, 116, 3 },
+	/* Transport */
+	{ { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 116, 2 },
+	{ { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11,
+		  0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 }, 116, 3 },
 };
 
 void
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 8b54beb..ab18b81 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -74,6 +74,24 @@ const struct ipsec_sa sa_out[] = {
 	.flags = IP4_TUNNEL
 	},
 	{
+	.spi = 10,
+	.cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.digest_len = 12,
+	.iv_len = 16,
+	.block_size = 16,
+	.flags = TRANSPORT
+	},
+	{
+	.spi = 11,
+	.cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.digest_len = 12,
+	.iv_len = 16,
+	.block_size = 16,
+	.flags = TRANSPORT
+	},
+	{
 	.spi = 15,
 	.src.ip4 = IPv4(172, 16, 1, 5),
 	.dst.ip4 = IPv4(172, 16, 2, 5),
@@ -148,6 +166,24 @@ const struct ipsec_sa sa_in[] = {
 	.flags = IP4_TUNNEL
 	},
 	{
+	.spi = 110,
+	.cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.digest_len = 12,
+	.iv_len = 16,
+	.block_size = 16,
+	.flags = TRANSPORT
+	},
+	{
+	.spi = 111,
+	.cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.digest_len = 12,
+	.iv_len = 16,
+	.block_size = 16,
+	.flags = TRANSPORT
+	},
+	{
 	.spi = 115,
 	.src.ip4 = IPv4(172, 16, 2, 5),
 	.dst.ip4 = IPv4(172, 16, 1, 5),
@@ -447,6 +483,9 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
 				!memcmp(&sa->src.ip6, src6_addr, 16) &&
 				!memcmp(&sa->dst.ip6, src6_addr + 16, 16))
 			*sa_ret = sa;
+		break;
+	case TRANSPORT:
+		*sa_ret = sa;
 	}
 }
 
diff --git a/examples/ipsec-secgw/sp4.c b/examples/ipsec-secgw/sp4.c
index 61720c8..9c4b256 100644
--- a/examples/ipsec-secgw/sp4.c
+++ b/examples/ipsec-secgw/sp4.c
@@ -135,6 +135,26 @@ const struct acl4_rules acl4_rules_out[] = {
 	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
 	},
 	{
+	.data = {.userdata = PROTECT(10), .category_mask = 1, .priority = 1},
+	/* destination IPv4 */
+	.field[2] = {.value.u32 = IPv4(192, 168, 175, 0),
+				.mask_range.u32 = 24,},
+	/* source port */
+	.field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
+	.data = {.userdata = PROTECT(11), .category_mask = 1, .priority = 1},
+	/* destination IPv4 */
+	.field[2] = {.value.u32 = IPv4(192, 168, 176, 0),
+				.mask_range.u32 = 24,},
+	/* source port */
+	.field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
 	.data = {.userdata = PROTECT(15), .category_mask = 1, .priority = 1},
 	/* destination IPv4 */
 	.field[2] = {.value.u32 = IPv4(192, 168, 200, 0),
@@ -218,6 +238,26 @@ const struct acl4_rules acl4_rules_in[] = {
 	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
 	},
 	{
+	.data = {.userdata = PROTECT(110), .category_mask = 1, .priority = 1},
+	/* destination IPv4 */
+	.field[2] = {.value.u32 = IPv4(192, 168, 185, 0),
+				.mask_range.u32 = 24,},
+	/* source port */
+	.field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
+	.data = {.userdata = PROTECT(111), .category_mask = 1, .priority = 1},
+	/* destination IPv4 */
+	.field[2] = {.value.u32 = IPv4(192, 168, 186, 0),
+				.mask_range.u32 = 24,},
+	/* source port */
+	.field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
 	.data = {.userdata = PROTECT(115), .category_mask = 1, .priority = 1},
 	/* destination IPv4 */
 	.field[2] = {.value.u32 = IPv4(192, 168, 210, 0),
diff --git a/examples/ipsec-secgw/sp6.c b/examples/ipsec-secgw/sp6.c
index c6fb851..1dda11a 100644
--- a/examples/ipsec-secgw/sp6.c
+++ b/examples/ipsec-secgw/sp6.c
@@ -170,6 +170,30 @@ const struct acl6_rules acl6_rules_out[] = {
 	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
 	},
 	{
+	.data = {.userdata = PROTECT(10), .category_mask = 1, .priority = 1},
+	/* destination IPv6 */
+	.field[5] = {.value.u32 = 0x0, .mask_range.u32 = 32,},
+	.field[6] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[7] = {.value.u32 = 0x00000000, .mask_range.u32 = 32,},
+	.field[8] = {.value.u32 = 0x0, .mask_range.u32 = 0,},
+	/* source port */
+	.field[9] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
+	.data = {.userdata = PROTECT(11), .category_mask = 1, .priority = 1},
+	/* destination IPv6 */
+	.field[5] = {.value.u32 = 0x0, .mask_range.u32 = 32,},
+	.field[6] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[7] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[8] = {.value.u32 = 0x0, .mask_range.u32 = 0,},
+	/* source port */
+	.field[9] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
 	.data = {.userdata = PROTECT(25), .category_mask = 1, .priority = 1},
 	/* destination IPv6 */
 	.field[5] = {.value.u32 = 0x0, .mask_range.u32 = 32,},
@@ -221,6 +245,30 @@ const struct acl6_rules acl6_rules_in[] = {
 	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
 	},
 	{
+	.data = {.userdata = PROTECT(110), .category_mask = 1, .priority = 1},
+	/* destination IPv6 */
+	.field[5] = {.value.u32 = 0xffff0000, .mask_range.u32 = 32,},
+	.field[6] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[7] = {.value.u32 = 0x00000000, .mask_range.u32 = 32,},
+	.field[8] = {.value.u32 = 0x0, .mask_range.u32 = 0,},
+	/* source port */
+	.field[9] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
+	.data = {.userdata = PROTECT(111), .category_mask = 1, .priority = 1},
+	/* destination IPv6 */
+	.field[5] = {.value.u32 = 0xffff0000, .mask_range.u32 = 32,},
+	.field[6] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[7] = {.value.u32 = 0x11111111, .mask_range.u32 = 32,},
+	.field[8] = {.value.u32 = 0x0, .mask_range.u32 = 0,},
+	/* source port */
+	.field[9] = {.value.u16 = 0, .mask_range.u16 = 0xffff,},
+	/* destination port */
+	.field[10] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}
+	},
+	{
 	.data = {.userdata = PROTECT(125), .category_mask = 1, .priority = 1},
 	/* destination IPv6 */
 	.field[5] = {.value.u32 = 0xffff0000, .mask_range.u32 = 32,},
-- 
2.5.5



More information about the dev mailing list