builtinurl: mark api as deprecated
[vpp.git] / src / plugins / lacp / selection.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdint.h>
17 #include <vlib/vlib.h>
18 #include <vlib/unix/unix.h>
19 #include <vnet/bonding/node.h>
20 #include <lacp/node.h>
21
22 static int
23 lacp_set_port_selected (vlib_main_t *vm, bond_if_t *bif, member_if_t *mif)
24 {
25   uword p;
26   member_if_t *mif2;
27
28   /* Handle loopback port */
29   if (!memcmp (mif->partner.system, mif->actor.system, 6) &&
30       (mif->partner.key == mif->actor.key))
31     {
32       mif->loopback_port = 1;
33       mif->actor.state &= ~LACP_STATE_AGGREGATION;
34       mif->selected = LACP_PORT_UNSELECTED;
35       lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
36                              LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
37       return LACP_ERROR_LOOPBACK_PORT;
38     }
39   if (vec_len (bif->active_members))
40     {
41       p = *vec_elt_at_index (bif->active_members, 0);
42       mif2 = bond_get_member_by_sw_if_index (p);
43       if (mif2 && ((mif2->partner.key != mif->partner.key) ||
44                    memcmp (mif2->partner.system, mif->partner.system, 6)))
45         {
46           mif->selected = LACP_PORT_UNSELECTED;
47           lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
48                                  LACP_MUX_EVENT_UNSELECTED, &mif->mux_state);
49           return LACP_ERROR_BAD_KEY;
50         }
51     }
52   mif->selected = LACP_PORT_SELECTED;
53
54   switch (mif->mux_state)
55     {
56     case LACP_MUX_STATE_DETACHED:
57       break;
58     case LACP_MUX_STATE_WAITING:
59       if (!mif->ready)
60         return LACP_ERROR_NONE;
61       break;
62     case LACP_MUX_STATE_ATTACHED:
63       if (!(mif->partner.state & LACP_STATE_SYNCHRONIZATION))
64         return LACP_ERROR_NONE;
65       break;
66     case LACP_MUX_STATE_COLLECTING_DISTRIBUTING:
67       break;
68     default:
69       break;
70     }
71   return lacp_machine_dispatch (&lacp_mux_machine, vm, mif,
72                                 LACP_MUX_EVENT_SELECTED, &mif->mux_state);
73 }
74
75 int
76 lacp_selection_logic (vlib_main_t *vm, member_if_t *mif)
77 {
78   member_if_t *mif2;
79   bond_if_t *bif;
80   u32 *sw_if_index;
81
82   bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance);
83   vec_foreach (sw_if_index, bif->members)
84   {
85     mif2 = bond_get_member_by_sw_if_index (*sw_if_index);
86     if (mif2 && (mif2->actor.state & LACP_STATE_SYNCHRONIZATION) &&
87         (mif2->ready_n == 0))
88       goto out;
89   }
90
91   vec_foreach (sw_if_index, bif->members)
92   {
93     mif2 = bond_get_member_by_sw_if_index (*sw_if_index);
94     if (mif2)
95       {
96         mif2->ready = 1;
97         if (mif2->selected == LACP_PORT_SELECTED)
98           lacp_machine_dispatch (&lacp_mux_machine, vm, mif2,
99                                  LACP_MUX_EVENT_READY, &mif2->mux_state);
100       }
101   }
102 out:
103   return lacp_set_port_selected (vm, bif, mif);
104 }
105
106 /*
107  * fd.io coding-style-patch-verification: ON
108  *
109  * Local Variables:
110  * eval: (c-set-style "gnu")
111  * End:
112  */