Line data Source code
1 : /* 2 : * vt_message.c -- the messaging module 3 : * 4 : * Copyright (c) 2015, Juniper Networks, Inc. 5 : * All rights reserved 6 : */ 7 : #include <string.h> 8 : #include <stdbool.h> 9 : #include <limits.h> 10 : 11 : #include <libxml/xmlmemory.h> 12 : #include <libxml/parser.h> 13 : 14 : #include <vtest.h> 15 : #include <vt_message.h> 16 : 17 : #include <vt_gen_message_modules.h> 18 : #include <vr_types.h> 19 : #include <vt_gen_lib.h> 20 : 21 : #include <vr_message.h> 22 : #include <vr_packet.h> 23 : #include <vr_interface.h> 24 : 25 : #include <net/if.h> 26 : #include <nl_util.h> 27 : 28 : extern struct vt_message_module vt_message_modules[]; 29 : extern unsigned int vt_message_modules_num; 30 : 31 : int 32 0 : vt_expect_node(xmlNodePtr node, struct vtest *test) 33 : { 34 : unsigned int i; 35 : bool result; 36 : 37 0 : if (!test || !node){ 38 0 : return E_MESSAGE_ERR_FARG ; 39 : } 40 0 : void *buf = test->messages.received_vrouter_msg->mem_handles[test->messages.received_vrouter_msg->ptr_num].mem; 41 : 42 0 : if (!buf) { 43 0 : return E_MESSAGE_ERR; 44 : } 45 0 : node = node->xmlChildrenNode; 46 0 : while (node) { 47 0 : for (i = 0; i < vt_message_modules_num; i++) { 48 0 : if (!strncmp(node->name, vt_message_modules[i].vmm_name, 49 0 : strlen(vt_message_modules[i].vmm_name))) { 50 0 : result = vt_message_modules[i].vmm_expect(node, test, buf); 51 0 : test->messages.data[test->message_ptr_num].return_from_expected = result; 52 0 : break; 53 : } 54 : } 55 0 : node = node->next; 56 : } 57 : 58 0 : return E_MESSAGE_OK; 59 : } 60 : 61 : void * 62 0 : vt_return_node(xmlNodePtr node, struct vtest *test) 63 : { 64 : 65 0 : if (!node || !node->children || !node->children->content ) { 66 0 : return NULL; 67 : } 68 0 : test->messages.data[test->message_ptr_num].xml_data.return_value = 69 0 : (strtoul(node->children->content, NULL, 0)); 70 0 : test->messages.data[test->message_ptr_num].xml_data.is_element_return = true; 71 : 72 0 : return NULL; 73 : } 74 : 75 : 76 : int 77 2794 : search_message_modules_by_name(const char *vmm_name) { 78 : 79 : // -1 = not found 80 2794 : int ret = -1; 81 2794 : size_t i = 0; 82 : 83 2794 : if (!vmm_name) { 84 0 : return -2; 85 : } 86 : 87 9340 : for (i = 0; i < vt_message_modules_num; i++) { 88 9340 : if (!strncmp(vmm_name, vt_message_modules[i].vmm_name, 89 9340 : strlen(vt_message_modules[i].vmm_name) + 1)) { 90 2794 : return (int)i; 91 : } 92 : } 93 0 : return ret; 94 : } 95 : 96 : 97 : int 98 2794 : vt_message(xmlNodePtr node, struct vtest *test) 99 : { 100 : void *buf; 101 2794 : node = node->xmlChildrenNode; 102 2794 : int message_modules_element_key = -1; 103 : int i; 104 : 105 2794 : if (!node || !test) { 106 0 : return E_MESSAGE_ERR_FARG; 107 : } 108 : 109 11176 : while (node) { 110 : 111 8382 : if (node->type != XML_ELEMENT_NODE) { 112 5588 : node = node->next; 113 5588 : continue; 114 : } 115 : 116 : //Save the pointer to the expected node if presents in XML, 117 : //Because we need first send a message, after it, we can call vt_expect node 118 2794 : if (!strncmp(node->name, "expect", sizeof("expect"))) { 119 0 : test->messages.data[test->message_ptr_num].xml_data.is_element_expect = true; 120 0 : test->messages.data[test->message_ptr_num].xml_data.element_expect_ptr = (uint64_t *) node; 121 0 : node = node->next; 122 0 : continue; 123 : } 124 : 125 2794 : message_modules_element_key = search_message_modules_by_name(node->name); 126 2794 : if (!(message_modules_element_key >= 0)) { 127 0 : return E_MESSAGE_ERR_MESSAGE_MODULES; 128 : } 129 : 130 : /* If it is a flow, we decide if multiple flows we want to insert */ 131 2794 : if (!strncmp(node->name, "vr_flow_req", sizeof("vr_flow_req"))) { 132 : 133 644 : for (i = 0; i < test->flow_count && i <= VT_MAX_FLOW; i++) { 134 322 : buf = vt_message_modules[message_modules_element_key].vmm_node(node, test); 135 322 : if (!buf && vt_message_modules[message_modules_element_key].vmm_size) { 136 0 : return E_MESSAGE_ERR_UNK; 137 : 138 322 : } else if (buf) { 139 322 : vr_flow_req *req = (vr_flow_req *)buf; 140 322 : uint64_t temp = ntohll(req->fr_flow_sip_l); 141 322 : temp += i; 142 322 : req->fr_flow_sip_l = htonll(temp); 143 322 : test->message_ptr_num++; 144 322 : test->messages.data[test->message_ptr_num].mem = buf; 145 322 : test->messages.data[test->message_ptr_num].type = 146 322 : (vt_message_modules[message_modules_element_key].vmm_name); 147 : } 148 : } 149 322 : test->message_ptr_start++; 150 322 : node = node->next; 151 322 : continue; 152 : } 153 : 154 2472 : buf = vt_message_modules[message_modules_element_key].vmm_node(node, test); 155 2472 : if (!buf && vt_message_modules[message_modules_element_key].vmm_size) { 156 0 : return E_MESSAGE_ERR_UNK; 157 : 158 2472 : } else if (buf) { 159 2472 : test->message_ptr_num++; 160 2472 : test->message_ptr_start++; 161 2472 : test->messages.data[test->message_ptr_num].mem = buf; 162 2472 : test->messages.data[test->message_ptr_num].type = 163 2472 : (vt_message_modules[message_modules_element_key].vmm_name); 164 : } 165 : 166 2472 : node = node->next; 167 : } 168 : 169 2794 : return E_MESSAGE_OK; 170 : 171 : } 172 :