Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 101 additions & 6 deletions src/plugins/udps/udps_node.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#include "udps_includes.h"

#define foreach_udps_rx_error \
_(UDPS_RX, "UDPS_RX outgoing packets") \
_(DROP, "UDPS_RX drops")
_(UDPS_RX, "UDPS outgoing packets") \
_(RULE_MATCHED, "Rule matched on intf") \
_(RULE_ACTION_FOUND, "Rule action found") \
_(VALID_OUT_PORT, "Out port rewritten") \
_(DROP, "UDPS drop pkt")

typedef enum
{
Expand All @@ -19,8 +22,11 @@ static char *udps_rx_error_strings[] = {
};

#define foreach_udps_tx_error \
_(UDPS_TX, "UDPS_TX outgoing packets") \
_(DROP, "UDPS_TX drops")
_(UDPS_TX, "UDPS outgoing packets") \
_(RULE_MATCHED, "Rule matched on intf") \
_(RULE_ACTION_FOUND, "Rule action found") \
_(VALID_OUT_PORT, "Out port rewritten") \
_(DROP, "UDPS drop pkt")

typedef enum
{
Expand Down Expand Up @@ -74,7 +80,59 @@ udps_node_policy_remove(u32 sw_if_index, u8 is_rx)
0, 0, 0);
}
}
void
udps_apply_rule_action (vlib_main_t *vm,
vlib_buffer_t * b,
udps_rule_action_t *ra,
bool is_rx)
{
u32 offset, len;
u8 *write_ptr;
/* rewrite the out_port and be done with this */
if (ra->out_port != UDPS_NO_PORT) {
vnet_buffer (b)->sw_if_index[VLIB_TX] = ra->out_port;
}

/* loop through all the rewrite actions and apply them one by one */
for (int i = 0; i < vec_len(ra->rewrite); i++) {
switch(ra->rewrite[i].oper) {
case UDPS_REWRITE_INSERT:
offset = ra->rewrite[i].offset;
len = ra->rewrite[i].len;
vlib_buffer_advance(b, offset);
vlib_buffer_move(vm, b, (len + offset));
/* alter pkt len and rewind current_data*/
b->current_length += len;
b->current_data -= len;
write_ptr = vlib_buffer_get_current (b);
clib_memcpy_fast (write_ptr, (u8 *)ra->rewrite[i].value, len);
/*rewind to start of l2 header again*/
vlib_buffer_advance(b, -offset);
break;
case UDPS_REWRITE_REPLACE:
offset = ra->rewrite[i].offset;
len = ra->rewrite[i].len;
vlib_buffer_advance(b, offset);
write_ptr = vlib_buffer_get_current (b);
clib_memcpy_fast (write_ptr, (u8 *)ra->rewrite[i].value, len);
/*rewind to start of l2 header again*/
vlib_buffer_advance(b, -offset);
break;
case UDPS_REWRITE_REMOVE:
offset = ra->rewrite[i].offset;
len = ra->rewrite[i].len;
vlib_buffer_advance(b, len+offset);
vlib_buffer_move(vm, b, offset);
/*rewind to start of l2 header again*/
vlib_buffer_advance(b, -offset);
break;
default:
break;
}
}

return;
}
VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
vlib_node_runtime_t *node,
vlib_frame_t *frame)
Expand All @@ -100,6 +158,8 @@ VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
vlib_buffer_t *b0;
u32 next0;
u32 sw_if_index0;
u8 *eth;
udps_rule_action_t *ra = NULL;

/* speculatively enqueue b0 to the current next frame */
bi0 = from[0];
Expand All @@ -116,9 +176,23 @@ VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
/* Determine the next node */
next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; // is this correct ??

// Do the business logic
/* Do the business logic */
counter[UDPS_RX_ERROR_UDPS_RX]++;


eth = (u8 *)vlib_buffer_get_current (b0);
if (udps_db_rule_match(sw_if_index0, true, eth,
vlib_buffer_length_in_chain(vm, b0),&ra)) {
counter[UDPS_RX_ERROR_RULE_MATCHED]++;
if (ra) {
counter[UDPS_RX_ERROR_RULE_ACTION_FOUND]++;
/* apply Rule action on b(0) */
udps_apply_rule_action(vm, b0, ra, true);
if (ra->out_port != UDPS_NO_PORT) {
counter[UDPS_RX_ERROR_VALID_OUT_PORT]++;
}
}
}

/* verify speculative enqueue, maybe switch current next frame */
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
to_next, n_left_to_next,
Expand Down Expand Up @@ -166,6 +240,10 @@ VLIB_NODE_FN (udps_tx_node) (vlib_main_t *vm,
vlib_buffer_t *b0;
u32 next0;
u32 sw_if_index0;
vnet_sw_interface_t *tx_parent_intf;
vnet_main_t *vnm = vnet_get_main ();
u8 *eth;
udps_rule_action_t *ra = NULL;

/* speculatively enqueue b0 to the current next frame */
bi0 = from[0];
Expand All @@ -178,10 +256,27 @@ VLIB_NODE_FN (udps_tx_node) (vlib_main_t *vm,
b0 = vlib_get_buffer (vm, bi0);

sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
tx_parent_intf = vnet_get_sup_sw_interface (vnm, sw_if_index0);

sw_if_index0 = tx_parent_intf->sw_if_index;

/* Determine the next node */
next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT; // is this correct ??

eth = (u8 *)vlib_buffer_get_current (b0);
if (udps_db_rule_match(sw_if_index0, false, eth,
vlib_buffer_length_in_chain(vm, b0),&ra)) {
counter[UDPS_TX_ERROR_RULE_MATCHED]++;
if (ra) {
counter[UDPS_TX_ERROR_RULE_ACTION_FOUND]++;
/* apply Rule action on b(0) */
udps_apply_rule_action(vm, b0, ra, false);
if (ra->out_port != UDPS_NO_PORT) {
counter[UDPS_TX_ERROR_VALID_OUT_PORT]++;
}
}
}

// Do the business logic
counter[UDPS_TX_ERROR_UDPS_TX]++;

Expand Down