Line data Source code
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 17 : 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 17 : if (!memcmp (mif->partner.system, mif->actor.system, 6) && 30 0 : (mif->partner.key == mif->actor.key)) 31 : { 32 0 : mif->loopback_port = 1; 33 0 : mif->actor.state &= ~LACP_STATE_AGGREGATION; 34 0 : mif->selected = LACP_PORT_UNSELECTED; 35 0 : lacp_machine_dispatch (&lacp_mux_machine, vm, mif, 36 : LACP_MUX_EVENT_UNSELECTED, &mif->mux_state); 37 0 : return LACP_ERROR_LOOPBACK_PORT; 38 : } 39 17 : if (vec_len (bif->active_members)) 40 : { 41 12 : p = *vec_elt_at_index (bif->active_members, 0); 42 12 : mif2 = bond_get_member_by_sw_if_index (p); 43 12 : if (mif2 && ((mif2->partner.key != mif->partner.key) || 44 12 : memcmp (mif2->partner.system, mif->partner.system, 6))) 45 : { 46 0 : mif->selected = LACP_PORT_UNSELECTED; 47 0 : lacp_machine_dispatch (&lacp_mux_machine, vm, mif, 48 : LACP_MUX_EVENT_UNSELECTED, &mif->mux_state); 49 0 : return LACP_ERROR_BAD_KEY; 50 : } 51 : } 52 17 : mif->selected = LACP_PORT_SELECTED; 53 : 54 17 : switch (mif->mux_state) 55 : { 56 5 : case LACP_MUX_STATE_DETACHED: 57 5 : break; 58 3 : case LACP_MUX_STATE_WAITING: 59 3 : if (!mif->ready) 60 3 : return LACP_ERROR_NONE; 61 0 : break; 62 3 : case LACP_MUX_STATE_ATTACHED: 63 3 : if (!(mif->partner.state & LACP_STATE_SYNCHRONIZATION)) 64 0 : return LACP_ERROR_NONE; 65 3 : break; 66 6 : case LACP_MUX_STATE_COLLECTING_DISTRIBUTING: 67 6 : break; 68 0 : default: 69 0 : break; 70 : } 71 14 : return lacp_machine_dispatch (&lacp_mux_machine, vm, mif, 72 : LACP_MUX_EVENT_SELECTED, &mif->mux_state); 73 : } 74 : 75 : int 76 17 : 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 17 : bif = bond_get_bond_if_by_dev_instance (mif->bif_dev_instance); 83 29 : vec_foreach (sw_if_index, bif->members) 84 : { 85 24 : mif2 = bond_get_member_by_sw_if_index (*sw_if_index); 86 24 : if (mif2 && (mif2->actor.state & LACP_STATE_SYNCHRONIZATION) && 87 17 : (mif2->ready_n == 0)) 88 12 : goto out; 89 : } 90 : 91 14 : vec_foreach (sw_if_index, bif->members) 92 : { 93 9 : mif2 = bond_get_member_by_sw_if_index (*sw_if_index); 94 9 : if (mif2) 95 : { 96 9 : mif2->ready = 1; 97 9 : if (mif2->selected == LACP_PORT_SELECTED) 98 4 : lacp_machine_dispatch (&lacp_mux_machine, vm, mif2, 99 : LACP_MUX_EVENT_READY, &mif2->mux_state); 100 : } 101 : } 102 5 : out: 103 17 : 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 : */