NAT44: add opaque string tag to static mapping APIs (VPP-1147)
Change-Id: I620e2081285ca8ac5c2da8efc12fe6f540ea4fd1
Signed-off-by: Matus Fabian <matfabia@cisco.com>
diff --git a/src/plugins/nat/nat.api b/src/plugins/nat/nat.api
index 02c1627..aff8f1d 100644
--- a/src/plugins/nat/nat.api
+++ b/src/plugins/nat/nat.api
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-option version = "2.3.0";
+option version = "2.4.0";
/**
* @file nat.api
@@ -353,6 +353,7 @@
@param twice_nat - if 1 translate external host address and port, only for
1:1 NAPT (addr_only must be 0)
@param out2in_only - if 1 rule match only out2in direction
+ @param tag - opaque string tag
*/
autoreply define nat44_add_del_static_mapping {
u32 client_index;
@@ -368,6 +369,7 @@
u32 vrf_id;
u8 twice_nat;
u8 out2in_only;
+ u8 tag[64];
};
/** \brief Dump NAT44 static mappings
@@ -391,6 +393,7 @@
@param vfr_id - VRF ID
@param twice_nat - if 1 translate external host address and port
@param out2in_only - if 1 rule match only out2in direction
+ @param tag - opaque string tag
*/
define nat44_static_mapping_details {
u32 context;
@@ -404,6 +407,7 @@
u32 vrf_id;
u8 twice_nat;
u8 out2in_only;
+ u8 tag[64];
};
/** \brief Add/delete NAT44 identity mapping
@@ -417,6 +421,7 @@
@param sw_if_index - interface (if set ip_address is ignored, ~0 means not
used)
@param vfr_id - VRF ID (if ~0 use default VRF)
+ @param tag - opaque string tag
*/
autoreply define nat44_add_del_identity_mapping {
u32 client_index;
@@ -428,6 +433,7 @@
u16 port;
u32 sw_if_index;
u32 vrf_id;
+ u8 tag[64];
};
/** \brief Dump NAT44 identity mappings
@@ -447,6 +453,7 @@
@param port - port number
@param sw_if_index - interface
@param vfr_id - VRF ID
+ @param tag - opaque string tag
*/
define nat44_identity_mapping_details {
u32 context;
@@ -456,6 +463,7 @@
u16 port;
u32 sw_if_index;
u32 vrf_id;
+ u8 tag[64];
};
/** \brief Add/delete NAT44 pool address from specific interfce
@@ -572,6 +580,7 @@
u32 vrf_id;
u8 twice_nat;
u8 out2in_only;
+ u8 tag[64];
u8 local_num;
vl_api_nat44_lb_addr_port_t locals[local_num];
};
@@ -589,6 +598,7 @@
u32 vrf_id;
u8 twice_nat;
u8 out2in_only;
+ u8 tag[64];
u8 local_num;
vl_api_nat44_lb_addr_port_t locals[local_num];
};
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index 5c324f2..95004da 100644
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -623,7 +623,8 @@
u32 vrf_id,
snat_protocol_t proto,
int addr_only,
- int is_add)
+ int is_add,
+ u8 * tag)
{
snat_static_map_resolve_t *rp;
@@ -636,6 +637,7 @@
rp->proto = proto;
rp->addr_only = addr_only;
rp->is_add = is_add;
+ rp->tag = vec_dup (tag);
}
/**
@@ -653,13 +655,14 @@
* @param is_add If 0 delete static mapping, otherwise add.
* @param twice_nat If 1 translate external host address and port.
* @param out2in_only If 1 rule match only out2in direction
+ * @param tag - opaque string tag
*
* @returns
*/
int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
u32 sw_if_index, snat_protocol_t proto, int is_add,
- u8 twice_nat, u8 out2in_only)
+ u8 twice_nat, u8 out2in_only, u8 * tag)
{
snat_main_t * sm = &snat_main;
snat_static_mapping_t *m;
@@ -686,7 +689,7 @@
{
snat_add_static_mapping_when_resolved
(sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
- addr_only, is_add);
+ addr_only, is_add, tag);
return 0;
}
else
@@ -770,6 +773,7 @@
pool_get (sm->static_mappings, m);
memset (m, 0, sizeof (*m));
+ m->tag = vec_dup (tag);
m->local_addr = l_addr;
m->external_addr = e_addr;
m->addr_only = addr_only;
@@ -955,6 +959,7 @@
}
}
+ vec_free (m->tag);
/* Delete static mapping from pool */
pool_put (sm->static_mappings, m);
}
@@ -986,7 +991,7 @@
int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
snat_protocol_t proto, u32 vrf_id,
nat44_lb_addr_port_t *locals, u8 is_add,
- u8 twice_nat, u8 out2in_only)
+ u8 twice_nat, u8 out2in_only, u8 *tag)
{
snat_main_t * sm = &snat_main;
snat_static_mapping_t *m;
@@ -1064,6 +1069,7 @@
pool_get (sm->static_mappings, m);
memset (m, 0, sizeof (*m));
+ m->tag = vec_dup (tag);
m->external_addr = e_addr;
m->addr_only = 0;
m->vrf_id = vrf_id;
@@ -1243,6 +1249,7 @@
}
}
vec_free(m->locals);
+ vec_free(m->tag);
pool_put (sm->static_mappings, m);
}
@@ -1287,7 +1294,7 @@
m->local_port, m->external_port,
m->vrf_id, m->addr_only, ~0,
m->proto, 0, m->twice_nat,
- m->out2in_only);
+ m->out2in_only, m->tag);
}));
}
else
@@ -2661,10 +2668,11 @@
~0 /* sw_if_index */,
rp->proto,
rp->is_add,
- 0, 0);
+ 0, 0, rp->tag);
if (rv)
clib_warning ("snat_add_static_mapping returned %d",
rv);
+ vec_free (rp->tag);
vec_add1 (indices_to_delete, j);
}
}
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h
index bf975a1..58bf8b3 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat.h
@@ -222,6 +222,7 @@
u32 fib_index;
snat_protocol_t proto;
u32 worker_index;
+ u8 *tag;
nat44_lb_addr_port_t *locals;
} snat_static_mapping_t;
@@ -240,6 +241,7 @@
int addr_only;
int twice_nat;
int is_add;
+ u8 *tag;
} snat_static_map_resolve_t;
typedef struct {
@@ -548,7 +550,7 @@
int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
u32 sw_if_index, snat_protocol_t proto, int is_add,
- u8 twice_nat, u8 out2in_only);
+ u8 twice_nat, u8 out2in_only, u8 *tag);
clib_error_t * snat_api_init(vlib_main_t * vm, snat_main_t * sm);
int snat_set_workers (uword * bitmap);
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del);
@@ -561,7 +563,7 @@
int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
snat_protocol_t proto, u32 vrf_id,
nat44_lb_addr_port_t *locals, u8 is_add,
- u8 twice_nat, u8 out2in_only);
+ u8 twice_nat, u8 out2in_only, u8 *tag);
int nat44_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port,
snat_protocol_t proto, u32 vrf_id, int is_in);
void nat_free_session_data (snat_main_t * sm, snat_session_t * s,
diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c
index 0aac1c0..5114615 100644
--- a/src/plugins/nat/nat44_cli.c
+++ b/src/plugins/nat/nat44_cli.c
@@ -543,7 +543,7 @@
rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
vrf_id, addr_only, sw_if_index, proto, is_add,
- twice_nat, out2in_only);
+ twice_nat, out2in_only, 0);
switch (rv)
{
@@ -618,7 +618,7 @@
rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
vrf_id, addr_only, sw_if_index, proto, is_add,
- 0, 0);
+ 0, 0, 0);
switch (rv)
{
@@ -715,7 +715,7 @@
rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, vrf_id,
locals, is_add, twice_nat,
- out2in_only);
+ out2in_only, 0);
switch (rv)
{
diff --git a/src/plugins/nat/nat_api.c b/src/plugins/nat/nat_api.c
index f23efa8..3cb7399 100644
--- a/src/plugins/nat/nat_api.c
+++ b/src/plugins/nat/nat_api.c
@@ -696,6 +696,7 @@
u32 vrf_id, external_sw_if_index;
int rv = 0;
snat_protocol_t proto;
+ u8 *tag = 0;
memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
@@ -707,11 +708,16 @@
vrf_id = clib_net_to_host_u32 (mp->vrf_id);
external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
proto = ip_proto_to_snat_proto (mp->protocol);
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
rv = snat_add_static_mapping (local_addr, external_addr, local_port,
external_port, vrf_id, mp->addr_only,
external_sw_if_index, proto, mp->is_add,
- mp->twice_nat, mp->out2in_only);
+ mp->twice_nat, mp->out2in_only, tag);
+
+ vec_free (tag);
REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
}
@@ -766,6 +772,8 @@
rmp->context = context;
rmp->twice_nat = m->twice_nat;
rmp->out2in_only = m->out2in_only;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
vl_api_send_msg (reg, (u8 *) rmp);
}
@@ -791,6 +799,8 @@
rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
rmp->twice_nat = m->twice_nat;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
vl_api_send_msg (reg, (u8 *) rmp);
}
@@ -847,6 +857,7 @@
u32 vrf_id, sw_if_index;
int rv = 0;
snat_protocol_t proto = ~0;
+ u8 *tag = 0;
if (mp->addr_only == 0)
{
@@ -859,11 +870,15 @@
addr.as_u32 = 0;
else
memcpy (&addr.as_u8, mp->ip_address, 4);
-
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
rv =
snat_add_static_mapping (addr, addr, port, port, vrf_id, mp->addr_only,
- sw_if_index, proto, mp->is_add, 0, 0);
+ sw_if_index, proto, mp->is_add, 0, 0, tag);
+
+ vec_free (tag);
REPLY_MACRO (VL_API_NAT44_ADD_DEL_IDENTITY_MAPPING_REPLY);
}
@@ -908,6 +923,8 @@
rmp->vrf_id = htonl (m->vrf_id);
rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
vl_api_send_msg (reg, (u8 *) rmp);
}
@@ -930,6 +947,8 @@
rmp->vrf_id = htonl (m->vrf_id);
rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
vl_api_send_msg (reg, (u8 *) rmp);
}
@@ -1238,19 +1257,24 @@
nat44_lb_addr_port_t *locals = 0;
ip4_address_t e_addr;
snat_protocol_t proto;
+ u8 *tag = 0;
locals = unformat_nat44_lb_addr_port (mp->locals, mp->local_num);
clib_memcpy (&e_addr, mp->external_addr, 4);
proto = ip_proto_to_snat_proto (mp->protocol);
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
rv =
nat44_add_del_lb_static_mapping (e_addr,
clib_net_to_host_u16 (mp->external_port),
proto, clib_net_to_host_u32 (mp->vrf_id),
locals, mp->is_add, mp->twice_nat,
- mp->out2in_only);
+ mp->out2in_only, tag);
vec_free (locals);
+ vec_free (tag);
REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
}
@@ -1291,6 +1315,8 @@
rmp->context = context;
rmp->twice_nat = m->twice_nat;
rmp->out2in_only = m->out2in_only;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
vec_foreach (ap, m->locals)
diff --git a/test/test_nat.py b/test/test_nat.py
index 46a6d42..f0614da 100644
--- a/test/test_nat.py
+++ b/test/test_nat.py
@@ -1030,6 +1030,7 @@
protocol=sm.protocol,
twice_nat=sm.twice_nat,
out2in_only=sm.out2in_only,
+ tag=sm.tag,
is_add=0)
lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
@@ -1041,6 +1042,7 @@
vrf_id=lb_sm.vrf_id,
twice_nat=lb_sm.twice_nat,
out2in_only=lb_sm.out2in_only,
+ tag=lb_sm.tag,
is_add=0,
local_num=0,
locals=[])
@@ -1069,7 +1071,7 @@
def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
local_port=0, external_port=0, vrf_id=0,
is_add=1, external_sw_if_index=0xFFFFFFFF,
- proto=0, twice_nat=0, out2in_only=0):
+ proto=0, twice_nat=0, out2in_only=0, tag=""):
"""
Add/delete NAT44 static mapping
@@ -1083,6 +1085,7 @@
:param proto: IP protocol (Mandatory if port specified)
:param twice_nat: 1 if translate external host address and port
:param out2in_only: if 1 rule is matching only out2in direction
+ :param tag: Opaque string tag
"""
addr_only = 1
if local_port and external_port:
@@ -1100,6 +1103,7 @@
proto,
twice_nat,
out2in_only,
+ tag,
is_add)
def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
@@ -1376,6 +1380,9 @@
self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
+ sm = self.vapi.nat44_static_mapping_dump()
+ self.assertEqual(len(sm), 1)
+ self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
# in2out
pkts = self.create_stream_in(self.pg0, self.pg1)
@@ -1400,11 +1407,15 @@
self.tcp_port_out = 6303
self.udp_port_out = 6304
self.icmp_id_out = 6305
+ tag = "testTAG"
- self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
+ self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
+ sm = self.vapi.nat44_static_mapping_dump()
+ self.assertEqual(len(sm), 1)
+ self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
# out2in
pkts = self.create_stream_out(self.pg1, nat_ip)
@@ -2338,16 +2349,20 @@
def test_interface_addr_static_mapping(self):
""" Static mapping with addresses from interface """
+ tag = "testTAG"
+
self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
self.nat44_add_static_mapping(
'1.2.3.4',
- external_sw_if_index=self.pg7.sw_if_index)
+ external_sw_if_index=self.pg7.sw_if_index,
+ tag=tag)
# static mappings with external interface
static_mappings = self.vapi.nat44_static_mapping_dump()
self.assertEqual(1, len(static_mappings))
self.assertEqual(self.pg7.sw_if_index,
static_mappings[0].external_sw_if_index)
+ self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
# configure interface address and check static mappings
self.pg7.config_ip4()
@@ -2356,6 +2371,7 @@
self.assertEqual(static_mappings[0].external_ip_address[0:4],
self.pg7.local_ip4n)
self.assertEqual(0xFFFFFFFF, static_mappings[0].external_sw_if_index)
+ self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
# remove interface address and check static mappings
self.pg7.unconfig_ip4()
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index db0f8e6..b791444 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -1236,6 +1236,7 @@
protocol=0,
twice_nat=0,
out2in_only=0,
+ tag="",
is_add=1):
"""Add/delete NAT44 static mapping
@@ -1249,6 +1250,7 @@
:param protocol: IP protocol (Default value = 0)
:param twice_nat: 1 if translate external host address and port
:param out2in_only: if 1 rule is matching only out2in direction
+ :param tag: Opaque string tag
:param is_add: 1 if add, 0 if delete (Default value = 1)
"""
return self.api(
@@ -1263,7 +1265,8 @@
'vrf_id': vrf_id,
'protocol': protocol,
'twice_nat': twice_nat,
- 'out2in_only': out2in_only})
+ 'out2in_only': out2in_only,
+ 'tag': tag})
def nat44_add_del_identity_mapping(
self,
@@ -1273,6 +1276,7 @@
addr_only=1,
vrf_id=0,
protocol=0,
+ tag='',
is_add=1):
"""Add/delete NAT44 identity mapping
@@ -1282,6 +1286,7 @@
:param addr_only: 1 if address only mapping, 0 if address and port
:param vrf_id: VRF ID
:param protocol: IP protocol (Default value = 0)
+ :param tag: Opaque string tag
:param is_add: 1 if add, 0 if delete (Default value = 1)
"""
return self.api(
@@ -1292,6 +1297,7 @@
'port': port,
'sw_if_index': sw_if_index,
'vrf_id': vrf_id,
+ 'tag': tag,
'protocol': protocol})
def nat44_add_del_address_range(
@@ -1424,12 +1430,14 @@
vrf_id=0,
twice_nat=0,
out2in_only=0,
+ tag='',
local_num=0,
locals=[],
is_add=1):
"""Add/delete NAT44 load balancing static mapping
:param twice_nat: 1 if translate external host address and port
+ :param tag: Opaque string tag
:param is_add - 1 if add, 0 if delete
"""
return self.api(
@@ -1441,6 +1449,7 @@
'vrf_id': vrf_id,
'twice_nat': twice_nat,
'out2in_only': out2in_only,
+ 'tag': tag,
'local_num': local_num,
'locals': locals})