Skip to content

Commit 7e0ac46

Browse files
authored
Merge pull request FDio#7 from bmital/udps-dev
rule action implemented in rx/tx nodes
2 parents 2e359ed + 860cef6 commit 7e0ac46

File tree

1 file changed

+101
-6
lines changed

1 file changed

+101
-6
lines changed

src/plugins/udps/udps_node.c

+101-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#include "udps_includes.h"
22

33
#define foreach_udps_rx_error \
4-
_(UDPS_RX, "UDPS_RX outgoing packets") \
5-
_(DROP, "UDPS_RX drops")
4+
_(UDPS_RX, "UDPS outgoing packets") \
5+
_(RULE_MATCHED, "Rule matched on intf") \
6+
_(RULE_ACTION_FOUND, "Rule action found") \
7+
_(VALID_OUT_PORT, "Out port rewritten") \
8+
_(DROP, "UDPS drop pkt")
69

710
typedef enum
811
{
@@ -19,8 +22,11 @@ static char *udps_rx_error_strings[] = {
1922
};
2023

2124
#define foreach_udps_tx_error \
22-
_(UDPS_TX, "UDPS_TX outgoing packets") \
23-
_(DROP, "UDPS_TX drops")
25+
_(UDPS_TX, "UDPS outgoing packets") \
26+
_(RULE_MATCHED, "Rule matched on intf") \
27+
_(RULE_ACTION_FOUND, "Rule action found") \
28+
_(VALID_OUT_PORT, "Out port rewritten") \
29+
_(DROP, "UDPS drop pkt")
2430

2531
typedef enum
2632
{
@@ -74,7 +80,59 @@ udps_node_policy_remove(u32 sw_if_index, u8 is_rx)
7480
0, 0, 0);
7581
}
7682
}
83+
void
84+
udps_apply_rule_action (vlib_main_t *vm,
85+
vlib_buffer_t * b,
86+
udps_rule_action_t *ra,
87+
bool is_rx)
88+
{
89+
u32 offset, len;
90+
u8 *write_ptr;
91+
/* rewrite the out_port and be done with this */
92+
if (ra->out_port != UDPS_NO_PORT) {
93+
vnet_buffer (b)->sw_if_index[VLIB_TX] = ra->out_port;
94+
}
95+
96+
/* loop through all the rewrite actions and apply them one by one */
97+
for (int i = 0; i < vec_len(ra->rewrite); i++) {
98+
switch(ra->rewrite[i].oper) {
99+
case UDPS_REWRITE_INSERT:
100+
offset = ra->rewrite[i].offset;
101+
len = ra->rewrite[i].len;
102+
vlib_buffer_advance(b, offset);
103+
vlib_buffer_move(vm, b, (len + offset));
104+
/* alter pkt len and rewind current_data*/
105+
b->current_length += len;
106+
b->current_data -= len;
107+
write_ptr = vlib_buffer_get_current (b);
108+
clib_memcpy_fast (write_ptr, (u8 *)ra->rewrite[i].value, len);
109+
/*rewind to start of l2 header again*/
110+
vlib_buffer_advance(b, -offset);
111+
break;
112+
case UDPS_REWRITE_REPLACE:
113+
offset = ra->rewrite[i].offset;
114+
len = ra->rewrite[i].len;
115+
vlib_buffer_advance(b, offset);
116+
write_ptr = vlib_buffer_get_current (b);
117+
clib_memcpy_fast (write_ptr, (u8 *)ra->rewrite[i].value, len);
118+
/*rewind to start of l2 header again*/
119+
vlib_buffer_advance(b, -offset);
120+
break;
121+
case UDPS_REWRITE_REMOVE:
122+
offset = ra->rewrite[i].offset;
123+
len = ra->rewrite[i].len;
124+
vlib_buffer_advance(b, len+offset);
125+
vlib_buffer_move(vm, b, offset);
126+
/*rewind to start of l2 header again*/
127+
vlib_buffer_advance(b, -offset);
128+
break;
129+
default:
130+
break;
131+
}
132+
}
77133

134+
return;
135+
}
78136
VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
79137
vlib_node_runtime_t *node,
80138
vlib_frame_t *frame)
@@ -100,6 +158,8 @@ VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
100158
vlib_buffer_t *b0;
101159
u32 next0;
102160
u32 sw_if_index0;
161+
u8 *eth;
162+
udps_rule_action_t *ra = NULL;
103163

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

119-
// Do the business logic
179+
/* Do the business logic */
120180
counter[UDPS_RX_ERROR_UDPS_RX]++;
121-
181+
182+
eth = (u8 *)vlib_buffer_get_current (b0);
183+
if (udps_db_rule_match(sw_if_index0, true, eth,
184+
vlib_buffer_length_in_chain(vm, b0),&ra)) {
185+
counter[UDPS_RX_ERROR_RULE_MATCHED]++;
186+
if (ra) {
187+
counter[UDPS_RX_ERROR_RULE_ACTION_FOUND]++;
188+
/* apply Rule action on b(0) */
189+
udps_apply_rule_action(vm, b0, ra, true);
190+
if (ra->out_port != UDPS_NO_PORT) {
191+
counter[UDPS_RX_ERROR_VALID_OUT_PORT]++;
192+
}
193+
}
194+
}
195+
122196
/* verify speculative enqueue, maybe switch current next frame */
123197
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
124198
to_next, n_left_to_next,
@@ -166,6 +240,10 @@ VLIB_NODE_FN (udps_tx_node) (vlib_main_t *vm,
166240
vlib_buffer_t *b0;
167241
u32 next0;
168242
u32 sw_if_index0;
243+
vnet_sw_interface_t *tx_parent_intf;
244+
vnet_main_t *vnm = vnet_get_main ();
245+
u8 *eth;
246+
udps_rule_action_t *ra = NULL;
169247

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

180258
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
259+
tx_parent_intf = vnet_get_sup_sw_interface (vnm, sw_if_index0);
260+
261+
sw_if_index0 = tx_parent_intf->sw_if_index;
181262

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

266+
eth = (u8 *)vlib_buffer_get_current (b0);
267+
if (udps_db_rule_match(sw_if_index0, false, eth,
268+
vlib_buffer_length_in_chain(vm, b0),&ra)) {
269+
counter[UDPS_TX_ERROR_RULE_MATCHED]++;
270+
if (ra) {
271+
counter[UDPS_TX_ERROR_RULE_ACTION_FOUND]++;
272+
/* apply Rule action on b(0) */
273+
udps_apply_rule_action(vm, b0, ra, false);
274+
if (ra->out_port != UDPS_NO_PORT) {
275+
counter[UDPS_TX_ERROR_VALID_OUT_PORT]++;
276+
}
277+
}
278+
}
279+
185280
// Do the business logic
186281
counter[UDPS_TX_ERROR_UDPS_TX]++;
187282

0 commit comments

Comments
 (0)