Example #1
0
switch_status_t
switch_stp_update_flood_list(switch_device_t device, switch_handle_t stg_handle,
                             switch_handle_t intf_handle, switch_stp_state_t state)
{
    switch_stp_info_t                 *stp_info = NULL;
    switch_bd_info_t                  *bd_info = NULL;
    switch_stp_vlan_entry_t           *vlan_entry = NULL;
    tommy_node                        *node = NULL;
    switch_handle_t                    bd_handle = 0;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    switch_vlan_interface_t            vlan_intf;

    if (!SWITCH_STP_HANDLE_VALID(stg_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    stp_info = switch_api_stp_get_internal(stg_handle);
    if (!stp_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    node = tommy_list_head(&(stp_info->vlan_list));
    while (node) {
        vlan_entry = node->data;
        bd_handle = vlan_entry->bd_handle;
        bd_info = switch_bd_get(bd_handle);
        if (!bd_info) {
            return SWITCH_STATUS_INVALID_VLAN_ID;
        }

        memset(&vlan_intf, 0, sizeof(vlan_intf));
        vlan_intf.vlan_handle = bd_handle;
        vlan_intf.intf_handle = intf_handle;
        switch (state) {
            case SWITCH_PORT_STP_STATE_FORWARDING:
                status = switch_api_multicast_member_add(
                    device, bd_info->uuc_mc_index, 1, &vlan_intf);
                break;
            case SWITCH_PORT_STP_STATE_BLOCKING:
            case SWITCH_PORT_STP_STATE_NONE:
                status = switch_api_multicast_member_delete(
                    device, bd_info->uuc_mc_index, 1, &vlan_intf);
                break;

            default:
                break;
        }
        node = node->next;
    }
    return status;
}
Example #2
0
switch_status_t
switch_api_stp_group_vlans_remove(switch_device_t device,
                                 switch_handle_t stg_handle,
                                 uint16_t vlan_count,
                                 switch_handle_t *vlan_handle)
{
    switch_stp_info_t                 *stp_info = NULL;
    switch_bd_info_t                  *bd_info = NULL;
    switch_stp_vlan_entry_t           *vlan_entry = NULL;
    tommy_node                        *node = NULL;
    switch_handle_t                    bd_handle;
    int                                count = 0;

    if (!SWITCH_STP_HANDLE_VALID(stg_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    stp_info = switch_api_stp_get_internal(stg_handle);
    if (!stp_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    for (count = 0; count < vlan_count; count++) {
        bd_handle = vlan_handle[count];
        bd_info = switch_bd_get(bd_handle);
        if (!bd_info) {
            return SWITCH_STATUS_INVALID_VLAN_ID;
        }

        node = tommy_list_head(&(stp_info->vlan_list));
        while (node) {
            vlan_entry = node->data;
            if (vlan_entry->bd_handle == bd_handle) {
                break;
            }
            node = node->next;
        }

        if (!node) {
            return SWITCH_STATUS_ITEM_NOT_FOUND;
        }

        bd_info->stp_handle = 0;
        switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle),
                                        bd_info);

        vlan_entry = tommy_list_remove_existing(&(stp_info->vlan_list), node);
        switch_free(vlan_entry);
    }
    return SWITCH_STATUS_SUCCESS;
}
Example #3
0
switch_status_t
switch_api_stp_group_vlans_add(switch_device_t device,
                              switch_handle_t stg_handle,
                              uint16_t vlan_count,
                              switch_handle_t *vlan_handle)
{
    switch_stp_info_t                 *stp_info = NULL;
    switch_bd_info_t                  *bd_info = NULL;
    switch_stp_vlan_entry_t           *vlan_entry = NULL;
    switch_handle_t                    bd_handle;
    int                                count = 0;

    if (!SWITCH_STP_HANDLE_VALID(stg_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    stp_info = switch_api_stp_get_internal(stg_handle);
    if (!stp_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    for (count = 0; count < vlan_count; count++) {
        bd_handle = vlan_handle[count];
        bd_info = switch_bd_get(bd_handle);
        if (!bd_info) {
            return SWITCH_STATUS_INVALID_VLAN_ID;
        }

        vlan_entry = switch_malloc(sizeof(switch_stp_vlan_entry_t), 1);
        if (!vlan_entry) {
            return SWITCH_STATUS_NO_MEMORY;
        }
        memset(vlan_entry, 0 , sizeof(switch_stp_vlan_entry_t));

        vlan_entry->bd_handle = bd_handle;
        bd_info->stp_handle = stg_handle;

        switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle),
                                        bd_info);

        tommy_list_insert_head(&(stp_info->vlan_list),
                        &(vlan_entry->node), vlan_entry);
    }
    return SWITCH_STATUS_SUCCESS;
}
Example #4
0
switch_status_t
switch_api_interface_router_mac_handle_set(switch_handle_t intf_handle, uint64_t value)
{

    switch_interface_info_t           *intf_info = NULL;
    switch_api_interface_info_t       *api_intf_info = NULL;
    switch_bd_info_t                  *bd_info = NULL;
    switch_rmac_info_t                *rmac_info = NULL;
    switch_handle_t                    rmac_handle = 0;
    switch_handle_t                    bd_handle = 0;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;

    intf_info = switch_api_interface_get(intf_handle);
    if (!intf_info) {
        return SWITCH_STATUS_INVALID_INTERFACE;
    }

    api_intf_info = &intf_info->api_intf_info;
    if (!SWITCH_INTF_IS_PORT_L3(intf_info)) {
        return SWITCH_STATUS_INVALID_INTERFACE;
    }

    rmac_handle = (switch_handle_t) value;
    rmac_info = switch_api_rmac_info_get_internal(rmac_handle);
    if (!rmac_info) {
        return SWITCH_STATUS_ITEM_NOT_FOUND;
    }

    bd_handle = intf_info->bd_handle;
    bd_info = switch_bd_get(bd_handle);
    if (!bd_info) {
        return SWITCH_STATUS_INVALID_VLAN_ID;
    }

    api_intf_info->rmac_handle = rmac_handle;
    status = switch_bd_router_mac_handle_set(bd_handle, rmac_handle);
    return status;
}
Example #5
0
switch_status_t switch_api_packet_net_filter_rx_create(
    switch_device_t device,
    switch_packet_rx_key_t *rx_key,
    switch_packet_rx_action_t *rx_action) {
  switch_hostif_info_t *hostif_info = NULL;
  switch_lag_info_t *lag_info = NULL;
  switch_port_info_t *port_info = NULL;
  switch_packet_rx_entry_t rx_entry;
  switch_packet_rx_info_t *rx_info = NULL;
  switch_handle_type_t handle_type = 0;
  switch_interface_info_t *intf_info = NULL;
  switch_handle_t bd_handle = 0;
  switch_bd_info_t *bd_info = NULL;
  switch_ifindex_t ifindex = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  if (!rx_key || !rx_action) {
    SWITCH_API_ERROR("filter rx create failed. invalid params");
    return SWITCH_STATUS_INVALID_PARAMETER;
  }

  memset(&rx_entry, 0x0, sizeof(rx_entry));

  if (rx_key->port_lag_valid) {
    handle_type = switch_handle_get_type(rx_key->port_lag_handle);
    if (handle_type == SWITCH_HANDLE_TYPE_LAG) {
      lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle);
      if (!lag_info) {
        SWITCH_API_ERROR("invalid lag handle");
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      ifindex = lag_info->ifindex;
    } else {
      port_info = switch_api_port_get_internal(rx_key->port_lag_handle);
      if (!port_info) {
        SWITCH_API_ERROR("invalid port handle");
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      ifindex = port_info->ifindex;
    }
    rx_entry.ifindex_valid = TRUE;
  }

  if (rx_key->handle_valid) {
    bd_handle = rx_key->handle;
    handle_type = switch_handle_get_type(rx_key->handle);
    if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) {
      intf_info = switch_api_interface_get(rx_key->handle);
      if (!intf_info) {
        SWITCH_API_ERROR("intf_handle %lx is invalid", rx_key->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      if (!SWITCH_INTF_IS_PORT_L3(intf_info)) {
        SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      bd_handle = intf_info->bd_handle;
    }

    bd_info = switch_bd_get(bd_handle);
    if (!bd_info) {
      SWITCH_API_ERROR("bd derivation failed %lx", rx_key->handle);
      return SWITCH_STATUS_INVALID_HANDLE;
    }
    rx_entry.bd_valid = TRUE;
  }

  if (rx_action->hostif_handle) {
    hostif_info = switch_hostif_get(rx_action->hostif_handle);
    if (!hostif_info) {
      SWITCH_API_ERROR("invalid hostif handle");
      return SWITCH_STATUS_INVALID_HANDLE;
    }
  }

  rx_entry.bd = handle_to_id(bd_handle);
  rx_entry.ifindex = ifindex;
  rx_entry.port_valid = rx_key->port_valid;
  rx_entry.port = handle_to_id(rx_key->port_handle);
  rx_entry.reason_code_valid = rx_key->reason_code_valid;
  rx_entry.reason_code = rx_key->reason_code;
  rx_entry.reason_code_mask = rx_key->reason_code_mask;
  rx_entry.priority = rx_key->priority;

  rx_info = switch_malloc(sizeof(switch_packet_rx_info_t), 0x1);
  if (!rx_info) {
    SWITCH_API_ERROR("port %lx port_lag %lx handle %lx malloc failed",
                     rx_key->port_handle,
                     rx_key->port_lag_handle,
                     rx_key->handle);
    return SWITCH_STATUS_NO_MEMORY;
  }

  memset(rx_info, 0x0, sizeof(switch_packet_rx_info_t));
  memcpy(&rx_info->rx_entry, &rx_entry, sizeof(rx_entry));
  rx_info->vlan_id = rx_action->vlan_id;
  rx_info->vlan_action = rx_action->vlan_action;
  if (hostif_info) {
    rx_info->intf_fd = hostif_info->intf_fd;
  }

  SWITCH_API_INFO(
      "net_filter_rx_create: port 0x%lx, port_lag_hdl = 0x%lx, "
      "if_bd_hdl 0x%lx, rcode 0x%x, rcode_mask 0x%x "
      "vlan_id %d, fd %d, action %d\n",
      rx_key->port_valid ? rx_key->port_handle : 0,
      rx_key->port_lag_valid ? rx_key->port_lag_handle : 0,
      rx_key->handle_valid ? rx_key->handle : 0,
      rx_key->reason_code_valid ? rx_key->reason_code : 0,
      rx_key->reason_code_mask,
      rx_info->vlan_id,
      rx_info->vlan_action,
      rx_info->intf_fd);
  /*
   * Adding an element to the list results in sorting the list.
   * tommy does not have a way to compare and insert the elements
   */
  tommy_list_insert_head(&packet_rx_filter_list, &(rx_info->node), rx_info);
  tommy_list_sort(&packet_rx_filter_list,
                  switch_packet_rx_filter_priority_compare);
  return status;
}
Example #6
0
switch_status_t switch_api_packet_net_filter_tx_create(
    switch_device_t device,
    switch_packet_tx_key_t *tx_key,
    switch_packet_tx_action_t *tx_action) {
  switch_packet_tx_entry_t tx_entry;
  switch_packet_tx_info_t *tx_info = NULL;
  switch_hostif_info_t *hostif_info = NULL;
  switch_handle_t bd_handle = 0;
  switch_interface_info_t *intf_info = NULL;
  switch_handle_type_t handle_type = 0;
  switch_bd_info_t *bd_info = NULL;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  if (!tx_key || !tx_action) {
    SWITCH_API_ERROR("filter tx create failed. invalid params");
    return SWITCH_STATUS_INVALID_PARAMETER;
  }

  if (tx_key->handle_valid) {
    hostif_info = switch_hostif_get(tx_key->hostif_handle);
    if (!hostif_info) {
      SWITCH_API_ERROR("invalid hostif handle");
      return SWITCH_STATUS_INVALID_HANDLE;
    }
  }

  memset(&tx_entry, 0x0, sizeof(tx_entry));
  if (tx_key->handle_valid) {
    tx_entry.intf_fd = hostif_info->intf_fd;
  }
  tx_entry.fd_valid = tx_key->handle_valid;
  tx_entry.vlan_id = tx_key->vlan_id;
  tx_entry.vlan_valid = tx_key->vlan_valid;
  tx_entry.priority = tx_key->priority;

  tx_info = switch_malloc(sizeof(switch_packet_tx_info_t), 0x1);
  if (!tx_info) {
    SWITCH_API_ERROR("hif %lx vlan %x malloc failure",
                     tx_key->hostif_handle,
                     tx_key->vlan_id);
    return SWITCH_STATUS_NO_MEMORY;
  }

  if (tx_action->bypass_flags != SWITCH_BYPASS_ALL) {
    bd_handle = tx_action->handle;

    handle_type = switch_handle_get_type(tx_action->handle);
    if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) {
      intf_info = switch_api_interface_get(tx_action->handle);
      if (!intf_info) {
        SWITCH_API_ERROR("intf_handle %lx is invalid", tx_action->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      if (!SWITCH_INTF_IS_PORT_L3(intf_info)) {
        SWITCH_API_ERROR("intf_handle %lx is not l3", tx_action->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      bd_handle = intf_info->bd_handle;
    }

    bd_info = switch_bd_get(bd_handle);
    if (!bd_info) {
      SWITCH_API_ERROR(
          "hif %lx vlan %x invalid bd", tx_key->hostif_handle, tx_key->vlan_id);
      return SWITCH_STATUS_INVALID_HANDLE;
    }
  }

  memcpy(&tx_info->tx_entry, &tx_entry, sizeof(tx_entry));
  tx_info->bd = handle_to_id(bd_handle);
  tx_info->bypass_flags = tx_action->bypass_flags;
  tx_info->port = handle_to_id(tx_action->port_handle);

  SWITCH_API_INFO(
      "net_filter_tx_create: hostif 0x%lx, vlan_id = %d, fd 0x%x, bypass "
      "0x%x\n",
      tx_key->hostif_handle,
      tx_key->vlan_valid ? tx_key->vlan_id : 0xFFF,
      tx_entry.intf_fd,
      tx_info->bypass_flags);

  tommy_list_insert_head(&packet_tx_filter_list, &(tx_info->node), tx_info);
  tommy_list_sort(&packet_tx_filter_list,
                  switch_packet_tx_filter_priority_compare);
  return status;
}
Example #7
0
switch_status_t switch_api_packet_net_filter_rx_delete(
    switch_device_t device, switch_packet_rx_key_t *rx_key) {
  switch_lag_info_t *lag_info = NULL;
  switch_port_info_t *port_info = NULL;
  switch_packet_rx_entry_t *tmp_rx_entry = NULL;
  switch_packet_rx_entry_t rx_entry;
  switch_packet_rx_info_t *tmp_rx_info = NULL;
  switch_handle_type_t handle_type = 0;
  switch_interface_info_t *intf_info = NULL;
  switch_handle_t bd_handle = 0;
  switch_bd_info_t *bd_info = NULL;
  tommy_node *node = NULL;
  bool node_found = FALSE;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  if (!rx_key) {
    SWITCH_API_ERROR("filter rx delete failed. invalid params");
    return SWITCH_STATUS_INVALID_PARAMETER;
  }

  memset(&rx_entry, 0, sizeof(switch_packet_rx_entry_t));

  if (rx_key->port_lag_valid && rx_key->port_lag_handle) {
    handle_type = switch_handle_get_type(rx_key->port_lag_handle);
    if (handle_type == SWITCH_HANDLE_TYPE_LAG) {
      lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle);
      if (!lag_info) {
        SWITCH_API_ERROR("invalid lag handle");
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      rx_entry.ifindex = lag_info->ifindex;
    } else {
      port_info = switch_api_port_get_internal(rx_key->port_lag_handle);
      if (!port_info) {
        SWITCH_API_ERROR("invalid port handle");
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      rx_entry.ifindex = port_info->ifindex;
    }
  }

  if (rx_key->handle_valid) {
    bd_handle = rx_key->handle;
    handle_type = switch_handle_get_type(rx_key->handle);
    if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) {
      intf_info = switch_api_interface_get(rx_key->handle);
      if (!intf_info) {
        SWITCH_API_ERROR("intf_handle %lx is invalid", rx_key->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      if (!SWITCH_INTF_IS_PORT_L3(intf_info)) {
        SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->handle);
        return SWITCH_STATUS_INVALID_HANDLE;
      }
      bd_handle = intf_info->bd_handle;
    }
    bd_info = switch_bd_get(bd_handle);
    if (!bd_info) {
      SWITCH_API_ERROR("bd derivation failed %lx", rx_key->handle);
      return SWITCH_STATUS_INVALID_HANDLE;
    }
    rx_entry.bd = handle_to_id(bd_handle);
  }

  if (rx_entry.port_valid) {
    rx_entry.port = handle_to_id(rx_key->port_handle);
  }
  rx_entry.bd_valid = rx_key->handle_valid;
  rx_entry.reason_code = rx_key->reason_code;

  node = tommy_list_head(&packet_rx_filter_list);
  while (node) {
    tmp_rx_info = (switch_packet_rx_info_t *)node->data;
    tmp_rx_entry = &tmp_rx_info->rx_entry;
    if (switch_packet_rx_filter_match(tmp_rx_entry, &rx_entry)) {
      node_found = TRUE;
      break;
    }
    node = node->next;
  }

  if (!node_found) {
    SWITCH_API_ERROR("tx filter delete failed. node find failed");
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }

  tommy_list_remove_existing(&packet_rx_filter_list, node);

  switch_free(tmp_rx_info);
  return status;
}
Example #8
0
switch_status_t
switch_nhop_ifindex_get(switch_handle_t nhop_handle,
                        switch_ifindex_t *ifindex,
                        bool *flood,
                        uint32_t *mc_index)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_neighbor_info_t            *neighbor_info = NULL;
    switch_api_neighbor_t             *neighbor = NULL;
    switch_api_mac_entry_t             mac_entry;
    switch_mac_info_t                 *mac_info = NULL;
    switch_handle_t                    neighbor_handle;
    switch_bd_info_t                  *bd_info = NULL;
    switch_port_info_t                *tmp_port_info = NULL;
    switch_lag_info_t                 *tmp_lag_info = NULL;
    switch_interface_info_t           *tmp_intf_info = NULL;
    switch_api_mac_entry_t            *tmp_mac_entry = NULL;
    switch_handle_type_t               handle_type = 0;
    switch_handle_t                    encap_if;
    switch_spath_info_t               *spath_info = NULL;

    nhop_info = switch_nhop_get(nhop_handle);
    if (!nhop_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info));
    intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle);
    if (!intf_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    *ifindex = intf_info->ifindex;
    *flood = FALSE;
    *mc_index = 0;

    if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) {
        encap_if = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info);
        intf_info = switch_api_interface_get(encap_if);
        if (!intf_info) {
            return SWITCH_STATUS_INVALID_HANDLE;
        }
        *ifindex = intf_info->ifindex;
        SWITCH_API_TRACE("%s:%d ifindex for tunnel interface: %x",
                         __FUNCTION__, __LINE__, *ifindex);
    }

    if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN) {
        neighbor_handle = spath_info->neighbor_handle;
        if (neighbor_handle == SWITCH_API_INVALID_HANDLE ||
            neighbor_handle == 0) {
            *ifindex = switch_api_cpu_glean_ifindex();
        } else {
            neighbor_info = switch_neighbor_info_get(neighbor_handle);
            if (!neighbor_info) {
                return SWITCH_STATUS_INVALID_HANDLE;
            }
            neighbor = &neighbor_info->neighbor;
            memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t));
            mac_entry.vlan_handle = intf_info->bd_handle;
            memcpy(&mac_entry.mac, &neighbor->mac_addr, ETH_LEN);
            mac_info = switch_mac_table_entry_find(&mac_entry);
            if (!mac_info) {
                bd_info = switch_bd_get(intf_info->bd_handle);
                if (!bd_info) {
                    return SWITCH_STATUS_INVALID_HANDLE;
                }
                *mc_index = handle_to_id(bd_info->uuc_mc_index);
                *flood = TRUE;
            } else {
                tmp_mac_entry = &mac_info->mac_entry;
                handle_type = switch_handle_get_type(tmp_mac_entry->handle);
                switch (handle_type) {
                    case SWITCH_HANDLE_TYPE_PORT:
                        tmp_port_info = switch_api_port_get_internal(tmp_mac_entry->handle);
                        if (!tmp_port_info) {
                            return SWITCH_STATUS_INVALID_HANDLE;
                        }
                        *ifindex = tmp_port_info->ifindex;
                        break;
                    case SWITCH_HANDLE_TYPE_LAG:
                        tmp_lag_info = switch_api_lag_get_internal(tmp_mac_entry->handle);
                        if (!tmp_lag_info) {
                            return SWITCH_STATUS_INVALID_HANDLE;
                        }
                        *ifindex = tmp_lag_info->ifindex;
                        break;
                    case SWITCH_HANDLE_TYPE_INTERFACE:
                        tmp_intf_info = switch_api_interface_get(tmp_mac_entry->handle);
                        if (!tmp_intf_info) {
                            return SWITCH_STATUS_INVALID_HANDLE;
                        }
                        *ifindex = tmp_intf_info->ifindex;
                        break;
                    default:
                        return SWITCH_STATUS_INVALID_HANDLE;
                }
            }
        }
    }
    return SWITCH_STATUS_SUCCESS;
}