CGN: fix outside port calculation and set buffer error (VPP-623)
Change-Id: I5143328b2da62ce4d6bb2915e2a51855696d87fc
Signed-off-by: Matus Fabian <matfabia@cisco.com>
diff --git a/src/plugins/snat/in2out.c b/src/plugins/snat/in2out.c
index 5970588..4abf875 100644
--- a/src/plugins/snat/in2out.c
+++ b/src/plugins/snat/in2out.c
@@ -1361,8 +1361,8 @@
ip4_header_t * ip0, * ip1;
ip_csum_t sum0, sum1;
ip4_address_t new_addr0, old_addr0, new_addr1, old_addr1;
- u16 old_port0, new_port0, lo_port0, i;
- u16 old_port1, new_port1, lo_port1;
+ u16 old_port0, new_port0, lo_port0, i0;
+ u16 old_port1, new_port1, lo_port1, i1;
udp_header_t * udp0, * udp1;
tcp_header_t * tcp0, * tcp1;
u32 proto0, proto1;
@@ -1409,6 +1409,7 @@
{
clib_warning("no match for internal host %U",
format_ip4_address, &ip0->src_address);
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
goto trace0;
}
@@ -1419,10 +1420,10 @@
{
key0.ext_host_addr = ip0->dst_address;
key0.ext_host_port = tcp0->dst;
- for (i = 0; i < dm0->ports_per_host; i++)
+ for (i0 = 0; i0 < dm0->ports_per_host; i0++)
{
- key0.out_port = clib_host_to_net_u16 (lo_port0 + i +
- (clib_net_to_host_u16 (tcp0->src) % dm0->ports_per_host));
+ key0.out_port = clib_host_to_net_u16 (lo_port0 +
+ ((i0 + clib_net_to_host_u16 (tcp0->src)) % dm0->ports_per_host));
if (snat_det_get_ses_by_out (dm0, &ip0->src_address, key0.as_u64))
continue;
@@ -1433,6 +1434,7 @@
if (PREDICT_FALSE(!ses0))
{
next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
goto trace0;
}
}
@@ -1528,6 +1530,7 @@
{
clib_warning("no match for internal host %U",
format_ip4_address, &ip0->src_address);
+ b1->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
goto trace1;
}
@@ -1539,10 +1542,10 @@
{
key1.ext_host_addr = ip1->dst_address;
key1.ext_host_port = tcp1->dst;
- for (i = 0; i < dm1->ports_per_host; i++)
+ for (i1 = 0; i1 < dm1->ports_per_host; i1++)
{
- key1.out_port = clib_host_to_net_u16 (lo_port1 + i +
- (clib_net_to_host_u16 (tcp1->src) % dm1->ports_per_host));
+ key1.out_port = clib_host_to_net_u16 (lo_port1 +
+ ((i1 + clib_net_to_host_u16 (tcp1->src)) % dm1->ports_per_host));
if (snat_det_get_ses_by_out (dm1, &ip1->src_address, key1.as_u64))
continue;
@@ -1553,6 +1556,7 @@
if (PREDICT_FALSE(!ses1))
{
next1 = SNAT_IN2OUT_NEXT_DROP;
+ b1->error = node->errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
goto trace1;
}
}
@@ -1652,7 +1656,7 @@
ip4_header_t * ip0;
ip_csum_t sum0;
ip4_address_t new_addr0, old_addr0;
- u16 old_port0, new_port0, lo_port0, i;
+ u16 old_port0, new_port0, lo_port0, i0;
udp_header_t * udp0;
tcp_header_t * tcp0;
u32 proto0;
@@ -1682,6 +1686,7 @@
{
clib_warning("no match for internal host %U",
format_ip4_address, &ip0->src_address);
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
goto trace00;
}
@@ -1692,10 +1697,10 @@
{
key0.ext_host_addr = ip0->dst_address;
key0.ext_host_port = tcp0->dst;
- for (i = 0; i < dm0->ports_per_host; i++)
+ for (i0 = 0; i0 < dm0->ports_per_host; i0++)
{
- key0.out_port = clib_host_to_net_u16 (lo_port0 + i +
- (clib_net_to_host_u16 (tcp0->src) % dm0->ports_per_host));
+ key0.out_port = clib_host_to_net_u16 (lo_port0 +
+ ((i0 + clib_net_to_host_u16 (tcp0->src)) % dm0->ports_per_host));
if (snat_det_get_ses_by_out (dm0, &ip0->src_address, key0.as_u64))
continue;
@@ -1706,6 +1711,7 @@
if (PREDICT_FALSE(!ses0))
{
next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
goto trace00;
}
}
diff --git a/src/plugins/snat/out2in.c b/src/plugins/snat/out2in.c
index 9b4c73d..178aa56 100644
--- a/src/plugins/snat/out2in.c
+++ b/src/plugins/snat/out2in.c
@@ -1081,6 +1081,7 @@
clib_warning("unknown dst address: %U",
format_ip4_address, &ip0->dst_address);
next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace0;
}
@@ -1090,12 +1091,14 @@
ses0 = snat_det_get_ses_by_out (dm0, &new_addr0, key0.as_u64);
if (PREDICT_FALSE(!ses0))
{
- clib_warning("no match src %U:%d dst %d for user %U",
- format_ip4_address, &ip0->dst_address,
+ clib_warning("no match src %U:%d dst %U:%d for user %U",
+ format_ip4_address, &ip0->src_address,
clib_net_to_host_u16 (tcp0->src),
+ format_ip4_address, &ip0->dst_address,
clib_net_to_host_u16 (tcp0->dst),
format_ip4_address, &new_addr0);
next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace0;
}
new_port0 = ses0->in_port;
@@ -1173,6 +1176,7 @@
clib_warning("unknown dst address: %U",
format_ip4_address, &ip1->dst_address);
next1 = SNAT_OUT2IN_NEXT_DROP;
+ b1->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace1;
}
@@ -1182,12 +1186,14 @@
ses1 = snat_det_get_ses_by_out (dm1, &new_addr1, key1.as_u64);
if (PREDICT_FALSE(!ses1))
{
- clib_warning("no match src %U:%d dst %d for user %U",
- format_ip4_address, &ip1->dst_address,
+ clib_warning("no match src %U:%d dst %U:%d for user %U",
+ format_ip4_address, &ip1->src_address,
clib_net_to_host_u16 (tcp1->src),
+ format_ip4_address, &ip1->dst_address,
clib_net_to_host_u16 (tcp1->dst),
format_ip4_address, &new_addr1);
next1 = SNAT_OUT2IN_NEXT_DROP;
+ b1->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace1;
}
new_port1 = ses1->in_port;
@@ -1296,6 +1302,7 @@
clib_warning("unknown dst address: %U",
format_ip4_address, &ip0->dst_address);
next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace00;
}
@@ -1305,12 +1312,14 @@
ses0 = snat_det_get_ses_by_out (dm0, &new_addr0, key0.as_u64);
if (PREDICT_FALSE(!ses0))
{
- clib_warning("no match src %U:%d dst %d for user %U",
- format_ip4_address, &ip0->dst_address,
+ clib_warning("no match src %U:%d dst %U:%d for user %U",
+ format_ip4_address, &ip0->src_address,
clib_net_to_host_u16 (tcp0->src),
+ format_ip4_address, &ip0->dst_address,
clib_net_to_host_u16 (tcp0->dst),
format_ip4_address, &new_addr0);
next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
goto trace00;
}
new_port0 = ses0->in_port;