u32 address_index = ~0;
u32 outside_fib_index;
uword * p;
- snat_static_mapping_key_t worker_by_out_key;
+ snat_worker_key_t worker_by_out_key;
p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id);
if (! p)
}
outside_fib_index = p[0];
+ key1.protocol = key0->protocol;
user_key.addr = ip0->src_address;
user_key.fib_index = rx_fib_index0;
kv0.key = user_key.as_u64;
u32 proto0)
{
snat_session_key_t key0, sm0;
- snat_static_mapping_key_t k0;
+ snat_worker_key_t k0;
snat_session_t * s0;
clib_bihash_kv_8_8_t kv0, value0;
ip_csum_t sum0;
next0 = next1 = SNAT_IN2OUT_NEXT_LOOKUP;
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
/* Next configured feature, probably ip4-lookup */
if (is_slow_path)
rx_fib_index1 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
sw_if_index1);
- proto1 = ~0;
- proto1 = (ip1->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto1;
- proto1 = (ip1->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto1;
- proto1 = (ip1->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto1;
+ proto1 = ip_proto_to_snat_proto (ip1->protocol);
/* Next configured feature, probably ip4-lookup */
if (is_slow_path)
rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
sw_if_index0);
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
/* Next configured feature, probably ip4-lookup */
if (is_slow_path)
sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0);
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
if (PREDICT_FALSE (proto0 == ~0))
goto trace0;
rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
sw_if_index0);
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
if (PREDICT_FALSE (proto0 == ~0))
goto trace0;
rx_fib_index1 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
sw_if_index1);
- proto1 = ~0;
- proto1 = (ip1->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto1;
- proto1 = (ip1->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto1;
- proto1 = (ip1->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto1;
+ proto1 = ip_proto_to_snat_proto (ip1->protocol);
if (PREDICT_FALSE (proto1 == ~0))
goto trace1;
rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
sw_if_index0);
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
if (PREDICT_FALSE (proto0 == ~0))
goto trace00;
u32 rx_fib_index0;
ip4_header_t * ip0;
udp_header_t * udp0;
- snat_static_mapping_key_t key0;
+ snat_worker_key_t key0;
clib_bihash_kv_8_8_t kv0, value0;
u8 do_handoff;
vnet_feature_next (sw_if_index0, &next0, b0);
- proto0 = ~0;
- proto0 = (ip0->protocol == IP_PROTOCOL_UDP)
- ? SNAT_PROTOCOL_UDP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_TCP)
- ? SNAT_PROTOCOL_TCP : proto0;
- proto0 = (ip0->protocol == IP_PROTOCOL_ICMP)
- ? SNAT_PROTOCOL_ICMP : proto0;
+ proto0 = ip_proto_to_snat_proto (ip0->protocol);
if (PREDICT_FALSE (proto0 == ~0))
goto trace00;
@param addr_only - 1 if address only mapping
@param local_ip_address - local IP address
@param external_ip_address - external IP address
+ @param protocol - IP protocol
@param local_port - local port number
@param external_port - external port number
@param external_sw_if_index - external interface (if set
u8 addr_only;
u8 local_ip_address[16];
u8 external_ip_address[16];
+ u8 protocol;
u16 local_port;
u16 external_port;
u32 external_sw_if_index;
@param addr_only - 1 if address only mapping
@param local_ip_address - local IP address
@param external_ip_address - external IP address
+ @param protocol - IP protocol
@param local_port - local port number
@param external_port - external port number
@param vfr_id - VRF ID
u8 addr_only;
u8 local_ip_address[16];
u8 external_ip_address[16];
+ u8 protocol;
u16 local_port;
u16 external_port;
u32 vrf_id;
vec_add2 (sm->addresses, ap, 1);
ap->addr = *addr;
- clib_bitmap_alloc (ap->busy_port_bitmap, 65535);
+#define _(N, i, n, s) \
+ clib_bitmap_alloc (ap->busy_##n##_port_bitmap, 65535);
+ foreach_snat_protocol
+#undef _
/* Add external address to FIB */
pool_foreach (i, sm->interfaces,
u32 sw_if_index,
u16 e_port,
u32 vrf_id,
+ snat_protocol_t proto,
int addr_only,
int is_add)
{
rp->sw_if_index = sw_if_index;
rp->e_port = e_port;
rp->vrf_id = vrf_id;
+ rp->proto = proto;
rp->addr_only = addr_only;
rp->is_add = is_add;
}
*/
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, int is_add)
+ u32 sw_if_index, snat_protocol_t proto, int is_add)
{
snat_main_t * sm = &snat_main;
snat_static_mapping_t *m;
- snat_static_mapping_key_t m_key;
+ snat_session_key_t m_key;
clib_bihash_kv_8_8_t kv, value;
snat_address_t *a = 0;
u32 fib_index = ~0;
if (first_int_addr == 0)
{
snat_add_static_mapping_when_resolved
- (sm, l_addr, l_port, sw_if_index, e_port, vrf_id,
+ (sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto,
addr_only, is_add);
return 0;
}
m_key.addr = e_addr;
m_key.port = addr_only ? 0 : e_port;
+ m_key.protocol = addr_only ? 0 : proto;
m_key.fib_index = sm->outside_fib_index;
kv.key = m_key.as_u64;
if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
{
a = sm->addresses + i;
/* External port must be unused */
- if (clib_bitmap_get_no_check (a->busy_port_bitmap, e_port))
- return VNET_API_ERROR_INVALID_VALUE;
- clib_bitmap_set_no_check (a->busy_port_bitmap, e_port, 1);
- if (e_port > 1024)
- a->busy_ports++;
-
+ switch (proto)
+ {
+#define _(N, j, n, s) \
+ case SNAT_PROTOCOL_##N: \
+ if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, e_port)) \
+ return VNET_API_ERROR_INVALID_VALUE; \
+ clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 1); \
+ if (e_port > 1024) \
+ a->busy_##n##_ports++; \
+ break;
+ foreach_snat_protocol
+#undef _
+ default:
+ clib_warning("unknown_protocol");
+ return VNET_API_ERROR_INVALID_VALUE_2;
+ }
break;
}
}
{
m->local_port = l_port;
m->external_port = e_port;
+ m->proto = proto;
}
m_key.addr = m->local_addr;
m_key.port = m->local_port;
+ m_key.protocol = m->proto;
m_key.fib_index = m->fib_index;
kv.key = m_key.as_u64;
kv.value = m - sm->static_mappings;
if (sm->workers)
{
snat_user_key_t w_key0;
- snat_static_mapping_key_t w_key1;
+ snat_worker_key_t w_key1;
w_key0.addr = m->local_addr;
w_key0.fib_index = m->fib_index;
if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
{
a = sm->addresses + i;
- clib_bitmap_set_no_check (a->busy_port_bitmap, e_port, 0);
- a->busy_ports--;
-
+ switch (proto)
+ {
+#define _(N, j, n, s) \
+ case SNAT_PROTOCOL_##N: \
+ clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, e_port, 0); \
+ if (e_port > 1024) \
+ a->busy_##n##_ports--; \
+ break;
+ foreach_snat_protocol
+#undef _
+ default:
+ clib_warning("unknown_protocol");
+ return VNET_API_ERROR_INVALID_VALUE_2;
+ }
break;
}
}
m_key.addr = m->local_addr;
m_key.port = m->local_port;
+ m_key.protocol = m->proto;
m_key.fib_index = m->fib_index;
kv.key = m_key.as_u64;
clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0);
if (m->external_addr.as_u32 == addr.as_u32)
(void) snat_add_static_mapping (m->local_addr, m->external_addr,
m->local_port, m->external_port,
- m->vrf_id, m->addr_only, ~0, 0);
+ m->vrf_id, m->addr_only, ~0,
+ m->proto, 0);
}));
}
else
}
/* Delete sessions using address */
- if (a->busy_ports)
+ if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
{
vec_foreach (tsm, sm->per_thread_data)
{
u16 local_port = 0, external_port = 0;
u32 vrf_id, external_sw_if_index;
int rv = 0;
+ snat_protocol_t proto;
if (mp->is_ip4 != 1)
{
}
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);
rv = snat_add_static_mapping(local_addr, external_addr, local_port,
external_port, vrf_id, mp->addr_only,
- external_sw_if_index,
- mp->is_add);
+ external_sw_if_index, proto, mp->is_add);
send_reply:
REPLY_MACRO (VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY);
u8 * s;
s = format (0, "SCRIPT: snat_add_static_mapping ");
- s = format (s, "local_addr %U external_addr %U ",
+ s = format (s, "protocol %d local_addr %U external_addr %U ",
+ mp->protocol,
format_ip4_address, mp->local_ip_address,
format_ip4_address, mp->external_ip_address);
rmp->local_port = htons (m->local_port);
rmp->external_port = htons (m->external_port);
rmp->vrf_id = htonl (m->vrf_id);
+ rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
vl_msg_api_send_shmem (q, (u8 *) & rmp);
a = sm->addresses + address_index;
- ASSERT (clib_bitmap_get_no_check (a->busy_port_bitmap,
- port_host_byte_order) == 1);
-
- clib_bitmap_set_no_check (a->busy_port_bitmap, port_host_byte_order, 0);
- a->busy_ports--;
+ switch (k->protocol)
+ {
+#define _(N, i, n, s) \
+ case SNAT_PROTOCOL_##N: \
+ ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \
+ port_host_byte_order) == 1); \
+ clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \
+ port_host_byte_order, 0); \
+ a->busy_##n##_ports--; \
+ break;
+ foreach_snat_protocol
+#undef _
+ default:
+ clib_warning("unknown_protocol");
+ return;
+ }
}
/**
{
clib_bihash_kv_8_8_t kv, value;
snat_static_mapping_t *m;
- snat_static_mapping_key_t m_key;
+ snat_session_key_t m_key;
clib_bihash_8_8_t *mapping_hash = &sm->static_mapping_by_local;
if (by_external)
m_key.addr = match.addr;
m_key.port = clib_net_to_host_u16 (match.port);
+ m_key.protocol = match.protocol;
m_key.fib_index = match.fib_index;
kv.key = m_key.as_u64;
{
/* Try address only mapping */
m_key.port = 0;
+ m_key.protocol = 0;
kv.key = m_key.as_u64;
if (clib_bihash_search_8_8 (mapping_hash, &kv, &value))
return 1;
for (i = 0; i < vec_len (sm->addresses); i++)
{
- if (sm->addresses[i].busy_ports < (65535-1024))
+ a = sm->addresses + i;
+ switch (k->protocol)
{
- a = sm->addresses + i;
-
- while (1)
- {
- portnum = random_u32 (&sm->random_seed);
- portnum &= 0xFFFF;
- if (portnum < 1024)
- continue;
- if (clib_bitmap_get_no_check (a->busy_port_bitmap, portnum))
- continue;
- clib_bitmap_set_no_check (a->busy_port_bitmap, portnum, 1);
- a->busy_ports++;
- /* Caller sets protocol and fib index */
- k->addr = a->addr;
- k->port = clib_host_to_net_u16(portnum);
- *address_indexp = i;
- return 0;
- }
+#define _(N, j, n, s) \
+ case SNAT_PROTOCOL_##N: \
+ if (a->busy_##n##_ports < (65535-1024)) \
+ { \
+ while (1) \
+ { \
+ portnum = random_u32 (&sm->random_seed); \
+ portnum &= 0xFFFF; \
+ if (portnum < 1024) \
+ continue; \
+ if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, portnum)) \
+ continue; \
+ clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, portnum, 1); \
+ a->busy_##n##_ports++; \
+ k->addr = a->addr; \
+ k->port = clib_host_to_net_u16(portnum); \
+ *address_indexp = i; \
+ return 0; \
+ } \
+ } \
+ break;
+ foreach_snat_protocol
+#undef _
+ default:
+ clib_warning("unknown protocol");
+ return 1;
}
+
}
/* Totally out of translations to use... */
snat_ipfix_logging_addresses_exhausted(0);
.short_help = "set interface snat in <intfc> out <intfc> [del]",
};
+uword
+unformat_snat_protocol (unformat_input_t * input, va_list * args)
+{
+ u32 *r = va_arg (*args, u32 *);
+
+ if (0);
+#define _(N, i, n, s) else if (unformat (input, s)) *r = SNAT_PROTOCOL_##N;
+ foreach_snat_protocol
+#undef _
+ else
+ return 0;
+ return 1;
+}
+
+u8 *
+format_snat_protocol (u8 * s, va_list * args)
+{
+ u32 i = va_arg (*args, u32);
+ u8 *t = 0;
+
+ switch (i)
+ {
+#define _(N, j, n, str) case SNAT_PROTOCOL_##N: t = (u8 *) str; break;
+ foreach_snat_protocol
+#undef _
+ default:
+ s = format (s, "unknown");
+ }
+ s = format (s, "%s", t);
+ return s;
+}
+
static clib_error_t *
add_static_mapping_command_fn (vlib_main_t * vm,
unformat_input_t * input,
u32 sw_if_index = ~0;
vnet_main_t * vnm = vnet_get_main();
int rv;
+ snat_protocol_t proto;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
;
else if (unformat (line_input, "vrf %u", &vrf_id))
;
+ else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
+ ;
else if (unformat (line_input, "del"))
is_add = 0;
else
unformat_free (line_input);
rv = snat_add_static_mapping(l_addr, e_addr, (u16) l_port, (u16) e_port,
- vrf_id, addr_only, sw_if_index, is_add);
+ vrf_id, addr_only, sw_if_index, proto, is_add);
switch (rv)
{
format_ip4_address, &m->external_addr,
m->vrf_id);
else
- s = format (s, "local %U:%d external %U:%d vrf %d",
+ s = format (s, "%U local %U:%d external %U:%d vrf %d",
+ format_snat_protocol, m->proto,
format_ip4_address, &m->local_addr, m->local_port,
format_ip4_address, &m->external_addr, m->external_port,
m->vrf_id);
vec_foreach (ap, sm->addresses)
{
- u8 * s = format (0, "");
vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
- clib_bitmap_foreach (j, ap->busy_port_bitmap,
- ({
- s = format (s, " %d", j);
- }));
- vlib_cli_output (vm, " %d busy ports:%s", ap->busy_ports, s);
+#define _(N, i, n, s) \
+ vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
+ foreach_snat_protocol
+#undef _
}
}
rp->vrf_id,
rp->addr_only,
~0 /* sw_if_index */,
+ rp->proto,
rp->is_add);
if (rv)
clib_warning ("snat_add_static_mapping returned %d",
};
u64 as_u64;
};
-} snat_static_mapping_key_t;
+} snat_worker_key_t;
+#define foreach_snat_protocol \
+ _(UDP, 0, udp, "udp") \
+ _(TCP, 1, tcp, "tcp") \
+ _(ICMP, 2, icmp, "icmp")
+
typedef enum {
- SNAT_PROTOCOL_UDP = 0,
- SNAT_PROTOCOL_TCP,
- SNAT_PROTOCOL_ICMP,
+#define _(N, i, n, s) SNAT_PROTOCOL_##N = i,
+ foreach_snat_protocol
+#undef _
} snat_protocol_t;
typedef struct {
ip4_address_t addr;
- u32 busy_ports;
- uword * busy_port_bitmap;
+#define _(N, i, n, s) \
+ u32 busy_##n##_ports; \
+ uword * busy_##n##_port_bitmap;
+ foreach_snat_protocol
+#undef _
} snat_address_t;
typedef struct {
u8 addr_only;
u32 vrf_id;
u32 fib_index;
+ snat_protocol_t proto;
} snat_static_mapping_t;
typedef struct {
u16 e_port;
u32 sw_if_index;
u32 vrf_id;
+ snat_protocol_t proto;
int addr_only;
int is_add;
} snat_static_map_resolve_t;
u16 sequence;
} icmp_echo_header_t;
+always_inline snat_protocol_t
+ip_proto_to_snat_proto (u8 ip_proto)
+{
+ snat_protocol_t snat_proto = ~0;
+
+ snat_proto = (ip_proto == IP_PROTOCOL_UDP) ? SNAT_PROTOCOL_UDP : snat_proto;
+ snat_proto = (ip_proto == IP_PROTOCOL_TCP) ? SNAT_PROTOCOL_TCP : snat_proto;
+ snat_proto = (ip_proto == IP_PROTOCOL_ICMP) ? SNAT_PROTOCOL_ICMP : snat_proto;
+
+ return snat_proto;
+}
+
+always_inline u8
+snat_proto_to_ip_proto (snat_protocol_t snat_proto)
+{
+ u8 ip_proto = ~0;
+
+ ip_proto = (snat_proto == SNAT_PROTOCOL_UDP) ? IP_PROTOCOL_UDP : ip_proto;
+ ip_proto = (snat_proto == SNAT_PROTOCOL_TCP) ? IP_PROTOCOL_TCP : ip_proto;
+ ip_proto = (snat_proto == SNAT_PROTOCOL_ICMP) ? IP_PROTOCOL_ICMP : ip_proto;
+
+ return ip_proto;
+}
+
#endif /* __included_snat_h__ */
if (!silm->enabled)
return;
- proto = (snat_proto == SNAT_PROTOCOL_UDP) ? IP_PROTOCOL_UDP : proto;
- proto = (snat_proto == SNAT_PROTOCOL_TCP) ? IP_PROTOCOL_TCP : proto;
- proto = (snat_proto == SNAT_PROTOCOL_ICMP) ? IP_PROTOCOL_ICMP : proto;
+ proto = snat_proto_to_ip_proto (snat_proto);
now = (u64) ((vlib_time_now (vm) - silm->vlib_time_0) * 1e3);
now += silm->milisecond_time_0;
unformat_input_t * i = vam->input;
vl_api_snat_add_static_mapping_t * mp;
u8 external_addr_set = 0;
- u8 local_addr_set;
+ u8 local_addr_set = 0;
u8 is_add = 1;
u8 addr_only = 1;
ip4_address_t local_addr, external_addr;
u32 local_port = 0, external_port = 0, vrf_id = ~0;
u32 sw_if_index = ~0;
u8 sw_if_index_set = 0;
+ u32 proto = ~0;
int ret;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
sw_if_index_set = 1;
else if (unformat (i, "external_sw_if_index %d", &sw_if_index))
sw_if_index_set = 1;
- else if (unformat (i, "vrf %u", &vrf_id))
+ else if (unformat (i, "vrf %u", &vrf_id))
+ ;
+ else if (unformat (i, "protocol %u", &proto))
;
else if (unformat (i, "del"))
is_add = 0;
mp->external_port = ntohs ((u16) external_port);
mp->external_sw_if_index = ntohl (sw_if_index);
mp->vrf_id = ntohl (vrf_id);
+ mp->protocol = (u8) proto;
memcpy (mp->local_ip_address, &local_addr, 4);
memcpy (mp->external_ip_address, &external_addr, 4);
vat_main_t *vam = sm->vat_main;
if (mp->addr_only)
- fformat (vam->ofp, "%15U%6s%15U%6s%11d\n",
+ fformat (vam->ofp, "%15U%6s%15U%6s%11d%6d\n",
format_ip4_address, &mp->local_ip_address, "",
format_ip4_address, &mp->external_ip_address, "",
- ntohl (mp->vrf_id));
+ ntohl (mp->vrf_id),
+ mp->protocol);
else
- fformat (vam->ofp, "%15U%6d%15U%6d%11d\n",
+ fformat (vam->ofp, "%15U%6d%15U%6d%11d%6d\n",
format_ip4_address, &mp->local_ip_address,
ntohs (mp->local_port),
format_ip4_address, &mp->external_ip_address,
ntohs (mp->external_port),
- ntohl (mp->vrf_id));
+ ntohl (mp->vrf_id),
+ mp->protocol);
}
}
fformat (vam->ofp, "%21s%21s\n", "local", "external");
- fformat (vam->ofp, "%15s%6s%15s%6s%11s\n", "address", "port", "address",
- "port", "vrf");
+ fformat (vam->ofp, "%15s%6s%15s%6s%11s%6s\n", "address", "port", "address",
+ "port", "vrf", "proto");
M(SNAT_STATIC_MAPPING_DUMP, mp);
S(mp);
_(snat_add_address_range, "<start-addr> [- <end-addr] [del]") \
_(snat_interface_add_del_feature, \
"<intfc> | sw_if_index <id> [in] [out] [del]") \
-_(snat_add_static_mapping, "local_addr <ip> external_addr <ip> " \
- "| external_if <intfc> | external_sw_if_ndex <id>) " \
- "[local_port <n>] [external_port <n>] [vrf <table-id>] [del]") \
+_(snat_add_static_mapping, "local_addr <ip> (external_addr <ip>" \
+ " | external_if <intfc> | external_sw_if_ndex <id>) " \
+ "[local_port <n>] [external_port <n>] [vrf <table-id>] [del] " \
+ "protocol <n>") \
_(snat_set_workers, "<wokrers_bitmap>") \
_(snat_static_mapping_dump, "") \
_(snat_show_config, "") \
external_port=sm.external_port,
addr_only=sm.addr_only,
vrf_id=sm.vrf_id,
+ protocol=sm.protocol,
is_add=0)
adresses = self.vapi.snat_address_dump()
def snat_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):
+ is_add=1, external_sw_if_index=0xFFFFFFFF,
+ proto=0):
"""
Add/delete S-NAT static mapping
:param vrf_id: VRF ID (Default 0)
:param is_add: 1 if add, 0 if delete (Default add)
:param external_sw_if_index: External interface instead of IP address
+ :param proto: IP protocol (Mandatory if port specified)
"""
addr_only = 1
if local_port and external_port:
external_port,
addr_only,
vrf_id,
+ proto,
is_add)
def snat_add_address(self, ip, is_add=1):
self.snat_add_address(self.snat_addr)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.tcp_port_in, self.tcp_port_out)
+ self.tcp_port_in, self.tcp_port_out,
+ proto=IP_PROTOS.tcp)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.udp_port_in, self.udp_port_out)
+ self.udp_port_in, self.udp_port_out,
+ proto=IP_PROTOS.udp)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.icmp_id_in, self.icmp_id_out)
+ self.icmp_id_in, self.icmp_id_out,
+ proto=IP_PROTOS.icmp)
self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
self.snat_add_address(self.snat_addr)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.tcp_port_in, self.tcp_port_out)
+ self.tcp_port_in, self.tcp_port_out,
+ proto=IP_PROTOS.tcp)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.udp_port_in, self.udp_port_out)
+ self.udp_port_in, self.udp_port_out,
+ proto=IP_PROTOS.udp)
self.snat_add_static_mapping(self.pg0.remote_ip4, self.snat_addr,
- self.icmp_id_in, self.icmp_id_out)
+ self.icmp_id_in, self.icmp_id_out,
+ proto=IP_PROTOS.icmp)
self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
is_inside=0)
# add static mapping for server
self.snat_add_static_mapping(server.ip4, self.snat_addr,
- server_in_port, server_out_port)
+ server_in_port, server_out_port,
+ proto=IP_PROTOS.tcp)
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
external_port=0,
addr_only=1,
vrf_id=0,
+ protocol=0,
is_add=1,
is_ip4=1):
"""Add/delete S-NAT static mapping
:param external_port: External port number (Default value = 0)
: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 is_add: 1 if add, 0 if delete (Default value = 1)
:param is_ip4: 1 if address type is IPv4 (Default value = 1)
"""
'local_port': local_port,
'external_port': external_port,
'external_sw_if_index': external_sw_if_index,
- 'vrf_id': vrf_id})
+ 'vrf_id': vrf_id,
+ 'protocol': protocol})
def snat_add_address_range(
self,