Пример #1
0
switch_status_t
switch_api_nhop_delete(switch_device_t device, switch_handle_t nhop_handle)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_spath_info_t               *spath_info = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;

    if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

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

    if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    if (nhop_info->ref_count) {
        return SWITCH_STATUS_RESOURCE_IN_USE;
    }

    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_INTERFACE;
    }
    nhop_info->valid = 0;
    if(nhop_info->u.spath.neighbor_handle == 0) {
#ifdef SWITCH_PD
        status = switch_pd_nexthop_table_delete_entry(device, spath_info->hw_entry);
        if (status != SWITCH_STATUS_SUCCESS) {
            return status;
        }
        if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) {
            status = switch_pd_urpf_bd_table_delete_entry(device, spath_info->urpf_hw_entry);
            if (status != SWITCH_STATUS_SUCCESS) {
                return status;
            }
        }
#endif
        switch_nhop_delete_hash(spath_info);
        switch_nhop_delete(nhop_handle);
    }
    return SWITCH_STATUS_SUCCESS;
}
Пример #2
0
switch_nhop_index_type_t
switch_api_nhop_type_get(switch_handle_t nhop_handle)
{
    switch_nhop_info_t                *nhop_info = NULL;

    if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
        return SWITCH_NHOP_INDEX_TYPE_NONE;
    }

    nhop_info = switch_nhop_get(nhop_handle);
    if (!nhop_info) {
        return SWITCH_NHOP_INDEX_TYPE_NONE;
    }
    return nhop_info->type;
}
Пример #3
0
switch_handle_t
switch_api_neighbor_handle_get(switch_handle_t nhop_handle)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_spath_info_t               *spath_info = NULL;

    if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
        return SWITCH_API_INVALID_HANDLE;
    }

    nhop_info = switch_nhop_get(nhop_handle);
    if (!nhop_info) {
        return SWITCH_API_INVALID_HANDLE;
    }
    spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info));
    return spath_info->neighbor_handle;
}
Пример #4
0
switch_status_t
switch_api_nhop_update(switch_device_t device, switch_handle_t nhop_handle)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_spath_info_t               *spath_info = NULL;
    switch_ifindex_t                   ifindex = 0;
    bool                               flood = FALSE;
    uint32_t                           mc_index = 0;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;

    if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

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

    status = switch_nhop_ifindex_get(nhop_handle, &ifindex, &flood, &mc_index);
    if (status != SWITCH_STATUS_SUCCESS) {
        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_INTERFACE;
    }

#ifdef SWITCH_PD
    bool tunnel = (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL);
    status = switch_pd_nexthop_table_update_entry(device,
                                  handle_to_id(nhop_handle),
                                  handle_to_id(intf_info->bd_handle),
                                  ifindex, flood, mc_index, tunnel,
                                  &spath_info->hw_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
        return SWITCH_API_INVALID_HANDLE;
    }

#endif
    return SWITCH_STATUS_SUCCESS;
}
Пример #5
0
switch_status_t
switch_api_ecmp_delete(switch_device_t device, switch_handle_t handle)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_ecmp_info_t                *ecmp_info = NULL;
    tommy_node                        *node = NULL;
    switch_ecmp_member_t              *ecmp_member = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;

    if (!SWITCH_NHOP_HANDLE_VALID(handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    nhop_info = switch_nhop_get(handle);
    if (!nhop_info) {
        return SWITCH_STATUS_INVALID_NHOP;
    }
    if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) {
        ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info));
        if (ecmp_info->count > 0) {
            node = tommy_list_head(&(ecmp_info->members));
            while (node) {
                ecmp_member = (switch_ecmp_member_t *) node->data;
                nhop_info = switch_nhop_get(ecmp_member->nhop_handle);
                if (!nhop_info) {
                    return SWITCH_STATUS_INVALID_NHOP;
                }
                nhop_info->ref_count--;
                node = node->next;
            }
        }
#ifdef SWITCH_PD
        status = switch_pd_ecmp_group_delete(device, ecmp_info->pd_group_hdl);
        if (status != SWITCH_STATUS_SUCCESS) {
            return status;
        }
#endif
    }
    return switch_nhop_delete(handle);
}
Пример #6
0
switch_status_t switch_api_l3_route_add(switch_device_t device,
                                        switch_handle_t vrf,
                                        switch_ip_addr_t *ip_addr,
                                        switch_handle_t nhop_handle) {
  switch_l3_hash_t *hash_entry = NULL;
  switch_nhop_info_t *nhop_info = NULL;
  uint32_t nhop_index = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;
  unsigned int v4_mask = 0;
  uint8_t v6_mask[16];
  switch_ip_addr_t masked_ip;

  if (!SWITCH_VRF_HANDLE_VALID(vrf)) {
    return SWITCH_STATUS_INVALID_HANDLE;
  }

  if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
    return SWITCH_STATUS_INVALID_HANDLE;
  }

  nhop_index = handle_to_id(nhop_handle);
  nhop_info = switch_nhop_get(nhop_handle);
  if (!nhop_info) {
    SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__);
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }

  hash_entry = switch_l3_search_hash(vrf, ip_addr);
  if (hash_entry) {
    hash_entry->nhop_handle = nhop_handle;
#ifdef SWITCH_PD
    status = switch_pd_ip_fib_update_entry(device,
                                           handle_to_id(vrf),
                                           ip_addr,
                                           SWITCH_NHOP_TYPE_IS_ECMP(nhop_info),
                                           nhop_index,
                                           hash_entry->hw_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      return status;
    }

    status = switch_pd_urpf_update_entry(device,
                                         handle_to_id(vrf),
                                         ip_addr,
                                         handle_to_id(nhop_handle),
                                         hash_entry->urpf_entry);
#endif
  } else {
    memcpy(&masked_ip, ip_addr, sizeof(switch_ip_addr_t));
    if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
      v4_mask = prefix_to_v4_mask(ip_addr->prefix_len);
      masked_ip.ip.v4addr = ip_addr->ip.v4addr & v4_mask;
    } else {
      int i = 0;
      prefix_to_v6_mask(ip_addr->prefix_len, v6_mask);
      for (i = 0; i < 16; i++) {
        masked_ip.ip.v6addr[i] = ip_addr->ip.v6addr[i] & v6_mask[i];
      }
    }
    hash_entry = switch_l3_insert_hash(vrf, ip_addr, nhop_handle);
    if (!hash_entry) {
      return SWITCH_STATUS_NO_MEMORY;
    }
    hash_entry->nhop_handle = nhop_handle;
#ifdef SWITCH_PD
    // set the HW entry
    status = switch_pd_ip_fib_add_entry(device,
                                        handle_to_id(vrf),
                                        ip_addr,
                                        SWITCH_NHOP_TYPE_IS_ECMP(nhop_info),
                                        nhop_index,
                                        &hash_entry->hw_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      return status;
    }

    status = switch_pd_urpf_add_entry(device,
                                      handle_to_id(vrf),
                                      ip_addr,
                                      handle_to_id(nhop_handle),
                                      &hash_entry->urpf_entry);
#endif
  }
  return status;
}
Пример #7
0
switch_status_t
switch_api_ecmp_member_delete(switch_device_t device, switch_handle_t ecmp_handle,
                              uint16_t nhop_count, switch_handle_t *nhop_handle_list)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_nhop_info_t                *e_nhop_info = NULL;
    switch_spath_info_t               *spath_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_ecmp_info_t                *ecmp_info = NULL;
    switch_ecmp_member_t              *ecmp_member = NULL;
    tommy_node                        *node = NULL;
    switch_handle_t                    nhop_handle;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    int                                count = 0;

    if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    e_nhop_info = switch_nhop_get(ecmp_handle);
    if (!e_nhop_info) {
        return SWITCH_STATUS_INVALID_NHOP;
    }
    for (count = 0; count < nhop_count; count++) {
        nhop_handle = nhop_handle_list[count];
        if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
            return SWITCH_STATUS_INVALID_HANDLE;
        }
        nhop_info = switch_nhop_get(nhop_handle);
        if (!nhop_info) {
            return SWITCH_STATUS_INVALID_NHOP;
        }
        spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info));
        ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info));
        node = tommy_list_head(&(ecmp_info->members));
        while (node) {
            ecmp_member = (switch_ecmp_member_t *) node->data;
            if (ecmp_member->nhop_handle == nhop_handle) {
                break;
            }
            node = node->next;
        }

        if (!node) {
            return SWITCH_STATUS_ITEM_NOT_FOUND;
        }
        intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle);
        if (!intf_info) {
            return SWITCH_STATUS_INVALID_INTERFACE;
        }

        nhop_info->ref_count--;
#if SWITCH_PD
        if (ecmp_info->count == 1) {
            status = switch_pd_ecmp_group_table_delete_entry(device, ecmp_info->hw_entry);
            if (status != SWITCH_STATUS_SUCCESS) {
                return status;
            }
        }
        status = switch_pd_ecmp_member_delete(device, ecmp_info->pd_group_hdl, 
                                              ecmp_member->mbr_hdl);
        if (status != SWITCH_STATUS_SUCCESS) {
            return status;
        }
        if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) {
            status = switch_pd_urpf_bd_table_delete_entry(device, ecmp_member->urpf_hw_entry);
            if (status != SWITCH_STATUS_SUCCESS) {
                return status;
            }
        }
#endif
        ecmp_info->count--;
        ecmp_member = tommy_list_remove_existing(&(ecmp_info->members), node);
        switch_free(ecmp_member);
    }
    return status;
}
Пример #8
0
switch_status_t
switch_api_ecmp_member_add(switch_device_t device, switch_handle_t ecmp_handle,
                           uint16_t nhop_count, switch_handle_t *nhop_handle_list)
{
    switch_nhop_info_t                *e_nhop_info = NULL;
    switch_nhop_info_t                *nhop_info = NULL;
    switch_ecmp_info_t                *ecmp_info = NULL;
    switch_ecmp_member_t              *ecmp_member = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_spath_info_t               *spath_info = NULL;
    switch_handle_t                    nhop_handle;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    int                                count = 0;

    if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    e_nhop_info = switch_nhop_get(ecmp_handle);
    if (!e_nhop_info) {
        return SWITCH_STATUS_INVALID_NHOP;
    }
    ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info));

    for (count = 0; count < nhop_count; count++) {
        nhop_handle = nhop_handle_list[count];
        if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) {
            return SWITCH_STATUS_INVALID_HANDLE;
        }
        nhop_info = switch_nhop_get(nhop_handle);
        if (!nhop_info) {
            return SWITCH_STATUS_INVALID_NHOP;
        }
        spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info));

        ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1);
        if (!ecmp_member) {
            return SWITCH_STATUS_NO_MEMORY;
        }
        ecmp_member->nhop_handle = nhop_handle;
        intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle);
        if (!intf_info) {
            return SWITCH_STATUS_INVALID_INTERFACE;
        }

        nhop_info->ref_count++;
#ifdef SWITCH_PD
        status = switch_pd_ecmp_member_add(device, ecmp_info->pd_group_hdl, 
                    handle_to_id(ecmp_member->nhop_handle), intf_info,
                    &(ecmp_member->mbr_hdl));
        if (status != SWITCH_STATUS_SUCCESS) {
            return status;
        }
        if (ecmp_info->count == 0) {
            status = switch_pd_ecmp_group_table_add_entry_with_selector(device, 
                    handle_to_id(ecmp_handle),
                    ecmp_info->pd_group_hdl, 
                    &(ecmp_info->hw_entry)); 
            if (status != SWITCH_STATUS_SUCCESS) {
                return status;
            }
        }
        if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) {
            status = switch_pd_urpf_bd_table_add_entry(device, handle_to_id(ecmp_handle),
                                     handle_to_id(intf_info->bd_handle),
                                     &(ecmp_member->urpf_hw_entry));
            if (status != SWITCH_STATUS_SUCCESS) {
                return status;
            }
        }
#endif
        ecmp_info->count++;
        tommy_list_insert_head(&ecmp_info->members, &(ecmp_member->node), ecmp_member);
    }
    return status;
}
Пример #9
0
switch_handle_t
switch_api_ecmp_create_with_members(switch_device_t device,
                                    uint32_t member_count,
                                    switch_handle_t *nhop_handle)
{
    switch_nhop_info_t                *nhop_info = NULL;
    switch_spath_info_t               *spath_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_ecmp_info_t                *ecmp_info = NULL;
    switch_ecmp_member_t              *ecmp_member = NULL;
    switch_handle_t                    ecmp_handle;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    uint32_t                           index = 0;

    ecmp_handle = switch_api_ecmp_create(device);
    nhop_info = switch_nhop_get(ecmp_handle);
    if (!nhop_info) {
        return SWITCH_API_INVALID_HANDLE;
    }

    ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info));
    tommy_list_init(&ecmp_info->members);

#ifdef SWITCH_PD
    status = switch_pd_ecmp_group_create(device, &(ecmp_info->pd_group_hdl));
    if (status != SWITCH_STATUS_SUCCESS) {
        return SWITCH_API_INVALID_HANDLE;
    }
#endif

    for (index = 0; index < member_count; index++) {
        if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle[index])) {
            return SWITCH_STATUS_INVALID_HANDLE;
        }

        ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1);
        if (!ecmp_member) {
            // TODO: Cleanup memory
            return SWITCH_API_INVALID_HANDLE;
        }
        ecmp_member->nhop_handle = nhop_handle[index];
        ecmp_member->mbr_hdl = 0;

        nhop_info = switch_nhop_get(ecmp_member->nhop_handle);
        if (!nhop_info) {
            return SWITCH_API_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_API_INVALID_HANDLE;
        }
        nhop_info->ref_count++;

#ifdef SWITCH_PD
        status = switch_pd_ecmp_member_add(device, ecmp_info->pd_group_hdl, 
                    handle_to_id(ecmp_member->nhop_handle), intf_info,
                    &(ecmp_member->mbr_hdl));
        if (status != SWITCH_STATUS_SUCCESS) {
            return SWITCH_API_INVALID_HANDLE;
        }

        if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) {
            status = switch_pd_urpf_bd_table_add_entry(device, handle_to_id(ecmp_handle),
                                                  handle_to_id(intf_info->bd_handle),
                                                  &(ecmp_member->urpf_hw_entry));
            if (status != SWITCH_STATUS_SUCCESS) {
                return SWITCH_API_INVALID_HANDLE;
            }
        }
#endif
        tommy_list_insert_head(&ecmp_info->members, &(ecmp_member->node), ecmp_member);
    }

#ifdef SWITCH_PD
    status = switch_pd_ecmp_group_table_add_entry_with_selector(device, handle_to_id(ecmp_handle), 
                    ecmp_info->pd_group_hdl, &(ecmp_info->hw_entry));
    if (status != SWITCH_STATUS_SUCCESS) {
        return SWITCH_API_INVALID_HANDLE;
    }
#endif
    ecmp_info->count = member_count;
    if (status != SWITCH_STATUS_SUCCESS) {
        return SWITCH_API_INVALID_HANDLE;
    }
    return ecmp_handle;
}