1
1
#include "udps_includes.h"
2
2
3
3
#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")
6
9
7
10
typedef enum
8
11
{
@@ -19,8 +22,11 @@ static char *udps_rx_error_strings[] = {
19
22
};
20
23
21
24
#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")
24
30
25
31
typedef enum
26
32
{
@@ -74,7 +80,59 @@ udps_node_policy_remove(u32 sw_if_index, u8 is_rx)
74
80
0 , 0 , 0 );
75
81
}
76
82
}
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
+ }
77
133
134
+ return ;
135
+ }
78
136
VLIB_NODE_FN (udps_rx_node ) (vlib_main_t * vm ,
79
137
vlib_node_runtime_t * node ,
80
138
vlib_frame_t * frame )
@@ -100,6 +158,8 @@ VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
100
158
vlib_buffer_t * b0 ;
101
159
u32 next0 ;
102
160
u32 sw_if_index0 ;
161
+ u8 * eth ;
162
+ udps_rule_action_t * ra = NULL ;
103
163
104
164
/* speculatively enqueue b0 to the current next frame */
105
165
bi0 = from [0 ];
@@ -116,9 +176,23 @@ VLIB_NODE_FN (udps_rx_node) (vlib_main_t *vm,
116
176
/* Determine the next node */
117
177
next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT ; // is this correct ??
118
178
119
- // Do the business logic
179
+ /* Do the business logic */
120
180
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
+
122
196
/* verify speculative enqueue, maybe switch current next frame */
123
197
vlib_validate_buffer_enqueue_x1 (vm , node , next_index ,
124
198
to_next , n_left_to_next ,
@@ -166,6 +240,10 @@ VLIB_NODE_FN (udps_tx_node) (vlib_main_t *vm,
166
240
vlib_buffer_t * b0 ;
167
241
u32 next0 ;
168
242
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 ;
169
247
170
248
/* speculatively enqueue b0 to the current next frame */
171
249
bi0 = from [0 ];
@@ -178,10 +256,27 @@ VLIB_NODE_FN (udps_tx_node) (vlib_main_t *vm,
178
256
b0 = vlib_get_buffer (vm , bi0 );
179
257
180
258
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 ;
181
262
182
263
/* Determine the next node */
183
264
next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT ; // is this correct ??
184
265
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
+
185
280
// Do the business logic
186
281
counter [UDPS_TX_ERROR_UDPS_TX ]++ ;
187
282
0 commit comments