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 static uint8_t chassis_mac
[ETH_ADDR_LEN
] = { 0x5e, 0x10, 0x8e, 0xe7, 0x84, 0xad };
30 static uint8_t eth_src
[ETH_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 */
36 static int num_tests
= 0;
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(memcmp(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
));
111 /* For each received isid/vlan mapping */
112 LIST_FOR_EACH (received_map
, m_entries
, &rport
->p_isid_vlan_maps
) {
114 /* Validate against mapping sent */
115 assert(smap
[i
].isid_vlan_data
.status
==
116 received_map
->isid_vlan_data
.status
);
117 assert(smap
[i
].isid_vlan_data
.vlan
==
118 received_map
->isid_vlan_data
.vlan
);
119 assert(smap
[i
].isid_vlan_data
.isid
==
120 received_map
->isid_vlan_data
.isid
);
122 /* Next mapping sent */
132 * Validate basic send/receive processing
138 struct lldpd_hardware hardware
;
139 struct lldpd_chassis chassis
;
141 struct lldpd_chassis
*nchassis
= NULL
;
142 struct lldpd_port
*nport
= NULL
;
144 struct lldpd_hardware
*hw
= NULL
;
145 struct lldpd_chassis
*ch
= NULL
;
147 struct lldpd_aa_isid_vlan_maps_tlv map_init
[2];
148 struct lldpd_aa_isid_vlan_maps_tlv map
[2];
150 uint32_t stub
[512 / 4];
151 struct dp_packet packet
;
155 /* Prepare data used to construct and validate LLDPPDU */
156 hardware
.h_lport
.p_id_subtype
= LLDP_PORTID_SUBTYPE_IFNAME
;
157 hardware
.h_lport
.p_id
= "FastEthernet 1/5";
158 hardware
.h_lport
.p_id_len
= strlen(hardware
.h_lport
.p_id
);
159 hardware
.h_lport
.p_descr
= "Fake port description";
160 hardware
.h_lport
.p_mfs
= 1516;
162 /* Auto attach element discovery info */
163 hardware
.h_lport
.p_element
.type
= LLDP_TLV_AA_ELEM_TYPE_TAG_CLIENT
;
164 hardware
.h_lport
.p_element
.mgmt_vlan
= 0xCDC;
165 hardware
.h_lport
.p_element
.system_id
.system_mac
[0] = 0x1;
166 hardware
.h_lport
.p_element
.system_id
.system_mac
[1] = 0x2;
167 hardware
.h_lport
.p_element
.system_id
.system_mac
[2] = 0x3;
168 hardware
.h_lport
.p_element
.system_id
.system_mac
[3] = 0x4;
169 hardware
.h_lport
.p_element
.system_id
.system_mac
[4] = 0x5;
170 hardware
.h_lport
.p_element
.system_id
.system_mac
[5] = 0x6;
172 hardware
.h_lport
.p_element
.system_id
.conn_type
= 0x5;
173 hardware
.h_lport
.p_element
.system_id
.smlt_id
= 0x3CC;
174 hardware
.h_lport
.p_element
.system_id
.mlt_id
[0] = 0xB;
175 hardware
.h_lport
.p_element
.system_id
.mlt_id
[1] = 0xE;
177 /* Local chassis info */
178 chassis
.c_id_subtype
= LLDP_CHASSISID_SUBTYPE_LLADDR
;
179 chassis
.c_id
= chassis_mac
;
180 chassis
.c_id_len
= ETHER_ADDR_LEN
;
181 chassis
.c_name
= "Dummy chassis";
182 chassis
.c_descr
= "Long dummy chassis description";
183 chassis
.c_cap_available
= LLDP_CAP_BRIDGE
;
184 chassis
.c_cap_enabled
= LLDP_CAP_BRIDGE
;
186 /* ISID/VLAN mappings */
187 map_init
[0].isid_vlan_data
.status
= 0xC;
188 map_init
[0].isid_vlan_data
.vlan
= 0x64;
189 map_init
[0].isid_vlan_data
.isid
= 0x010203;
191 map_init
[1].isid_vlan_data
.status
= 0xD;
192 map_init
[1].isid_vlan_data
.vlan
= 0xF;
193 map_init
[1].isid_vlan_data
.isid
= 0x040506;
195 /* Prepare an empty packet buffer */
196 dp_packet_use_stub(&packet
, stub
, sizeof stub
);
197 dp_packet_clear(&packet
);
199 /* Create a dummy lldp instance */
200 lldp
= lldp_create_dummy();
201 if ((lldp
== NULL
) ||
202 (lldp
->lldpd
== NULL
) ||
203 list_is_empty(&lldp
->lldpd
->g_hardware
)) {
204 printf("Error: unable to create dummy lldp instance");
208 /* Populate instance with local chassis info */
209 hw
= lldpd_first_hardware(lldp
->lldpd
);
210 ch
= hw
->h_lport
.p_chassis
;
211 ch
->c_id_subtype
= chassis
.c_id_subtype
;
212 ch
->c_id
= chassis
.c_id
;
213 ch
->c_id_len
= chassis
.c_id_len
;
214 ch
->c_name
= chassis
.c_name
;
215 ch
->c_descr
= chassis
.c_descr
;
216 ch
->c_cap_available
= chassis
.c_cap_available
;
217 ch
->c_cap_enabled
= chassis
.c_cap_enabled
;
219 /* Populate instance with local port info */
220 hw
->h_lport
.p_id_subtype
= hardware
.h_lport
.p_id_subtype
;
221 hw
->h_lport
.p_id
= hardware
.h_lport
.p_id
;
222 hw
->h_lport
.p_id_len
= strlen(hw
->h_lport
.p_id
);
223 hw
->h_lport
.p_descr
= hardware
.h_lport
.p_descr
;
224 hw
->h_lport
.p_mfs
= hardware
.h_lport
.p_mfs
;
226 /* Populate instance with auto attach element discovery info */
228 hw
->h_lport
.p_element
.type
= hardware
.h_lport
.p_element
.type
;
229 hw
->h_lport
.p_element
.mgmt_vlan
= hardware
.h_lport
.p_element
.mgmt_vlan
;
230 hw
->h_lport
.p_element
.system_id
.system_mac
[0] =
231 hardware
.h_lport
.p_element
.system_id
.system_mac
[0];
232 hw
->h_lport
.p_element
.system_id
.system_mac
[1] =
233 hardware
.h_lport
.p_element
.system_id
.system_mac
[1];
234 hw
->h_lport
.p_element
.system_id
.system_mac
[2] =
235 hardware
.h_lport
.p_element
.system_id
.system_mac
[2];
236 hw
->h_lport
.p_element
.system_id
.system_mac
[3] =
237 hardware
.h_lport
.p_element
.system_id
.system_mac
[3];
238 hw
->h_lport
.p_element
.system_id
.system_mac
[4] =
239 hardware
.h_lport
.p_element
.system_id
.system_mac
[4];
240 hw
->h_lport
.p_element
.system_id
.system_mac
[5] =
241 hardware
.h_lport
.p_element
.system_id
.system_mac
[5];
243 hw
->h_lport
.p_element
.system_id
.conn_type
=
244 hardware
.h_lport
.p_element
.system_id
.conn_type
;
245 hw
->h_lport
.p_element
.system_id
.smlt_id
=
246 hardware
.h_lport
.p_element
.system_id
.smlt_id
;
247 hw
->h_lport
.p_element
.system_id
.mlt_id
[0] =
248 hardware
.h_lport
.p_element
.system_id
.mlt_id
[0];
249 hw
->h_lport
.p_element
.system_id
.mlt_id
[1] =
250 hardware
.h_lport
.p_element
.system_id
.mlt_id
[1];
252 /* Populate instance with two auto attach isid/vlan mappings */
253 map
[0].isid_vlan_data
.status
= map_init
[0].isid_vlan_data
.status
;
254 map
[0].isid_vlan_data
.vlan
= map_init
[0].isid_vlan_data
.vlan
;
255 map
[0].isid_vlan_data
.isid
= map_init
[0].isid_vlan_data
.isid
;
257 map
[1].isid_vlan_data
.status
= map_init
[1].isid_vlan_data
.status
;
258 map
[1].isid_vlan_data
.vlan
= map_init
[1].isid_vlan_data
.vlan
;
259 map
[1].isid_vlan_data
.isid
= map_init
[1].isid_vlan_data
.isid
;
261 list_init(&hw
->h_lport
.p_isid_vlan_maps
);
262 list_push_back(&hw
->h_lport
.p_isid_vlan_maps
, &map
[0].m_entries
);
263 list_push_back(&hw
->h_lport
.p_isid_vlan_maps
, &map
[1].m_entries
);
265 /* Construct LLDPPDU (including Ethernet header) */
266 eth_compose(&packet
, eth_addr_lldp
, eth_src
, ETH_TYPE_LLDP
, 0);
267 n
= lldp_send(lldp
->lldpd
, hw
, &packet
);
270 printf("Error: unable to build packet\n");
274 /* Decode the constructed LLDPPDU */
275 assert(lldp_decode(NULL
, packet
.data_
, packet
.size_
, hw
,
276 &nchassis
, &nport
) != -1);
278 /* Expecting returned pointers to allocated structures */
279 if (!nchassis
|| !nport
) {
280 printf("Error: unable to decode packet");
284 /* Verify chassis values */
285 check_received_chassis(&chassis
, nchassis
);
287 /* Verify port values */
288 check_received_port(&hardware
.h_lport
, nport
);
290 /* Verify auto attach values */
291 check_received_aa(&hardware
.h_lport
, nport
, map_init
);
298 test_aa_main(int argc OVS_UNUSED
, char *argv
[] OVS_UNUSED
)
302 /* Make sure we emit valid auto-attach LLDPPDUs */
304 num_errors
+= test_aa_send();
306 /* Add more tests here */
308 printf("executed %d tests, %d errors\n", num_tests
, num_errors
);
310 exit(num_errors
!= 0);
313 OVSTEST_REGISTER("test-aa", test_aa_main
);