Skip to content

Commit

Permalink
Merge pull request FDio#7 from bmital/udps-dev
Browse files Browse the repository at this point in the history
rule action implemented in rx/tx nodes
  • Loading branch information
rajithpr-eng authored Dec 15, 2022
2 parents 2e359ed + 860cef6 commit 7e0ac46
Showing 1 changed file with 101 additions and 6 deletions.
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

0 comments on commit 7e0ac46

Please sign in to comment.