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