X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fmactime%2Fnode.c;h=608773d5ce4cdb574a3b0ddebc261fb10f979ec2;hb=21a438465ca0dee88d13d9dd9621929116c95614;hp=1d45a39e1cee60d0bef644a3d0fda172a9f6f053;hpb=2a8d02df15e71881754bab0bb16b85ccd65f8f74;p=vpp.git diff --git a/src/plugins/mactime/node.c b/src/plugins/mactime/node.c index 1d45a39e1ce..608773d5ce4 100644 --- a/src/plugins/mactime/node.c +++ b/src/plugins/mactime/node.c @@ -19,6 +19,7 @@ #include #include #include +#include typedef struct { @@ -32,8 +33,11 @@ vlib_node_registration_t mactime_node; vlib_node_registration_t mactime_tx_node; #define foreach_mactime_error \ -_(DROP, "Dropped packets") \ -_(OK, "Permitted packets") +_(OK, "Permitted packets") \ +_(STATIC_DROP, "Static drop packets") \ +_(RANGE_DROP, "Range drop packets") \ +_(QUOTA_DROP, "Data quota drop packets") \ +_(DROP_10001, "Dropped UDP DST-port 10001") typedef enum { @@ -82,7 +86,7 @@ mactime_node_inline (vlib_main_t * vm, mactime_device_t *dp; clib_bihash_kv_8_8_t kv; clib_bihash_8_8_t *lut = &mm->lookup_table; - u32 packets_ok = 0, packets_dropped = 0; + u32 packets_ok = 0; f64 now; u32 thread_index = vm->thread_index; vnet_main_t *vnm = vnet_get_main (); @@ -116,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 */ @@ -142,9 +147,9 @@ mactime_node_inline (vlib_main_t * vm, en0 = vlib_buffer_get_current (b0); kv.key = 0; if (is_tx) - clib_memcpy (&kv.key, en0->dst_address, 6); + clib_memcpy_fast (&kv.key, en0->dst_address, 6); else - clib_memcpy (&kv.key, en0->src_address, 6); + clib_memcpy_fast (&kv.key, en0->src_address, 6); /* Lookup the src/dst mac address */ if (clib_bihash_search_8_8 (lut, &kv, &kv) < 0) @@ -164,6 +169,25 @@ mactime_node_inline (vlib_main_t * vm, dp = pool_elt_at_index (mm->devices, device_index0); + /* 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, + dp - mm->devices, + &device_current_count); + if (device_current_count.bytes >= 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; + } + } + /* Static drop / allow? */ if (PREDICT_FALSE (dp->flags & @@ -173,17 +197,41 @@ mactime_node_inline (vlib_main_t * vm, if (dp->flags & MACTIME_DEVICE_FLAG_STATIC_DROP) { next0 = MACTIME_NEXT_DROP; + b0->error = node->errors[MACTIME_ERROR_STATIC_DROP]; vlib_increment_combined_counter (&mm->drop_counters, thread_index, dp - mm->devices, 1, len0); - packets_dropped++; } else /* note next0 set to allow */ { - vlib_increment_combined_counter - (&mm->allow_counters, thread_index, dp - mm->devices, 1, - len0); - packets_ok++; + /* + * Special-case mini-ACL for a certain species of + * home security DVR which likes to "call home." + */ + if (PREDICT_FALSE + (dp->flags & MACTIME_DEVICE_FLAG_DROP_UDP_10001)) + { + ip4_header_t *ip = (void *) (((u8 *) en0) + 14); + udp_header_t *udp = (udp_header_t *) (ip + 1); + if (ip->protocol != IP_PROTOCOL_UDP) + goto pass; + if (clib_net_to_host_u16 (udp->dst_port) == 10001 || + clib_net_to_host_u16 (udp->dst_port) == 9603) + { + next0 = MACTIME_NEXT_DROP; + b0->error = node->errors[MACTIME_ERROR_DROP_10001]; + } + else + goto pass; + } + else + { + pass: + vlib_increment_combined_counter + (&mm->allow_counters, thread_index, dp - mm->devices, + 1, len0); + packets_ok++; + } } goto trace0; } @@ -196,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) { @@ -205,17 +256,37 @@ mactime_node_inline (vlib_main_t * vm, vlib_increment_combined_counter (&mm->drop_counters, thread_index, dp - mm->devices, 1, len0); - packets_dropped++; 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; } } /* @@ -225,15 +296,17 @@ mactime_node_inline (vlib_main_t * vm, if (dp->flags & MACTIME_DEVICE_FLAG_DYNAMIC_ALLOW) { next0 = MACTIME_NEXT_DROP; + b0->error = node->errors[MACTIME_ERROR_STATIC_DROP]; vlib_increment_combined_counter (&mm->drop_counters, thread_index, dp - mm->devices, 1, len0); - packets_dropped++; } - 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++; } @@ -242,15 +315,16 @@ mactime_node_inline (vlib_main_t * vm, && (b0->flags & VLIB_BUFFER_IS_TRACED))) { mactime_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t)); - clib_memcpy (t->src_mac, en0->src_address, sizeof (t->src_mac)); + clib_memcpy_fast (t->src_mac, en0->src_address, + sizeof (t->src_mac)); t->next_index = next0; t->device_index = device_index0; if (dp) { - clib_memcpy (t->device_name, dp->device_name, - ARRAY_LEN (t->device_name)); + clib_memcpy_fast (t->device_name, dp->device_name, + ARRAY_LEN (t->device_name)); t->device_name[ARRAY_LEN (t->device_name) - 1] = 0; } } @@ -264,8 +338,6 @@ mactime_node_inline (vlib_main_t * vm, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, node->node_index, - MACTIME_ERROR_DROP, packets_dropped); vlib_node_increment_counter (vm, node->node_index, MACTIME_ERROR_OK, packets_ok); return frame->n_vectors;