session/tcp: filtering improvements
- make allow action explicit (-3)
- add session lookup is_filtered return flag that is set if lookup hit a
deny filter
- change tcp logic to drop filtered packets when punting is enabled
Change-Id: Ic38f294424663a4e108439b7571511f46f8e0be1
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/session/application_namespace.c b/src/vnet/session/application_namespace.c
index eaf09e8..21c1cbc 100644
--- a/src/vnet/session/application_namespace.c
+++ b/src/vnet/session/application_namespace.c
@@ -248,7 +248,8 @@
format_app_namespace (u8 * s, va_list * args)
{
app_namespace_t *app_ns = va_arg (*args, app_namespace_t *);
- s = format (s, "%-20v%-20lu%-20u", app_ns->ns_id, app_ns->ns_secret,
+ s = format (s, "%-20v%-10u%-20lu%-20u", app_ns->ns_id,
+ app_namespace_index (app_ns), app_ns->ns_secret,
app_ns->sw_if_index);
return s;
}
@@ -301,9 +302,10 @@
goto done;
}
- vlib_cli_output (vm, "%-20s%-20s%-20s", "Namespace", "Secret",
- "sw_if_index");
do_ns_list:
+ vlib_cli_output (vm, "%-20s%-10s%-20s%-20s", "Namespace", "Index", "Secret",
+ "sw_if_index");
+
/* *INDENT-OFF* */
pool_foreach (app_ns, app_namespace_pool, ({
vlib_cli_output (vm, "%U", format_app_namespace, app_ns);
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 30e3913..2e4e96a 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -378,12 +378,28 @@
return session_lookup_del_connection (ts);
}
-static u32
-session_lookup_action_to_session_index (u32 action_index)
+static u8
+session_lookup_action_index_is_valid (u32 action_index)
{
- if (action_index != SESSION_RULES_TABLE_ACTION_DROP)
- return action_index;
- return SESSION_INVALID_INDEX;
+ if (action_index == SESSION_RULES_TABLE_ACTION_ALLOW
+ || action_index == SESSION_RULES_TABLE_INVALID_INDEX)
+ return 0;
+ return 1;
+}
+
+static u32
+session_lookup_action_to_app_index (u32 action_index)
+{
+ switch (action_index)
+ {
+ case SESSION_RULES_TABLE_ACTION_DROP:
+ return APP_DROP_INDEX;
+ case SESSION_RULES_TABLE_ACTION_ALLOW:
+ case SESSION_RULES_TABLE_INVALID_INDEX:
+ return APP_INVALID_INDEX;
+ default:
+ return action_index;
+ }
}
static stream_session_t *
@@ -391,7 +407,7 @@
u8 transport_proto)
{
application_t *app;
- app = application_get (app_index);
+ app = application_get_if_valid (app_index);
if (!app)
return 0;
@@ -402,10 +418,10 @@
session_lookup_action_to_session (u32 action_index, u8 fib_proto,
u8 transport_proto)
{
- u32 session_index;
- session_index = session_lookup_action_to_session_index (action_index);
+ u32 app_index;
+ app_index = session_lookup_action_to_app_index (action_index);
/* Nothing sophisticated for now, action index is app index */
- return session_lookup_app_listen_session (session_index, fib_proto,
+ return session_lookup_app_listen_session (app_index, fib_proto,
transport_proto);
}
@@ -415,26 +431,26 @@
ip4_address_t * rmt, u16 rmt_port)
{
session_rules_table_t *srt = &st->session_rules[proto];
- u32 action_index, session_index;
+ u32 action_index, app_index;
action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
rmt_port);
- session_index = session_lookup_action_to_session_index (action_index);
+ app_index = session_lookup_action_to_app_index (action_index);
/* Nothing sophisticated for now, action index is app index */
- return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP4,
+ return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4,
proto);
}
stream_session_t *
-session_lookup_rules_table6 (session_table_t * st, u8 proto,
- ip6_address_t * lcl, u16 lcl_port,
- ip6_address_t * rmt, u16 rmt_port)
+session_lookup_rules_table_session6 (session_table_t * st, u8 proto,
+ ip6_address_t * lcl, u16 lcl_port,
+ ip6_address_t * rmt, u16 rmt_port)
{
session_rules_table_t *srt = &st->session_rules[proto];
- u32 action_index, session_index;
+ u32 action_index, app_index;
action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
rmt_port);
- session_index = session_lookup_action_to_session_index (action_index);
- return session_lookup_app_listen_session (session_index, FIB_PROTOCOL_IP6,
+ app_index = session_lookup_action_to_app_index (action_index);
+ return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6,
proto);
}
@@ -477,8 +493,8 @@
srt = &st->session_rules[sep->transport_proto];
ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
sep->port);
- if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
- return session_lookup_action_to_session_index (ai);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_app_index (ai);
}
}
else
@@ -497,8 +513,8 @@
srt = &st->session_rules[sep->transport_proto];
ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
sep->port);
- if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
- return session_lookup_action_to_session_index (ai);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_app_index (ai);
}
}
return SESSION_INVALID_HANDLE;
@@ -545,10 +561,8 @@
srt = &st->session_rules[sep->transport_proto];
ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
sep->port);
- if (ai == SESSION_RULES_TABLE_ACTION_DROP)
- return APP_DROP_INDEX;
- if (ai != SESSION_RULES_TABLE_ACTION_NONE)
- return session_lookup_action_to_session_index (ai);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_app_index (ai);
/*
* Check if session endpoint is a listener
@@ -585,10 +599,8 @@
srt = &st->session_rules[sep->transport_proto];
ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
sep->port);
- if (ai == SESSION_RULES_TABLE_ACTION_DROP)
- return APP_DROP_INDEX;
- if (ai != SESSION_RULES_TABLE_INVALID_INDEX)
- return session_lookup_action_to_session_index (ai);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_app_index (ai);
make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
sep->transport_proto);
@@ -828,13 +840,15 @@
* @param rmt_port remote port
* @param proto transport protocol (e.g., tcp, udp)
* @param thread_index thread index for request
+ * @param is_filtered return flag that indicates if connection was filtered.
*
* @return pointer to transport connection, if one is found, 0 otherwise
*/
transport_connection_t *
session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
ip4_address_t * rmt, u16 lcl_port,
- u16 rmt_port, u8 proto, u32 thread_index)
+ u16 rmt_port, u8 proto, u32 thread_index,
+ u8 * is_filtered)
{
session_table_t *st;
session_kv4_t kv4;
@@ -874,14 +888,14 @@
*/
action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto);
- if (s)
+ if ((*is_filtered = (action_index == SESSION_RULES_TABLE_ACTION_DROP)))
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP4, proto)))
return tp_vfts[s->session_type].get_listener (s->connection_index);
+ return 0;
}
/*
@@ -952,14 +966,14 @@
*/
action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto);
- if (s)
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP4, proto)))
return tp_vfts[s->session_type].get_listener (s->connection_index);
+ return 0;
}
/*
@@ -1012,13 +1026,12 @@
*/
action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- if ((s = session_lookup_action_to_session (action_index,
- FIB_PROTOCOL_IP4, proto)))
- return s;
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
+ proto);
}
/*
@@ -1058,7 +1071,8 @@
transport_connection_t *
session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
ip6_address_t * rmt, u16 lcl_port,
- u16 rmt_port, u8 proto, u32 thread_index)
+ u16 rmt_port, u8 proto, u32 thread_index,
+ u8 * is_filtered)
{
session_table_t *st;
stream_session_t *s;
@@ -1091,14 +1105,14 @@
/* Check the session rules table */
action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto);
- if (s)
+ if ((*is_filtered = (action_index == SESSION_RULES_TABLE_ACTION_DROP)))
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP6, proto)))
return tp_vfts[s->session_type].get_listener (s->connection_index);
+ return 0;
}
/* If nothing is found, check if any listener is available */
@@ -1160,14 +1174,14 @@
/* Check the session rules table */
action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- s = session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto);
- if (s)
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP6, proto)))
return tp_vfts[s->session_type].get_listener (s->connection_index);
+ return 0;
}
/* If nothing is found, check if any listener is available */
@@ -1213,14 +1227,12 @@
/* Check the session rules table */
action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
rmt, lcl_port, rmt_port);
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if (action_index != SESSION_RULES_TABLE_ACTION_NONE)
+ if (session_lookup_action_index_is_valid (action_index))
{
- if ((s =
- session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto)))
- return s;
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6,
+ proto);
}
/* If nothing is found, check if any listener is available */
@@ -1639,8 +1651,8 @@
VLIB_CLI_COMMAND (show_session_rules_command, static) =
{
.path = "show session rules",
- .short_help = "show session rules [appns <id> proto <proto> <lcl-ip/plen>"
- " <lcl-port> <rmt-ip/plen> <rmt-port>]",
+ .short_help = "show session rules [<proto> appns <id> <lcl-ip/plen> "
+ "<lcl-port> <rmt-ip/plen> <rmt-port> scope <scope>]",
.function = show_session_rules_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 00ef19f..1bdf6d1 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -32,7 +32,8 @@
ip4_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto,
- u32 thread_index);
+ u32 thread_index,
+ u8 * is_filtered);
transport_connection_t *session_lookup_connection4 (u32 fib_index,
ip4_address_t * lcl,
ip4_address_t * rmt,
@@ -43,7 +44,8 @@
ip6_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto,
- u32 thread_index);
+ u32 thread_index,
+ u8 * is_filtered);
transport_connection_t *session_lookup_connection6 (u32 fib_index,
ip6_address_t * lcl,
ip6_address_t * rmt,
diff --git a/src/vnet/session/session_rules_table.h b/src/vnet/session/session_rules_table.h
index ecd2d9b..9088afc 100644
--- a/src/vnet/session/session_rules_table.h
+++ b/src/vnet/session/session_rules_table.h
@@ -56,8 +56,8 @@
#define SESSION_RULE_TAG_MAX_LEN 64
#define SESSION_RULES_TABLE_INVALID_INDEX MMA_TABLE_INVALID_INDEX
-#define SESSION_RULES_TABLE_ACTION_DROP (((u32)~0) - 1)
-#define SESSION_RULES_TABLE_ACTION_NONE SESSION_RULES_TABLE_INVALID_INDEX
+#define SESSION_RULES_TABLE_ACTION_DROP (MMA_TABLE_INVALID_INDEX - 1)
+#define SESSION_RULES_TABLE_ACTION_ALLOW (MMA_TABLE_INVALID_INDEX - 2)
typedef struct _session_rules_table_add_del_args
{
diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c
index 8194a31..58d0d28 100644
--- a/src/vnet/session/session_test.c
+++ b/src/vnet/session/session_test.c
@@ -496,7 +496,8 @@
* Cleanup
*/
vec_free (ns_id);
- vnet_delete_loopback_interface (sw_if_index);
+ /* fails in multi core scenarions .. */
+ /* vnet_delete_loopback_interface (sw_if_index); */
return 0;
}
@@ -780,11 +781,11 @@
transport_connection_t *tc;
u32 dummy_port = 1111;
clib_error_t *error = 0;
- u8 segment_name[128];
+ u8 segment_name[128], is_filtered = 0;
stream_session_t *listener, *s;
app_namespace_t *default_ns = app_namespace_get_default ();
u32 local_ns_index = default_ns->local_table_index;
- int verbose = 0;
+ int verbose = 0, rv;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -852,7 +853,8 @@
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
/*
@@ -878,7 +880,8 @@
"optimized lookup should return the listener");
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc->c_index == listener->connection_index),
"lookup should return the listener");
s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
@@ -897,7 +900,8 @@
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port + 1,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0),
"optimized lookup for wrong lcl port + 1 should not work");
@@ -911,7 +915,8 @@
args.table_args.action_index);
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port + 1,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc->c_index == listener->connection_index),
"optimized lookup for lcl port + 1 should work");
app_index = session_lookup_local_endpoint (local_ns_index, &sep);
@@ -923,12 +928,12 @@
*/
args.table_args.lcl_port = 1234;
args.table_args.lcl.fp_addr.ip4 = lcl_ip;
- args.table_args.lcl.fp_len = 32;
+ args.table_args.lcl.fp_len = 30;
args.table_args.rmt.fp_addr.ip4 = rmt_ip;
- args.table_args.rmt.fp_len = 32;
+ args.table_args.rmt.fp_len = 30;
args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
error = vnet_session_rule_add_del (&args);
- SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
+ SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
args.table_args.action_index);
if (verbose)
@@ -941,26 +946,97 @@
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
"should fail (deny rule)");
+ SESSION_TEST ((is_filtered == 1), "lookup should be filtered (deny)");
+
app_index = session_lookup_local_endpoint (local_ns_index, &sep);
SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
"5.6.7.8/16 4321 in local table should return deny");
- tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
- &rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
- SESSION_TEST ((tc == 0),
- "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 should not work");
+
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port + 1,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc->c_index == listener->connection_index),
"lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
/*
+ * "Mask" deny rule with more specific allow:
+ * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
+ */
+ args.table_args.is_add = 1;
+ args.table_args.lcl_port = 1234;
+ args.table_args.lcl.fp_addr.ip4 = lcl_ip;
+ args.table_args.lcl.fp_len = 32;
+ args.table_args.rmt.fp_addr.ip4 = rmt_ip;
+ args.table_args.rmt.fp_len = 32;
+ args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
+ error = vnet_session_rule_add_del (&args);
+ SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
+ "4321 action %d", args.table_args.action_index);
+
+ is_filtered = 0;
+ tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
+ &rmt_pref.fp_addr.ip4, lcl_port,
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
+ SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
+ "should fail (allow without app)");
+ SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
+
+ app_index = session_lookup_local_endpoint (local_ns_index, &sep);
+ SESSION_TEST ((app_index == APP_INVALID_INDEX), "lookup for 1.2.3.4/32 1234"
+ " 5.6.7.8/16 4321 in local table should return invalid");
+
+ if (verbose)
+ {
+ vlib_cli_output (vm, "Local rules");
+ session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
+ TRANSPORT_PROTO_TCP);
+ }
+
+ sep.ip.ip4.as_u32 += 1 << 24;
+ app_index = session_lookup_local_endpoint (local_ns_index, &sep);
+ SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234"
+ " 5.6.7.9/16 4321 in local table should return invalid");
+
+ vnet_connect_args_t connect_args = {
+ .sep = sep,
+ .app_index = attach_args.app_index,
+ .api_context = 0,
+ };
+
+ /* Try connecting */
+ error = vnet_connect (&connect_args);
+ SESSION_TEST ((error != 0), "connect should fail");
+ rv = clib_error_get_code (error);
+ SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
+ "connect should be filtered");
+
+ sep.ip.ip4.as_u32 -= 1 << 24;
+
+
+
+ /*
+ * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
+ */
+ args.table_args.is_add = 0;
+ args.table_args.lcl_port = 1234;
+ args.table_args.lcl.fp_addr.ip4 = lcl_ip;
+ args.table_args.lcl.fp_len = 32;
+ args.table_args.rmt.fp_addr.ip4 = rmt_ip;
+ args.table_args.rmt.fp_len = 32;
+ error = vnet_session_rule_add_del (&args);
+ SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
+
+
+ /*
* Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
*/
+ args.table_args.is_add = 1;
args.table_args.lcl_port = 0;
args.table_args.lcl.fp_len = 0;
args.table_args.rmt.fp_len = 16;
@@ -979,7 +1055,7 @@
app_index = session_lookup_local_endpoint (local_ns_index, &sep);
SESSION_TEST ((app_index == APP_DROP_INDEX),
- "local session endpoint lookup " "should return deny");
+ "local session endpoint lookup should return deny");
/*
* Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
@@ -987,9 +1063,9 @@
args.table_args.is_add = 0;
args.table_args.lcl_port = 1234;
args.table_args.lcl.fp_addr.ip4 = lcl_ip;
- args.table_args.lcl.fp_len = 32;
+ args.table_args.lcl.fp_len = 30;
args.table_args.rmt.fp_addr.ip4 = rmt_ip;
- args.table_args.rmt.fp_len = 32;
+ args.table_args.rmt.fp_len = 30;
error = vnet_session_rule_add_del (&args);
SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
@@ -1028,7 +1104,8 @@
SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port + 1,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0),
"lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
"work (del)");
@@ -1044,14 +1121,16 @@
SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
"not work (del + deny)");
SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
" not work (no-rule)");
@@ -1079,7 +1158,8 @@
}
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc->c_index == listener->connection_index),
"lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
@@ -1097,7 +1177,8 @@
"tag test_rule");
tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
&rmt_pref.fp_addr.ip4, lcl_port,
- rmt_port, TRANSPORT_PROTO_TCP, 0);
+ rmt_port, TRANSPORT_PROTO_TCP, 0,
+ &is_filtered);
SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should not"
" work (del)");
vec_free (args.table_args.tag);
@@ -1118,7 +1199,7 @@
u32 server_index, app_index;
u32 dummy_server_api_index = ~0, sw_if_index = 0;
clib_error_t *error = 0;
- u8 segment_name[128], intf_mac[6], sst;
+ u8 segment_name[128], intf_mac[6], sst, is_filtered = 0;
stream_session_t *s;
transport_connection_t *tc;
u16 lcl_port = 1234, rmt_port = 4321;
@@ -1202,7 +1283,7 @@
}
tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
- TRANSPORT_PROTO_TCP, 0);
+ TRANSPORT_PROTO_TCP, 0, &is_filtered);
SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
"successful");
sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
@@ -1211,7 +1292,7 @@
" server");
tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
- TRANSPORT_PROTO_TCP, 0);
+ TRANSPORT_PROTO_TCP, 0, &is_filtered);
SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
" not work");
@@ -1237,7 +1318,8 @@
app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
"local session endpoint lookup should not work after detach");
- unformat_free (&tmp_input);
+ if (verbose)
+ unformat_free (&tmp_input);
return 0;
}
diff --git a/src/vnet/tcp/tcp_error.def b/src/vnet/tcp/tcp_error.def
index a179717..5bff5ee 100644
--- a/src/vnet/tcp/tcp_error.def
+++ b/src/vnet/tcp/tcp_error.def
@@ -40,4 +40,5 @@
tcp_error (NO_WND, "No window")
tcp_error (CONNECTION_CLOSED, "Connection closed")
tcp_error (CREATE_EXISTS, "Connection already exists")
-tcp_error (PUNT, "Packets punted")
\ No newline at end of file
+tcp_error (PUNT, "Packets punted")
+tcp_error (FILTERED, "Packets filtered")
\ No newline at end of file
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index 6d7beba..d3db7ef 100644
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1902,6 +1902,7 @@
tcp_header_t *tcp;
transport_connection_t *tconn;
tcp_connection_t *tc;
+ u8 is_filtered = 0;
if (is_ip4)
{
ip4_header_t *ip4;
@@ -1913,7 +1914,7 @@
tcp->dst_port,
tcp->src_port,
TRANSPORT_PROTO_TCP,
- thread_index);
+ thread_index, &is_filtered);
tc = tcp_get_connection_from_transport (tconn);
ASSERT (tcp_lookup_is_valid (tc, tcp));
}
@@ -1928,7 +1929,7 @@
tcp->dst_port,
tcp->src_port,
TRANSPORT_PROTO_TCP,
- thread_index);
+ thread_index, &is_filtered);
tc = tcp_get_connection_from_transport (tconn);
ASSERT (tcp_lookup_is_valid (tc, tcp));
}
@@ -2939,7 +2940,7 @@
ip4_header_t *ip40;
ip6_header_t *ip60;
u32 error0 = TCP_ERROR_NO_LISTENER, next0 = TCP_INPUT_NEXT_DROP;
- u8 flags0;
+ u8 flags0, is_filtered = 0;
bi0 = from[0];
to_next[0] = bi0;
@@ -2968,9 +2969,8 @@
tcp0->dst_port,
tcp0->src_port,
TRANSPORT_PROTO_TCP,
- my_thread_index);
- tc0 = tcp_get_connection_from_transport (tconn);
- ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+ my_thread_index,
+ &is_filtered);
}
else
{
@@ -2986,9 +2986,8 @@
tcp0->dst_port,
tcp0->src_port,
TRANSPORT_PROTO_TCP,
- my_thread_index);
- tc0 = tcp_get_connection_from_transport (tconn);
- ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+ my_thread_index,
+ &is_filtered);
}
/* Length check */
@@ -2999,8 +2998,11 @@
}
/* Session exists */
- if (PREDICT_TRUE (0 != tc0))
+ if (PREDICT_TRUE (0 != tconn))
{
+ tc0 = tcp_get_connection_from_transport (tconn);
+ ASSERT (tcp_lookup_is_valid (tc0, tcp0));
+
/* Save connection index */
vnet_buffer (b0)->tcp.connection_index = tc0->c_c_index;
vnet_buffer (b0)->tcp.seq_number =
@@ -3032,8 +3034,13 @@
}
else
{
- if ((is_ip4 && tm->punt_unknown4) ||
- (!is_ip4 && tm->punt_unknown6))
+ if (is_filtered)
+ {
+ next0 = TCP_INPUT_NEXT_DROP;
+ error0 = TCP_ERROR_FILTERED;
+ }
+ else if ((is_ip4 && tm->punt_unknown4) ||
+ (!is_ip4 && tm->punt_unknown6))
{
next0 = TCP_INPUT_NEXT_PUNT;
error0 = TCP_ERROR_PUNT;
@@ -3044,6 +3051,7 @@
next0 = TCP_INPUT_NEXT_RESET;
error0 = TCP_ERROR_NO_LISTENER;
}
+ tc0 = 0;
}
done:
@@ -3051,8 +3059,8 @@
if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
{
- tcp_rx_trace_t *t0 =
- vlib_add_trace (vm, node, b0, sizeof (*t0));
+ tcp_rx_trace_t *t0;
+ t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
}
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
diff --git a/src/vnet/tcp/tcp_test.c b/src/vnet/tcp/tcp_test.c
index 021f416..e3cdb1b 100644
--- a/src/vnet/tcp/tcp_test.c
+++ b/src/vnet/tcp/tcp_test.c
@@ -1558,7 +1558,7 @@
transport_connection_t _tc1, *tc1 = &_tc1, _tc2, *tc2 = &_tc2, *tconn;
tcp_connection_t *tc;
stream_session_t *s;
- u8 cmp = 0;
+ u8 cmp = 0, is_filtered = 0;
pool_get (smm->sessions[0], s);
memset (s, 0, sizeof (*s));
@@ -1601,7 +1601,7 @@
tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4,
&tc1->rmt_ip.ip4,
tc1->lcl_port, tc1->rmt_port,
- tc1->proto, 0);
+ tc1->proto, 0, &is_filtered);
cmp = (memcmp (&tconn->rmt_ip, &tc1->rmt_ip, sizeof (tc1->rmt_ip)) == 0);
TCP_TEST ((cmp), "rmt ip is identical %d", cmp);
TCP_TEST ((tconn->lcl_port == tc1->lcl_port),
@@ -1614,7 +1614,7 @@
tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
&tc2->rmt_ip.ip4,
tc2->lcl_port, tc2->rmt_port,
- tc2->proto, 0);
+ tc2->proto, 0, &is_filtered);
TCP_TEST ((tconn == 0), "lookup result should be null");
/*
@@ -1624,12 +1624,12 @@
tconn = session_lookup_connection_wt4 (0, &tc1->lcl_ip.ip4,
&tc1->rmt_ip.ip4,
tc1->lcl_port, tc1->rmt_port,
- tc1->proto, 0);
+ tc1->proto, 0, &is_filtered);
TCP_TEST ((tconn == 0), "lookup result should be null");
tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
&tc2->rmt_ip.ip4,
tc2->lcl_port, tc2->rmt_port,
- tc2->proto, 0);
+ tc2->proto, 0, &is_filtered);
TCP_TEST ((tconn == 0), "lookup result should be null");
/*
@@ -1639,7 +1639,7 @@
tconn = session_lookup_connection_wt4 (0, &tc2->lcl_ip.ip4,
&tc2->rmt_ip.ip4,
tc2->lcl_port, tc2->rmt_port,
- tc2->proto, 0);
+ tc2->proto, 0, &is_filtered);
TCP_TEST ((tconn == 0), "lookup result should be null");
return 0;