aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2019-06-08 12:33:13 -0400
committerFlorin Coras <florin.coras@gmail.com>2019-06-08 19:39:57 +0000
commit7681b1c469eda79003eef550fda460f48e5a08d7 (patch)
treea7bc4e892fd2b60efc2b39775487f51c524c10f0
parent8875248f5e0602f4b4872ea12e542826df3df1f8 (diff)
mactime: add per-mac allow-with-quota feature
Specify a data limit during specified time ranges. Outside of the specified time ranges, data will be allowed. Clean up "show mactime" output. Type: feature Change-Id: Iddd6678e7ded1d0f9cb88d69c656de8d87d5694c Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/plugins/mactime/mactime.api3
-rw-r--r--src/plugins/mactime/mactime.c34
-rw-r--r--src/plugins/mactime/mactime.h4
-rw-r--r--src/plugins/mactime/mactime_test.c10
-rw-r--r--src/plugins/mactime/node.c37
5 files changed, 73 insertions, 15 deletions
diff --git a/src/plugins/mactime/mactime.api b/src/plugins/mactime/mactime.api
index d9049d8dbd1..3ba6464ec43 100644
--- a/src/plugins/mactime/mactime.api
+++ b/src/plugins/mactime/mactime.api
@@ -16,7 +16,7 @@
/** \file
This file defines vpp mactime control-plane API messages
*/
-option version = "1.1.0";
+option version = "1.1.1";
/** \brief api to enable or disable the time-based src mac filter on
an interface
@@ -74,6 +74,7 @@ autoreply define mactime_add_del_range
u8 is_add; /**< add=1, del=0 */
u8 drop; /**< drop flag */
u8 allow; /**< allow flag */
+ u8 allow_quota; /**< allow subject to quota */
u8 no_udp_10001; /**< drop udp to port 10001 */
u64 data_quota; /**< max bytes this device */
u8 mac_address[6]; /**< src mac address */
diff --git a/src/plugins/mactime/mactime.c b/src/plugins/mactime/mactime.c
index d84151ed29e..57895404390 100644
--- a/src/plugins/mactime/mactime.c
+++ b/src/plugins/mactime/mactime.c
@@ -266,6 +266,8 @@ static void vl_api_mactime_add_del_range_t_handler
dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_DROP;
if (mp->allow)
dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW;
+ if (mp->allow_quota)
+ dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA;
}
else
{
@@ -303,6 +305,8 @@ static void vl_api_mactime_add_del_range_t_handler
dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_DROP;
if (mp->allow)
dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW;
+ if (mp->allow_quota)
+ dp->flags = MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA;
}
else
{
@@ -462,7 +466,10 @@ format_bytes_with_width (u8 * s, va_list * va)
u8 *fmt;
char *suffix = "";
- fmt = format (0, "%%%d.3f%%s%c", width, 0);
+ if (width > 0)
+ fmt = format (0, "%%%d.3f%%s%c", width, 0);
+ else
+ fmt = format (0, "%%.3f%%s%c", 0);
if (nbytes > (1024ULL * 1024ULL * 1024ULL))
{
@@ -480,7 +487,10 @@ format_bytes_with_width (u8 * s, va_list * va)
suffix = "K";
}
else
- nbytes_f64 = (f64) nbytes;
+ {
+ nbytes_f64 = (f64) nbytes;
+ suffix = "B";
+ }
s = format (s, (char *) fmt, nbytes_f64, suffix);
vec_free (fmt);
@@ -534,7 +544,7 @@ show_mactime_command_fn (vlib_main_t * vm,
}));
/* *INDENT-ON* */
- vlib_cli_output (vm, "%-15s %18s %14s %10s %11s %10s",
+ vlib_cli_output (vm, "%-15s %18s %14s %10s %11s %13s",
"Device Name", "Addresses", "Status",
"AllowPkt", "AllowByte", "DropPkt");
@@ -559,6 +569,8 @@ show_mactime_command_fn (vlib_main_t * vm,
{
if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
current_status = 3;
+ else if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
+ current_status = 5;
else
current_status = 2;
if (verbose)
@@ -581,6 +593,8 @@ show_mactime_command_fn (vlib_main_t * vm,
current_status = 2;
if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_DROP)
current_status = 3;
+ if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
+ current_status = 4;
print:
vec_reset_length (macstring);
@@ -599,6 +613,12 @@ show_mactime_command_fn (vlib_main_t * vm,
case 3:
status_string = "dynamic allow";
break;
+ case 4:
+ status_string = "d-quota inact";
+ break;
+ case 5:
+ status_string = "d-quota activ";
+ break;
default:
status_string = "code bug!";
break;
@@ -606,13 +626,15 @@ show_mactime_command_fn (vlib_main_t * vm,
vlib_get_combined_counter (&mm->allow_counters, dp - mm->devices,
&allow);
vlib_get_combined_counter (&mm->drop_counters, dp - mm->devices, &drop);
- vlib_cli_output (vm, "%-15s %18s %14s %10lld %U %10lld",
+ vlib_cli_output (vm, "%-15s %18s %14s %10lld %U %13lld",
dp->device_name, macstring, status_string,
allow.packets, format_bytes_with_width, allow.bytes,
10, drop.packets);
if (dp->data_quota > 0)
- vlib_cli_output (vm, "%-54s %s%U", " ", "Quota ",
- format_bytes_with_width, dp->data_quota, 10);
+ vlib_cli_output (vm, "%-54s %s%U %s%U", " ", "Quota ",
+ format_bytes_with_width, dp->data_quota, 10,
+ "Use ", format_bytes_with_width,
+ dp->data_used_in_range, 8);
/* This is really only good for small N... */
for (j = 0; j < vec_len (mm->arp_cache_copy); j++)
{
diff --git a/src/plugins/mactime/mactime.h b/src/plugins/mactime/mactime.h
index 928d7e940b6..11e33c1122b 100644
--- a/src/plugins/mactime/mactime.h
+++ b/src/plugins/mactime/mactime.h
@@ -37,6 +37,7 @@ typedef struct
u8 *device_name;
u8 mac_address[6];
u64 data_quota;
+ u64 data_used_in_range;
u32 flags;
clib_timebase_range_t *ranges;
} mactime_device_t;
@@ -46,7 +47,8 @@ typedef struct
#define MACTIME_DEVICE_FLAG_STATIC_ALLOW (1<<1)
#define MACTIME_DEVICE_FLAG_DYNAMIC_DROP (1<<2)
#define MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW (1<<3)
-#define MACTIME_DEVICE_FLAG_DROP_UDP_10001 (1<<4)
+#define MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA (1<<4)
+#define MACTIME_DEVICE_FLAG_DROP_UDP_10001 (1<<5)
typedef struct
{
diff --git a/src/plugins/mactime/mactime_test.c b/src/plugins/mactime/mactime_test.c
index 36ee063135d..4557e57dbff 100644
--- a/src/plugins/mactime/mactime_test.c
+++ b/src/plugins/mactime/mactime_test.c
@@ -158,6 +158,7 @@ api_mactime_add_del_range (vat_main_t * vam)
int mac_set = 0;
u8 is_add = 1;
u8 allow = 0;
+ u8 allow_quota = 0;
u8 drop = 0;
u8 no_udp_10001 = 0;
u64 data_quota = 0;
@@ -175,6 +176,9 @@ api_mactime_add_del_range (vat_main_t * vam)
else if (unformat (i, "allow-range %U",
unformat_clib_timebase_range_vector, &rp))
allow = 1;
+ else if (unformat (i, "allow-quota-range %U",
+ unformat_clib_timebase_range_vector, &rp))
+ allow_quota = 1;
else if (unformat (i, "drop-range %U",
unformat_clib_timebase_range_vector, &rp))
drop = 1;
@@ -206,11 +210,12 @@ api_mactime_add_del_range (vat_main_t * vam)
}
/* allow-range / drop-range parse errors cause this condition */
- if (is_add && allow == 0 && drop == 0)
+ if (is_add && allow == 0 && drop == 0 && allow_quota == 0)
{
vec_free (rp);
vec_free (device_name);
- errmsg ("neither allow nor drop set, parse error...\n");
+ errmsg ("parse error...\n");
+ return -99;
}
/* Unlikely, but check anyhow */
@@ -234,6 +239,7 @@ api_mactime_add_del_range (vat_main_t * vam)
mp->is_add = is_add;
mp->drop = drop;
mp->allow = allow;
+ mp->allow_quota = allow_quota;
mp->no_udp_10001 = no_udp_10001;
mp->data_quota = clib_host_to_net_u64 (data_quota);
memcpy (mp->mac_address, mac_address, sizeof (mp->mac_address));
diff --git a/src/plugins/mactime/node.c b/src/plugins/mactime/node.c
index e4d12f80db4..608773d5ce4 100644
--- a/src/plugins/mactime/node.c
+++ b/src/plugins/mactime/node.c
@@ -120,6 +120,7 @@ mactime_node_inline (vlib_main_t * vm,
u32 device_index0;
u32 len0;
ethernet_header_t *en0;
+ int has_dynamic_range_allow = 0;
int i;
/* speculatively enqueue b0 to the current next frame */
@@ -168,8 +169,9 @@ mactime_node_inline (vlib_main_t * vm,
dp = pool_elt_at_index (mm->devices, device_index0);
- /* Known device, check for a traffic quota */
- if (PREDICT_FALSE (dp->data_quota))
+ /* Known device, check for an always-on traffic quota */
+ if ((dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW)
+ && PREDICT_FALSE (dp->data_quota))
{
vlib_counter_t device_current_count;
vlib_get_combined_counter (&mm->allow_counters,
@@ -242,6 +244,9 @@ mactime_node_inline (vlib_main_t * vm,
start0 = r->start + mm->sunday_midnight;
end0 = r->end + mm->sunday_midnight;
+ if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW_QUOTA)
+ has_dynamic_range_allow = 1;
+
/* Packet within time range */
if (now >= start0 && now <= end0)
{
@@ -253,15 +258,35 @@ mactime_node_inline (vlib_main_t * vm,
dp - mm->devices, 1, len0);
next0 = MACTIME_NEXT_DROP;
b0->error = node->errors[MACTIME_ERROR_RANGE_DROP];
+ goto trace0;
}
- else /* it's an allow range, allow it */
+ /* Quota-check allow range? */
+ else if (has_dynamic_range_allow)
{
+ if (dp->data_used_in_range + len0 >= dp->data_quota)
+ {
+ next0 = MACTIME_NEXT_DROP;
+ b0->error = node->errors[MACTIME_ERROR_QUOTA_DROP];
+ vlib_increment_combined_counter
+ (&mm->drop_counters, thread_index,
+ dp - mm->devices, 1, len0);
+ goto trace0;
+ }
+ else
+ {
+ dp->data_used_in_range += len0;
+ goto allow0;
+ }
+ }
+ else
+ { /* it's an allow range, allow it */
+ allow0:
vlib_increment_combined_counter
(&mm->allow_counters, thread_index,
dp - mm->devices, 1, len0);
packets_ok++;
+ goto trace0;
}
- goto trace0;
}
}
/*
@@ -275,11 +300,13 @@ mactime_node_inline (vlib_main_t * vm,
vlib_increment_combined_counter
(&mm->drop_counters, thread_index, dp - mm->devices, 1, len0);
}
- else
+ else /* DYNAMIC_DROP, DYNAMIC_RANGE_ALLOW_QUOTA */
{
vlib_increment_combined_counter
(&mm->allow_counters, thread_index, dp - mm->devices, 1,
len0);
+ /* Clear the data quota accumulater */
+ dp->data_used_in_range = 0;
packets_ok++;
}