Line data Source code
1 : /*
2 : * vr_util.c -- common functions used by utilities in a library form
3 : *
4 : * Copyright (c) 2015, Juniper Networks, Inc.
5 : * Copyright Contributors to the OpenSDN project
6 : * All rights reserved
7 : */
8 : #include <ctype.h>
9 : #include <stdio.h>
10 : #include <stdlib.h>
11 : #include <unistd.h>
12 : #include <errno.h>
13 : #include <stdbool.h>
14 : #include <stdint.h>
15 : #include <ctype.h>
16 : #include <inttypes.h>
17 : #include <fcntl.h>
18 : #include <time.h>
19 :
20 : #include <sys/types.h>
21 : #include <sys/stat.h>
22 : #include <sys/socket.h>
23 : #include <sys/mman.h>
24 : #if defined(__linux__)
25 : #include <linux/netlink.h>
26 : #include <linux/rtnetlink.h>
27 : #include <linux/if_ether.h>
28 : #include <linux/dcbnl.h>
29 : #endif
30 :
31 : #include <net/if.h>
32 : #include <netinet/in.h>
33 :
34 : #include "vr_types.h"
35 : #include "nl_util.h"
36 : #include "vr_message.h"
37 : #include "vr_genetlink.h"
38 : #include "vr_interface.h"
39 : #include "vr_packet.h"
40 : #include "vr_nexthop.h"
41 : #include "vr_route.h"
42 : #include "vr_bridge.h"
43 : #include "vr_mem.h"
44 : #include "ini_parser.h"
45 :
46 : /* Suppress NetLink error messages */
47 : bool vr_ignore_nl_errors = false;
48 : int genetlink_group_id = 0;
49 : static bool vr_header_include = 0;
50 :
51 : char *
52 0 : vr_extract_token(char *string, char token_separator)
53 : {
54 : int ret;
55 : unsigned int length;
56 :
57 : char *sep;
58 :
59 : /* skip over leading white spaces */
60 0 : while ((*string == ' ') && string++);
61 :
62 : /* if there is nothing left after the spaces, return */
63 0 : if (!(length = strlen(string))) {
64 0 : return NULL;
65 : }
66 :
67 : /* If first character is a separator its a malforned request */
68 0 : if (*string == token_separator) {
69 0 : printf("Malformed request: separator used incorrectly \n");
70 0 : return NULL;
71 : }
72 :
73 : /* start searching for the token */
74 0 : sep = strchr(string, token_separator);
75 0 : if (sep) {
76 0 : length = sep - string;
77 : /* terminate the token with NULL */
78 0 : string[sep - string] = '\0';
79 0 : length = strlen(string);
80 : }
81 :
82 : /* remove trailing spaces */
83 0 : length -= 1;
84 0 : while ((*(string + length) == ' ') && --length);
85 0 : *(string + length + 1) = '\0';
86 :
87 : /*
88 : * reset the separator to space, since a space at the beginning
89 : * will be snipped
90 : */
91 0 : if (sep && (((sep - string)) != strlen(string)))
92 0 : string[sep - string] = ' ';
93 :
94 0 : return string;
95 : }
96 :
97 : bool
98 0 : vr_valid_ipv6_address(const char *addr)
99 : {
100 0 : unsigned int i = 0, j = 0, sep_count = 0;
101 :
102 : /* a '*' is treated as a valid address */
103 0 : if (!strncmp(addr, "*", 1) && (strlen(addr) == 1))
104 0 : return true;
105 :
106 0 : while (*(addr + i)) {
107 0 : if (isalnum(*(addr + i))) {
108 0 : j++;
109 0 : } else if (*(addr + i) == ':') {
110 0 : j = 0;
111 0 : sep_count++;
112 : } else {
113 0 : printf("match: \"%s\" is not a valid ipv6 address format\n", addr);
114 0 : return false;
115 : }
116 :
117 0 : if ((j > 4) || (sep_count > 7)) {
118 0 : printf("match: \"%s\" is not a valid ipv6 address format\n", addr);
119 0 : return false;
120 : }
121 :
122 0 : i++;
123 : }
124 :
125 0 : return true;
126 : }
127 :
128 : bool
129 0 : vr_valid_ipv4_address(const char *addr)
130 : {
131 0 : unsigned int i = 0, j = 0, sep_count = 0;
132 :
133 : /* a '*' is treated as a valid address */
134 0 : if (!strncmp(addr, "*", 1) && (strlen(addr) == 1))
135 0 : return true;
136 :
137 : /* every character should be either a digit or a '.' */
138 0 : while (*(addr + i)) {
139 0 : if (isdigit(*(addr + i))) {
140 0 : j++;
141 0 : } else if (i && (*(addr + i) == '.')) {
142 0 : j = 0;
143 0 : ++sep_count;
144 : } else {
145 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
146 0 : return false;
147 : }
148 :
149 0 : if ((j > 3) || (sep_count > 3)) {
150 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
151 0 : return false;
152 : }
153 :
154 0 : i++;
155 : }
156 :
157 0 : if (sep_count != 3) {
158 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
159 0 : return false;
160 : }
161 :
162 0 : return true;
163 : }
164 :
165 : bool
166 10 : vr_valid_mac_address(const char *mac)
167 : {
168 10 : uint8_t null_mac[VR_ETHER_ALEN] = { 0 };
169 :
170 10 : if (!mac || !memcmp(mac, null_mac, VR_ETHER_ALEN))
171 10 : return false;
172 :
173 0 : return true;
174 : }
175 :
176 : char *
177 5 : vr_proto_string(unsigned short proto)
178 : {
179 5 : switch (proto) {
180 2 : case VR_IP_PROTO_TCP:
181 2 : return "TCP";
182 : break;
183 :
184 0 : case VR_IP_PROTO_UDP:
185 0 : return "UDP";
186 : break;
187 :
188 3 : case VR_IP_PROTO_ICMP:
189 3 : return "ICMP";
190 : break;
191 :
192 0 : case VR_IP_PROTO_SCTP:
193 0 : return "SCTP";
194 : break;
195 :
196 0 : case VR_IP_PROTO_ICMP6:
197 0 : return "ICMPv6";
198 : break;
199 :
200 :
201 0 : default:
202 0 : return "UNKNOWN";
203 : }
204 :
205 : return "UNKNOWN";
206 : }
207 :
208 : /* send and receive */
209 : int
210 2862 : vr_recvmsg_generic(struct nl_client *cl, bool dump, bool msg_wait)
211 : {
212 2862 : int ret = 0;
213 2862 : bool pending = true;
214 : struct nl_response *resp;
215 : struct nlmsghdr *nlh;
216 :
217 2863 : while (pending) {
218 2863 : if (msg_wait) {
219 0 : ret = nl_recvmsg_waitall(cl);
220 : } else {
221 2863 : ret = nl_recvmsg(cl);
222 : }
223 2863 : if (ret > 0) {
224 2863 : if (dump) {
225 2 : pending = true;
226 : } else {
227 2861 : pending = false;
228 : }
229 :
230 2863 : resp = nl_parse_reply(cl);
231 2863 : if (resp->nl_op == SANDESH_REQUEST) {
232 2863 : sandesh_decode(resp->nl_data, resp->nl_len,
233 : vr_find_sandesh_info, &ret);
234 0 : } else if (resp->nl_type == NL_MSG_TYPE_DONE) {
235 0 : pending = false;
236 : }
237 : } else {
238 0 : return ret;
239 : }
240 :
241 2863 : nlh = (struct nlmsghdr *)cl->cl_buf;
242 2863 : if (!nlh || !nlh->nlmsg_flags)
243 : break;
244 : }
245 :
246 2862 : return ret;
247 : }
248 :
249 : int
250 2862 : vr_recvmsg(struct nl_client *cl, bool dump)
251 : {
252 2862 : return vr_recvmsg_generic(cl, dump, false);
253 : }
254 :
255 : int
256 0 : vr_recvmsg_waitall(struct nl_client *cl, bool dump)
257 : {
258 0 : return vr_recvmsg_generic(cl, dump, true);
259 : }
260 :
261 : int
262 2862 : vr_sendmsg(struct nl_client *cl, void *request,
263 : char *request_string)
264 : {
265 : int ret, error, attr_len;
266 :
267 : /* nlmsg header */
268 2862 : ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST);
269 2862 : if (ret)
270 0 : return ret;
271 :
272 : /* Generic nlmsg header */
273 2862 : ret = nl_build_genlh(cl, SANDESH_REQUEST, 0);
274 2862 : if (ret)
275 0 : return ret;
276 :
277 2862 : attr_len = nl_get_attr_hdr_size();
278 5724 : ret = sandesh_encode(request, request_string, vr_find_sandesh_info,
279 2862 : (nl_get_buf_ptr(cl) + attr_len),
280 2862 : (nl_get_buf_len(cl) - attr_len), &error);
281 2862 : if (ret <= 0)
282 0 : return ret;
283 :
284 : /* Add sandesh attribute */
285 2862 : nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL);
286 2862 : nl_update_nlh(cl);
287 :
288 2862 : return nl_sendmsg(cl);
289 : }
290 :
291 : struct nl_client *
292 2951 : vr_get_nl_client(int proto)
293 : {
294 : int ret;
295 2951 : int sock_proto = proto;
296 : struct nl_client *cl;
297 :
298 2951 : cl = nl_register_client();
299 2951 : if (!cl)
300 0 : return NULL;
301 :
302 2951 : parse_ini_file();
303 :
304 2951 : if (proto == VR_NETLINK_PROTO_DEFAULT)
305 2951 : sock_proto = get_protocol();
306 :
307 2951 : ret = nl_socket(cl, get_domain(), get_type(), sock_proto);
308 2951 : if (ret <= 0)
309 0 : goto fail;
310 :
311 2951 : ret = nl_connect(cl, get_ip(), get_port(), genetlink_group_id);
312 2951 : if (ret < 0)
313 0 : goto fail;
314 :
315 5902 : if ((proto == VR_NETLINK_PROTO_DEFAULT) &&
316 2951 : (get_platform() != VTEST_PLATFORM) &&
317 0 : (vrouter_obtain_family_id(cl) <= 0))
318 0 : goto fail;
319 :
320 2951 : return cl;
321 :
322 0 : fail:
323 0 : if (cl)
324 0 : nl_free_client(cl);
325 :
326 0 : return NULL;
327 : }
328 :
329 : int
330 0 : vr_send_get_bridge_table_data(struct nl_client *cl)
331 : {
332 : int ret;
333 : vr_bridge_table_data req;
334 :
335 0 : memset(&req, 0, sizeof(req));
336 0 : req.btable_op = SANDESH_OP_GET;
337 0 : req.btable_rid = 0;
338 :
339 0 : return vr_sendmsg(cl, &req, "vr_bridge_table_data");
340 : }
341 :
342 : int
343 0 : vr_send_set_dcb_state(struct nl_client *cl, uint8_t *ifname, uint8_t state)
344 : {
345 : int ret;
346 :
347 0 : ret = nl_build_set_dcb_state_msg(cl, ifname, state);
348 0 : if (ret < 0)
349 0 : return ret;
350 :
351 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_SSTATE, NULL);
352 0 : if (ret <= 0)
353 0 : return ret;
354 :
355 0 : if (ret != state) {
356 0 : printf("vRouter: Set DCB State failed (Req/Resp: %u/%d)\n",
357 : state, ret);
358 0 : return -1;
359 : }
360 :
361 0 : return 0;
362 : }
363 :
364 : int
365 0 : vr_send_get_dcb_state(struct nl_client *cl, uint8_t *ifname)
366 : {
367 : int ret;
368 :
369 0 : ret = nl_build_get_dcb_state_msg(cl, ifname);
370 0 : if (ret < 0)
371 0 : return ret;
372 :
373 0 : return nl_dcb_sendmsg(cl, DCB_CMD_GSTATE, NULL);
374 : }
375 :
376 : int
377 0 : vr_send_set_dcbx(struct nl_client *cl, uint8_t *ifname, uint8_t dcbx)
378 : {
379 : int ret;
380 :
381 0 : ret = nl_build_set_dcbx(cl, ifname, dcbx);
382 0 : if (ret < 0)
383 0 : return ret;
384 :
385 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_SDCBX, NULL);
386 0 : if (ret < 0)
387 0 : return ret;
388 :
389 0 : if (ret) {
390 0 : printf("vRouter: Set DCBX failed (Req/Resp: %u/%d)\n",
391 : dcbx, ret);
392 0 : return -1;
393 : }
394 :
395 0 : return 0;
396 : }
397 :
398 : int
399 0 : vr_send_get_dcbx(struct nl_client *cl, uint8_t *ifname)
400 : {
401 : int ret;
402 :
403 0 : ret = nl_build_get_dcbx(cl, ifname);
404 0 : if (ret < 0)
405 0 : return ret;
406 :
407 0 : return nl_dcb_sendmsg(cl, DCB_CMD_GDCBX, NULL);
408 : }
409 :
410 : int
411 0 : vr_send_get_priority_config(struct nl_client *cl, uint8_t *ifname,
412 : struct priority *p)
413 : {
414 : int ret;
415 :
416 0 : ret = nl_build_get_priority_config_msg(cl, ifname);
417 0 : if (ret < 0)
418 0 : return ret;
419 :
420 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_PGTX_GCFG, p);
421 0 : if (ret < 0)
422 0 : return ret;
423 :
424 0 : return 0;
425 : }
426 :
427 : int
428 0 : vr_send_set_priority_config(struct nl_client *cl, uint8_t *ifname,
429 : struct priority *p)
430 : {
431 : int ret;
432 :
433 0 : ret = nl_build_set_priority_config_msg(cl, ifname, p);
434 0 : if (ret < 0)
435 0 : return ret;
436 :
437 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_PGTX_SCFG, NULL);
438 0 : if (ret < 0)
439 0 : return ret;
440 :
441 0 : return 0;
442 : }
443 :
444 : int
445 0 : vr_send_set_dcb_all(struct nl_client *cl, uint8_t *ifname)
446 : {
447 : int ret;
448 :
449 0 : ret = nl_build_set_dcb_all(cl, ifname);
450 0 : if (ret < 0)
451 0 : return ret;
452 :
453 0 : return nl_dcb_sendmsg(cl, DCB_CMD_SET_ALL, NULL);
454 : }
455 :
456 : int
457 0 : vr_send_get_ieee_ets(struct nl_client *cl, uint8_t *ifname,
458 : struct priority *p)
459 : {
460 : int ret;
461 :
462 0 : ret = nl_build_get_ieee_ets(cl, ifname, p);
463 0 : if (ret < 0)
464 0 : return ret;
465 :
466 0 : return nl_dcb_sendmsg(cl, DCB_CMD_IEEE_GET, p);
467 : }
468 :
469 : int
470 0 : vr_send_set_ieee_ets(struct nl_client *cl, uint8_t *ifname,
471 : struct priority *p)
472 : {
473 : int ret;
474 :
475 0 : ret = nl_build_set_ieee_ets(cl, ifname, p);
476 0 : if (ret < 0)
477 0 : return ret;
478 :
479 0 : return nl_dcb_sendmsg(cl, DCB_CMD_IEEE_SET, NULL);
480 : }
481 :
482 : void
483 1 : vr_print_drop_stats(vr_drop_stats_req *stats, int core)
484 : {
485 1 : int platform = get_platform();
486 :
487 1 : if (core != (unsigned)-1)
488 0 : printf("Statistics for core %u\n\n", core);
489 :
490 1 : if (stats->vds_pcpu_stats_failure_status)
491 0 : printf("Failed to maintain PerCPU stats for this interface\n\n");
492 :
493 1 : PRINT_DROP_STAT("Invalid IF", stats->vds_invalid_if);
494 1 : PRINT_DROP_STAT("Invalid ARP", stats->vds_invalid_arp);
495 1 : PRINT_DROP_STAT("Trap No IF", stats->vds_trap_no_if);
496 1 : PRINT_DROP_STAT("IF TX Discard", stats->vds_interface_tx_discard);
497 1 : PRINT_DROP_STAT("IF Drop", stats->vds_interface_drop);
498 1 : PRINT_DROP_STAT("IF RX Discard", stats->vds_interface_rx_discard);
499 1 : PRINT_DROP_STAT("Flow Unusable", stats->vds_flow_unusable);
500 1 : PRINT_DROP_STAT("Flow No Memory",stats->vds_flow_no_memory);
501 1 : PRINT_DROP_STAT("Flow Table Full", stats->vds_flow_table_full);
502 1 : PRINT_DROP_STAT("Flow NAT no rflow", stats->vds_flow_nat_no_rflow);
503 1 : PRINT_DROP_STAT("Flow Action Drop", stats->vds_flow_action_drop);
504 1 : PRINT_DROP_STAT("Flow Action Invalid", stats->vds_flow_action_invalid);
505 1 : PRINT_DROP_STAT("Flow Invalid Protocol", stats->vds_flow_invalid_protocol);
506 1 : PRINT_DROP_STAT("Flow Queue Limit Exceeded", stats->vds_flow_queue_limit_exceeded);
507 1 : PRINT_DROP_STAT("New Flow Drops", stats->vds_drop_new_flow);
508 1 : PRINT_DROP_STAT("Flow Unusable (Eviction)", stats->vds_flow_evict);
509 1 : PRINT_DROP_STAT("Original Packet Trapped", stats->vds_trap_original);
510 1 : PRINT_DROP_STAT("Discards", stats->vds_discard);
511 1 : PRINT_DROP_STAT("TTL Exceeded", stats->vds_ttl_exceeded);
512 1 : PRINT_DROP_STAT("Mcast Clone Fail", stats->vds_mcast_clone_fail);
513 1 : PRINT_DROP_STAT("Invalid NH", stats->vds_invalid_nh);
514 1 : PRINT_DROP_STAT("Invalid Label", stats->vds_invalid_label);
515 1 : PRINT_DROP_STAT("Invalid Protocol", stats->vds_invalid_protocol);
516 1 : PRINT_DROP_STAT("Etree Leaf to Leaf", stats->vds_leaf_to_leaf);
517 1 : PRINT_DROP_STAT("Bmac/ISID Mismatch", stats->vds_bmac_isid_mismatch);
518 1 : PRINT_DROP_STAT("Rewrite Fail", stats->vds_rewrite_fail);
519 1 : PRINT_DROP_STAT("Invalid Mcast Source", stats->vds_invalid_mcast_source);
520 1 : PRINT_DROP_STAT("Packet Loop", stats->vds_pkt_loop);
521 1 : PRINT_DROP_STAT("Push Fails", stats->vds_push);
522 1 : PRINT_DROP_STAT("Pull Fails", stats->vds_pull);
523 1 : PRINT_DROP_STAT("Duplicate", stats->vds_duplicated);
524 1 : PRINT_DROP_STAT("Head Alloc Fails", stats->vds_head_alloc_fail);
525 1 : PRINT_DROP_STAT("PCOW fails", stats->vds_pcow_fail);
526 1 : PRINT_DROP_STAT("Invalid Packets", stats->vds_invalid_packet);
527 1 : PRINT_DROP_STAT("Misc", stats->vds_misc);
528 1 : PRINT_DROP_STAT("Nowhere to go", stats->vds_nowhere_to_go);
529 1 : PRINT_DROP_STAT("Checksum errors", stats->vds_cksum_err);
530 1 : PRINT_DROP_STAT("No Fmd", stats->vds_no_fmd);
531 1 : PRINT_DROP_STAT("Invalid VNID", stats->vds_invalid_vnid);
532 1 : PRINT_DROP_STAT("Fragment errors", stats->vds_frag_err);
533 1 : PRINT_DROP_STAT("Invalid Source", stats->vds_invalid_source);
534 1 : PRINT_DROP_STAT("Jumbo Mcast Pkt with DF Bit", stats->vds_mcast_df_bit);
535 1 : PRINT_DROP_STAT("No L2 Route", stats->vds_l2_no_route);
536 1 : PRINT_DROP_STAT("Memory Failures", stats->vds_no_memory);
537 1 : PRINT_DROP_STAT("Fragment Queueing Failures", stats->vds_fragment_queue_fail);
538 1 : PRINT_DROP_STAT("No Encrypt Path Failures", stats->vds_no_crypt_path);
539 1 : PRINT_DROP_STAT("Invalid HBS received packet", stats->vds_invalid_hbs_pkt);
540 1 : PRINT_DROP_STAT("No Fragment Entries", stats->vds_no_frag_entry);
541 1 : PRINT_DROP_STAT("ICMP errors", stats->vds_icmp_error);
542 1 : PRINT_DROP_STAT("Clone Failures", stats->vds_clone_fail);
543 1 : PRINT_DROP_STAT("Invalid underlay ECMP", stats->vds_invalid_underlay_ecmp);
544 :
545 1 : if (platform == DPDK_PLATFORM)
546 : {
547 0 : PRINT_DROP_STAT("VLAN fwd intf failed TX", stats->vds_vlan_fwd_tx);
548 0 : PRINT_DROP_STAT("VLAN fwd intf failed enq", stats->vds_vlan_fwd_enq);
549 : }
550 1 : return;
551 : }
552 :
553 : void
554 0 : vr_print_drop_dbg_stats(vr_drop_stats_req *stats, int core)
555 : {
556 0 : printf("Cloned Original %" PRIu64 "\n",
557 : stats->vds_cloned_original);
558 0 : return;
559 : }
560 :
561 : const char *
562 0 : vr_pkt_vp_type_rsn(unsigned char vp_type)
563 : {
564 0 : switch(vp_type) {
565 0 : case VP_TYPE_ARP: return "ARP";
566 0 : case VP_TYPE_IP : return "IP";
567 0 : case VP_TYPE_IP6: return "IP6";
568 0 : case VP_TYPE_IPOIP: return "IPOIP";
569 0 : case VP_TYPE_IP6OIP: return "IP6OIP";
570 0 : case VP_TYPE_AGENT: return "AGENT";
571 0 : case VP_TYPE_PBB: return "PBB";
572 0 : default: return "UNKNOWN";
573 : }
574 : }
575 :
576 : const char *
577 0 : vr_pkt_droplog_rsn(unsigned short drop_reason)
578 : {
579 0 : switch(drop_reason) {
580 0 : case VP_DROP_DISCARD:
581 0 : return "Discards";
582 0 : case VP_DROP_PULL:
583 0 : return "Pull Fails";
584 0 : case VP_DROP_INVALID_IF:
585 0 : return "Invalid IF";
586 0 : case VP_DROP_INVALID_ARP:
587 0 : return "Invalid ARP";
588 0 : case VP_DROP_TRAP_NO_IF:
589 0 : return "Trap No IF";
590 0 : case VP_DROP_NOWHERE_TO_GO:
591 0 : return "Nowhere to go";
592 0 : case VP_DROP_FLOW_QUEUE_LIMIT_EXCEEDED:
593 0 : return "Flow Queue Limit Exceeded";
594 0 : case VP_DROP_FLOW_NO_MEMORY:
595 0 : return "Flow No Memory";
596 0 : case VP_DROP_FLOW_INVALID_PROTOCOL:
597 0 : return "Flow Invalid Protocol";
598 0 : case VP_DROP_FLOW_NAT_NO_RFLOW:
599 0 : return "Flow NAT no rflow";
600 0 : case VP_DROP_FLOW_ACTION_DROP:
601 0 : return "Flow Action Drop";
602 0 : case VP_DROP_FLOW_ACTION_INVALID:
603 0 : return "Flow Action Invalid";
604 0 : case VP_DROP_FLOW_UNUSABLE:
605 0 : return "Flow Unusable";
606 0 : case VP_DROP_FLOW_TABLE_FULL:
607 0 : return "Flow Table Full";
608 0 : case VP_DROP_INTERFACE_TX_DISCARD:
609 0 : return "IF TX Discard";
610 0 : case VP_DROP_INTERFACE_DROP:
611 0 : return "IF Drop";
612 0 : case VP_DROP_DUPLICATED:
613 0 : return "Duplicate";
614 0 : case VP_DROP_PUSH:
615 0 : return "Push Fails";
616 0 : case VP_DROP_TTL_EXCEEDED:
617 0 : return "TTL Exceeded";
618 0 : case VP_DROP_INVALID_NH:
619 0 : return "Invalid NH";
620 0 : case VP_DROP_INVALID_LABEL:
621 0 : return "Invalid Label";
622 0 : case VP_DROP_INVALID_PROTOCOL:
623 0 : return "Invalid Protocol";
624 0 : case VP_DROP_INTERFACE_RX_DISCARD:
625 0 : return "IF RX Discard";
626 0 : case VP_DROP_INVALID_MCAST_SOURCE:
627 0 : return "Invalid Mcast Source";
628 0 : case VP_DROP_HEAD_ALLOC_FAIL:
629 0 : return "Head Alloc Fails";
630 0 : case VP_DROP_PCOW_FAIL:
631 0 : return "PCOW fails";
632 0 : case VP_DROP_MCAST_DF_BIT:
633 0 : return "Jumbo Mcast Pkt with DF Bit";
634 0 : case VP_DROP_MCAST_CLONE_FAIL:
635 0 : return "Mcast Clone Fail";
636 0 : case VP_DROP_NO_MEMORY:
637 0 : return "Memory Failures";
638 0 : case VP_DROP_REWRITE_FAIL:
639 0 : return "Rewrite Fail";
640 0 : case VP_DROP_MISC:
641 0 : return "Misc";
642 0 : case VP_DROP_INVALID_PACKET:
643 0 : return "Invalid Packets";
644 0 : case VP_DROP_CKSUM_ERR:
645 0 : return "Checksum errors";
646 0 : case VP_DROP_NO_FMD:
647 0 : return "No Fmd";
648 0 : case VP_DROP_CLONED_ORIGINAL:
649 0 : return "Cloned Original";
650 0 : case VP_DROP_INVALID_VNID:
651 0 : return "Invalid VNID";
652 0 : case VP_DROP_FRAGMENTS:
653 0 : return "Fragment errors";
654 0 : case VP_DROP_INVALID_SOURCE:
655 0 : return "Invalid Source";
656 0 : case VP_DROP_L2_NO_ROUTE:
657 0 : return "No L2 Route";
658 0 : case VP_DROP_FRAGMENT_QUEUE_FAIL:
659 0 : return "Fragment Queueing Failures";
660 0 : case VP_DROP_VLAN_FWD_TX:
661 0 : return "VLAN fwd intf failed TX";
662 0 : case VP_DROP_VLAN_FWD_ENQ:
663 0 : return "VLAN fwd intf failed enq";
664 0 : case VP_DROP_NEW_FLOWS:
665 0 : return "New Flow Drops";
666 0 : case VP_DROP_FLOW_EVICT:
667 0 : return "Flow Unusable (Eviction)";
668 0 : case VP_DROP_TRAP_ORIGINAL:
669 0 : return "Original Packet Trapped";
670 0 : case VP_DROP_LEAF_TO_LEAF:
671 0 : return "Etree Leaf to Leaf";
672 0 : case VP_DROP_BMAC_ISID_MISMATCH:
673 0 : return "Bmac/ISID Mismatch";
674 0 : case VP_DROP_PKT_LOOP:
675 0 : return "Packet Loop";
676 0 : case VP_DROP_NO_CRYPT_PATH:
677 0 : return "No Encrypt Path Failures";
678 0 : case VP_DROP_INVALID_HBS_PKT:
679 0 : return "Invalid HBS received packet";
680 0 : case VP_DROP_NO_FRAG_ENTRY:
681 0 : return "No Fragment Entries";
682 0 : case VP_DROP_ICMP_ERROR:
683 0 : return "ICMP errors";
684 0 : case VP_DROP_CLONE_FAIL:
685 0 : return "Clone Failures";
686 0 : case VP_DROP_INVALID_UNDERLAY_ECMP:
687 0 : return "Invalid underlay ECMP";
688 0 : default:
689 0 : return "Unknow";
690 : }
691 :
692 : }
693 0 : void vr_print_pkt_drop_log_data(vr_pkt_drop_log_req *pkt_log, int i,
694 : uint8_t show_pkt_drop_type)
695 : {
696 0 : int j = 0;
697 0 : vr_pkt_drop_log_t *pkt_log_utils =
698 : (vr_pkt_drop_log_t*)pkt_log->vdl_pkt_droplog_arr;
699 : struct tm *ptr_time;
700 0 : char ipv6_addr[INET6_ADDRSTRLEN] = "";
701 :
702 : /* String mapping for packet drop log */
703 0 : char vr_pkt_droplog_str[][50] = {
704 : FILE_MAP(string)
705 : };
706 :
707 0 : if (!pkt_log_utils[i].vp_type)
708 0 : return;
709 :
710 0 : if ((show_pkt_drop_type != VP_DROP_MAX) &&
711 0 : (show_pkt_drop_type != pkt_log_utils[i].drop_reason))
712 0 : return;
713 :
714 0 : if((pkt_log->vdl_log_idx+i < VR_PKT_DROP_LOG_MAX) &&
715 0 : (!vr_header_include))
716 : {
717 0 : vr_print_pkt_drop_log_header(pkt_log);
718 0 : vr_header_include = 1;
719 : }
720 :
721 0 : ptr_time = localtime(&(pkt_log_utils[i].timestamp));
722 :
723 0 : printf("sl no: %d ", pkt_log->vdl_log_idx+i);
724 0 : printf("Epoch Time: %ld ", pkt_log_utils[i].timestamp);
725 0 : printf("Local Time: %s ", asctime(ptr_time));
726 0 : printf("Packet Type: %s ", vr_pkt_vp_type_rsn(pkt_log_utils[i].vp_type));
727 0 : if(pkt_log_utils[i].drop_reason)
728 0 : printf("Drop reason: %s ", vr_pkt_droplog_rsn(pkt_log_utils[i].drop_reason));
729 0 : PRINT_PKT_LOG("Vif idx:", pkt_log_utils[i].vif_idx);
730 0 : PRINT_PKT_LOG("Nexthop id:", pkt_log_utils[i].nh_id);
731 0 : if(pkt_log_utils[i].vp_type == VP_TYPE_IP)
732 : {
733 0 : printf("Src IP: %s ", inet_ntoa(pkt_log_utils[i].src.ipv4));
734 0 : printf("Dst IP: %s ", inet_ntoa(pkt_log_utils[i].dst.ipv4));
735 : }
736 0 : else if (pkt_log_utils[i].vp_type == VP_TYPE_IP6)
737 : {
738 0 : inet_ntop(AF_INET6, &pkt_log_utils[i].src.ipv6, ipv6_addr, INET6_ADDRSTRLEN);
739 0 : printf("Src IPv6: %s ", ipv6_addr);
740 0 : inet_ntop(AF_INET6, &pkt_log_utils[i].dst.ipv6, ipv6_addr, INET6_ADDRSTRLEN);
741 0 : printf("Dst IPv6: %s ", ipv6_addr);
742 : }
743 :
744 0 : PRINT_PKT_LOG("Source port:", pkt_log_utils[i].sport);
745 0 : PRINT_PKT_LOG("Dest port:", pkt_log_utils[i].dport);
746 0 : if(pkt_log_utils[i].drop_loc.file)
747 0 : printf("file: %s ", vr_pkt_droplog_str[pkt_log_utils[i].drop_loc.file]);
748 0 : printf("line no: %d ", pkt_log_utils[i].drop_loc.line);
749 :
750 0 : if(pkt_log_utils[i].pkt_len)
751 : {
752 0 : printf("Packet Length: %d ", pkt_log_utils[i].pkt_len);
753 0 : printf("Packet Data: ");
754 :
755 0 : if(pkt_log_utils[i].pkt_len > 100)
756 0 : for(j = 0; j < 100; j++)
757 0 : printf("%02X ", pkt_log_utils[i].pkt_header[j]);
758 : else
759 0 : for(j=0;j<pkt_log_utils[i].pkt_len;j++)
760 0 : printf("%02X ", pkt_log_utils[i].pkt_header[j]);
761 : }
762 0 : printf("\n\n");
763 : }
764 0 : void vr_print_pkt_drop_log_header(vr_pkt_drop_log_req *pkt_log)
765 : {
766 0 : printf("**********PKT DROP LOG**********\n");
767 0 : printf("Total No. of CPU's %d\n", pkt_log->vdl_max_num_cores);
768 : /* When requested for core 0, it will try to log for all cores
769 : * so here manually printing as core 1 */
770 0 : if(pkt_log->vdl_core == 0)
771 0 : printf("Pkt Drop Log for Core 1\n\n");
772 : else
773 0 : printf("Pkt Drop Log for Core %d\n\n", pkt_log->vdl_core);
774 0 : }
775 : void
776 0 : vr_print_pkt_drop_log(vr_pkt_drop_log_req *pkt_log, uint8_t show_pkt_drop_type)
777 : {
778 0 : int i = 0, log_buffer_iter = 0;
779 : static bool vr_header_include = 0;
780 :
781 : /* When configured pkt buffer size is than MAX_ALLOWED_BUFFER_SIZE */
782 0 : if(pkt_log->vdl_pkt_droplog_max_bufsz - pkt_log->vdl_log_idx <
783 : VR_PKT_DROPLOG_MAX_ALLOW_BUFSZ)
784 : {
785 0 : log_buffer_iter = pkt_log->vdl_pkt_droplog_max_bufsz - pkt_log->vdl_log_idx;
786 : }
787 : else
788 0 : log_buffer_iter = VR_PKT_DROPLOG_MAX_ALLOW_BUFSZ;
789 :
790 0 : for(i = 0; i < log_buffer_iter; i++)
791 0 : vr_print_pkt_drop_log_data(pkt_log, i, show_pkt_drop_type);
792 :
793 : /* On Every VR_PKT_DROP_LOG_MAX count time need to check this
794 : * flag to print PKT DROP header
795 : */
796 0 : if((pkt_log->vdl_log_idx + log_buffer_iter == VR_PKT_DROP_LOG_MAX) &&
797 : (vr_header_include))
798 : {
799 0 : vr_header_include = 0;
800 : }
801 0 : return;
802 : }
803 :
804 : int
805 17 : vr_response_common_process(vr_response *resp, bool *dump_pending)
806 : {
807 17 : int ret = 0;
808 :
809 17 : if (dump_pending)
810 17 : *dump_pending = false;
811 :
812 17 : if (resp->resp_code < 0) {
813 4 : if (!vr_ignore_nl_errors) {
814 4 : printf("vRouter(Response): %s (%d)\n", strerror(-resp->resp_code),
815 4 : -resp->resp_code);
816 : }
817 4 : ret = resp->resp_code;
818 : } else {
819 13 : if ((resp->resp_code & VR_MESSAGE_DUMP_INCOMPLETE) &&
820 : dump_pending)
821 0 : *dump_pending = true;
822 : }
823 :
824 17 : return ret;
825 : }
826 :
827 : /* dropstats start */
828 : uint64_t
829 5 : vr_sum_drop_stats(vr_drop_stats_req *req)
830 : {
831 5 : uint64_t sum = 0;
832 :
833 5 : sum += req->vds_discard;
834 5 : sum += req->vds_pull;
835 5 : sum += req->vds_invalid_if;
836 5 : sum += req->vds_invalid_arp;
837 5 : sum += req->vds_trap_no_if;
838 5 : sum += req->vds_nowhere_to_go;
839 5 : sum += req->vds_flow_queue_limit_exceeded;
840 5 : sum += req->vds_flow_no_memory;
841 5 : sum += req->vds_flow_invalid_protocol;
842 5 : sum += req->vds_flow_nat_no_rflow;
843 5 : sum += req->vds_flow_action_drop;
844 5 : sum += req->vds_flow_action_invalid;
845 5 : sum += req->vds_flow_unusable;
846 5 : sum += req->vds_flow_table_full;
847 5 : sum += req->vds_interface_tx_discard;
848 5 : sum += req->vds_interface_drop;
849 5 : sum += req->vds_duplicated;
850 5 : sum += req->vds_push;
851 5 : sum += req->vds_ttl_exceeded;
852 5 : sum += req->vds_invalid_nh;
853 5 : sum += req->vds_invalid_label;
854 5 : sum += req->vds_invalid_protocol;
855 5 : sum += req->vds_interface_rx_discard;
856 5 : sum += req->vds_invalid_mcast_source;
857 5 : sum += req->vds_head_alloc_fail;
858 5 : sum += req->vds_pcow_fail;
859 5 : sum += req->vds_mcast_df_bit;
860 5 : sum += req->vds_mcast_clone_fail;
861 5 : sum += req->vds_no_memory;
862 5 : sum += req->vds_rewrite_fail;
863 5 : sum += req->vds_misc;
864 5 : sum += req->vds_invalid_packet;
865 5 : sum += req->vds_cksum_err;
866 5 : sum += req->vds_no_fmd;
867 5 : sum += req->vds_cloned_original;
868 5 : sum += req->vds_invalid_vnid;
869 5 : sum += req->vds_frag_err;
870 5 : sum += req->vds_invalid_source;
871 5 : sum += req->vds_l2_no_route;
872 5 : sum += req->vds_fragment_queue_fail;
873 5 : sum += req->vds_vlan_fwd_tx;
874 5 : sum += req->vds_vlan_fwd_enq;
875 5 : sum += req->vds_drop_new_flow;
876 5 : sum += req->vds_trap_original;
877 5 : sum += req->vds_pkt_loop;
878 5 : sum += req->vds_no_crypt_path;
879 5 : sum += req->vds_invalid_underlay_ecmp;
880 :
881 5 : return sum;
882 : }
883 :
884 : void
885 5 : vr_drop_stats_req_destroy(vr_drop_stats_req *req)
886 : {
887 5 : if (!req)
888 0 : return;
889 :
890 5 : free(req);
891 5 : return;
892 : }
893 :
894 : vr_drop_stats_req *
895 5 : vr_drop_stats_req_get_copy(vr_drop_stats_req *src)
896 : {
897 : vr_drop_stats_req *dst;
898 :
899 5 : if (!src)
900 0 : return NULL;
901 :
902 5 : dst = malloc(sizeof(*dst));
903 5 : if (!dst)
904 0 : return NULL;
905 :
906 5 : *dst = *src;
907 5 : return dst;
908 : }
909 :
910 : int
911 6 : vr_send_drop_stats_get(struct nl_client *cl, unsigned int router_id,
912 : short core)
913 : {
914 : vr_drop_stats_req req;
915 :
916 6 : memset(&req, 0, sizeof(req));
917 6 : req.h_op = SANDESH_OP_GET;
918 6 : req.vds_rid = router_id;
919 6 : req.vds_core = core;
920 :
921 6 : return vr_sendmsg(cl, &req, "vr_drop_stats_req");
922 : }
923 :
924 :
925 : int
926 1 : vr_send_info_dump(struct nl_client *cl, unsigned int router_id,
927 : int marker, int buff_table_id, vr_info_msg_en msginfo, int buffsz,
928 : uint8_t *vr_info_inbuf)
929 : {
930 : vr_info_req req;
931 :
932 1 : memset(&req, 0, sizeof(req));
933 1 : req.h_op = SANDESH_OP_DUMP;
934 1 : req.vdu_rid = router_id;
935 1 : req.vdu_marker = marker;
936 1 : req.vdu_buff_table_id = buff_table_id;
937 1 : req.vdu_msginfo = msginfo;
938 1 : req.vdu_outbufsz = buffsz;
939 1 : if(vr_info_inbuf != NULL) {
940 1 : req.vdu_inbuf_size = strlen(vr_info_inbuf);
941 1 : req.vdu_inbuf = vr_info_inbuf;
942 : }
943 1 : return vr_sendmsg(cl, &req, "vr_info_req");
944 : }
945 :
946 : int
947 0 : vr_pkt_drop_log_reset(struct nl_client *cl)
948 : {
949 : vr_pkt_drop_log_req req;
950 :
951 0 : memset(&req, 0, sizeof(req));
952 0 : req.h_op = SANDESH_OP_RESET;
953 :
954 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
955 : }
956 :
957 : int
958 0 : vr_drop_stats_reset(struct nl_client *cl)
959 : {
960 : vr_drop_stats_req req;
961 :
962 0 : memset(&req, 0, sizeof(req));
963 0 : req.h_op = SANDESH_OP_RESET;
964 :
965 0 : return vr_sendmsg(cl, &req, "vr_drop_stats_req");
966 : }
967 :
968 : int
969 0 : vr_drop_type_set(struct nl_client *cl, uint8_t pkt_drop_log_type)
970 : {
971 : vr_pkt_drop_log_req req;
972 :
973 0 : memset(&req, 0, sizeof(req));
974 0 : req.h_op = SANDESH_OP_ADD;
975 0 : req.vdl_pkt_droplog_type = pkt_drop_log_type;
976 :
977 : /* this flag is to indentify bettwn min log config and drop type set
978 : if 1 used for drop type config
979 : if 0 used for min log config
980 : */
981 0 : req.vdl_pkt_droplog_config = true;
982 :
983 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
984 : }
985 :
986 : int
987 0 : vr_min_log_enable(struct nl_client *cl, bool min_log)
988 : {
989 : vr_pkt_drop_log_req req;
990 :
991 0 : memset(&req, 0, sizeof(req));
992 0 : req.h_op = SANDESH_OP_ADD;
993 0 : req.vdl_pkt_droplog_min_sysctl_en = min_log;
994 :
995 : /* this flag is to indentify between min log config and drop type set
996 : if 1 used for drop type config
997 : if 0 used for min log config
998 : */
999 0 : req.vdl_pkt_droplog_config = false;
1000 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
1001 : }
1002 :
1003 0 : int vr_pkt_drop_log_request(struct nl_client *cl, unsigned int router_id,
1004 : unsigned int core, int log_idx )
1005 : {
1006 0 : int ret = 0;
1007 : vr_pkt_drop_log_req req;
1008 :
1009 0 : memset(&req, 0, sizeof(req));
1010 :
1011 0 : req.vdl_pkt_droplog_arr = (char *)malloc(1);
1012 :
1013 0 : req.h_op = SANDESH_OP_GET;
1014 0 : req.vdl_rid = router_id;
1015 0 : req.vdl_core = core;
1016 0 : req.vdl_log_idx = log_idx;
1017 :
1018 0 : ret = vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
1019 :
1020 0 : free(req.vdl_pkt_droplog_arr);
1021 :
1022 0 : return ret;
1023 : }
1024 : /* dropstats end */
1025 :
1026 : /* Interface start */
1027 : void
1028 25 : vr_interface_req_destroy(vr_interface_req *req)
1029 : {
1030 25 : if (!req)
1031 18 : return;
1032 :
1033 7 : if (req->vifr_name) {
1034 7 : free(req->vifr_name);
1035 7 : req->vifr_name = NULL;
1036 : }
1037 :
1038 7 : if (req->vifr_queue_ierrors_to_lcore_size &&
1039 7 : req->vifr_queue_ierrors_to_lcore) {
1040 7 : free(req->vifr_queue_ierrors_to_lcore);
1041 7 : req->vifr_queue_ierrors_to_lcore = NULL;
1042 7 : req->vifr_queue_ierrors_to_lcore_size = 0;
1043 : }
1044 :
1045 :
1046 7 : if (req->vifr_mac && req->vifr_mac_size) {
1047 7 : free(req->vifr_mac);
1048 7 : req->vifr_mac = NULL;
1049 7 : req->vifr_mac_size = 0;
1050 : }
1051 :
1052 7 : if (req->vifr_src_mac && req->vifr_src_mac_size) {
1053 0 : free(req->vifr_src_mac);
1054 0 : req->vifr_src_mac = NULL;
1055 0 : req->vifr_src_mac_size = 0;
1056 : }
1057 :
1058 7 : if (req->vifr_fat_flow_protocol_port_size &&
1059 0 : req->vifr_fat_flow_protocol_port) {
1060 0 : free(req->vifr_fat_flow_protocol_port);
1061 0 : req->vifr_fat_flow_protocol_port = NULL;
1062 0 : req->vifr_fat_flow_protocol_port_size = 0;
1063 : }
1064 :
1065 7 : if (req->vifr_fat_flow_src_prefix_h &&
1066 0 : req->vifr_fat_flow_src_prefix_h_size) {
1067 0 : free(req->vifr_fat_flow_src_prefix_h);
1068 0 : req->vifr_fat_flow_src_prefix_h = NULL;
1069 0 : req->vifr_fat_flow_src_prefix_h_size = 0;
1070 : }
1071 7 : if (req->vifr_fat_flow_src_prefix_l &&
1072 0 : req->vifr_fat_flow_src_prefix_l_size) {
1073 0 : free(req->vifr_fat_flow_src_prefix_l);
1074 0 : req->vifr_fat_flow_src_prefix_l = NULL;
1075 0 : req->vifr_fat_flow_src_prefix_l_size = 0;
1076 : }
1077 7 : if (req->vifr_fat_flow_src_prefix_mask &&
1078 0 : req->vifr_fat_flow_src_prefix_mask_size) {
1079 0 : free(req->vifr_fat_flow_src_prefix_mask);
1080 0 : req->vifr_fat_flow_src_prefix_mask = NULL;
1081 0 : req->vifr_fat_flow_src_prefix_mask_size = 0;
1082 : }
1083 7 : if (req->vifr_fat_flow_src_aggregate_plen &&
1084 0 : req->vifr_fat_flow_src_aggregate_plen_size) {
1085 0 : free(req->vifr_fat_flow_src_aggregate_plen);
1086 0 : req->vifr_fat_flow_src_aggregate_plen = NULL;
1087 0 : req->vifr_fat_flow_src_aggregate_plen_size = 0;
1088 : }
1089 7 : if (req->vifr_fat_flow_dst_prefix_h &&
1090 0 : req->vifr_fat_flow_dst_prefix_h_size) {
1091 0 : free(req->vifr_fat_flow_dst_prefix_h);
1092 0 : req->vifr_fat_flow_dst_prefix_h = NULL;
1093 0 : req->vifr_fat_flow_dst_prefix_h_size = 0;
1094 : }
1095 7 : if (req->vifr_fat_flow_dst_prefix_l &&
1096 0 : req->vifr_fat_flow_dst_prefix_l_size) {
1097 0 : free(req->vifr_fat_flow_dst_prefix_l);
1098 0 : req->vifr_fat_flow_dst_prefix_l = NULL;
1099 0 : req->vifr_fat_flow_dst_prefix_l_size = 0;
1100 : }
1101 7 : if (req->vifr_fat_flow_dst_prefix_mask &&
1102 0 : req->vifr_fat_flow_dst_prefix_mask_size) {
1103 0 : free(req->vifr_fat_flow_dst_prefix_mask);
1104 0 : req->vifr_fat_flow_dst_prefix_mask = NULL;
1105 0 : req->vifr_fat_flow_dst_prefix_mask_size = 0;
1106 : }
1107 7 : if (req->vifr_fat_flow_dst_aggregate_plen &&
1108 0 : req->vifr_fat_flow_dst_aggregate_plen_size) {
1109 0 : free(req->vifr_fat_flow_dst_aggregate_plen);
1110 0 : req->vifr_fat_flow_dst_aggregate_plen = NULL;
1111 0 : req->vifr_fat_flow_dst_aggregate_plen_size = 0;
1112 : }
1113 :
1114 7 : if (req->vifr_fat_flow_exclude_ip_list_size &&
1115 0 : req->vifr_fat_flow_exclude_ip_list) {
1116 0 : free(req->vifr_fat_flow_exclude_ip_list);
1117 0 : req->vifr_fat_flow_exclude_ip_list = NULL;
1118 0 : req->vifr_fat_flow_exclude_ip_list_size = 0;
1119 : }
1120 7 : if (req->vifr_fat_flow_exclude_ip6_u_list_size &&
1121 0 : req->vifr_fat_flow_exclude_ip6_u_list) {
1122 0 : free(req->vifr_fat_flow_exclude_ip6_u_list);
1123 0 : req->vifr_fat_flow_exclude_ip6_u_list = NULL;
1124 0 : req->vifr_fat_flow_exclude_ip6_u_list_size = 0;
1125 : }
1126 7 : if (req->vifr_fat_flow_exclude_ip6_l_list_size &&
1127 0 : req->vifr_fat_flow_exclude_ip6_l_list) {
1128 0 : free(req->vifr_fat_flow_exclude_ip6_l_list);
1129 0 : req->vifr_fat_flow_exclude_ip6_l_list = NULL;
1130 0 : req->vifr_fat_flow_exclude_ip6_l_list_size = 0;
1131 : }
1132 :
1133 7 : free(req);
1134 7 : return;
1135 : }
1136 :
1137 :
1138 : vr_interface_req *
1139 7 : vr_interface_req_get_copy(vr_interface_req *src)
1140 : {
1141 : vr_interface_req *dst;
1142 :
1143 7 : dst = malloc(sizeof(*dst));
1144 7 : if (!dst)
1145 0 : return NULL;
1146 :
1147 7 : *dst = *src;
1148 7 : dst->vifr_name = NULL;
1149 7 : dst->vifr_queue_ierrors_to_lcore_size = 0;
1150 7 : dst->vifr_queue_ierrors_to_lcore = NULL;
1151 7 : dst->vifr_mac_size = 0;
1152 7 : dst->vifr_mac = NULL;
1153 7 : dst->vifr_src_mac_size = 0;
1154 7 : dst->vifr_src_mac = NULL;
1155 7 : dst->vifr_fat_flow_protocol_port_size = 0;
1156 7 : dst->vifr_fat_flow_protocol_port = NULL;
1157 7 : dst->vifr_fat_flow_src_prefix_h = NULL;
1158 7 : dst->vifr_fat_flow_src_prefix_h_size = 0;
1159 7 : dst->vifr_fat_flow_src_prefix_l = NULL;
1160 7 : dst->vifr_fat_flow_src_prefix_l_size = 0;
1161 7 : dst->vifr_fat_flow_src_prefix_mask = NULL;
1162 7 : dst->vifr_fat_flow_src_prefix_mask_size = 0;
1163 7 : dst->vifr_fat_flow_src_aggregate_plen = NULL;
1164 7 : dst->vifr_fat_flow_src_aggregate_plen_size = 0;
1165 7 : dst->vifr_fat_flow_dst_prefix_h = NULL;
1166 7 : dst->vifr_fat_flow_dst_prefix_h_size = 0;
1167 7 : dst->vifr_fat_flow_dst_prefix_l = NULL;
1168 7 : dst->vifr_fat_flow_dst_prefix_l_size = 0;
1169 7 : dst->vifr_fat_flow_dst_prefix_mask = NULL;
1170 7 : dst->vifr_fat_flow_dst_prefix_mask_size = 0;
1171 7 : dst->vifr_fat_flow_dst_aggregate_plen = NULL;
1172 7 : dst->vifr_fat_flow_dst_aggregate_plen_size = 0;
1173 7 : dst->vifr_fat_flow_exclude_ip_list_size = 0;
1174 7 : dst->vifr_fat_flow_exclude_ip_list = NULL;
1175 7 : dst->vifr_fat_flow_exclude_ip6_u_list_size = 0;
1176 7 : dst->vifr_fat_flow_exclude_ip6_u_list = NULL;
1177 7 : dst->vifr_fat_flow_exclude_ip6_l_list_size = 0;
1178 7 : dst->vifr_fat_flow_exclude_ip6_l_list = NULL;
1179 :
1180 7 : if (src->vifr_name) {
1181 7 : dst->vifr_name = malloc(strlen(src->vifr_name) + 1);
1182 7 : if (!dst->vifr_name)
1183 0 : goto free_vif;
1184 7 : memcpy(dst->vifr_name, src->vifr_name, strlen(src->vifr_name) + 1);
1185 : }
1186 :
1187 7 : if (src->vifr_queue_ierrors_to_lcore_size &&
1188 7 : src->vifr_queue_ierrors_to_lcore) {
1189 7 : dst->vifr_queue_ierrors_to_lcore =
1190 7 : malloc(src->vifr_queue_ierrors_to_lcore_size * sizeof(uint64_t));
1191 7 : if (!dst->vifr_queue_ierrors_to_lcore)
1192 0 : goto free_vif;
1193 :
1194 7 : memcpy(dst->vifr_queue_ierrors_to_lcore,
1195 7 : src->vifr_queue_ierrors_to_lcore,
1196 7 : src->vifr_queue_ierrors_to_lcore_size);
1197 7 : dst->vifr_queue_ierrors_to_lcore_size =
1198 7 : src->vifr_queue_ierrors_to_lcore_size;
1199 : }
1200 :
1201 7 : if (src->vifr_mac && src->vifr_mac_size) {
1202 7 : dst->vifr_mac = malloc(src->vifr_mac_size);
1203 7 : if (!dst->vifr_mac)
1204 0 : goto free_vif;
1205 :
1206 7 : memcpy(dst->vifr_mac, src->vifr_mac, src->vifr_mac_size);
1207 7 : dst->vifr_mac_size = src->vifr_mac_size;
1208 : }
1209 :
1210 7 : if (src->vifr_src_mac && src->vifr_src_mac_size) {
1211 0 : dst->vifr_src_mac = malloc(src->vifr_src_mac_size);
1212 0 : if (!dst->vifr_src_mac)
1213 0 : goto free_vif;
1214 :
1215 0 : memcpy(dst->vifr_src_mac, src->vifr_src_mac, src->vifr_src_mac_size);
1216 0 : dst->vifr_src_mac_size = src->vifr_src_mac_size;
1217 : }
1218 :
1219 :
1220 7 : if (src->vifr_fat_flow_protocol_port_size &&
1221 0 : src->vifr_fat_flow_protocol_port) {
1222 0 : dst->vifr_fat_flow_protocol_port =
1223 0 : malloc(src->vifr_fat_flow_protocol_port_size * sizeof(uint32_t));
1224 0 : if (!dst->vifr_fat_flow_protocol_port)
1225 0 : goto free_vif;
1226 :
1227 0 : memcpy(dst->vifr_fat_flow_protocol_port,
1228 0 : src->vifr_fat_flow_protocol_port,
1229 0 : src->vifr_fat_flow_protocol_port_size);
1230 0 : dst->vifr_fat_flow_protocol_port_size =
1231 0 : src->vifr_fat_flow_protocol_port_size;
1232 : }
1233 :
1234 7 : if (src->vifr_fat_flow_src_prefix_h_size &&
1235 0 : src->vifr_fat_flow_src_prefix_h) {
1236 0 : dst->vifr_fat_flow_src_prefix_h =
1237 0 : malloc(src->vifr_fat_flow_src_prefix_h_size * sizeof(uint64_t));
1238 0 : if (!dst->vifr_fat_flow_src_prefix_h)
1239 0 : goto free_vif;
1240 0 : memcpy(dst->vifr_fat_flow_src_prefix_h, src->vifr_fat_flow_src_prefix_h,
1241 0 : src->vifr_fat_flow_src_prefix_h_size);
1242 0 : dst->vifr_fat_flow_src_prefix_h_size = src->vifr_fat_flow_src_prefix_h_size;
1243 : }
1244 :
1245 7 : if (src->vifr_fat_flow_src_prefix_l_size &&
1246 0 : src->vifr_fat_flow_src_prefix_l) {
1247 0 : dst->vifr_fat_flow_src_prefix_l =
1248 0 : malloc(src->vifr_fat_flow_src_prefix_l_size * sizeof(uint64_t));
1249 0 : if (!dst->vifr_fat_flow_src_prefix_l)
1250 0 : goto free_vif;
1251 0 : memcpy(dst->vifr_fat_flow_src_prefix_l, src->vifr_fat_flow_src_prefix_l,
1252 0 : src->vifr_fat_flow_src_prefix_l_size);
1253 0 : dst->vifr_fat_flow_src_prefix_l_size = src->vifr_fat_flow_src_prefix_l_size;
1254 : }
1255 7 : if (src->vifr_fat_flow_src_prefix_mask_size &&
1256 0 : src->vifr_fat_flow_src_prefix_mask) {
1257 0 : dst->vifr_fat_flow_src_prefix_mask =
1258 0 : malloc(src->vifr_fat_flow_src_prefix_mask_size * sizeof(uint8_t));
1259 0 : if (!dst->vifr_fat_flow_src_prefix_mask)
1260 0 : goto free_vif;
1261 0 : memcpy(dst->vifr_fat_flow_src_prefix_mask, src->vifr_fat_flow_src_prefix_mask,
1262 0 : src->vifr_fat_flow_src_prefix_mask_size);
1263 0 : dst->vifr_fat_flow_src_prefix_mask_size = src->vifr_fat_flow_src_prefix_mask_size;
1264 : }
1265 7 : if (src->vifr_fat_flow_src_aggregate_plen_size &&
1266 0 : src->vifr_fat_flow_src_aggregate_plen) {
1267 0 : dst->vifr_fat_flow_src_aggregate_plen =
1268 0 : malloc(src->vifr_fat_flow_src_aggregate_plen_size * sizeof(uint8_t));
1269 0 : if (!dst->vifr_fat_flow_src_aggregate_plen)
1270 0 : goto free_vif;
1271 0 : memcpy(dst->vifr_fat_flow_src_aggregate_plen, src->vifr_fat_flow_src_aggregate_plen,
1272 0 : src->vifr_fat_flow_src_aggregate_plen_size);
1273 0 : dst->vifr_fat_flow_src_aggregate_plen_size = src->vifr_fat_flow_src_aggregate_plen_size;
1274 : }
1275 7 : if (src->vifr_fat_flow_dst_prefix_h_size &&
1276 0 : src->vifr_fat_flow_dst_prefix_h) {
1277 0 : dst->vifr_fat_flow_dst_prefix_h =
1278 0 : malloc(src->vifr_fat_flow_dst_prefix_h_size * sizeof(uint64_t));
1279 0 : if (!dst->vifr_fat_flow_dst_prefix_h)
1280 0 : goto free_vif;
1281 0 : memcpy(dst->vifr_fat_flow_dst_prefix_h, src->vifr_fat_flow_dst_prefix_h,
1282 0 : src->vifr_fat_flow_dst_prefix_h_size);
1283 0 : dst->vifr_fat_flow_dst_prefix_h_size = src->vifr_fat_flow_dst_prefix_h_size;
1284 : }
1285 7 : if (src->vifr_fat_flow_dst_prefix_l_size &&
1286 0 : src->vifr_fat_flow_dst_prefix_l) {
1287 0 : dst->vifr_fat_flow_dst_prefix_l =
1288 0 : malloc(src->vifr_fat_flow_dst_prefix_l_size * sizeof(uint64_t));
1289 0 : if (!dst->vifr_fat_flow_dst_prefix_l)
1290 0 : goto free_vif;
1291 0 : memcpy(dst->vifr_fat_flow_dst_prefix_l, src->vifr_fat_flow_dst_prefix_l,
1292 0 : src->vifr_fat_flow_dst_prefix_l_size);
1293 0 : dst->vifr_fat_flow_dst_prefix_l_size = src->vifr_fat_flow_dst_prefix_l_size;
1294 : }
1295 7 : if (src->vifr_fat_flow_dst_prefix_mask_size &&
1296 0 : src->vifr_fat_flow_dst_prefix_mask) {
1297 0 : dst->vifr_fat_flow_dst_prefix_mask =
1298 0 : malloc(src->vifr_fat_flow_dst_prefix_mask_size * sizeof(uint8_t));
1299 0 : if (!dst->vifr_fat_flow_dst_prefix_mask)
1300 0 : goto free_vif;
1301 0 : memcpy(dst->vifr_fat_flow_dst_prefix_mask, src->vifr_fat_flow_dst_prefix_mask,
1302 0 : src->vifr_fat_flow_dst_prefix_mask_size);
1303 0 : dst->vifr_fat_flow_dst_prefix_mask_size = src->vifr_fat_flow_dst_prefix_mask_size;
1304 : }
1305 7 : if (src->vifr_fat_flow_dst_aggregate_plen_size &&
1306 0 : src->vifr_fat_flow_dst_aggregate_plen) {
1307 0 : dst->vifr_fat_flow_dst_aggregate_plen =
1308 0 : malloc(src->vifr_fat_flow_dst_aggregate_plen_size * sizeof(uint8_t));
1309 0 : if (!dst->vifr_fat_flow_dst_aggregate_plen)
1310 0 : goto free_vif;
1311 0 : memcpy(dst->vifr_fat_flow_dst_aggregate_plen, src->vifr_fat_flow_dst_aggregate_plen,
1312 0 : src->vifr_fat_flow_dst_aggregate_plen_size);
1313 0 : dst->vifr_fat_flow_dst_aggregate_plen_size = src->vifr_fat_flow_dst_aggregate_plen_size;
1314 : }
1315 :
1316 7 : if (src->vifr_fat_flow_exclude_ip_list_size &&
1317 0 : src->vifr_fat_flow_exclude_ip_list) {
1318 0 : dst->vifr_fat_flow_exclude_ip_list = malloc(src->vifr_fat_flow_exclude_ip_list_size * sizeof(uint64_t));
1319 0 : if (!dst->vifr_fat_flow_exclude_ip_list) {
1320 0 : goto free_vif;
1321 : }
1322 0 : memcpy(dst->vifr_fat_flow_exclude_ip_list, src->vifr_fat_flow_exclude_ip_list,
1323 0 : src->vifr_fat_flow_exclude_ip_list_size * sizeof(uint64_t));
1324 0 : dst->vifr_fat_flow_exclude_ip_list_size = src->vifr_fat_flow_exclude_ip_list_size;
1325 : }
1326 :
1327 7 : if (src->vifr_fat_flow_exclude_ip6_u_list_size &&
1328 0 : src->vifr_fat_flow_exclude_ip6_u_list) {
1329 0 : dst->vifr_fat_flow_exclude_ip6_u_list = malloc(src->vifr_fat_flow_exclude_ip6_u_list_size * sizeof(uint64_t));
1330 0 : if (!dst->vifr_fat_flow_exclude_ip6_u_list) {
1331 0 : goto free_vif;
1332 : }
1333 0 : memcpy(dst->vifr_fat_flow_exclude_ip6_u_list, src->vifr_fat_flow_exclude_ip6_u_list,
1334 0 : src->vifr_fat_flow_exclude_ip6_u_list_size * sizeof(uint64_t));
1335 0 : dst->vifr_fat_flow_exclude_ip6_u_list_size = src->vifr_fat_flow_exclude_ip6_u_list_size;
1336 : }
1337 7 : if (src->vifr_fat_flow_exclude_ip6_l_list_size &&
1338 0 : src->vifr_fat_flow_exclude_ip6_l_list) {
1339 0 : dst->vifr_fat_flow_exclude_ip6_l_list = malloc(src->vifr_fat_flow_exclude_ip6_l_list_size * sizeof(uint64_t));
1340 0 : if (!dst->vifr_fat_flow_exclude_ip6_l_list) {
1341 0 : goto free_vif;
1342 : }
1343 0 : memcpy(dst->vifr_fat_flow_exclude_ip6_l_list, src->vifr_fat_flow_exclude_ip6_l_list,
1344 0 : src->vifr_fat_flow_exclude_ip6_l_list_size * sizeof(uint64_t));
1345 0 : dst->vifr_fat_flow_exclude_ip6_l_list_size = src->vifr_fat_flow_exclude_ip6_l_list_size;
1346 : }
1347 :
1348 7 : return dst;
1349 :
1350 0 : free_vif:
1351 0 : vr_interface_req_destroy(dst);
1352 0 : dst = NULL;
1353 0 : return NULL;
1354 : }
1355 :
1356 : int
1357 0 : vr_send_interface_dump(struct nl_client *cl, unsigned int router_id,
1358 : int marker, int core)
1359 : {
1360 : vr_interface_req req;
1361 :
1362 0 : memset(&req, 0, sizeof(req));
1363 0 : req.h_op = SANDESH_OP_DUMP;
1364 0 : req.vifr_rid = router_id;
1365 0 : req.vifr_marker = marker;
1366 0 : req.vifr_core = core;
1367 0 : return vr_sendmsg(cl, &req, "vr_interface_req");
1368 : }
1369 :
1370 : int
1371 10 : vr_send_interface_get(struct nl_client *cl, unsigned int router_id,
1372 : int vif_index, int os_index, int core, int get_drops)
1373 : {
1374 : vr_interface_req req;
1375 :
1376 10 : memset(&req, 0, sizeof(req));
1377 :
1378 10 : req.h_op = SANDESH_OP_GET;
1379 10 : req.vifr_rid = router_id;
1380 10 : req.vifr_os_idx = os_index;
1381 10 : req.vifr_idx = vif_index;
1382 10 : req.vifr_core = core;
1383 10 : if (get_drops)
1384 0 : req.vifr_flags |= VIF_FLAG_GET_DROP_STATS;
1385 :
1386 10 : return vr_sendmsg(cl, &req, "vr_interface_req");
1387 : }
1388 :
1389 : int
1390 8 : vr_send_interface_delete(struct nl_client *cl, unsigned int router_id,
1391 : char *vif_name, int vif_index)
1392 : {
1393 : vr_interface_req req;
1394 :
1395 8 : memset(&req, 0, sizeof(req));
1396 :
1397 8 : req.h_op = SANDESH_OP_DEL;
1398 8 : req.vifr_rid = router_id;
1399 8 : req.vifr_name = vif_name;
1400 8 : req.vifr_idx = vif_index;
1401 :
1402 8 : return vr_sendmsg(cl, &req, "vr_interface_req");
1403 : }
1404 :
1405 : int
1406 0 : vr_send_interface_add(struct nl_client *cl, int router_id, char *vif_name,
1407 : int os_index, int vif_index, int *vif_xconnect_index, int vif_type,
1408 : unsigned int vrf, unsigned int flags, int8_t *vif_mac, int8_t vif_transport,
1409 : const char *guid)
1410 : {
1411 0 : int platform, i = 0;
1412 : vr_interface_req req;
1413 :
1414 0 : platform = get_platform();
1415 0 : memset(&req, 0, sizeof(req));
1416 :
1417 0 : req.h_op = SANDESH_OP_ADD;
1418 0 : if (vif_name)
1419 0 : req.vifr_name = vif_name;
1420 0 : if (vif_mac) {
1421 0 : req.vifr_mac_size = 6;
1422 0 : req.vifr_mac = vif_mac;
1423 : }
1424 0 : req.vifr_vrf = vrf;
1425 0 : req.vifr_mcast_vrf = (uint16_t)(-1);
1426 :
1427 0 : if (os_index > 0)
1428 0 : req.vifr_os_idx = os_index;
1429 :
1430 0 : req.vifr_idx = vif_index;
1431 0 : req.vifr_rid = router_id;
1432 0 : req.vifr_type = vif_type;
1433 0 : req.vifr_flags = flags;
1434 0 : req.vifr_transport = vif_transport;
1435 :
1436 0 : if (vif_type == VIF_TYPE_HOST) {
1437 0 : for(i = 0; i < VR_MAX_PHY_INF; i++) {
1438 0 : if(vif_xconnect_index[i] < 0) {
1439 0 : break;
1440 : }
1441 : }
1442 0 : req.vifr_cross_connect_idx_size = i;
1443 0 : req.vifr_cross_connect_idx = vif_xconnect_index;
1444 : }
1445 :
1446 0 : return vr_sendmsg(cl, &req, "vr_interface_req");
1447 : }
1448 :
1449 : int
1450 1 : vr_send_vif_clear_stats(struct nl_client *cl, unsigned int router_id,
1451 : int vif_idx, int core)
1452 : {
1453 : vr_interface_req req;
1454 :
1455 1 : memset(&req, 0, sizeof(req));
1456 1 : req.h_op = SANDESH_OP_RESET;
1457 1 : req.vifr_rid = router_id;
1458 1 : req.vifr_idx = vif_idx;
1459 1 : req.vifr_core = core + 1;
1460 :
1461 1 : return vr_sendmsg(cl, &req, "vr_interface_req");
1462 : }
1463 :
1464 : /* interface end */
1465 :
1466 :
1467 : int
1468 0 : vr_send_mem_stats_get(struct nl_client *cl, unsigned int router_id)
1469 : {
1470 : vr_mem_stats_req req;
1471 :
1472 0 : memset(&req, 0, sizeof(req));
1473 0 : req.h_op = SANDESH_OP_GET;
1474 0 : req.vms_rid = router_id;
1475 :
1476 0 : return vr_sendmsg(cl, &req, "vr_mem_stats_req");
1477 : }
1478 :
1479 : /* mirror start */
1480 : void
1481 0 : vr_mirror_req_destroy(vr_mirror_req *req)
1482 : {
1483 0 : if (!req)
1484 0 : return;
1485 :
1486 0 : free(req);
1487 :
1488 0 : return;
1489 : }
1490 :
1491 : vr_mirror_req *
1492 0 : vr_mirror_req_get_copy(vr_mirror_req *req)
1493 : {
1494 : vr_mirror_req *dst;
1495 :
1496 0 : if (!req)
1497 0 : return NULL;
1498 :
1499 0 : dst = malloc(sizeof(*req));
1500 0 : if (!dst)
1501 0 : return NULL;
1502 :
1503 0 : *dst = *req;
1504 :
1505 0 : return dst;
1506 : }
1507 :
1508 : int
1509 0 : vr_send_mirror_dump(struct nl_client *cl, unsigned int router_id,
1510 : int marker)
1511 : {
1512 : vr_mirror_req req;
1513 :
1514 0 : req.h_op = SANDESH_OP_DUMP;
1515 0 : req.mirr_rid = router_id;
1516 0 : req.mirr_marker = marker;
1517 :
1518 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1519 : }
1520 :
1521 : int
1522 0 : vr_send_mirror_get(struct nl_client *cl, unsigned int router_id,
1523 : unsigned int mirror_index)
1524 : {
1525 : vr_mirror_req req;
1526 :
1527 0 : req.h_op = SANDESH_OP_GET;
1528 0 : req.mirr_rid = router_id;
1529 0 : req.mirr_index = mirror_index;
1530 :
1531 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1532 : }
1533 :
1534 : int
1535 0 : vr_send_mirror_delete(struct nl_client *cl, unsigned int router_id,
1536 : unsigned int mirror_index)
1537 : {
1538 : vr_mirror_req req;
1539 :
1540 0 : req.h_op = SANDESH_OP_DEL;
1541 0 : req.mirr_rid = router_id;
1542 0 : req.mirr_index = mirror_index;
1543 :
1544 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1545 : }
1546 :
1547 : int
1548 0 : vr_send_mirror_add(struct nl_client *cl, unsigned int router_id,
1549 : unsigned int mirror_index, int mirror_nh_index,
1550 : unsigned int mirror_flags, int vni_id)
1551 : {
1552 : vr_mirror_req req;
1553 :
1554 0 : memset(&req, 0, sizeof(req));
1555 :
1556 0 : req.h_op = SANDESH_OP_ADD;
1557 0 : req.mirr_rid = router_id;
1558 0 : req.mirr_index = mirror_index;
1559 0 : req.mirr_nhid = mirror_nh_index;
1560 0 : req.mirr_flags = mirror_flags;
1561 0 : req.mirr_vni = vni_id;
1562 :
1563 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1564 : }
1565 : /* mirror end */
1566 :
1567 : int
1568 0 : vr_send_vrf_dump(struct nl_client *cl, unsigned int router_id,
1569 : int marker)
1570 : {
1571 : vr_vrf_req req;
1572 :
1573 0 : req.h_op = SANDESH_OP_DUMP;
1574 0 : req.vrf_rid = router_id;
1575 0 : req.vrf_marker = marker;
1576 :
1577 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1578 : }
1579 :
1580 : int
1581 0 : vr_send_vrf_get(struct nl_client *cl, unsigned int router_id,
1582 : unsigned int vrf_index)
1583 : {
1584 : vr_vrf_req req;
1585 :
1586 0 : req.h_op = SANDESH_OP_GET;
1587 0 : req.vrf_rid = router_id;
1588 0 : req.vrf_idx = vrf_index;
1589 :
1590 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1591 : }
1592 :
1593 : int
1594 0 : vr_send_vrf_delete(struct nl_client *cl, unsigned int router_id,
1595 : unsigned int vrf_index)
1596 : {
1597 : vr_vrf_req req;
1598 :
1599 0 : req.h_op = SANDESH_OP_DEL;
1600 0 : req.vrf_rid = router_id;
1601 0 : req.vrf_idx = vrf_index;
1602 :
1603 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1604 : }
1605 :
1606 : int
1607 0 : vr_send_vrf_add(struct nl_client *cl, unsigned int router_id,
1608 : unsigned int vrf_index, int hbfl_idx, int hbfr_idx,
1609 : unsigned int vrf_flags)
1610 : {
1611 : vr_vrf_req req;
1612 :
1613 0 : memset(&req, 0, sizeof(req));
1614 :
1615 0 : req.h_op = SANDESH_OP_ADD;
1616 0 : req.vrf_rid = router_id;
1617 0 : req.vrf_idx = vrf_index;
1618 0 : req.vrf_flags = vrf_flags;
1619 0 : req.vrf_hbfl_vif_idx = hbfl_idx;
1620 0 : req.vrf_hbfr_vif_idx = hbfr_idx;
1621 :
1622 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1623 : }
1624 :
1625 : int
1626 0 : vr_send_mpls_delete(struct nl_client *cl, unsigned int router_id,
1627 : unsigned int label)
1628 : {
1629 : vr_mpls_req req;
1630 :
1631 0 : memset(&req, 0, sizeof(req));
1632 0 : req.h_op = SANDESH_OP_DEL;
1633 0 : req.mr_rid = router_id;
1634 0 : req.mr_label = label;
1635 :
1636 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1637 : }
1638 :
1639 : int
1640 0 : vr_send_mpls_dump(struct nl_client *cl, unsigned int router_id, int marker)
1641 : {
1642 : vr_mpls_req req;
1643 :
1644 0 : memset(&req, 0, sizeof(req));
1645 0 : req.h_op = SANDESH_OP_DUMP;
1646 0 : req.mr_rid = router_id;
1647 0 : req.mr_marker = marker;
1648 :
1649 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1650 : }
1651 :
1652 : int
1653 0 : vr_send_mpls_get(struct nl_client *cl, unsigned int router_id, unsigned int label)
1654 : {
1655 : vr_mpls_req req;
1656 :
1657 0 : memset(&req, 0, sizeof(req));
1658 0 : req.h_op = SANDESH_OP_GET;
1659 0 : req.mr_rid = router_id;
1660 0 : req.mr_label = label;
1661 :
1662 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1663 : }
1664 :
1665 : int
1666 0 : vr_send_mpls_add(struct nl_client *cl, unsigned int router_id,
1667 : unsigned int label, unsigned int nh_index)
1668 : {
1669 : vr_mpls_req req;
1670 :
1671 0 : memset(&req, 0, sizeof(req));
1672 0 : req.h_op = SANDESH_OP_ADD;
1673 0 : req.mr_rid = router_id;
1674 0 : req.mr_label = label;
1675 0 : req.mr_nhid = nh_index;
1676 :
1677 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1678 : }
1679 :
1680 : char *
1681 7 : vr_nexthop_type_string(vr_nexthop_req *nh)
1682 : {
1683 7 : switch (nh->nhr_type) {
1684 0 : case NH_DEAD:
1685 0 : return "DEAD";
1686 : break;
1687 :
1688 0 : case NH_RCV:
1689 0 : return "RECEIVE";
1690 : break;
1691 :
1692 7 : case NH_ENCAP:
1693 7 : return "ENCAP";
1694 : break;
1695 :
1696 0 : case NH_TUNNEL:
1697 0 : return "TUNNEL";
1698 : break;
1699 :
1700 0 : case NH_RESOLVE:
1701 0 : return "RESOLVE";
1702 : break;
1703 :
1704 0 : case NH_DISCARD:
1705 0 : return "DISCARD";
1706 : break;
1707 :
1708 0 : case NH_COMPOSITE:
1709 0 : return "COMPOSITE";
1710 : break;
1711 :
1712 0 : case NH_VRF_TRANSLATE:
1713 0 : return "VRF_TRANSLATE";
1714 : break;
1715 :
1716 0 : case NH_L2_RCV:
1717 0 : return "L2_RECEIVE";
1718 : break;
1719 :
1720 0 : default:
1721 0 : return "NONE";
1722 : }
1723 :
1724 : return "NONE";
1725 : }
1726 :
1727 :
1728 : bool
1729 10 : vr_nexthop_req_has_vif(vr_nexthop_req *req)
1730 : {
1731 10 : switch (req->nhr_type) {
1732 2 : case NH_ENCAP:
1733 : case NH_TUNNEL:
1734 : case NH_RCV:
1735 : case NH_L2_RCV:
1736 2 : return true;
1737 : break;
1738 :
1739 8 : case NH_COMPOSITE:
1740 : default:
1741 8 : return false;
1742 : break;
1743 : }
1744 :
1745 : return false;
1746 : }
1747 :
1748 : void
1749 115 : vr_nexthop_req_destroy(vr_nexthop_req *req)
1750 : {
1751 115 : if (!req)
1752 100 : return;
1753 :
1754 15 : if (req->nhr_encap_size && req->nhr_encap) {
1755 7 : free(req->nhr_encap);
1756 7 : req->nhr_encap = NULL;
1757 7 : req->nhr_encap_size = 0;
1758 7 : req->nhr_encap_len = 0;
1759 : }
1760 :
1761 15 : if (req->nhr_nh_list_size && req->nhr_nh_list) {
1762 0 : free(req->nhr_nh_list);
1763 0 : req->nhr_nh_list = NULL;
1764 0 : req->nhr_nh_list_size = 0;
1765 : }
1766 :
1767 15 : if (req->nhr_label_list_size && req->nhr_label_list) {
1768 0 : free(req->nhr_label_list);
1769 0 : req->nhr_label_list = NULL;
1770 0 : req->nhr_label_list_size = 0;
1771 : }
1772 :
1773 15 : if (req->nhr_tun_sip6_size && req->nhr_tun_sip6) {
1774 0 : free(req->nhr_tun_sip6);
1775 0 : req->nhr_tun_sip6 = NULL;
1776 0 : req->nhr_tun_sip6_size = 0;
1777 : }
1778 :
1779 15 : if (req->nhr_tun_dip6_size && req->nhr_tun_dip6) {
1780 0 : free(req->nhr_tun_dip6);
1781 0 : req->nhr_tun_dip6 = NULL;
1782 0 : req->nhr_tun_dip6_size = 0;
1783 : }
1784 :
1785 15 : if (req->nhr_encap_oif_id_size && req->nhr_encap_oif_id) {
1786 15 : free(req->nhr_encap_oif_id);
1787 15 : req->nhr_encap_oif_id = NULL;
1788 15 : req->nhr_encap_oif_id_size = 0;
1789 : }
1790 :
1791 15 : if (req->nhr_encap_valid_size && req->nhr_encap_valid) {
1792 0 : free(req->nhr_encap_valid);
1793 0 : req->nhr_encap_valid = NULL;
1794 0 : req->nhr_encap_valid_size = 0;
1795 : }
1796 :
1797 15 : free(req);
1798 :
1799 15 : return;
1800 : }
1801 :
1802 : vr_nexthop_req *
1803 15 : vr_nexthop_req_get_copy(vr_nexthop_req *src)
1804 : {
1805 : vr_nexthop_req *dst;
1806 :
1807 15 : dst = calloc(sizeof(vr_nexthop_req), 1);
1808 15 : if (!dst)
1809 0 : return NULL;
1810 :
1811 : /* first copy the in-built members */
1812 15 : *dst = *src;
1813 :
1814 15 : dst->nhr_encap = NULL;
1815 15 : dst->nhr_encap_size = 0;
1816 15 : dst->nhr_nh_list = NULL;
1817 15 : dst->nhr_nh_list_size = 0;
1818 15 : dst->nhr_label_list = NULL;
1819 15 : dst->nhr_label_list_size = 0;
1820 15 : dst->nhr_tun_sip6 = NULL;
1821 15 : dst->nhr_tun_sip6_size = 0;
1822 15 : dst->nhr_tun_dip6 = NULL;
1823 15 : dst->nhr_tun_dip6_size = 0;
1824 15 : dst->nhr_encap_oif_id = NULL;
1825 15 : dst->nhr_encap_oif_id_size = 0;
1826 15 : dst->nhr_encap_valid = NULL;
1827 15 : dst->nhr_encap_valid_size = 0;
1828 :
1829 : /* ...and then the list elements */
1830 15 : if (src->nhr_encap_size && src->nhr_encap) {
1831 7 : dst->nhr_encap = malloc(src->nhr_encap_size);
1832 7 : if (!dst->nhr_encap)
1833 0 : goto free_nh;
1834 7 : memcpy(dst->nhr_encap, src->nhr_encap, src->nhr_encap_size);
1835 7 : dst->nhr_encap_size = src->nhr_encap_size;
1836 : }
1837 :
1838 : /* component nexthop list */
1839 15 : if (src->nhr_nh_list_size && src->nhr_nh_list) {
1840 0 : dst->nhr_nh_list = malloc(src->nhr_nh_list_size * sizeof(uint32_t));
1841 0 : if (!src->nhr_nh_list)
1842 0 : goto free_nh;
1843 0 : memcpy(dst->nhr_nh_list, src->nhr_nh_list,
1844 0 : src->nhr_nh_list_size * sizeof(uint32_t));
1845 0 : dst->nhr_nh_list_size = src->nhr_nh_list_size;
1846 : }
1847 :
1848 : /* label list */
1849 15 : if (src->nhr_label_list_size && src->nhr_label_list) {
1850 0 : dst->nhr_label_list = malloc(src->nhr_label_list_size * sizeof(uint32_t));
1851 0 : if (!src->nhr_label_list)
1852 0 : goto free_nh;
1853 0 : memcpy(dst->nhr_label_list, src->nhr_label_list,
1854 0 : src->nhr_label_list_size * sizeof(uint32_t));
1855 0 : dst->nhr_label_list_size = src->nhr_label_list_size;
1856 : }
1857 :
1858 : /* ipv6 tunnel source */
1859 15 : if (src->nhr_tun_sip6_size && src->nhr_tun_sip6) {
1860 0 : dst->nhr_tun_sip6 = malloc(src->nhr_tun_sip6_size);
1861 0 : if (!src->nhr_tun_sip6)
1862 0 : goto free_nh;
1863 0 : memcpy(dst->nhr_tun_sip6, src->nhr_tun_sip6, src->nhr_tun_sip6_size);
1864 0 : dst->nhr_tun_sip6_size = src->nhr_tun_sip6_size;
1865 : }
1866 :
1867 : /* ipv6 tunnel destination */
1868 15 : if (src->nhr_tun_dip6_size && src->nhr_tun_dip6) {
1869 0 : dst->nhr_tun_dip6 = malloc(src->nhr_tun_dip6_size);
1870 0 : if (!src->nhr_tun_dip6)
1871 0 : goto free_nh;
1872 0 : memcpy(dst->nhr_tun_dip6, src->nhr_tun_dip6, src->nhr_tun_dip6_size);
1873 0 : dst->nhr_tun_dip6_size = src->nhr_tun_dip6_size;
1874 : }
1875 :
1876 : /* encap oif id list */
1877 15 : if (src->nhr_encap_oif_id_size && src->nhr_encap_oif_id) {
1878 15 : dst->nhr_encap_oif_id = malloc(src->nhr_encap_oif_id_size * sizeof(int32_t));
1879 15 : if (!src->nhr_encap_oif_id)
1880 0 : goto free_nh;
1881 15 : memcpy(dst->nhr_encap_oif_id, src->nhr_encap_oif_id,
1882 15 : src->nhr_encap_oif_id_size * sizeof(int32_t));
1883 15 : dst->nhr_encap_oif_id_size = src->nhr_encap_oif_id_size;
1884 : }
1885 :
1886 : /* encap valid list */
1887 15 : if (src->nhr_encap_valid_size && src->nhr_encap_valid &&
1888 0 : (src->nhr_flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP)) {
1889 0 : dst->nhr_encap_valid = malloc(src->nhr_encap_valid_size * sizeof(int32_t));
1890 0 : if (!src->nhr_encap_valid)
1891 0 : goto free_nh;
1892 0 : memcpy(dst->nhr_encap_valid, src->nhr_encap_valid,
1893 0 : src->nhr_encap_valid_size * sizeof(int32_t));
1894 0 : dst->nhr_encap_valid_size = src->nhr_encap_valid_size;
1895 : }
1896 :
1897 15 : return dst;
1898 :
1899 0 : free_nh:
1900 0 : vr_nexthop_req_destroy(dst);
1901 0 : return NULL;
1902 : }
1903 :
1904 : int
1905 0 : vr_send_nexthop_delete(struct nl_client *cl, unsigned int router_id,
1906 : unsigned int nh_index)
1907 : {
1908 : vr_nexthop_req req;
1909 :
1910 0 : memset(&req, 0, sizeof(req));
1911 0 : req.h_op = SANDESH_OP_DEL;
1912 0 : req.nhr_rid = router_id;
1913 0 : req.nhr_id = nh_index;
1914 :
1915 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1916 : }
1917 :
1918 : int
1919 0 : vr_send_nexthop_dump(struct nl_client *cl, unsigned int router_id,
1920 : int marker)
1921 : {
1922 : vr_nexthop_req req;
1923 :
1924 0 : memset(&req, 0, sizeof(req));
1925 0 : req.h_op = SANDESH_OP_DUMP;
1926 0 : req.nhr_rid = router_id;
1927 0 : req.nhr_marker = marker;
1928 :
1929 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1930 : }
1931 :
1932 : int
1933 19 : vr_send_nexthop_get(struct nl_client *cl, unsigned int router_id,
1934 : unsigned int nh_index)
1935 : {
1936 : vr_nexthop_req req;
1937 :
1938 19 : memset(&req, 0, sizeof(req));
1939 19 : req.h_op = SANDESH_OP_GET;
1940 19 : req.nhr_rid = router_id;
1941 19 : req.nhr_id = nh_index;
1942 :
1943 19 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1944 : }
1945 :
1946 : int
1947 0 : vr_send_pbb_tunnel_add(struct nl_client *cl, unsigned int router_id, int
1948 : nh_index, unsigned int flags, int vrf_index, int8_t *bmac,
1949 : unsigned int direct_nh_id, unsigned int direct_label)
1950 : {
1951 0 : int ret = 0;
1952 : unsigned int i;
1953 : vr_nexthop_req req;
1954 :
1955 0 : memset(&req, 0, sizeof(req));
1956 0 : req.h_op = SANDESH_OP_ADD;
1957 0 : req.nhr_rid = router_id;
1958 0 : req.nhr_vrf = vrf_index;
1959 0 : req.nhr_id = nh_index;
1960 0 : req.nhr_flags = flags;
1961 0 : req.nhr_type = NH_TUNNEL;
1962 :
1963 0 : req.nhr_encap_oif_id_size = 1;
1964 0 : req.nhr_encap_oif_id = calloc(req.nhr_encap_oif_id_size, sizeof(unsigned int));
1965 0 : if (!req.nhr_encap_oif_id) {
1966 0 : ret = -ENOMEM;
1967 0 : goto fail;
1968 : }
1969 0 : req.nhr_encap_oif_id[0] = 0;
1970 :
1971 0 : req.nhr_nh_list_size = 1;
1972 0 : req.nhr_nh_list = calloc(1, sizeof(uint32_t));
1973 0 : if (!req.nhr_nh_list) {
1974 0 : ret = -ENOMEM;
1975 0 : goto fail;
1976 : }
1977 :
1978 0 : req.nhr_label_list = calloc(1, sizeof(uint32_t));
1979 0 : if (!req.nhr_label_list) {
1980 0 : ret = -ENOMEM;
1981 0 : goto fail;
1982 : }
1983 :
1984 0 : req.nhr_pbb_mac_size = VR_ETHER_ALEN;
1985 0 : req.nhr_pbb_mac = calloc(VR_ETHER_ALEN, sizeof(uint8_t));
1986 0 : if (!req.nhr_pbb_mac) {
1987 0 : ret = -ENOMEM;
1988 0 : goto fail;
1989 : }
1990 0 : VR_MAC_COPY(req.nhr_pbb_mac, bmac);
1991 :
1992 0 : req.nhr_label_list_size = 1;
1993 0 : req.nhr_nh_list[0] = direct_nh_id;
1994 0 : req.nhr_label_list[0] = direct_label;
1995 0 : req.nhr_family = AF_BRIDGE;
1996 :
1997 0 : ret = vr_sendmsg(cl, &req, "vr_nexthop_req");
1998 0 : fail:
1999 0 : if (req.nhr_nh_list) {
2000 0 : free(req.nhr_nh_list);
2001 0 : req.nhr_nh_list = NULL;
2002 : }
2003 :
2004 0 : if (req.nhr_label_list) {
2005 0 : free(req.nhr_label_list);
2006 0 : req.nhr_label_list = NULL;
2007 : }
2008 :
2009 0 : return ret;
2010 : }
2011 :
2012 : int
2013 0 : vr_send_nexthop_composite_add(struct nl_client *cl, unsigned int router_id,
2014 : int nh_index, unsigned int flags, int vrf_index,
2015 : unsigned int num_components, unsigned int *component_nh_indices,
2016 : unsigned int *component_labels, unsigned int family)
2017 : {
2018 0 : int ret = 0;
2019 : unsigned int i;
2020 : vr_nexthop_req req;
2021 :
2022 0 : memset(&req, 0, sizeof(req));
2023 0 : req.h_op = SANDESH_OP_ADD;
2024 0 : req.nhr_rid = router_id;
2025 0 : req.nhr_vrf = vrf_index;
2026 0 : req.nhr_id = nh_index;
2027 0 : req.nhr_flags = flags;
2028 0 : req.nhr_type = NH_COMPOSITE;
2029 :
2030 0 : req.nhr_nh_list_size = num_components;
2031 0 : req.nhr_nh_list = calloc(num_components, sizeof(uint32_t));
2032 0 : if (!req.nhr_nh_list) {
2033 0 : ret = -ENOMEM;
2034 0 : goto fail;
2035 : }
2036 :
2037 0 : req.nhr_label_list = calloc(num_components, sizeof(uint32_t));
2038 0 : if (!req.nhr_label_list) {
2039 0 : ret = -ENOMEM;
2040 0 : goto fail;
2041 : }
2042 :
2043 0 : req.nhr_label_list_size = num_components;
2044 0 : for (i = 0; i < num_components; i++) {
2045 0 : req.nhr_nh_list[i] = component_nh_indices[i];
2046 0 : req.nhr_label_list[i] = component_labels[i];
2047 : }
2048 :
2049 :
2050 0 : req.nhr_family = family;
2051 :
2052 0 : ret = vr_sendmsg(cl, &req, "vr_nexthop_req");
2053 0 : fail:
2054 0 : if (req.nhr_nh_list) {
2055 0 : free(req.nhr_nh_list);
2056 0 : req.nhr_nh_list = NULL;
2057 : }
2058 :
2059 0 : if (req.nhr_label_list) {
2060 0 : free(req.nhr_label_list);
2061 0 : req.nhr_label_list = NULL;
2062 : }
2063 :
2064 0 : return ret;
2065 : }
2066 :
2067 :
2068 : int
2069 0 : vr_send_nexthop_encap_tunnel_add(struct nl_client *cl, unsigned int router_id,
2070 : unsigned int type, int nh_index, unsigned int flags, int vrf_index,
2071 : int *vif_index, int8_t smac[][6], int8_t dmac[][6], struct in_addr sip,
2072 : struct in_addr dip, int sport, int dport, int8_t *l3_vxlan_mac, int family,
2073 : int count)
2074 : {
2075 : vr_nexthop_req req;
2076 : int i;
2077 :
2078 0 : memset(&req, 0, sizeof(req));
2079 :
2080 0 : req.h_op = SANDESH_OP_ADD;
2081 0 : req.nhr_rid = router_id;
2082 0 : req.nhr_vrf = vrf_index;
2083 0 : req.nhr_id = nh_index;
2084 0 : req.nhr_flags = flags;
2085 0 : req.nhr_type = type;
2086 0 : if (req.nhr_flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP) {
2087 0 : req.nhr_encap_oif_id_size = VR_MAX_PHY_INF;
2088 0 : req.nhr_encap_valid_size = VR_MAX_PHY_INF;
2089 0 : req.nhr_encap_valid = malloc(req.nhr_encap_valid_size * sizeof(unsigned int));
2090 : } else {
2091 0 : req.nhr_encap_oif_id_size = 1;
2092 0 : req.nhr_encap_valid_size = 0;
2093 0 : req.nhr_encap_valid = NULL;
2094 : }
2095 0 : req.nhr_encap_oif_id = malloc(req.nhr_encap_oif_id_size * sizeof(unsigned int));
2096 0 : if (flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP) {
2097 0 : for (i = 0; i < VR_MAX_PHY_INF; i++) {
2098 0 : if (vif_index[i] < 0)
2099 0 : req.nhr_encap_valid[i] = 0;
2100 : else
2101 0 : req.nhr_encap_valid[i] = 1;
2102 0 : req.nhr_encap_oif_id[i] = vif_index[i];
2103 : }
2104 : }
2105 : else
2106 0 : req.nhr_encap_oif_id[0] = vif_index[0];
2107 0 : if (count)
2108 0 : req.nhr_encap_len = 14;
2109 0 : req.nhr_encap_size = 14 * count;
2110 0 : req.nhr_encap = malloc(req.nhr_encap_size);
2111 0 : if (!req.nhr_encap)
2112 0 : return -ENOMEM;
2113 0 : for (i = 0; i < count; i++) {
2114 0 : memcpy(req.nhr_encap + i*14, dmac, 6);
2115 0 : memcpy(req.nhr_encap + i*14 + 6, smac, 6);
2116 0 : *(uint16_t *)(&req.nhr_encap[12 + i*14]) = htons(0x0800);
2117 : }
2118 :
2119 : #if defined(__linux__)
2120 0 : req.nhr_encap_family = ETH_P_ARP;
2121 : #endif
2122 :
2123 0 : if (type == NH_TUNNEL) {
2124 0 : req.nhr_tun_sip = sip.s_addr;
2125 0 : req.nhr_tun_dip = dip.s_addr;
2126 0 : if ((sport >= 0) && (dport >= 0)) {
2127 0 : req.nhr_tun_sport = htons(sport);
2128 0 : req.nhr_tun_dport = htons(dport);
2129 : }
2130 0 : if (flags & NH_FLAG_L3_VXLAN) {
2131 0 : req.nhr_rw_dst_mac_size = 6;
2132 0 : req.nhr_rw_dst_mac = malloc(req.nhr_rw_dst_mac_size);
2133 0 : memcpy(req.nhr_rw_dst_mac, l3_vxlan_mac, 6);
2134 : }
2135 : }
2136 :
2137 0 : if (type == NH_ENCAP)
2138 0 : req.nhr_family = family;
2139 :
2140 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
2141 : }
2142 :
2143 : int
2144 0 : vr_send_nexthop_add(struct nl_client *cl, unsigned int router_id,
2145 : unsigned int type, int nh_index, unsigned int flags, int vrf_index,
2146 : int *vif_index, int family)
2147 : {
2148 : vr_nexthop_req req;
2149 :
2150 0 : memset(&req, 0, sizeof(req));
2151 :
2152 0 : req.h_op = SANDESH_OP_ADD;
2153 0 : req.nhr_rid = router_id;
2154 0 : req.nhr_vrf = vrf_index;
2155 0 : req.nhr_id = nh_index;
2156 0 : req.nhr_flags = flags;
2157 0 : req.nhr_type = type;
2158 0 : req.nhr_family = family;
2159 0 : req.nhr_encap_oif_id_size = 1;
2160 0 : req.nhr_encap_valid_size = 0;
2161 0 : req.nhr_encap_valid = NULL;
2162 0 : req.nhr_encap_oif_id = malloc(req.nhr_encap_oif_id_size * sizeof(unsigned int));
2163 0 : req.nhr_encap_len = 14;
2164 0 : req.nhr_encap_oif_id[0] = vif_index[0];
2165 :
2166 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
2167 : }
2168 :
2169 : void
2170 20 : vr_route_req_destroy(vr_route_req *req)
2171 : {
2172 20 : if (!req)
2173 10 : return;
2174 :
2175 10 : if (req->rtr_prefix_size && req->rtr_prefix) {
2176 0 : free(req->rtr_prefix);
2177 0 : req->rtr_prefix = NULL;
2178 0 : req->rtr_prefix_size = 0;
2179 : }
2180 :
2181 10 : if (req->rtr_mac_size && req->rtr_mac) {
2182 0 : free(req->rtr_mac);
2183 0 : req->rtr_mac = NULL;
2184 0 : req->rtr_mac_size = 0;
2185 : }
2186 :
2187 10 : free(req);
2188 10 : return;
2189 : }
2190 :
2191 : void
2192 10 : address_mask(uint8_t *addr, uint8_t plen, unsigned int family)
2193 : {
2194 : int i;
2195 : uint8_t address_bits;
2196 : uint8_t mask[VR_IP6_ADDRESS_LEN];
2197 :
2198 10 : if (family == AF_INET) {
2199 10 : address_bits = VR_IP_ADDRESS_LEN * 8;
2200 : } else {
2201 0 : address_bits = VR_IP6_ADDRESS_LEN * 8;
2202 : }
2203 :
2204 10 : memset(mask, 0xFF, sizeof(mask));
2205 74 : for (i = address_bits - 1; i >= plen; i--) {
2206 64 : mask[i / 8] ^= (1 << (7 - (i % 8)));
2207 : }
2208 :
2209 50 : for (i = 0; i < (address_bits / 8); i++) {
2210 40 : addr[i] &= mask[i];
2211 : }
2212 :
2213 10 : return;
2214 : }
2215 :
2216 : vr_route_req *
2217 10 : vr_route_req_get_copy(vr_route_req *src)
2218 : {
2219 : vr_route_req *dst;
2220 :
2221 10 : dst = malloc(sizeof(*dst));
2222 10 : if (!dst)
2223 0 : return NULL;
2224 :
2225 10 : *dst = *src;
2226 :
2227 10 : dst->rtr_prefix_size = 0;
2228 10 : dst->rtr_prefix = NULL;
2229 :
2230 10 : dst->rtr_marker_size = 0;
2231 10 : dst->rtr_marker = NULL;
2232 :
2233 10 : dst->rtr_mac_size = 0;
2234 10 : dst->rtr_mac = NULL;
2235 :
2236 10 : if (src->rtr_prefix_size && src->rtr_prefix) {
2237 10 : dst->rtr_prefix = malloc(src->rtr_prefix_size);
2238 10 : if (!dst->rtr_prefix)
2239 0 : goto free_rtr_req;
2240 10 : memcpy(dst->rtr_prefix, src->rtr_prefix, src->rtr_prefix_size);
2241 : }
2242 :
2243 10 : if (src->rtr_mac_size && src->rtr_mac) {
2244 6 : dst->rtr_mac = malloc(src->rtr_mac_size);
2245 6 : if (!dst->rtr_mac)
2246 0 : goto free_rtr_req;
2247 6 : memcpy(dst->rtr_mac, src->rtr_mac, src->rtr_mac_size);
2248 : }
2249 :
2250 10 : return dst;
2251 :
2252 0 : free_rtr_req:
2253 0 : vr_route_req_destroy(dst);
2254 0 : return NULL;
2255 : }
2256 :
2257 : int
2258 0 : vr_send_route_dump(struct nl_client *cl, unsigned int router_id, unsigned int vrf,
2259 : unsigned int family, uint8_t *marker)
2260 : {
2261 : vr_route_req req;
2262 :
2263 0 : memset(&req, 0, sizeof(req));
2264 0 : req.h_op = SANDESH_OP_DUMP;
2265 0 : req.rtr_rid = router_id;
2266 0 : req.rtr_vrf_id = vrf;
2267 0 : req.rtr_family = family;
2268 :
2269 0 : if (family == AF_BRIDGE) {
2270 0 : req.rtr_mac = marker;
2271 0 : req.rtr_mac_size = VR_ETHER_ALEN;
2272 : } else {
2273 0 : req.rtr_prefix = marker;
2274 0 : req.rtr_prefix_size = RT_IP_ADDR_SIZE(family);
2275 0 : req.rtr_marker = marker;
2276 0 : req.rtr_marker_size = RT_IP_ADDR_SIZE(family);
2277 : }
2278 :
2279 0 : return vr_sendmsg(cl, &req, "vr_route_req");
2280 : }
2281 :
2282 : static int
2283 10 : vr_send_route_common(struct nl_client *cl, unsigned int op,
2284 : unsigned int router_id, unsigned int vrf, unsigned int family,
2285 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2286 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2287 : {
2288 : vr_route_req req;
2289 :
2290 10 : memset(&req, 0, sizeof(req));
2291 10 : req.h_op = op;
2292 10 : req.rtr_rid = router_id;
2293 10 : req.rtr_vrf_id = vrf;
2294 10 : req.rtr_family = family;
2295 :
2296 10 : if ((family == AF_INET) || (family == AF_INET6)) {
2297 10 : req.rtr_prefix = prefix;
2298 10 : req.rtr_prefix_size = RT_IP_ADDR_SIZE(family);
2299 10 : req.rtr_prefix_len = prefix_len;
2300 0 : } else if (family == AF_BRIDGE) {
2301 0 : req.rtr_index = VR_BE_INVALID_INDEX;
2302 : }
2303 :
2304 10 : if (mac) {
2305 10 : req.rtr_mac = mac;
2306 10 : req.rtr_mac_size = VR_ETHER_ALEN;
2307 : }
2308 :
2309 10 : req.rtr_replace_plen = replace_len;
2310 10 : req.rtr_label_flags = flags;
2311 10 : req.rtr_label = label;
2312 10 : if (label != -1)
2313 10 : req.rtr_label_flags |= VR_RT_LABEL_VALID_FLAG;
2314 :
2315 10 : req.rtr_nh_id = nh_index;
2316 :
2317 10 : return vr_sendmsg(cl, &req, "vr_route_req");
2318 : }
2319 :
2320 : int
2321 10 : vr_send_route_get(struct nl_client *cl,
2322 : unsigned int router_id, unsigned int vrf, unsigned int family,
2323 : uint8_t *prefix, unsigned int prefix_len, uint8_t *mac)
2324 : {
2325 10 : return vr_send_route_common(cl, SANDESH_OP_GET, router_id, vrf,
2326 : family, prefix, prefix_len, 0, 0, mac, 0, 0);
2327 : }
2328 :
2329 : int
2330 0 : vr_send_route_delete(struct nl_client *cl,
2331 : unsigned int router_id, unsigned int vrf, unsigned int family,
2332 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2333 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2334 : {
2335 0 : return vr_send_route_common(cl, SANDESH_OP_DEL, router_id, vrf,
2336 : family, prefix, prefix_len, nh_index, label,
2337 : mac, replace_len, flags);
2338 : }
2339 :
2340 : int
2341 0 : vr_send_route_add(struct nl_client *cl,
2342 : unsigned int router_id, unsigned int vrf, unsigned int family,
2343 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2344 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2345 : {
2346 0 : return vr_send_route_common(cl, SANDESH_OP_ADD, router_id, vrf,
2347 : family, prefix, prefix_len, nh_index, label,
2348 : mac, replace_len,flags);
2349 : }
2350 :
2351 : /* vrf assign start */
2352 : int
2353 0 : vr_send_vrf_assign_dump(struct nl_client *cl, unsigned int router_id,
2354 : unsigned int vif_index, int marker)
2355 : {
2356 : vr_vrf_assign_req req;
2357 :
2358 0 : memset(&req, 0, sizeof(req));
2359 0 : req.h_op = SANDESH_OP_DUMP;
2360 0 : req.var_rid = router_id;
2361 0 : req.var_vif_index = vif_index;
2362 0 : req.var_marker = marker;
2363 :
2364 0 : return vr_sendmsg(cl, &req, "vr_vrf_assign_req");
2365 : }
2366 :
2367 : int
2368 0 : vr_send_vrf_assign_set(struct nl_client *cl, unsigned int router_id,
2369 : unsigned int vif_index, unsigned int vlan_id, unsigned int vrf_id)
2370 : {
2371 :
2372 : vr_vrf_assign_req req;
2373 :
2374 0 : memset(&req, 0, sizeof(req));
2375 0 : req.h_op = SANDESH_OP_ADD;
2376 0 : req.var_rid = router_id;
2377 0 : req.var_vif_index = vif_index;
2378 0 : req.var_vif_vrf = vrf_id;
2379 0 : req.var_vlan_id = vlan_id;
2380 :
2381 0 : return vr_sendmsg(cl, &req, "vr_vrf_assign_req");
2382 : }
2383 : /* vrf assign end */
2384 :
2385 : int
2386 0 : vr_send_vrf_stats_dump(struct nl_client *cl, unsigned int router_id, int marker)
2387 : {
2388 : vr_vrf_stats_req req;
2389 :
2390 0 : memset(&req, 0, sizeof(req));
2391 0 : req.h_op = SANDESH_OP_DUMP;
2392 0 : req.vsr_rid = router_id;
2393 0 : req.vsr_marker = marker;
2394 0 : req.vsr_family = AF_INET;
2395 :
2396 0 : return vr_sendmsg(cl, &req, "vr_vrf_stats_req");
2397 : }
2398 :
2399 : int
2400 0 : vr_send_vrf_stats_get(struct nl_client *cl, unsigned int router_id,
2401 : unsigned int vrf)
2402 : {
2403 : vr_vrf_stats_req req;
2404 :
2405 0 : memset(&req, 0, sizeof(req));
2406 0 : req.h_op = SANDESH_OP_GET;
2407 0 : req.vsr_rid = router_id;
2408 0 : req.vsr_vrf = vrf;
2409 0 : req.vsr_family = AF_INET;
2410 :
2411 0 : return vr_sendmsg(cl, &req, "vr_vrf_stats_req");
2412 : }
2413 :
2414 : int
2415 0 : vr_send_vrouter_get(struct nl_client *cl, unsigned int router_id)
2416 : {
2417 : vrouter_ops req;
2418 :
2419 0 : memset(&req, 0, sizeof(req));
2420 0 : req.h_op = SANDESH_OP_GET;
2421 :
2422 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2423 : }
2424 :
2425 : int
2426 0 : vr_send_vrouter_set_logging(struct nl_client *cl, unsigned int router_id,
2427 : unsigned int log_level, unsigned int *e_log_types, unsigned int e_size,
2428 : unsigned int *d_log_types, unsigned int d_size)
2429 : {
2430 : vrouter_ops req;
2431 :
2432 0 : memset(&req, 0, sizeof(req));
2433 0 : req.h_op = SANDESH_OP_ADD;
2434 :
2435 0 : if (log_level > 0)
2436 0 : req.vo_log_level = log_level;
2437 :
2438 0 : if (e_log_types && e_size) {
2439 0 : req.vo_log_type_enable_size = e_size;
2440 0 : req.vo_log_type_enable = e_log_types;
2441 : }
2442 :
2443 0 : if (d_log_types && d_size) {
2444 0 : req.vo_log_type_disable_size = d_size;
2445 0 : req.vo_log_type_disable = d_log_types;
2446 : }
2447 :
2448 : /*
2449 : * We create request to change logging options only. As we do not change
2450 : * vRouter's runtime parameters here, they need to be set to a meaningless
2451 : * value. They cannot be left zeroed, because 0 means 'feature turned off'.
2452 : */
2453 0 : req.vo_perfr = -1;
2454 0 : req.vo_perfs = -1;
2455 0 : req.vo_from_vm_mss_adj = -1;
2456 0 : req.vo_to_vm_mss_adj = -1;
2457 0 : req.vo_perfr1 = -1;
2458 0 : req.vo_perfr2 = -1;
2459 0 : req.vo_perfr3 = -1;
2460 0 : req.vo_perfp = -1;
2461 0 : req.vo_perfq1 = -1;
2462 0 : req.vo_perfq2 = -1;
2463 0 : req.vo_perfq3 = -1;
2464 0 : req.vo_udp_coff = -1;
2465 0 : req.vo_flow_hold_limit = -1;
2466 0 : req.vo_mudp = -1;
2467 0 : req.vo_packet_dump = -1;
2468 :
2469 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2470 : }
2471 :
2472 : int
2473 0 : vr_send_vrouter_set_runtime_opts(struct nl_client *cl, unsigned int router_id,
2474 : int perfr, int perfs, int from_vm_mss_adj, int to_vm_mss_adj,
2475 : int perfr1, int perfr2, int perfr3, int perfp, int perfq1,
2476 : int perfq2, int perfq3, int udp_coff, int flow_hold_limit,
2477 : int mudp, int btokens, int binterval, int bstep,
2478 : unsigned int priority_tagging, int packet_dump)
2479 : {
2480 : vrouter_ops req;
2481 :
2482 0 : memset(&req, 0, sizeof(req));
2483 0 : req.h_op = SANDESH_OP_ADD;
2484 :
2485 : /*
2486 : * vRouter runtime options. Adjustable by sysctl as well.
2487 : *
2488 : * No real validation is required, as sysctl does not perform any.
2489 : * Variables are only tested to be -1 ('do not change'),
2490 : * 0 ('feature turned off'), or non-zero ('feature turned on').
2491 : */
2492 0 : req.vo_perfr = perfr;
2493 0 : req.vo_perfs = perfs;
2494 0 : req.vo_from_vm_mss_adj = from_vm_mss_adj;
2495 0 : req.vo_to_vm_mss_adj = to_vm_mss_adj;
2496 0 : req.vo_perfr1 = perfr1;
2497 0 : req.vo_perfr2 = perfr2;
2498 0 : req.vo_perfr3 = perfr3;
2499 0 : req.vo_perfp = perfp;
2500 0 : req.vo_perfq1 = perfq1;
2501 0 : req.vo_perfq2 = perfq2;
2502 0 : req.vo_perfq3 = perfq3;
2503 0 : req.vo_udp_coff = udp_coff;
2504 0 : req.vo_flow_hold_limit = flow_hold_limit;
2505 0 : req.vo_mudp = mudp;
2506 0 : req.vo_burst_tokens = btokens;
2507 0 : req.vo_burst_interval = binterval;
2508 0 : req.vo_burst_step = bstep;
2509 0 : req.vo_priority_tagging = priority_tagging;
2510 0 : req.vo_packet_dump = packet_dump;
2511 :
2512 : /*
2513 : * We create request to change runtime (sysctl) options only. Log level
2514 : * fields can be left zeroed, because only non-zero values are meaningful
2515 : * in this case.
2516 : */
2517 :
2518 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2519 : }
2520 :
2521 : int
2522 0 : vr_send_vxlan_delete(struct nl_client *cl, unsigned int router_id,
2523 : unsigned int vnid)
2524 : {
2525 : vr_vxlan_req req;
2526 :
2527 0 : memset(&req, 0, sizeof(req));
2528 0 : req.h_op = SANDESH_OP_DEL;
2529 0 : req.vxlanr_vnid = vnid;
2530 :
2531 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2532 : }
2533 :
2534 : int
2535 0 : vr_send_vxlan_dump(struct nl_client *cl, unsigned int router_id,
2536 : int marker)
2537 : {
2538 : vr_vxlan_req req;
2539 :
2540 0 : memset(&req, 0, sizeof(req));
2541 0 : req.h_op = SANDESH_OP_DUMP;
2542 0 : req.vxlanr_vnid = marker;
2543 :
2544 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2545 : }
2546 :
2547 : int
2548 0 : vr_send_vxlan_get(struct nl_client *cl, unsigned int router_id,
2549 : unsigned int vnid)
2550 : {
2551 : vr_vxlan_req req;
2552 :
2553 0 : memset(&req, 0, sizeof(req));
2554 0 : req.h_op = SANDESH_OP_GET;
2555 0 : req.vxlanr_vnid = vnid;
2556 :
2557 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2558 : }
2559 :
2560 : int
2561 0 : vr_send_vxlan_add(struct nl_client *cl, unsigned int router_id,
2562 : unsigned int vnid, unsigned int nh_index)
2563 : {
2564 : vr_vxlan_req req;
2565 :
2566 0 : memset(&req, 0, sizeof(req));
2567 0 : req.h_op = SANDESH_OP_ADD;
2568 0 : req.vxlanr_vnid = vnid;
2569 0 : req.vxlanr_nhid = nh_index;
2570 :
2571 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2572 : }
2573 :
2574 : int
2575 0 : vr_send_fc_map_get(struct nl_client *cl, unsigned int router_id,
2576 : uint8_t fc_map_id)
2577 : {
2578 : vr_fc_map_req req;
2579 0 : int16_t id = fc_map_id;
2580 :
2581 0 : memset(&req, 0, sizeof(req));
2582 0 : req.h_op = SANDESH_OP_GET;
2583 0 : req.fmr_rid = router_id;
2584 0 : req.fmr_id = &id;
2585 0 : req.fmr_id_size = 1;
2586 :
2587 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2588 : }
2589 :
2590 : int
2591 0 : vr_send_fc_map_dump(struct nl_client *cl, unsigned int router_id,
2592 : int marker)
2593 : {
2594 : vr_fc_map_req req;
2595 :
2596 0 : memset(&req, 0, sizeof(req));
2597 0 : req.h_op = SANDESH_OP_DUMP;
2598 0 : req.fmr_rid = router_id;
2599 0 : req.fmr_marker = marker;
2600 :
2601 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2602 : }
2603 :
2604 : int
2605 0 : vr_send_fc_map_delete(struct nl_client *cl, unsigned int router_id,
2606 : uint8_t fc_id)
2607 : {
2608 : vr_fc_map_req req;
2609 0 : int16_t id = fc_id;
2610 :
2611 0 : memset(&req, 0, sizeof(req));
2612 0 : req.h_op = SANDESH_OP_DEL;
2613 0 : req.fmr_rid = router_id;
2614 0 : req.fmr_id = &id;
2615 0 : req.fmr_id_size = 1;
2616 :
2617 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2618 : }
2619 :
2620 : int
2621 0 : vr_send_fc_map_add(struct nl_client *cl, unsigned int router_id,
2622 : int16_t *fc_id, uint8_t fc_id_size,
2623 : uint8_t *dscp, uint8_t *mpls_qos, uint8_t *dotonep, uint8_t *queue)
2624 : {
2625 : vr_fc_map_req req;
2626 :
2627 0 : memset(&req, 0, sizeof(req));
2628 0 : req.fmr_rid = router_id;
2629 :
2630 0 : req.fmr_id = fc_id;
2631 0 : req.fmr_id_size = fc_id_size;
2632 0 : req.fmr_dscp = dscp;
2633 0 : req.fmr_dscp_size = fc_id_size;
2634 0 : req.fmr_mpls_qos = mpls_qos;
2635 0 : req.fmr_mpls_qos_size = fc_id_size;
2636 0 : req.fmr_dotonep = dotonep;
2637 0 : req.fmr_dotonep_size = fc_id_size;
2638 0 : req.fmr_queue_id = queue;
2639 0 : req.fmr_queue_id_size = fc_id_size;
2640 :
2641 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2642 : }
2643 :
2644 : int
2645 0 : vr_send_qos_map_get(struct nl_client *cl, unsigned int router_id,
2646 : unsigned int qos_map_id)
2647 : {
2648 : vr_qos_map_req req;
2649 :
2650 0 : memset(&req, 0, sizeof(req));
2651 0 : req.h_op = SANDESH_OP_GET;
2652 0 : req.qmr_rid = router_id;
2653 0 : req.qmr_id = qos_map_id;
2654 :
2655 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2656 : }
2657 :
2658 :
2659 : int
2660 0 : vr_send_qos_map_dump(struct nl_client *cl, unsigned int router_id,
2661 : int marker)
2662 : {
2663 : vr_qos_map_req req;
2664 :
2665 0 : memset(&req, 0, sizeof(req));
2666 0 : req.h_op = SANDESH_OP_DUMP;
2667 0 : req.qmr_rid = router_id;
2668 0 : req.qmr_marker = marker;
2669 :
2670 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2671 : }
2672 :
2673 : int
2674 0 : vr_send_qos_map_delete(struct nl_client *cl, unsigned int router_id,
2675 : unsigned int qos_map_id)
2676 : {
2677 : vr_qos_map_req req;
2678 :
2679 0 : memset(&req, 0, sizeof(req));
2680 0 : req.h_op = SANDESH_OP_DEL;
2681 0 : req.qmr_rid = router_id;
2682 0 : req.qmr_id = qos_map_id;
2683 :
2684 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2685 : }
2686 :
2687 : int
2688 0 : vr_send_qos_map_add(struct nl_client *cl, unsigned int router_id,
2689 : unsigned int qos_id,
2690 : uint8_t *dscp, uint8_t num_dscp, uint8_t *dscp_fc_id,
2691 : uint8_t *mpls_qos, uint8_t num_mpls_qos, uint8_t *mpls_qos_fc_id,
2692 : uint8_t *dotonep, uint8_t num_dotonep, uint8_t *dotonep_fc_id)
2693 : {
2694 : vr_qos_map_req req;
2695 :
2696 0 : memset(&req, 0, sizeof(req));
2697 0 : req.h_op = SANDESH_OP_ADD;
2698 0 : req.qmr_rid = router_id;
2699 0 : req.qmr_id = qos_id;
2700 :
2701 0 : if (num_dscp) {
2702 0 : req.qmr_dscp = dscp;
2703 0 : req.qmr_dscp_size = num_dscp;
2704 0 : req.qmr_dscp_fc_id = dscp_fc_id;
2705 0 : req.qmr_dscp_fc_id_size = num_dscp;
2706 : }
2707 :
2708 0 : if (num_mpls_qos) {
2709 0 : req.qmr_mpls_qos = mpls_qos;
2710 0 : req.qmr_mpls_qos_size = num_mpls_qos;
2711 0 : req.qmr_mpls_qos_fc_id = mpls_qos_fc_id;
2712 0 : req.qmr_mpls_qos_fc_id_size = num_mpls_qos;
2713 : }
2714 :
2715 0 : if (num_dotonep) {
2716 0 : req.qmr_dotonep = dotonep;
2717 0 : req.qmr_dotonep_size = num_dotonep;
2718 0 : req.qmr_dotonep_fc_id = dotonep_fc_id;
2719 0 : req.qmr_dotonep_fc_id_size = num_dotonep;
2720 : }
2721 :
2722 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2723 : }
2724 :
2725 : int
2726 0 : vr_send_ddp_req(struct nl_client *cl, vr_info_msg_en msginfo, uint8_t *vr_info_inbuf)
2727 : {
2728 : vr_info_req req;
2729 :
2730 0 : memset(&req, 0, sizeof(req));
2731 :
2732 0 : req.h_op = SANDESH_OP_DUMP;
2733 0 : req.vdu_msginfo = msginfo;
2734 :
2735 0 : if (vr_info_inbuf != NULL) {
2736 0 : req.vdu_inbuf_size = strlen(vr_info_inbuf);
2737 0 : req.vdu_inbuf = vr_info_inbuf;
2738 : }
2739 0 : return vr_sendmsg(cl, &req, "vr_info_req");
2740 : }
|