2 * Copyright (c) 2015 Avaya, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 #define ETH_TYPE_LLDP 0x88cc
28 /* Dummy MAC addresses */
29 char chassis_mac[ETHER_ADDR_LEN] = { 0x5e, 0x10, 0x8e, 0xe7, 0x84, 0xad };
30 uint8_t eth_src[ETHER_ADDR_LEN] = { 0x5e, 0x10, 0x8e, 0xe7, 0x84, 0xad };
32 /* LLDP multicast address */
33 static const uint8_t eth_addr_lldp[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x0e};
35 /* Count of tests run */
40 * Helper function to validate port info
43 check_received_port(struct lldpd_port *sport,
44 struct lldpd_port *rport)
46 assert(rport->p_id_subtype == sport->p_id_subtype);
47 assert(rport->p_id_len == sport->p_id_len);
48 assert(strncmp(rport->p_id, sport->p_id, sport->p_id_len) == 0);
49 assert(strcmp(rport->p_descr, sport->p_descr) == 0);
56 * Helper function to validate chassis info
59 check_received_chassis(struct lldpd_chassis *schassis,
60 struct lldpd_chassis *rchassis)
62 assert(rchassis->c_id_subtype == schassis->c_id_subtype);
63 assert(rchassis->c_id_len == schassis->c_id_len);
64 assert(strncmp(rchassis->c_id, schassis->c_id, schassis->c_id_len) == 0);
65 assert(strcmp(rchassis->c_name, schassis->c_name) == 0);
66 assert(strcmp(rchassis->c_descr, schassis->c_descr) == 0);
67 assert(rchassis->c_cap_available == schassis->c_cap_available);
68 assert(rchassis->c_cap_enabled == schassis->c_cap_enabled);
75 * Helper function to validate auto-attach info
78 check_received_aa(struct lldpd_port *sport,
79 struct lldpd_port *rport,
80 struct lldpd_aa_isid_vlan_maps_tlv *smap)
82 struct lldpd_aa_isid_vlan_maps_tlv *received_map;
85 assert(rport->p_element.type == sport->p_element.type);
86 assert(rport->p_element.mgmt_vlan == sport->p_element.mgmt_vlan);
87 assert(rport->p_element.system_id.system_mac[0] ==
88 sport->p_element.system_id.system_mac[0]);
89 assert(rport->p_element.system_id.system_mac[1] ==
90 sport->p_element.system_id.system_mac[1]);
91 assert(rport->p_element.system_id.system_mac[2] ==
92 sport->p_element.system_id.system_mac[2]);
93 assert(rport->p_element.system_id.system_mac[3] ==
94 sport->p_element.system_id.system_mac[3]);
95 assert(rport->p_element.system_id.system_mac[4] ==
96 sport->p_element.system_id.system_mac[4]);
97 assert(rport->p_element.system_id.system_mac[5] ==
98 sport->p_element.system_id.system_mac[5]);
99 assert(rport->p_element.system_id.conn_type ==
100 sport->p_element.system_id.conn_type);
101 assert(rport->p_element.system_id.smlt_id ==
102 sport->p_element.system_id.smlt_id);
103 assert(rport->p_element.system_id.mlt_id[0] ==
104 sport->p_element.system_id.mlt_id[0]);
105 assert(rport->p_element.system_id.mlt_id[1] ==
106 sport->p_element.system_id.mlt_id[1]);
108 /* Should receive 2 mappings */
109 assert(!list_is_empty(&rport->p_isid_vlan_maps.m_entries));
111 /* For each received isid/vlan mapping */
112 LIST_FOR_EACH (received_map, m_entries,
113 &rport->p_isid_vlan_maps.m_entries) {
115 /* Validate against mapping sent */
116 assert(smap[i].isid_vlan_data.status ==
117 received_map->isid_vlan_data.status);
118 assert(smap[i].isid_vlan_data.vlan ==
119 received_map->isid_vlan_data.vlan);
120 assert(smap[i].isid_vlan_data.isid[0] ==
121 received_map->isid_vlan_data.isid[0]);
122 assert(smap[i].isid_vlan_data.isid[1] ==
123 received_map->isid_vlan_data.isid[1]);
124 assert(smap[i].isid_vlan_data.isid[2] ==
125 received_map->isid_vlan_data.isid[2]);
127 /* Next mapping sent */
137 * Validate basic send/receive processing
143 struct lldpd_hardware hardware;
144 struct lldpd_chassis chassis;
146 struct lldpd_chassis *nchassis = NULL;
147 struct lldpd_port *nport = NULL;
149 struct lldpd_hardware *hw = NULL;
150 struct lldpd_chassis *ch = NULL;
152 struct lldpd_aa_isid_vlan_maps_tlv map_init[2];
153 struct lldpd_aa_isid_vlan_maps_tlv map[2];
155 uint32_t stub[512 / 4];
156 struct dp_packet packet;
160 /* Prepare data used to construct and validate LLDPPDU */
161 hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
162 hardware.h_lport.p_id = "FastEthernet 1/5";
163 hardware.h_lport.p_id_len = strlen(hardware.h_lport.p_id);
164 hardware.h_lport.p_descr = "Fake port description";
165 hardware.h_lport.p_mfs = 1516;
167 /* Auto attach element discovery info */
168 hardware.h_lport.p_element.type = LLDP_TLV_AA_ELEM_TYPE_TAG_CLIENT;
169 hardware.h_lport.p_element.mgmt_vlan = 0xCDC;
170 hardware.h_lport.p_element.system_id.system_mac[0] = 0x1;
171 hardware.h_lport.p_element.system_id.system_mac[1] = 0x2;
172 hardware.h_lport.p_element.system_id.system_mac[2] = 0x3;
173 hardware.h_lport.p_element.system_id.system_mac[3] = 0x4;
174 hardware.h_lport.p_element.system_id.system_mac[4] = 0x5;
175 hardware.h_lport.p_element.system_id.system_mac[5] = 0x6;
177 hardware.h_lport.p_element.system_id.conn_type = 0x5;
178 hardware.h_lport.p_element.system_id.smlt_id = 0x3CC;
179 hardware.h_lport.p_element.system_id.mlt_id[0] = 0xB;
180 hardware.h_lport.p_element.system_id.mlt_id[1] = 0xE;
182 /* Local chassis info */
183 chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
184 chassis.c_id = chassis_mac;
185 chassis.c_id_len = ETHER_ADDR_LEN;
186 chassis.c_name = "Dummy chassis";
187 chassis.c_descr = "Long dummy chassis description";
188 chassis.c_cap_available = LLDP_CAP_BRIDGE;
189 chassis.c_cap_enabled = LLDP_CAP_BRIDGE;
191 /* ISID/VLAN mappings */
192 map_init[0].isid_vlan_data.status = 0xC;
193 map_init[0].isid_vlan_data.vlan = 0x64;
194 map_init[0].isid_vlan_data.isid[0] = 1;
195 map_init[0].isid_vlan_data.isid[1] = 2;
196 map_init[0].isid_vlan_data.isid[2] = 3;
198 map_init[1].isid_vlan_data.status = 0xD;
199 map_init[1].isid_vlan_data.vlan = 0xF;
200 map_init[1].isid_vlan_data.isid[0] = 4;
201 map_init[1].isid_vlan_data.isid[1] = 5;
202 map_init[1].isid_vlan_data.isid[2] = 6;
204 /* Prepare an empty packet buffer */
205 dp_packet_use_stub(&packet, stub, sizeof stub);
206 dp_packet_clear(&packet);
208 /* Create a dummy lldp instance */
209 lldp = lldp_create_dummy();
210 if ((lldp == NULL) ||
211 (lldp->lldpd == NULL) ||
212 (lldp->lldpd->g_hardware.h_entries.next == NULL)) {
214 printf("Error: unable to create dummy lldp instance");
218 /* Populate instance with local chassis info */
219 hw = (struct lldpd_hardware *) lldp->lldpd->g_hardware.h_entries.next;
220 ch = hw->h_lport.p_chassis;
221 ch->c_id_subtype = chassis.c_id_subtype;
222 ch->c_id = chassis.c_id;
223 ch->c_id_len = chassis.c_id_len;
224 ch->c_name = chassis.c_name;
225 ch->c_descr = chassis.c_descr;
226 ch->c_cap_available = chassis.c_cap_available;
227 ch->c_cap_enabled = chassis.c_cap_enabled;
229 /* Populate instance with local port info */
230 hw->h_lport.p_id_subtype = hardware.h_lport.p_id_subtype;
231 hw->h_lport.p_id = hardware.h_lport.p_id;
232 hw->h_lport.p_id_len = strlen(hw->h_lport.p_id);
233 hw->h_lport.p_descr = hardware.h_lport.p_descr;
234 hw->h_lport.p_mfs = hardware.h_lport.p_mfs;
236 /* Populate instance with auto attach element discovery info */
238 hw->h_lport.p_element.type = hardware.h_lport.p_element.type;
239 hw->h_lport.p_element.mgmt_vlan = hardware.h_lport.p_element.mgmt_vlan;
240 hw->h_lport.p_element.system_id.system_mac[0] =
241 hardware.h_lport.p_element.system_id.system_mac[0];
242 hw->h_lport.p_element.system_id.system_mac[1] =
243 hardware.h_lport.p_element.system_id.system_mac[1];
244 hw->h_lport.p_element.system_id.system_mac[2] =
245 hardware.h_lport.p_element.system_id.system_mac[2];
246 hw->h_lport.p_element.system_id.system_mac[3] =
247 hardware.h_lport.p_element.system_id.system_mac[3];
248 hw->h_lport.p_element.system_id.system_mac[4] =
249 hardware.h_lport.p_element.system_id.system_mac[4];
250 hw->h_lport.p_element.system_id.system_mac[5] =
251 hardware.h_lport.p_element.system_id.system_mac[5];
253 hw->h_lport.p_element.system_id.conn_type =
254 hardware.h_lport.p_element.system_id.conn_type;
255 hw->h_lport.p_element.system_id.smlt_id =
256 hardware.h_lport.p_element.system_id.smlt_id;
257 hw->h_lport.p_element.system_id.mlt_id[0] =
258 hardware.h_lport.p_element.system_id.mlt_id[0];
259 hw->h_lport.p_element.system_id.mlt_id[1] =
260 hardware.h_lport.p_element.system_id.mlt_id[1];
262 /* Populate instance with two auto attach isid/vlan mappings */
263 map[0].isid_vlan_data.status = map_init[0].isid_vlan_data.status;
264 map[0].isid_vlan_data.vlan = map_init[0].isid_vlan_data.vlan;
265 map[0].isid_vlan_data.isid[0] = map_init[0].isid_vlan_data.isid[0];
266 map[0].isid_vlan_data.isid[1] = map_init[0].isid_vlan_data.isid[1];
267 map[0].isid_vlan_data.isid[2] = map_init[0].isid_vlan_data.isid[2];
269 map[1].isid_vlan_data.status = map_init[1].isid_vlan_data.status;
270 map[1].isid_vlan_data.vlan = map_init[1].isid_vlan_data.vlan;
271 map[1].isid_vlan_data.isid[0] = map_init[1].isid_vlan_data.isid[0];
272 map[1].isid_vlan_data.isid[1] = map_init[1].isid_vlan_data.isid[1];
273 map[1].isid_vlan_data.isid[2] = map_init[1].isid_vlan_data.isid[2];
275 list_init(&hw->h_lport.p_isid_vlan_maps.m_entries);
276 list_push_back(&hw->h_lport.p_isid_vlan_maps.m_entries,
278 list_push_back(&hw->h_lport.p_isid_vlan_maps.m_entries,
281 /* Construct LLDPPDU (including Ethernet header) */
282 eth_compose(&packet, eth_addr_lldp, eth_src, ETH_TYPE_LLDP, 0);
283 n = lldp_send(lldp->lldpd, hw, &packet);
286 printf("Error: unable to build packet\n");
290 /* Decode the constructed LLDPPDU */
291 assert(lldp_decode(NULL, packet.data_, packet.size_, hw,
292 &nchassis, &nport) != -1);
294 /* Expecting returned pointers to allocated structures */
295 if (!nchassis || !nport) {
296 printf("Error: unable to decode packet");
300 /* Verify chassis values */
301 check_received_chassis(&chassis, nchassis);
303 /* Verify port values */
304 check_received_port(&hardware.h_lport, nport);
306 /* Verify auto attach values */
307 check_received_aa(&hardware.h_lport, nport, map_init);
314 test_aa_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
318 /* Make sure we emit valid auto-attach LLDPPDUs */
320 num_errors += test_aa_send();
322 /* Add more tests here */
324 printf("executed %d tests, %d errors\n", num_tests, num_errors);
326 exit(num_errors != 0);
329 OVSTEST_REGISTER("test-aa", test_aa_main);