Exemple #1
0
static switch_l3_hash_t *switch_l3_lookup_lpm_trie(switch_handle_t vrf,
                                                   switch_ip_addr_t *ip_addr) {
  switch_lpm_trie_t *lpm_trie = NULL;
  void *temp = NULL;
  switch_l3_hash_t *hash_entry;
  char *prefix;
  uint32_t v4addr;

  if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
    JLG(temp, switch_vrf_v4_lpm_tries, vrf);
    v4addr = htonl(ip_addr->ip.v4addr);
    prefix = (char *)(&v4addr);
  } else {
    JLG(temp, switch_vrf_v6_lpm_tries, vrf);
    prefix = (char *)(ip_addr->ip.v6addr);
  }

  if (!temp) {
    SWITCH_API_ERROR(
        "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf);
    return NULL;
  }

  lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp);
  if (switch_lpm_trie_lookup(lpm_trie, prefix, (unsigned long *)(&hash_entry)))
    return hash_entry;

  SWITCH_API_ERROR("%s: hash_entry not found.\n", __FUNCTION__);
  return NULL;
}
Exemple #2
0
switch_handle_t switch_api_neighbor_entry_add(switch_device_t device,
                                              switch_api_neighbor_t *neighbor) {
  switch_neighbor_info_t *neighbor_info = NULL;
  switch_interface_info_t *intf_info = NULL;
  switch_handle_t handle = SWITCH_API_INVALID_HANDLE;
  switch_status_t status = SWITCH_STATUS_SUCCESS;
  switch_nhop_info_t *nhop_info = NULL;
  switch_spath_info_t *spath_info = NULL;
  switch_handle_t nhop_handle = 0;

  intf_info = switch_api_interface_get(neighbor->interface);
  if (!intf_info) {
    SWITCH_API_ERROR(
        "%s:%d: invalid interface for rewrite!", __FUNCTION__, __LINE__);
    return SWITCH_STATUS_INVALID_INTERFACE;
  }

  handle = switch_neighbor_info_create();
  neighbor_info = switch_neighbor_info_get(handle);
  memcpy(&neighbor_info->neighbor, neighbor, sizeof(switch_api_neighbor_t));

#ifdef SWITCH_PD
  nhop_handle = neighbor->nhop_handle;
  if (neighbor->nhop_handle == SWITCH_API_INVALID_HANDLE) {
    // check for neighbor type
    if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_NONE &&
        neighbor->rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L3) {
      switch_nhop_key_t nhop_key;
      // allocate nhop and set neighbor handle
      memset(&nhop_key, 0, sizeof(nhop_key));
      nhop_key.ip_addr = neighbor->ip_addr;
      nhop_key.intf_handle = neighbor->interface;
      nhop_key.ip_addr_valid = 1;
      nhop_handle = switch_api_nhop_create(device, &nhop_key);
    }
  }
  if (nhop_handle != SWITCH_API_INVALID_HANDLE && nhop_handle) {
    nhop_info = switch_nhop_get(nhop_handle);
    if (!nhop_info) {
      return SWITCH_API_INVALID_HANDLE;
    }
    spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info));
    spath_info->neighbor_handle = handle;
    neighbor_info->neighbor.nhop_handle = nhop_handle;
    status = switch_api_nhop_update(device, nhop_handle);
    status =
        switch_api_neighbor_entry_add_rewrite(device, handle, neighbor_info);
  } else {
    status =
        switch_api_neighbor_entry_add_tunnel_rewrite(device, neighbor_info);
  }
#endif
  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR(
        "%s:%d: failed to create neighbor entry!", __FUNCTION__, __LINE__);
  }
  neighbor->nhop_handle = nhop_handle;
  return handle;
}
Exemple #3
0
switch_status_t switch_api_packet_net_filter_tx_delete(
    switch_device_t device, switch_packet_tx_key_t *tx_key) {
  switch_packet_tx_entry_t *tmp_tx_entry = NULL;
  switch_packet_tx_info_t *tmp_tx_info = NULL;
  switch_packet_tx_entry_t tx_entry;
  tommy_node *node = NULL;
  switch_hostif_info_t *hostif_info = NULL;
  bool node_found = FALSE;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

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

  memset(&tx_entry, 0x0, sizeof(tx_entry));
  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;
    }
    tx_entry.intf_fd = hostif_info->intf_fd;
  }

  if (tx_key->vlan_valid) {
    tx_entry.vlan_id = tx_key->vlan_id;
  }

  node = tommy_list_head(&packet_tx_filter_list);
  while (node) {
    tmp_tx_info = (switch_packet_tx_info_t *)node->data;
    tmp_tx_entry = &tmp_tx_info->tx_entry;

    if (switch_packet_tx_filter_match(tmp_tx_entry, &tx_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_tx_filter_list, node);
  switch_free(tmp_tx_info);
  return status;
}
Exemple #4
0
static uint16_t switch_dmac_rewrite_insert_hash(switch_device_t device,
                                                switch_mac_addr_t *mac) {
  unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE];
  unsigned int len = 0;
  uint32_t hash = 0;
  uint16_t mac_index = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;
  switch_dmac_rewrite_t *dmac_rewrite = NULL;

  dmac_rewrite = switch_dmac_rewrite_search_hash(mac);
  if (dmac_rewrite) {
    mac_index = dmac_rewrite->index;
    dmac_rewrite->ref_count++;
  } else {
    switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash);
    dmac_rewrite = switch_malloc(sizeof(switch_dmac_rewrite_t), 1);
    if (!dmac_rewrite) {
      return mac_index;
    }
    mac_index = switch_api_id_allocator_allocate(dmac_rewrite_index_allocator);
    memcpy(&dmac_rewrite->mac, mac, sizeof(switch_mac_addr_t));
    dmac_rewrite->index = mac_index;
    dmac_rewrite->ref_count = 1;
    status = switch_pd_tunnel_dmac_rewrite_table_add_entry(
        device, mac_index, mac, &dmac_rewrite->rewrite_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      SWITCH_API_ERROR(
          "%s:%d: unable to add tunnel dmac entry!", __FUNCTION__, __LINE__);
      return mac_index;
    }
    tommy_hashtable_insert(
        &switch_dmac_rewrite_table, &(dmac_rewrite->node), dmac_rewrite, hash);
  }
  return mac_index;
}
Exemple #5
0
static switch_status_t switch_dmac_rewrite_delete_hash(switch_device_t device,
                                                       switch_mac_addr_t *mac) {
  switch_dmac_rewrite_t *dmac_rewrite = NULL;
  unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE];
  unsigned int len = 0;
  uint32_t hash = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  dmac_rewrite = switch_dmac_rewrite_search_hash(mac);
  if (!dmac_rewrite) {
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }
  dmac_rewrite->ref_count--;
  if (dmac_rewrite->ref_count == 0) {
    switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash);
    dmac_rewrite = tommy_hashtable_remove(
        &switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash);
    status = switch_pd_tunnel_dmac_rewrite_table_delete_entry(
        device, dmac_rewrite->rewrite_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      SWITCH_API_ERROR(
          "%s:%d unabl to delete tunnel dmac entry!", __FUNCTION__, __LINE__);
      return status;
    }
    switch_api_id_allocator_release(dmac_rewrite_index_allocator,
                                    dmac_rewrite->index);
    switch_free(dmac_rewrite);
  }
  return status;
}
Exemple #6
0
void switch_packet_tx_switched(switch_packet_header_t *packet_header,
                               char *in_packet,
                               int in_packet_size) {
  int packet_size = 0;
  static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE];
  switch_ethernet_header_t *eth_header = NULL;
  switch_vlan_header_t *vlan_header = NULL;
  switch_vlan_t vlan_id1 = 0;
  switch_packet_tx_entry_t tx_entry;
  switch_packet_tx_info_t *tx_info = NULL;
  switch_status_t status;

  eth_header = (switch_ethernet_header_t *)in_packet;
  if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) {
    vlan_header = (switch_vlan_header_t *)(in_packet + 2 * ETH_LEN);
    uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1;
    vlan_id1 = ntohs(*vlan_h);
  }

  tx_entry.fd_valid = false;
  tx_entry.vlan_id = vlan_id1;
  status = switch_packet_tx_info_get(&tx_entry, &tx_info);
  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR("net filter tx not found. dropping packet");
    return;
  }

  memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE);
  switch_packet_tx_bd_transform(
      in_packet, in_packet_size, packet, &packet_size, tx_info);
  switch_packet_tx_to_hw(packet_header, packet, packet_size);
}
Exemple #7
0
switch_status_t switch_api_l3_route_lookup(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;

  if (switch_l3_host_entry(ip_addr)) {
    // host entry, first search hash
    hash_entry = switch_l3_search_hash(vrf, ip_addr);
  }

  if (!hash_entry) {
    // try LPM lookup
    hash_entry = switch_l3_lookup_lpm_trie(vrf, ip_addr);
  }

  if (!hash_entry) {
    *nhop_handle = SWITCH_API_INVALID_HANDLE;
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }

  nhop_info = switch_nhop_get(hash_entry->nhop_handle);
  if (!nhop_info) {
    SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__);
    *nhop_handle = SWITCH_API_INVALID_HANDLE;
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }

  *nhop_handle = hash_entry->nhop_handle;
  return SWITCH_STATUS_SUCCESS;
}
Exemple #8
0
static switch_status_t switch_l3_remove_from_lpm_trie(
    switch_handle_t vrf, switch_ip_addr_t *ip_addr) {
  switch_lpm_trie_t *lpm_trie = NULL;
  void *temp = NULL;
  char *prefix;
  uint32_t v4addr;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
    JLG(temp, switch_vrf_v4_lpm_tries, vrf);
    v4addr = htonl(ip_addr->ip.v4addr);
    prefix = (char *)(&v4addr);
  } else {
    JLG(temp, switch_vrf_v6_lpm_tries, vrf);
    prefix = (char *)(ip_addr->ip.v6addr);
  }

  if (!temp) {
    SWITCH_API_ERROR(
        "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf);
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }

  lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp);
  switch_lpm_trie_delete(lpm_trie, prefix, ip_addr->prefix_len);
  if (switch_lpm_trie_size(lpm_trie) == 0) {
    if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
      JLD(status, switch_vrf_v4_lpm_tries, vrf);
    } else {
      JLD(status, switch_vrf_v6_lpm_tries, vrf);
    }
  }

  return status;
}
Exemple #9
0
switch_status_t switch_api_neighbor_entry_remove(
    switch_device_t device, switch_handle_t neighbor_handle) {
  switch_neighbor_info_t *neighbor_info = NULL;
  switch_api_neighbor_t *neighbor = NULL;
  switch_nhop_info_t *nhop_info = NULL;
  switch_interface_info_t *intf_info = NULL;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  if (!SWITCH_NEIGHBOR_HANDLE_VALID(neighbor_handle)) {
    return SWITCH_STATUS_INVALID_HANDLE;
  }

  neighbor_info = switch_neighbor_info_get(neighbor_handle);
  if (!neighbor_info) {
    return SWITCH_STATUS_ITEM_NOT_FOUND;
  }
#ifdef SWITCH_PD
  if (neighbor_info->neighbor.nhop_handle) {
    status = switch_pd_rewrite_table_delete_entry(device,
                                                  neighbor_info->rewrite_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      return status;
    }
    neighbor = &neighbor_info->neighbor;
    intf_info = switch_api_interface_get(neighbor->interface);
    if (!intf_info) {
      SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__);
      return SWITCH_STATUS_INVALID_INTERFACE;
    }
    switch_neighbor_dmac_delete_hash(
        device, intf_info->bd_handle, &neighbor->mac_addr);
  } else {
    status = switch_dmac_rewrite_delete_hash(device,
                                             &neighbor_info->neighbor.mac_addr);
    if (status != SWITCH_STATUS_SUCCESS) {
      return status;
    }
    status = switch_pd_tunnel_rewrite_table_delete_entry(
        device, neighbor_info->rewrite_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      return status;
    }
  }
#endif
  switch_neighbor_info_delete(neighbor_handle);
  nhop_info = switch_nhop_get(neighbor_info->neighbor.nhop_handle);
  if (nhop_info) {
    nhop_info->u.spath.neighbor_handle = 0;
    status =
        switch_api_nhop_update(device, neighbor_info->neighbor.nhop_handle);
    if (nhop_info->valid == 0) {
      switch_api_nhop_delete(device, neighbor_info->neighbor.nhop_handle);
    }
  }
  return status;
}
Exemple #10
0
static switch_status_t switch_l3_insert_into_lpm_trie(
    switch_handle_t vrf,
    switch_ip_addr_t *ip_addr,
    switch_l3_hash_t *hash_entry) {
  switch_lpm_trie_t *lpm_trie = NULL;
  void *temp = NULL;
  size_t key_width_bytes;
  char *prefix;
  uint32_t v4addr;

  if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
    JLG(temp, switch_vrf_v4_lpm_tries, vrf);
    key_width_bytes = 4;
    v4addr = htonl(ip_addr->ip.v4addr);
    prefix = (char *)(&v4addr);
  } else {
    JLG(temp, switch_vrf_v6_lpm_tries, vrf);
    key_width_bytes = 16;
    prefix = (char *)(ip_addr->ip.v6addr);
  }

  if (!temp) {
    lpm_trie = switch_lpm_trie_create(key_width_bytes, TRUE);
    if (!lpm_trie) {
      SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__);
      return SWITCH_STATUS_NO_MEMORY;
    }

    if (ip_addr->type == SWITCH_API_IP_ADDR_V4) {
      JLI(temp, switch_vrf_v4_lpm_tries, vrf);
    } else {
      JLI(temp, switch_vrf_v6_lpm_tries, vrf);
    }
    *(unsigned long *)temp = (unsigned long)(lpm_trie);
  }

  lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp);
  switch_lpm_trie_insert(
      lpm_trie, prefix, ip_addr->prefix_len, (unsigned long)hash_entry);

  return SWITCH_STATUS_SUCCESS;
}
switch_status_t
switch_smac_rewrite_delete_entry(switch_mac_addr_t *mac)
{
    switch_smac_entry_t               *smac_entry = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    switch_device_t                    device = SWITCH_DEV_ID;

    smac_entry = switch_smac_rewrite_search_entry(mac);
    if (!smac_entry) {
        SWITCH_API_ERROR("%s:%d: unable to find mac!", __FUNCTION__, __LINE__);
        return SWITCH_STATUS_ITEM_NOT_FOUND;
    }

    smac_entry->ref_count--;
    if (smac_entry->ref_count == 0) {
        switch_pd_smac_rewrite_table_delete_entry(device, smac_entry);
        switch_smac_rewrite_hash_delete(smac_entry);
        switch_api_id_allocator_release(smac_rewrite_index_allocator, smac_entry->smac_index);
        free(smac_entry);
    }
    return status;
}
Exemple #12
0
void switch_packet_rx_to_host(switch_packet_header_t *packet_header,
                              char *packet,
                              int packet_size) {
  switch_cpu_header_t *cpu_header = NULL;
  switch_packet_rx_info_t *rx_info = NULL;
  static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE];
  switch_packet_rx_entry_t rx_entry;
  int intf_fd = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  cpu_header = &packet_header->cpu_header;

  memset(&rx_entry, 0x0, sizeof(rx_entry));
  rx_entry.port = cpu_header->ingress_port;
  rx_entry.ifindex = cpu_header->ingress_ifindex;
  rx_entry.bd = cpu_header->ingress_bd;
  rx_entry.reason_code = cpu_header->reason_code;

  status = switch_packet_rx_info_get(&rx_entry, &rx_info);
  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR("failed to find fd. dropping packet");
    return;
  }

  SWITCH_API_INFO("Rx packet reason_code 0x%x - send to fd %d, action %d\n",
                  rx_entry.reason_code,
                  rx_info->intf_fd,
                  rx_info->vlan_action);

  switch_packet_rx_transform(packet_header, in_packet, packet, &packet_size);

  intf_fd = rx_info->intf_fd;

  if (write(intf_fd, in_packet, packet_size) < 0) {
    perror("sendto host interface failed");
    return;
  }
  return;
}
Exemple #13
0
static switch_status_t switch_l3_insert_into_vrf_list(
    switch_l3_hash_t *hash_entry) {
  switch_vrf_route_list_t *vrf_route_list = NULL;
  void *temp = NULL;
  switch_ip_addr_t ip_addr;
  switch_handle_t vrf_handle = 0;

  memset(&ip_addr, 0, sizeof(switch_ip_addr_t));
  switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr);
  if (ip_addr.type == SWITCH_API_IP_ADDR_V4) {
    JLG(temp, switch_vrf_v4_routes, vrf_handle);
  } else {
    JLG(temp, switch_vrf_v6_routes, vrf_handle);
  }

  if (!temp) {
    vrf_route_list = switch_malloc(sizeof(switch_vrf_route_list_t), 1);
    if (!vrf_route_list) {
      SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__);
      return SWITCH_STATUS_NO_MEMORY;
    }
    tommy_list_init(&(vrf_route_list->routes));
    vrf_route_list->num_entries = 0;
    if (ip_addr.type == SWITCH_API_IP_ADDR_V4) {
      JLI(temp, switch_vrf_v4_routes, vrf_handle);
    } else {
      JLI(temp, switch_vrf_v6_routes, vrf_handle);
    }
    *(unsigned long *)temp = (unsigned long)(vrf_route_list);
  }
  vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp);
  tommy_list_insert_tail(
      &(vrf_route_list->routes), &(hash_entry->vrf_route_node), hash_entry);
  vrf_route_list->num_entries++;
  return SWITCH_STATUS_SUCCESS;
}
switch_status_t
switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_handle,
                                switch_handle_t handle)
{
    switch_stp_info_t                 *stp_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_stp_port_entry_t           *port_entry = NULL;
    tommy_node                        *node = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    switch_handle_t                    intf_handle = 0; 
    switch_handle_type_t               handle_type = 0;

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

    if ((!SWITCH_PORT_HANDLE_VALID(handle)) &&
        (!SWITCH_LAG_HANDLE_VALID(handle)) &&
        (!SWITCH_INTERFACE_HANDLE_VALID(handle))) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

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

    handle_type = switch_handle_get_type(handle);
    intf_handle = handle;
    if (handle_type == SWITCH_HANDLE_TYPE_PORT ||
        handle_type == SWITCH_HANDLE_TYPE_LAG) {
        status = switch_interface_handle_get(
                             handle,
                             0x0,
                             &intf_handle);
        if (status != SWITCH_STATUS_SUCCESS) {
            SWITCH_API_ERROR("stp port state clear failed");
            return status;
        }
    }

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

    if (SWITCH_INTF_IS_PORT_L3(intf_info)) {
        return SWITCH_STATUS_INVALID_INTERFACE;
    }

    node = tommy_list_head(&(stp_info->port_list));
    while (node) {
        port_entry = node->data;
        if (port_entry->intf_handle == intf_handle) {
            break;
        }
        node = node->next;
    }
    if (!node) {
        return SWITCH_STATUS_ITEM_NOT_FOUND;
    }

    tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node));
    switch_free(port_entry);
    return status;
}
switch_status_t
switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle,
                              switch_handle_t handle, switch_stp_state_t state)
{
    switch_stp_info_t                 *stp_info = NULL;
    switch_interface_info_t           *intf_info = NULL;
    switch_stp_port_entry_t           *port_entry = NULL;
    tommy_node                        *node = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    switch_handle_t                    intf_handle; 
    switch_handle_type_t               handle_type = 0;
    bool                               new_entry = FALSE;

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

    if ((!SWITCH_PORT_HANDLE_VALID(handle)) &&
        (!SWITCH_LAG_HANDLE_VALID(handle)) &&
        (!SWITCH_INTERFACE_HANDLE_VALID(handle))) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

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

    handle_type = switch_handle_get_type(handle);
    intf_handle = handle;
    if (handle_type == SWITCH_HANDLE_TYPE_PORT ||
        handle_type == SWITCH_HANDLE_TYPE_LAG) {
        status = switch_interface_handle_get(
                             handle,
                             0x0,
                             &intf_handle);
        if (status != SWITCH_STATUS_SUCCESS) {
            SWITCH_API_ERROR("stp port state set failed");
            return status;
        }
    }

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

    if (SWITCH_INTF_IS_PORT_L3(intf_info)) {
        return SWITCH_STATUS_INVALID_INTERFACE;
    }

    node = tommy_list_head(&stp_info->port_list);
    while (node) {
        port_entry = node->data;
        if (port_entry->intf_handle == intf_handle) {
            port_entry->intf_state = state;
            break;
        }
        node = node->next;
    }

    if (state == SWITCH_PORT_STP_STATE_NONE) {
        if (!node) {
            return SWITCH_STATUS_ITEM_NOT_FOUND;
        }
        status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state);
        status = switch_pd_spanning_tree_table_delete_entry(device, port_entry->hw_entry);
        tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node));
        switch_free(port_entry);
    } else {
        if (!node) {
            new_entry = TRUE;
            port_entry = switch_malloc(sizeof(switch_stp_port_entry_t), 1);
            if (!port_entry) {
                return SWITCH_STATUS_NO_MEMORY;
            }
            memset(port_entry, 0, sizeof(switch_stp_port_entry_t));
            port_entry->intf_handle = intf_handle;
            port_entry->intf_state = state;
            tommy_list_insert_head(&(stp_info->port_list),
                                   &(port_entry->node), port_entry);
        }

        status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state);

        if (new_entry) {
            status = switch_pd_spanning_tree_table_add_entry(device,
                                        handle_to_id(stg_handle),
                                        intf_info->ifindex,
                                        port_entry->intf_state,
                                        &port_entry->hw_entry);
        } else {
            status = switch_pd_spanning_tree_table_update_entry(device,
                                        handle_to_id(stg_handle),
                                        intf_info->ifindex,
                                        port_entry->intf_state,
                                        port_entry->hw_entry);
        }
    }
    return status;
}
Exemple #16
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;
}
Exemple #17
0
void switch_packet_rx_transform(switch_packet_header_t *packet_header,
                                char *transformed_packet,
                                char *packet,
                                int *packet_size) {
  switch_cpu_header_t *cpu_header = NULL;
  switch_packet_rx_info_t *rx_info = NULL;
  switch_ethernet_header_t *eth_header = NULL;
  switch_vlan_header_t *vlan_header = NULL;
  switch_packet_rx_entry_t rx_entry;
  uint16_t offset = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  cpu_header = &packet_header->cpu_header;

  memset(&rx_entry, 0x0, sizeof(rx_entry));
  rx_entry.port = cpu_header->ingress_port;
  rx_entry.ifindex = cpu_header->ingress_ifindex;
  rx_entry.bd = cpu_header->ingress_bd;
  rx_entry.reason_code = cpu_header->reason_code;

  status = switch_packet_rx_info_get(&rx_entry, &rx_info);
  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR("failed to find filter. packet not transformed");
    memcpy(transformed_packet, packet, *packet_size);
    return;
  }

  if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) {
    eth_header = (switch_ethernet_header_t *)packet;
    if (ntohs(eth_header->ether_type) != SWITCH_ETHERTYPE_DOT1Q &&
        rx_info->vlan_id) {
      offset = 2 * ETH_LEN;
      memcpy(transformed_packet, packet, offset);
      vlan_header = (switch_vlan_header_t *)(transformed_packet + offset);
      vlan_header->tpid = htons(SWITCH_ETHERTYPE_DOT1Q);
      uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1;
      *vlan_h = htons(rx_info->vlan_id);
      memcpy(transformed_packet + offset + sizeof(switch_vlan_header_t),
             packet + offset,
             *packet_size - offset);
      *packet_size += sizeof(switch_vlan_header_t);
    } else {
      memcpy(transformed_packet, packet, *packet_size);
    }
  } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_REMOVE) {
    eth_header = (switch_ethernet_header_t *)packet;
    if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) {
      offset = 2 * ETH_LEN;
      memcpy(transformed_packet, packet, offset);
      memcpy(transformed_packet, packet + offset, *packet_size - offset);
      *packet_size -= sizeof(switch_vlan_header_t);
    } else {
      memcpy(transformed_packet, packet, *packet_size);
    }
  } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_SWAP) {
    eth_header = (switch_ethernet_header_t *)packet;
    if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q &&
        rx_info->vlan_id) {
      offset = 2 * ETH_LEN;
      vlan_header = (switch_vlan_header_t *)(transformed_packet + offset);
      vlan_header->vid = htons(rx_info->vlan_id);
    } else {
      memcpy(transformed_packet, packet, *packet_size);
    }
  } else {
    memcpy(transformed_packet, packet, *packet_size);
  }
}
Exemple #18
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;
}
Exemple #19
0
switch_status_t switch_api_neighbor_entry_add_rewrite(
    switch_device_t device,
    switch_handle_t neighbor_handle,
    switch_neighbor_info_t *neighbor_info) {
  switch_status_t status = SWITCH_STATUS_SUCCESS;
  uint16_t nhop_index = 0;
  switch_api_neighbor_t *neighbor = NULL;
  switch_interface_info_t *intf_info = NULL;
  switch_tunnel_info_t *tunnel_info = NULL;
  uint16_t tunnel_index = 0;
  switch_encap_type_t encap_type = 0;
  uint16_t bd = 0;

  neighbor = &neighbor_info->neighbor;
  nhop_index = handle_to_id(neighbor->nhop_handle);

  intf_info = switch_api_interface_get(neighbor->interface);
  if (!intf_info) {
    SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__);
    return SWITCH_STATUS_INVALID_INTERFACE;
  }
  if (intf_info->ln_bd_handle) {
    bd = handle_to_id(intf_info->ln_bd_handle);
  } else {
    bd = handle_to_id(intf_info->bd_handle);
  }
  if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN ||
      neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN ||
      neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN ||
      neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN ||
      neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN ||
      neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN) {
    tunnel_index = handle_to_id(neighbor->interface);
    status = switch_pd_rewrite_table_mpls_rewrite_add_entry(
        device,
        bd,
        nhop_index,
        tunnel_index,
        neighbor->neigh_type,
        neighbor->mac_addr,
        neighbor->mpls_label,
        neighbor->header_count,
        &neighbor_info->rewrite_entry);
  } else if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) {
    tunnel_index = handle_to_id(neighbor->interface);
    tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info));
    if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) {
      encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info);
      status = switch_pd_rewrite_table_tunnel_rewrite_add_entry(
          device,
          bd,
          nhop_index,
          neighbor->mac_addr,
          neighbor->neigh_type,
          neighbor->rw_type,
          tunnel_index,
          encap_type,
          &neighbor_info->rewrite_entry);
    }
  } else {
    status = switch_pd_rewrite_table_unicast_rewrite_add_entry(
        device,
        bd,
        nhop_index,
        neighbor->mac_addr,
        neighbor->rw_type,
        &neighbor_info->rewrite_entry);
  }
  switch_neighbor_dmac_insert_hash(
      device, intf_info->bd_handle, &neighbor->mac_addr, neighbor_handle);

  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR(
        "%s:%d: Unable to add unicast rewrite entry!.", __FUNCTION__, __LINE__);
  }
  return status;
}
Exemple #20
0
void switch_packet_tx_from_host(int intf_fd) {
  switch_hostif_info_t *hostif_info = NULL;
  int packet_size = 0;
  int in_packet_size = 0;
  static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE];
  static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE];
  void *temp = NULL;
  switch_packet_header_t packet_header;
  switch_fabric_header_t *fabric_header = NULL;
  switch_cpu_header_t *cpu_header = NULL;
  switch_ethernet_header_t *eth_header = NULL;
  switch_vlan_header_t *vlan_header = NULL;
  switch_vlan_t vlan_id1 = 0;
  switch_packet_tx_entry_t tx_entry;
  switch_packet_tx_info_t *tx_info = NULL;
  switch_device_t device = 0;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  memset(in_packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE);
  memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE);

  while ((in_packet_size = read(intf_fd, in_packet, sizeof(in_packet))) > 0) {
    JLG(temp, switch_intf_fd_array, intf_fd);
    hostif_info = (switch_hostif_info_t *)(*(unsigned long *)temp);
    if (!hostif_info) {
      perror("invalid hostif fd");
      return;
    }
    SWITCH_API_TRACE("Received packet from host port %s through netdev\n",
                     hostif_info->hostif.intf_name);

    eth_header = (switch_ethernet_header_t *)in_packet;
    if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) {
      vlan_header = (switch_vlan_header_t *)(in_packet + 2 * ETH_LEN);
      uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1;
      vlan_id1 = ntohs(*vlan_h);
    }

    tx_entry.intf_fd = intf_fd;
    tx_entry.vlan_id = vlan_id1;
    status = switch_packet_tx_info_get(&tx_entry, &tx_info);
    if (status != SWITCH_STATUS_SUCCESS) {
      SWITCH_API_ERROR("net filter tx not found. dropping packet");
      continue;
    }

    memset(&packet_header, 0x0, sizeof(packet_header));
    cpu_header = &packet_header.cpu_header;
    fabric_header = &packet_header.fabric_header;

    if (tx_info->bypass_flags == SWITCH_BYPASS_ALL) {
      cpu_header->tx_bypass = TRUE;
      cpu_header->reason_code = tx_info->bypass_flags;
      fabric_header->dst_port_or_group = tx_info->port;
      memcpy(packet, in_packet, in_packet_size);
      packet_size = in_packet_size;
    } else {
      cpu_header->tx_bypass = FALSE;
      cpu_header->reason_code = tx_info->bypass_flags;
      switch_packet_tx_bd_transform(
          in_packet, in_packet_size, packet, &packet_size, tx_info);
    }

    fabric_header = &packet_header.fabric_header;
    cpu_header = &packet_header.cpu_header;
    fabric_header->dst_device = device;
    fabric_header->packet_type = SWITCH_FABRIC_HEADER_TYPE_CPU;
    fabric_header->ether_type = SWITCH_FABRIC_HEADER_ETHTYPE;

    switch_packet_tx_to_hw(&packet_header, packet, packet_size);
  }
}
Exemple #21
0
switch_status_t switch_api_neighbor_entry_add_tunnel_rewrite(
    switch_device_t device, switch_neighbor_info_t *neighbor_info) {
  switch_interface_info_t *intf_info = NULL;
  switch_api_neighbor_t *neighbor = NULL;
  switch_status_t status = SWITCH_STATUS_SUCCESS;
  uint16_t smac_index = 1;
  uint16_t dmac_index = 0;
  uint16_t sip_index = 0;
  uint16_t dip_index = 0;
  switch_handle_t vrf_handle = 0;
  switch_ip_encap_t *ip_encap = NULL;
  switch_mpls_encap_t *mpls_encap = NULL;
  switch_tunnel_info_t *tunnel_info = NULL;
  switch_ip_addr_t *src_ip = NULL;
  switch_ip_addr_t *dst_ip = NULL;
  switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE;

  neighbor = &neighbor_info->neighbor;
  intf_info = switch_api_interface_get(neighbor->interface);
  if (!intf_info) {
    SWITCH_API_ERROR(
        "%s:%d: invalid interface for tunnel rewrite!", __FUNCTION__, __LINE__);
    return SWITCH_STATUS_INVALID_INTERFACE;
  }

  tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info));
  dmac_index = switch_dmac_rewrite_insert_hash(device, &neighbor->mac_addr);

  if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) {
    ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info));
    vrf_handle = ip_encap->vrf_handle;
    encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info);

    src_ip = &ip_encap->src_ip;
    sip_index =
        switch_tunnel_src_vtep_index_get(vrf_handle, encap_type, src_ip);

    dst_ip = &ip_encap->dst_ip;
    dip_index =
        switch_tunnel_dst_vtep_index_get(vrf_handle, encap_type, dst_ip);

    status = switch_pd_tunnel_rewrite_table_add_entry(
        device,
        handle_to_id(neighbor->interface),
        sip_index,
        dip_index,
        smac_index,
        dmac_index,
        &neighbor_info->rewrite_entry);
  } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) {
    mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info));
    status = switch_pd_tunnel_rewrite_table_mpls_add_entry(
        device,
        handle_to_id(neighbor->interface),
        smac_index,
        dmac_index,
        mpls_encap,
        &neighbor_info->rewrite_entry);
  }

  if (status != SWITCH_STATUS_SUCCESS) {
    SWITCH_API_ERROR(
        "%s:%d unable to add tunnel rewrite entry", __FUNCTION__, __LINE__);
    return status;
  }

  return status;
}
Exemple #22
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;
}
Exemple #23
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;
}