Skip to content

Commit eca860c

Browse files
Hadi Rayan Al-Sandidbganne
authored andcommitted
ip_session_redirect: add dump api for session redirects
Type: improvement Change-Id: Icd6e94535d388e4c2c08c8ab383fea8cac324d66 Signed-off-by: Hadi Rayan Al-Sandid <halsandi@cisco.com>
1 parent 9e37f96 commit eca860c

File tree

6 files changed

+273
-23
lines changed

6 files changed

+273
-23
lines changed

src/plugins/ip_session_redirect/api.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
* limitations under the License. */
1313

1414
#include <vlib/vlib.h>
15+
#include <vnet/fib/fib_path_list.h>
1516
#include <vnet/fib/fib_api.h>
1617
#include <vnet/ip/ip_format_fns.h>
18+
#include <vnet/classify/vnet_classify.h>
1719
#include <vlibmemory/api.h>
1820
#include <vlibapi/api.h>
1921

@@ -105,6 +107,68 @@ vl_api_ip_session_redirect_del_t_handler (vl_api_ip_session_redirect_del_t *mp)
105107
REPLY_MACRO (VL_API_IP_SESSION_REDIRECT_DEL_REPLY);
106108
}
107109

110+
static void
111+
send_ip_session_redirect_details (vl_api_registration_t *reg, u32 table_index,
112+
u32 context)
113+
{
114+
ip_session_redirect_main_t *im = &ip_session_redirect_main;
115+
ip_session_redirect_t *ipr;
116+
ip_session_redirect_t *iprs = im->pool;
117+
118+
pool_foreach (ipr, iprs)
119+
{
120+
if (~0 == table_index || ipr->table_index == table_index)
121+
{
122+
vl_api_ip_session_redirect_details_t *rmp;
123+
vl_api_fib_path_t *fp;
124+
fib_route_path_t *rpath;
125+
fib_path_encode_ctx_t walk_ctx = {
126+
.rpaths = NULL,
127+
};
128+
u8 n_paths = fib_path_list_get_n_paths (ipr->pl);
129+
/* match_len is computed without table index at the end of the match
130+
* string */
131+
u32 match_len = vec_len (ipr->match_and_table_index) - 4;
132+
133+
rmp = vl_msg_api_alloc_zero (sizeof (*rmp) +
134+
sizeof (rmp->paths[0]) * n_paths);
135+
rmp->_vl_msg_id =
136+
ntohs (REPLY_MSG_ID_BASE + VL_API_IP_SESSION_REDIRECT_DETAILS);
137+
rmp->context = context;
138+
rmp->opaque_index = htonl (ipr->opaque_index);
139+
rmp->table_index = htonl (ipr->table_index);
140+
rmp->match_length = htonl (match_len);
141+
rmp->is_punt = ipr->is_punt;
142+
rmp->is_ip6 = ipr->is_ip6;
143+
clib_memcpy (rmp->match, ipr->match_and_table_index, match_len);
144+
rmp->n_paths = n_paths;
145+
fp = rmp->paths;
146+
rmp->retval = 0;
147+
fib_path_list_walk_w_ext (ipr->pl, NULL, fib_path_encode, &walk_ctx);
148+
vec_foreach (rpath, walk_ctx.rpaths)
149+
{
150+
fib_api_path_encode (rpath, fp);
151+
fp++;
152+
}
153+
154+
vl_api_send_msg (reg, (u8 *) rmp);
155+
}
156+
}
157+
}
158+
159+
static void
160+
vl_api_ip_session_redirect_dump_t_handler (
161+
vl_api_ip_session_redirect_dump_t *mp)
162+
{
163+
vl_api_registration_t *reg;
164+
u32 table_index = ntohl (mp->table_index);
165+
reg = vl_api_client_index_to_registration (mp->client_index);
166+
if (reg == 0)
167+
return;
168+
169+
send_ip_session_redirect_details (reg, table_index, mp->context);
170+
}
171+
108172
#include "ip_session_redirect.api.c"
109173
static clib_error_t *
110174
ip_session_redirect_plugin_api_hookup (vlib_main_t *vm)

src/plugins/ip_session_redirect/ip_session_redirect.api

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,47 @@ autoreply define ip_session_redirect_del
9999
option status="in_progress";
100100
};
101101

102+
/** \brief Dump available session redirections
103+
@param client_index - opaque cookie to identify the sender
104+
@param context - sender context, to match reply w/ request
105+
@param table_index - classifier table index
106+
*/
107+
108+
define ip_session_redirect_dump
109+
{
110+
u32 client_index;
111+
u32 context;
112+
u32 table_index;
113+
};
114+
115+
/** \brief Session redirection operational state response
116+
@param client_index - opaque cookie to identify the sender
117+
@param context - sender context, to match reply w/ request
118+
@param table_index - classifier table index
119+
@param opaque_index - classifier session opaque index
120+
@param is_punt - true = punted traffic, false = forwarded traffic
121+
@param is_ip6 - true = payload proto is ip6, false = payload proto is ip4
122+
@param match_len - classifier session match length in bytes (max is 80-bytes)
123+
@param match - classifier session match
124+
@param n_paths - number of paths
125+
@param paths - the paths of the redirect
126+
*/
127+
128+
define ip_session_redirect_details
129+
{
130+
u32 context;
131+
i32 retval;
132+
u32 table_index;
133+
u32 opaque_index;
134+
bool is_punt;
135+
bool is_ip6;
136+
u32 match_length;
137+
u8 match[80];
138+
u8 n_paths;
139+
vl_api_fib_path_t paths[n_paths];
140+
};
141+
142+
102143
/*
103144
* Local Variables:
104145
* eval: (c-set-style "gnu")

src/plugins/ip_session_redirect/ip_session_redirect.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,30 @@
1616

1717
#include <vnet/fib/fib_node.h>
1818

19+
typedef struct
20+
{
21+
u8 *match_and_table_index;
22+
dpo_id_t dpo; /* forwarding dpo */
23+
fib_node_t node; /* linkage into the FIB graph */
24+
fib_node_index_t pl;
25+
u32 sibling;
26+
u32 parent_node_index;
27+
u32 opaque_index;
28+
u32 table_index;
29+
fib_forward_chain_type_t payload_type;
30+
u8 is_punt : 1;
31+
u8 is_ip6 : 1;
32+
} ip_session_redirect_t;
33+
34+
typedef struct
35+
{
36+
ip_session_redirect_t *pool;
37+
u32 *session_by_match_and_table_index;
38+
fib_node_type_t fib_node_type;
39+
} ip_session_redirect_main_t;
40+
41+
extern ip_session_redirect_main_t ip_session_redirect_main;
42+
1943
int ip_session_redirect_add (vlib_main_t *vm, u32 table_index,
2044
u32 opaque_index, dpo_proto_t proto, int is_punt,
2145
const u8 *match, const fib_route_path_t *rpaths);

src/plugins/ip_session_redirect/redirect.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,7 @@
1818
#include <vpp/app/version.h>
1919
#include "ip_session_redirect.h"
2020

21-
typedef struct
22-
{
23-
u8 *match_and_table_index;
24-
dpo_id_t dpo; /* forwarding dpo */
25-
fib_node_t node; /* linkage into the FIB graph */
26-
fib_node_index_t pl;
27-
u32 sibling;
28-
u32 parent_node_index;
29-
u32 opaque_index;
30-
u32 table_index;
31-
fib_forward_chain_type_t payload_type;
32-
u8 is_punt : 1;
33-
u8 is_ip6 : 1;
34-
} ip_session_redirect_t;
35-
36-
typedef struct
37-
{
38-
ip_session_redirect_t *pool;
39-
u32 *session_by_match_and_table_index;
40-
fib_node_type_t fib_node_type;
41-
} ip_session_redirect_main_t;
42-
43-
static ip_session_redirect_main_t ip_session_redirect_main;
21+
ip_session_redirect_main_t ip_session_redirect_main;
4422

4523
static int
4624
ip_session_redirect_stack (ip_session_redirect_t *ipr)

src/plugins/ip_session_redirect/test_api.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <vlib/vlib.h>
1515
#include <vnet/fib/fib_api.h>
1616
#include <vnet/ip/ip_format_fns.h>
17+
#include <vnet/fib/fib_path_list.h>
1718
#include <vnet/classify/vnet_classify.h>
1819
#include <vat/vat.h>
1920
#include <vlibapi/api.h>
@@ -184,6 +185,79 @@ api_ip_session_redirect_del (vat_main_t *vam)
184185
return ret;
185186
}
186187

188+
static int
189+
api_ip_session_redirect_dump (vat_main_t *vam)
190+
{
191+
unformat_input_t *i = vam->input;
192+
vl_api_ip_session_redirect_dump_t *mp;
193+
u32 table_index = ~0;
194+
int ret;
195+
196+
/* Parse args required to build the message */
197+
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
198+
{
199+
if (unformat (i, "table %d", &table_index))
200+
;
201+
else
202+
break;
203+
}
204+
205+
/* Construct the API message */
206+
M (IP_SESSION_REDIRECT_DUMP, mp);
207+
mp->table_index = htonl (table_index);
208+
209+
S (mp)
210+
211+
/* Wait for a reply... */
212+
W (ret);
213+
return ret;
214+
}
215+
216+
static void
217+
vl_api_ip_session_redirect_details_t_handler (
218+
vl_api_ip_session_redirect_details_t *mp)
219+
{
220+
vat_main_t *vam = ip_session_redirect_test_main.vat_main;
221+
int rv;
222+
u32 table_index;
223+
u32 opaque_index;
224+
u32 match_len;
225+
u8 match[80];
226+
u8 n_paths;
227+
fib_route_path_t *paths_ = 0;
228+
u8 *out = 0;
229+
230+
table_index = ntohl (mp->table_index);
231+
opaque_index = ntohl (mp->opaque_index);
232+
match_len = ntohl (mp->match_length);
233+
const char *type = mp->is_punt ? "[punt]" : "[acl]";
234+
const char *ip = mp->is_ip6 ? "[ip6]" : "[ip4]";
235+
clib_memcpy (match, mp->match, match_len);
236+
n_paths = mp->n_paths;
237+
238+
for (int i = 0; i < n_paths; i++)
239+
{
240+
fib_route_path_t path;
241+
if ((rv = fib_api_path_decode (&mp->paths[i], &path)))
242+
goto err;
243+
vec_add1 (paths_, path);
244+
}
245+
246+
out =
247+
format (out, "table %d match %U %s %s opaque_index 0x%x\n", table_index,
248+
format_hex_bytes, match, match_len, type, ip, opaque_index);
249+
out = format (out, " via:\n");
250+
for (int i = 0; i < n_paths; i++)
251+
{
252+
fib_route_path_t *path = &paths_[i];
253+
out = format (out, " %U", format_fib_route_path, path);
254+
}
255+
256+
fformat (vam->ofp, (char *) out);
257+
err:
258+
vec_free (out);
259+
}
260+
187261
#include "ip_session_redirect.api_test.c"
188262

189263
/*

test/test_ip_session_redirect.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import unittest
44

5+
import ipaddress
56
import socket
67

78
from scapy.packet import Raw
@@ -83,6 +84,33 @@ def create_table(self, is_ip6):
8384
)
8485
return r.new_table_index
8586

87+
def verify_session_dump_entry(
88+
self,
89+
sess,
90+
table_index,
91+
is_punt,
92+
is_ip6,
93+
match_len,
94+
match,
95+
n_paths,
96+
sess_path_ip,
97+
):
98+
self.assertEqual(sess.table_index, table_index)
99+
self.assertEqual(sess.is_punt, is_punt)
100+
self.assertEqual(sess.is_ip6, is_ip6)
101+
self.assertEqual(sess.match_length, match_len)
102+
self.assertEqual(sess.match[:match_len], match)
103+
self.assertEqual(sess.n_paths, n_paths)
104+
for i, ip in enumerate(sess_path_ip):
105+
if is_ip6:
106+
self.assertEqual(
107+
sess.paths[i].nh.address.ip6, ipaddress.IPv6Address(ip)
108+
)
109+
else:
110+
self.assertEqual(
111+
sess.paths[i].nh.address.ip4, ipaddress.IPv4Address(ip)
112+
)
113+
86114
def __test_redirect(self, sport, dport, is_punt, is_ip6):
87115
if is_ip6:
88116
af = VppEnum.vl_api_address_family_t.ADDRESS_IP6
@@ -194,6 +222,47 @@ def __test_redirect(self, sport, dport, is_punt, is_ip6):
194222
t = self.vapi.classify_table_info(table_id=table_index)
195223
self.assertEqual(t.active_sessions, 2)
196224

225+
# update matching entry so that it is multi-path
226+
paths = [
227+
VppRoutePath(nh1, 0xFFFFFFFF).encode(),
228+
VppRoutePath(nh2, 0xFFFFFFFF).encode(),
229+
]
230+
self.vapi.ip_session_redirect_add_v2(
231+
table_index=table_index,
232+
match_len=len(match2),
233+
match=match2,
234+
is_punt=is_punt,
235+
n_paths=2,
236+
paths=paths,
237+
proto=proto,
238+
)
239+
240+
# verify that session dump has 2 entries
241+
sessions_dump = self.vapi.ip_session_redirect_dump(table_index=table_index)
242+
self.assertEqual(len(sessions_dump), 2)
243+
244+
# verify session dump entries
245+
self.verify_session_dump_entry(
246+
sessions_dump[0],
247+
table_index,
248+
is_punt,
249+
is_ip6,
250+
len(match1),
251+
match1,
252+
1,
253+
[nh1],
254+
)
255+
self.verify_session_dump_entry(
256+
sessions_dump[1],
257+
table_index,
258+
is_punt,
259+
is_ip6,
260+
len(match2),
261+
match2,
262+
2,
263+
[nh1, nh2],
264+
)
265+
197266
# cleanup
198267
self.vapi.ip_session_redirect_del(table_index, len(match2), match2)
199268
self.vapi.ip_session_redirect_del(table_index, len(match1), match1)

0 commit comments

Comments
 (0)