1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 /**************************************************************************/
12 /**************************************************************************/
13 /**                                                                       */
14 /** NetX Component                                                        */
15 /**                                                                       */
16 /**   Multiple VLAN Registration Protocol (MVRP)                          */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 /* Include necessary system files.  */
22 #include "nx_mvrp.h"
23 
24 #ifdef NX_ENABLE_VLAN
25 NX_MVRP_ATTRIBUTE mvrp_attribute_array[NX_MVRP_ATTRIBUTE_ARRAY_MAX_SIZE];
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    nx_mvrp_indication_process                          PORTABLE C      */
32 /*                                                           6.4.0        */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Yajun Xia, Microsoft Corporation                                    */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function process the MVRP indication.                          */
40 /*                                                                        */
41 /*  INPUT                                                                 */
42 /*                                                                        */
43 /*    mrp                                   MRP instance                  */
44 /*    participant                           MRP participant               */
45 /*    attribute                             MRP attribute                 */
46 /*    indication_type                       Indication type               */
47 /*                                                                        */
48 /*  OUTPUT                                                                */
49 /*                                                                        */
50 /*    status                                Completion status             */
51 /*                                                                        */
52 /*  CALLS                                                                 */
53 /*                                                                        */
54 /*    nx_mvrp_action_request                MVRP action request           */
55 /*                                                                        */
56 /*  CALLED BY                                                             */
57 /*                                                                        */
58 /*    Internal function                                                   */
59 /*                                                                        */
60 /*  RELEASE HISTORY                                                       */
61 /*                                                                        */
62 /*    DATE              NAME                      DESCRIPTION             */
63 /*                                                                        */
64 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
65 /*                                                                        */
66 /**************************************************************************/
nx_mvrp_indication_process(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)67 UINT nx_mvrp_indication_process(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
68 {
69 UINT   status;
70 USHORT vlan_id;
71 NX_MVRP *mvrp = (NX_MVRP *)participant;
72 
73     NX_PARAMETER_NOT_USED(mrp);
74     if (mvrp -> mvrp_event_callback)
75     {
76         status = mvrp -> mvrp_event_callback(participant, attribute, indication_type, NX_NULL);
77         if (status != NX_SUCCESS)
78         {
79             return(status);
80         }
81     }
82 
83     vlan_id = ((NX_MVRP_ATTRIBUTE *)attribute) -> vlan_id;
84     status = nx_mvrp_action_request(mrp, participant, vlan_id, indication_type);
85 
86     return(status);
87 }
88 
89 /**************************************************************************/
90 /*                                                                        */
91 /*  FUNCTION                                               RELEASE        */
92 /*                                                                        */
93 /*    nx_mvrp_mrpdu_unpack                                PORTABLE C      */
94 /*                                                           6.4.0        */
95 /*  AUTHOR                                                                */
96 /*                                                                        */
97 /*    Yajun Xia, Microsoft Corporation                                    */
98 /*                                                                        */
99 /*  DESCRIPTION                                                           */
100 /*                                                                        */
101 /*    This function unpack the MVRP message.                              */
102 /*                                                                        */
103 /*  INPUT                                                                 */
104 /*                                                                        */
105 /*    mrp                                   MRP instance                  */
106 /*    participant                           MRP participant               */
107 /*    packet_ptr                            MRP packet                    */
108 /*                                                                        */
109 /*  OUTPUT                                                                */
110 /*                                                                        */
111 /*    status                                Completion status             */
112 /*                                                                        */
113 /*  CALLS                                                                 */
114 /*                                                                        */
115 /*    nx_mvrp_attribute_get                 Get MVRP attribute            */
116 /*    nx_mrp_event_process                  Process MRP event             */
117 /*                                                                        */
118 /*  CALLED BY                                                             */
119 /*                                                                        */
120 /*    Internal Function                                                   */
121 /*                                                                        */
122 /*  RELEASE HISTORY                                                       */
123 /*                                                                        */
124 /*    DATE              NAME                      DESCRIPTION             */
125 /*                                                                        */
126 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
127 /*                                                                        */
128 /**************************************************************************/
nx_mvrp_mrpdu_unpack(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_PACKET * packet_ptr)129 UINT nx_mvrp_mrpdu_unpack(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_PACKET *packet_ptr)
130 {
131 UINT              status;
132 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
133 UCHAR             attribute_type;
134 UCHAR             attribute_len;
135 UCHAR            *data_ptr = packet_ptr -> nx_packet_prepend_ptr;
136 UCHAR            *end = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
137 UCHAR            *attribute_list_end;
138 USHORT            vector_header;
139 USHORT            leave_all_event;
140 USHORT            number_of_values;
141 USHORT            vlan_id;
142 USHORT            event_cycle_cnt;
143 USHORT            i;
144 UCHAR             three_packed_event, first_event, second_event, third_event;
145 
146     if (*data_ptr++ != NX_MRP_MVRP_PROTOCOL_VERSION)
147     {
148         return(NX_INVALID_PARAMETERS);
149     }
150 
151     end = end - NX_MVRP_ATTRIBUTE_END_MARK_SIZE;
152 
153     /* Message loop */
154     while (data_ptr < end)
155     {
156         /* Attribute start */
157         attribute_type = *data_ptr++;
158         if (attribute_type != NX_MVRP_ATTRIBUTE_TYPE_VLAN_ID)
159         {
160             return(NX_INVALID_PACKET);
161         }
162 
163         attribute_len = *data_ptr++;
164         if (attribute_len != NX_MVRP_ATTRIBUTE_LENGTH_VLAN_ID)
165         {
166             return(NX_INVALID_PACKET);
167         }
168 
169         attribute_list_end = end - NX_MVRP_ATTRIBUTE_END_MARK_SIZE;
170 
171         /* Vector attribute loop */
172         while (data_ptr < attribute_list_end)
173         {
174             vector_header = (USHORT)*data_ptr++;
175             vector_header = (USHORT)(vector_header << 8);
176             vector_header |= (USHORT)*data_ptr++;
177 
178             /* no need to process the case of vector header is 0 */
179             if (vector_header == 0)
180             {
181                 return(NX_SUCCESS);
182             }
183 
184             leave_all_event = vector_header >> 13;
185             number_of_values = vector_header & 0x1fff;
186 
187             /* First Value */
188             vlan_id = (USHORT)*data_ptr++;
189             vlan_id = (USHORT)(vlan_id << 8);
190             vlan_id |= (USHORT)*data_ptr++;
191 
192             event_cycle_cnt = (number_of_values % 3 == 0) ? 0 : 1;
193             event_cycle_cnt = (USHORT)(event_cycle_cnt + number_of_values / 3);
194 
195             if (data_ptr + event_cycle_cnt >= attribute_list_end)
196             {
197                 return(NX_PACKET_OFFSET_ERROR);
198             }
199 
200             /* Attribite event loop */
201             for (i = 0; i < event_cycle_cnt; i++)
202             {
203                 /* ThreePackedEvents BYTE ::= (((((AttributeEvent_first) *6) + AttributeEvent_second) *6) + AttributeEvent_third) */
204                 three_packed_event = *data_ptr++;
205                 third_event = three_packed_event % 6;
206                 second_event = (UCHAR)((three_packed_event - third_event) / 6) % 6;
207                 first_event = (UCHAR)((three_packed_event - third_event) / 6 - second_event) / 6;
208 
209                 /* Get the first vlan id with event */
210                 if (number_of_values > 0)
211                 {
212                     status = nx_mvrp_attribute_get(mrp, participant, &attribute, vlan_id);
213                     if (status != NX_SUCCESS)
214                     {
215                         return(NX_NOT_SUCCESSFUL);
216                     }
217 
218                     if (leave_all_event)
219                     {
220                         nx_mrp_event_process(mrp, participant, attribute, NX_MRP_EVENT_RLA);
221                     }
222                     else
223                     {
224                         nx_mrp_event_process(mrp, participant, attribute, first_event);
225                     }
226                     number_of_values--;
227                     vlan_id++;
228                 }
229                 else
230                 {
231                     return(NX_INVALID_PACKET);
232                 }
233 
234                 /* Get the second vlan id with event */
235                 if (number_of_values > 0)
236                 {
237                     status = nx_mvrp_attribute_get(mrp, participant, &attribute, vlan_id);
238                     if (status != NX_SUCCESS)
239                     {
240                         return(NX_NOT_SUCCESSFUL);
241                     }
242 
243                     if (leave_all_event)
244                     {
245                         nx_mrp_event_process(mrp, participant, attribute, NX_MRP_EVENT_RLA);
246                     }
247                     else
248                     {
249                         nx_mrp_event_process(mrp, participant, attribute, second_event);
250                     }
251                     number_of_values--;
252                     vlan_id++;
253                 }
254 
255                 /* Get the third vlan id with event */
256                 if (number_of_values > 0)
257                 {
258                     status = nx_mvrp_attribute_get(mrp, participant, &attribute, vlan_id);
259                     if (status != NX_SUCCESS)
260                     {
261                         return(NX_NOT_SUCCESSFUL);
262                     }
263 
264                     if (leave_all_event)
265                     {
266                         nx_mrp_event_process(mrp, participant, attribute, NX_MRP_EVENT_RLA);
267                     }
268                     else
269                     {
270                         nx_mrp_event_process(mrp, participant, attribute, third_event);
271                     }
272                     number_of_values--;
273                     vlan_id++;
274                 }
275             }
276         }
277         data_ptr += NX_MVRP_ATTRIBUTE_END_MARK_SIZE;
278     }
279 
280     return(NX_SUCCESS);
281 }
282 
283 /**************************************************************************/
284 /*                                                                        */
285 /*  FUNCTION                                               RELEASE        */
286 /*                                                                        */
287 /*    nx_mvrp_mrpdu_pack                                  PORTABLE C      */
288 /*                                                           6.4.0        */
289 /*  AUTHOR                                                                */
290 /*                                                                        */
291 /*    Yajun Xia, Microsoft Corporation                                    */
292 /*                                                                        */
293 /*  DESCRIPTION                                                           */
294 /*                                                                        */
295 /*    This function pack the MVRP message.                                */
296 /*                                                                        */
297 /*  INPUT                                                                 */
298 /*                                                                        */
299 /*    mrp                                   MRP instance                  */
300 /*    participant                           MRP participant               */
301 /*    packet_ptr                            MRP packet                    */
302 /*                                                                        */
303 /*  OUTPUT                                                                */
304 /*                                                                        */
305 /*    status                                Completion status             */
306 /*                                                                        */
307 /*  CALLS                                                                 */
308 /*                                                                        */
309 /*    nx_mrp_attribute_event_get            Get MRP attribute event       */
310 /*                                                                        */
311 /*  CALLED BY                                                             */
312 /*                                                                        */
313 /*    Internal Function                                                   */
314 /*                                                                        */
315 /*  RELEASE HISTORY                                                       */
316 /*                                                                        */
317 /*    DATE              NAME                      DESCRIPTION             */
318 /*                                                                        */
319 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
320 /*                                                                        */
321 /**************************************************************************/
nx_mvrp_mrpdu_pack(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_PACKET * packet_ptr)322 UINT nx_mvrp_mrpdu_pack(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_PACKET *packet_ptr)
323 {
324 NX_MRP_ATTRIBUTE *attribute = participant -> inused_head;
325 NX_MRP_ATTRIBUTE *vector_attribute;
326 UCHAR            *data_ptr = packet_ptr -> nx_packet_prepend_ptr;
327 USHORT            leave_all_event;
328 USHORT            number_of_values = 0;
329 UCHAR             attribute_find = NX_FALSE;
330 USHORT            vector_header;
331 USHORT            first_value, vlan_id;
332 USHORT            event_cycle_cnt;
333 UCHAR             three_packed_event, first_event, second_event, third_event;
334 USHORT            i;
335 
336     NX_PARAMETER_NOT_USED(mrp);
337     /* Encaps the protocol version */
338     *data_ptr++ = NX_MRP_MVRP_PROTOCOL_VERSION;
339 
340     /* Message start */
341     /* Attribute type */
342     *data_ptr++ = NX_MVRP_ATTRIBUTE_TYPE_VLAN_ID;
343 
344     /* Attribute length */
345     *data_ptr++ = NX_MVRP_ATTRIBUTE_LENGTH_VLAN_ID;
346 
347     /* Attribute list */
348     while (attribute)
349     {
350         if (attribute -> applicant.action == NX_MRP_ACTION_NULL)
351         {
352             attribute = attribute -> next;
353             continue;
354         }
355 
356         if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
357         {
358             leave_all_event = NX_TRUE;
359         }
360 
361         /* Get the first value */
362         first_value = ((NX_MVRP_ATTRIBUTE *)attribute) -> vlan_id;
363         vlan_id = (USHORT)(first_value + 1);
364         vector_attribute = attribute -> next;
365         number_of_values = 1;
366         attribute_find = NX_TRUE;
367         while (vector_attribute)
368         {
369             if (((NX_MVRP_ATTRIBUTE *)vector_attribute) -> vlan_id == vlan_id)
370             {
371                 if (attribute -> applicant.action == NX_MRP_ACTION_NULL)
372                 {
373                     vector_attribute = vector_attribute -> next;
374                     break;
375                 }
376                 number_of_values++;
377                 vlan_id++;
378                 vector_attribute = vector_attribute -> next;
379                 continue;
380             }
381             else
382             {
383                 break;
384             }
385         }
386 
387         vector_header = (USHORT)(leave_all_event << 13);
388         vector_header = (USHORT)(vector_header | number_of_values);
389 
390         /* Vector header */
391         *data_ptr++ = (UCHAR)(vector_header >> 8);
392         *data_ptr++ = (UCHAR)(vector_header & 0xff);
393 
394         /* First Value */
395         *data_ptr++ = (UCHAR)(first_value >> 8);
396         *data_ptr++ = (UCHAR)(first_value & 0xff);
397 
398         /* Attribute event */
399         event_cycle_cnt = (number_of_values % 3 == 0) ? 0 : 1;
400         event_cycle_cnt = (USHORT)(event_cycle_cnt + number_of_values / 3);
401 
402         for (i = 0; i < event_cycle_cnt; i++)
403         {
404             nx_mrp_attribute_event_get(attribute, &first_event);
405             attribute = attribute -> next;
406             number_of_values--;
407 
408             if (number_of_values == 0)
409             {
410                 second_event = 0;
411                 third_event = 0;
412             }
413             else
414             {
415                 nx_mrp_attribute_event_get(attribute, &second_event);
416                 attribute = attribute -> next;
417                 number_of_values--;
418 
419                 if (number_of_values == 0)
420                 {
421                     third_event = 0;
422                 }
423                 else
424                 {
425                     nx_mrp_attribute_event_get(attribute, &third_event);
426                     attribute = attribute -> next;
427                     number_of_values--;
428                 }
429             }
430 
431             /* ThreePackedEvents BYTE ::= (((((AttributeEvent_first) *6) + AttributeEvent_second) *6) + AttributeEvent_third) */
432             three_packed_event = (UCHAR)(first_event * 6);
433             three_packed_event = (UCHAR)(three_packed_event + second_event);
434             three_packed_event = (UCHAR)(three_packed_event * 6);
435             three_packed_event = (UCHAR)(three_packed_event + third_event);
436 
437             *data_ptr++ = three_packed_event;
438         }
439     }
440 
441     if (attribute_find == NX_FALSE)
442     {
443         return(NX_NOT_FOUND);
444     }
445 
446     /* Attribute list end (add the end mark) */
447     *data_ptr++ = 0;
448     *data_ptr++ = 0;
449 
450     /* Message end (add the end mark) */
451     *data_ptr++ = 0;
452     *data_ptr++ = 0;
453 
454     packet_ptr -> nx_packet_append_ptr = data_ptr;
455     packet_ptr -> nx_packet_length = (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
456     return(NX_SUCCESS);
457 }
458 
459 /**************************************************************************/
460 /*                                                                        */
461 /*  FUNCTION                                               RELEASE        */
462 /*                                                                        */
463 /*    nx_mvrp_attribute_find                              PORTABLE C      */
464 /*                                                           6.4.0        */
465 /*  AUTHOR                                                                */
466 /*                                                                        */
467 /*    Yajun Xia, Microsoft Corporation                                    */
468 /*                                                                        */
469 /*  DESCRIPTION                                                           */
470 /*                                                                        */
471 /*    This function find the MVRP attribute.                              */
472 /*                                                                        */
473 /*  INPUT                                                                 */
474 /*                                                                        */
475 /*    mrp                                   MRP instance                  */
476 /*    participant                           MRP participant               */
477 /*    attribute_ptr                         MRP attribute                 */
478 /*    vlan_id                               VLAN ID                       */
479 /*                                                                        */
480 /*  OUTPUT                                                                */
481 /*                                                                        */
482 /*    status                                Completion status             */
483 /*                                                                        */
484 /*  CALLS                                                                 */
485 /*                                                                        */
486 /*    None                                                                */
487 /*                                                                        */
488 /*  CALLED BY                                                             */
489 /*                                                                        */
490 /*    Internal Function                                                   */
491 /*                                                                        */
492 /*  RELEASE HISTORY                                                       */
493 /*                                                                        */
494 /*    DATE              NAME                      DESCRIPTION             */
495 /*                                                                        */
496 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
497 /*                                                                        */
498 /**************************************************************************/
nx_mvrp_attribute_find(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE ** attribute_ptr,USHORT vlan_id)499 UINT nx_mvrp_attribute_find(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE **attribute_ptr, USHORT vlan_id)
500 {
501 NX_MRP_ATTRIBUTE  *attribute;
502 NX_MVRP_ATTRIBUTE *mvrp_attribute;
503 
504     NX_PARAMETER_NOT_USED(mrp);
505     attribute = participant -> inused_head;
506 
507     while (attribute != NX_NULL)
508     {
509         mvrp_attribute = (NX_MVRP_ATTRIBUTE *)attribute;
510         if (mvrp_attribute -> vlan_id == vlan_id)
511         {
512             *attribute_ptr = attribute;
513             return(NX_SUCCESS);
514         }
515 
516         if (mvrp_attribute -> vlan_id > vlan_id)
517         {
518             /* The vlan id is not found */
519             break;
520         }
521         attribute = attribute -> next;
522     }
523 
524     return(NX_NOT_SUCCESSFUL);
525 }
526 
527 /**************************************************************************/
528 /*                                                                        */
529 /*  FUNCTION                                               RELEASE        */
530 /*                                                                        */
531 /*    nx_mvrp_attribute_insert                            PORTABLE C      */
532 /*                                                           6.4.0        */
533 /*  AUTHOR                                                                */
534 /*                                                                        */
535 /*    Yajun Xia, Microsoft Corporation                                    */
536 /*                                                                        */
537 /*  DESCRIPTION                                                           */
538 /*                                                                        */
539 /*    This function insert the MVRP attribute into attribute list.        */
540 /*                                                                        */
541 /*  INPUT                                                                 */
542 /*                                                                        */
543 /*    mrp                                   MRP instance                  */
544 /*    participant                           MRP participant               */
545 /*    attribute                             MRP attribute                 */
546 /*                                                                        */
547 /*  OUTPUT                                                                */
548 /*                                                                        */
549 /*    None                                                                */
550 /*                                                                        */
551 /*  CALLS                                                                 */
552 /*                                                                        */
553 /*    None                                                                */
554 /*                                                                        */
555 /*  CALLED BY                                                             */
556 /*                                                                        */
557 /*    nx_mvrp_attribute_get                 MVRP attribute get            */
558 /*                                                                        */
559 /*  RELEASE HISTORY                                                       */
560 /*                                                                        */
561 /*    DATE              NAME                      DESCRIPTION             */
562 /*                                                                        */
563 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
564 /*                                                                        */
565 /**************************************************************************/
nx_mvrp_attribute_insert(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute)566 void nx_mvrp_attribute_insert(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute)
567 {
568 NX_MRP_ATTRIBUTE *tmp_attribute;
569 USHORT            vlan_id = ((NX_MVRP_ATTRIBUTE *)attribute) -> vlan_id;
570 
571     NX_PARAMETER_NOT_USED(mrp);
572     tmp_attribute = participant -> inused_head;
573 
574     if (tmp_attribute == NX_NULL)
575     {
576         participant -> inused_head = attribute;
577         attribute -> next = NX_NULL;
578         attribute -> pre = NX_NULL;
579         return;
580     }
581 
582     while (tmp_attribute != NX_NULL)
583     {
584         if (((NX_MVRP_ATTRIBUTE *)tmp_attribute) -> vlan_id > vlan_id)
585         {
586             /* The node should be inserted into the head of the list */
587             if (participant -> inused_head == tmp_attribute)
588             {
589 
590                 attribute -> next = tmp_attribute;
591                 attribute -> pre = NX_NULL;
592                 tmp_attribute -> pre = attribute;
593                 participant -> inused_head = attribute;
594             }
595             else
596             {
597                 attribute -> next = tmp_attribute;
598                 attribute -> pre = tmp_attribute -> pre;
599                 tmp_attribute -> pre -> next = attribute;
600                 tmp_attribute -> pre = attribute;
601             }
602             return;
603         }
604 
605         /* The node should be inserted into the tail of the list */
606         if (tmp_attribute -> next == NX_NULL)
607         {
608             attribute -> next = NX_NULL;
609             attribute -> pre = tmp_attribute;
610 
611             tmp_attribute -> next = attribute;
612 
613             return;
614         }
615         tmp_attribute = tmp_attribute -> next;
616     }
617 
618     return;
619 }
620 
621 /**************************************************************************/
622 /*                                                                        */
623 /*  FUNCTION                                               RELEASE        */
624 /*                                                                        */
625 /*    nx_mvrp_attribute_get                               PORTABLE C      */
626 /*                                                           6.4.0        */
627 /*  AUTHOR                                                                */
628 /*                                                                        */
629 /*    Yajun Xia, Microsoft Corporation                                    */
630 /*                                                                        */
631 /*  DESCRIPTION                                                           */
632 /*                                                                        */
633 /*    This function gets the MVRP attribute.                              */
634 /*                                                                        */
635 /*  INPUT                                                                 */
636 /*                                                                        */
637 /*    mrp                                   MRP instance                  */
638 /*    participant                           MRP participant               */
639 /*    attribute_ptr                         MRP attribute                 */
640 /*    vlan_id                               VLAN ID                       */
641 /*                                                                        */
642 /*  OUTPUT                                                                */
643 /*                                                                        */
644 /*    status                                Completion status             */
645 /*                                                                        */
646 /*  CALLS                                                                 */
647 /*                                                                        */
648 /*    nx_mvrp_attribute_find                Find MVRP attribute           */
649 /*    nx_mvrp_attribute_new                 New MVRP attribute            */
650 /*    nx_mvrp_attribute_insert              Insert MVRP attribute         */
651 /*                                                                        */
652 /*  CALLED BY                                                             */
653 /*                                                                        */
654 /*    nx_mvrp_action_request                MVRP action request           */
655 /*    nx_mvrp_mrpdu_unpack                  MVRP message unpack           */
656 /*                                                                        */
657 /*  RELEASE HISTORY                                                       */
658 /*                                                                        */
659 /*    DATE              NAME                      DESCRIPTION             */
660 /*                                                                        */
661 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
662 /*                                                                        */
663 /**************************************************************************/
nx_mvrp_attribute_get(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE ** attribute_ptr,USHORT vlan_id)664 UINT nx_mvrp_attribute_get(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE **attribute_ptr, USHORT vlan_id)
665 {
666 NX_MRP_ATTRIBUTE *attribute;
667 UINT              status;
668 
669     if ((mrp == NX_NULL) ||
670         (participant == NX_NULL) ||
671         (attribute_ptr == NX_NULL))
672     {
673         return(NX_INVALID_PARAMETERS);
674     }
675 
676     status = nx_mvrp_attribute_find(mrp, participant, attribute_ptr, vlan_id);
677     if (status == NX_SUCCESS)
678     {
679         return(status);
680     }
681 
682     /* no attribute find, new an attribute */
683     attribute = nx_mrp_attribute_new(mrp, participant, (NX_MRP_ATTRIBUTE *)mvrp_attribute_array,
684                                      sizeof(struct NX_MVRP_ATTRIBUTE_STRUCT), NX_MVRP_ATTRIBUTE_ARRAY_MAX_SIZE);
685 
686     if (attribute == NX_NULL)
687     {
688         return(NX_NO_MORE_ENTRIES);
689     }
690 
691     attribute -> attribute_type = NX_MVRP_ATTRIBUTE_TYPE_VLAN_ID;
692     ((NX_MVRP_ATTRIBUTE *)attribute) -> vlan_id = vlan_id;
693 
694     nx_mvrp_attribute_insert(mrp, participant, attribute);
695 
696     *attribute_ptr = attribute;
697 
698     return(NX_SUCCESS);
699 }
700 
701 /**************************************************************************/
702 /*                                                                        */
703 /*  FUNCTION                                               RELEASE        */
704 /*                                                                        */
705 /*    nx_mvrp_action_request                              PORTABLE C      */
706 /*                                                           6.4.0        */
707 /*  AUTHOR                                                                */
708 /*                                                                        */
709 /*    Yajun Xia, Microsoft Corporation                                    */
710 /*                                                                        */
711 /*  DESCRIPTION                                                           */
712 /*                                                                        */
713 /*    This function is used for requesting MVRP action.                   */
714 /*                                                                        */
715 /*  INPUT                                                                 */
716 /*                                                                        */
717 /*    mrp                                   MRP instance                  */
718 /*    participant                           MRP participant               */
719 /*    vlan_id                               VLAN ID                       */
720 /*    action_type                           Action type                   */
721 /*                                                                        */
722 /*  OUTPUT                                                                */
723 /*                                                                        */
724 /*    status                                Completion status             */
725 /*                                                                        */
726 /*  CALLS                                                                 */
727 /*                                                                        */
728 /*    nx_mvrp_attribute_get                 Get MVRP attribute            */
729 /*    nx_mrp_event_process                  Process MRP event             */
730 /*                                                                        */
731 /*  CALLED BY                                                             */
732 /*                                                                        */
733 /*    nx_mvrp_indication_process            MVRP indication process       */
734 /*                                                                        */
735 /*  RELEASE HISTORY                                                       */
736 /*                                                                        */
737 /*    DATE              NAME                      DESCRIPTION             */
738 /*                                                                        */
739 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
740 /*                                                                        */
741 /**************************************************************************/
nx_mvrp_action_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,USHORT vlan_id,UCHAR action_type)742 UINT nx_mvrp_action_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, USHORT vlan_id, UCHAR action_type)
743 {
744 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
745 UINT              status;
746 UCHAR             mrp_event;
747 
748     /* Get mutex. */
749     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
750 
751     status = nx_mvrp_attribute_get(mrp, participant, &attribute, vlan_id);
752 
753     if (status != NX_SUCCESS)
754     {
755         tx_mutex_put(&(mrp -> mrp_mutex));
756         return(status);
757     }
758 
759     switch (action_type)
760     {
761     case NX_MVRP_ACTION_NEW:
762         mrp_event = NX_MRP_EVENT_NEW;
763         break;
764 
765     case NX_MVRP_ACTION_TYPE_JOIN:
766         mrp_event = NX_MRP_EVENT_JOIN;
767         break;
768 
769     case NX_MVRP_ACTION_TYPE_LEAVE:
770         mrp_event = NX_MRP_EVENT_LV;
771         break;
772 
773     default:
774         tx_mutex_put(&(mrp -> mrp_mutex));
775         return(NX_INVALID_PARAMETERS);
776     }
777 
778     status = nx_mrp_event_process(mrp, participant, attribute, mrp_event);
779 
780     /* Release the mutex.  */
781     tx_mutex_put(&(mrp -> mrp_mutex));
782 
783     return(status);
784 }
785 
786 /**************************************************************************/
787 /*                                                                        */
788 /*  FUNCTION                                               RELEASE        */
789 /*                                                                        */
790 /*    nx_mvrp_init                                        PORTABLE C      */
791 /*                                                           6.4.0        */
792 /*  AUTHOR                                                                */
793 /*                                                                        */
794 /*    Yajun Xia, Microsoft Corporation                                    */
795 /*                                                                        */
796 /*  DESCRIPTION                                                           */
797 /*                                                                        */
798 /*    This function init the MVRP instance.                               */
799 /*                                                                        */
800 /*  INPUT                                                                 */
801 /*                                                                        */
802 /*    mvrp_ptr                              MVRP instance                 */
803 /*                                                                        */
804 /*  OUTPUT                                                                */
805 /*                                                                        */
806 /*    status                                Completion status             */
807 /*                                                                        */
808 /*  CALLS                                                                 */
809 /*                                                                        */
810 /*    None                                                                */
811 /*                                                                        */
812 /*  CALLED BY                                                             */
813 /*                                                                        */
814 /*    nx_srp_init                           SRP init                      */
815 /*                                                                        */
816 /*  RELEASE HISTORY                                                       */
817 /*                                                                        */
818 /*    DATE              NAME                      DESCRIPTION             */
819 /*                                                                        */
820 /*  12-31-2023     Yajun Xia                Initial Version 6.4.0         */
821 /*                                                                        */
822 /**************************************************************************/
nx_mvrp_init(NX_MVRP * mvrp_ptr)823 UINT nx_mvrp_init(NX_MVRP *mvrp_ptr)
824 {
825 
826     mvrp_ptr -> participant.participant_type = NX_MRP_PARTICIPANT_MVRP;
827     mvrp_ptr -> participant.protocol_version = NX_MRP_MVRP_PROTOCOL_VERSION;
828     mvrp_ptr -> participant.indication_function = nx_mvrp_indication_process;
829     mvrp_ptr -> participant.unpack_function = nx_mvrp_mrpdu_unpack;
830     mvrp_ptr -> participant.pack_function = nx_mvrp_mrpdu_pack;
831 
832     mvrp_ptr -> participant.join_timer = NX_MRP_TIMER_JOIN;
833     mvrp_ptr -> participant.leaveall_timer = NX_MRP_TIMER_LEAVEALL;
834 
835     mvrp_ptr -> participant.inused_head = NX_NULL;
836     mvrp_ptr -> participant.next = NX_NULL;
837 
838     return(NX_SUCCESS);
839 }
840 #endif /* NX_ENABLE_VLAN */
841