Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
static switch_l3_hash_t *switch_l3_insert_hash(switch_handle_t vrf,
                                               switch_ip_addr_t *ip_addr,
                                               switch_handle_t interface) {
  switch_l3_hash_t *hash_entry = NULL;
  unsigned char key[SWITCH_L3_HASH_KEY_SIZE];
  unsigned int len = 0;
  uint32_t hash;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash);
  hash_entry = switch_malloc(sizeof(switch_l3_hash_t), 1);
  if (!hash_entry) {
    return NULL;
  }
  memcpy(hash_entry->key, key, SWITCH_L3_HASH_KEY_SIZE);
  hash_entry->path_count = 1;

  if (!switch_l3_host_entry(ip_addr)) {
    status = switch_l3_insert_into_lpm_trie(vrf, ip_addr, hash_entry);
    if (status != SWITCH_STATUS_SUCCESS) {
      switch_free(hash_entry);
      return NULL;
    }
  }

  tommy_hashtable_insert(
      &switch_l3_hash_table, &(hash_entry->node), hash_entry, hash);
  switch_l3_insert_into_vrf_list(hash_entry);
  return hash_entry;
}
Ejemplo n.º 3
0
switch_status_t switch_capability_init(switch_device_t device) {
  switch_api_capability_t *api_switch_info = NULL;
  switch_port_info_t *port_info = NULL;
  int index = 0;

  switch_info = switch_malloc(sizeof(switch_capability_info_t), 1);
  if (!switch_info) {
    return SWITCH_STATUS_NO_MEMORY;
  }
  api_switch_info = &switch_info->api_switch_info;
  memset(switch_info, 0, sizeof(switch_capability_info_t));
  memset(api_switch_info, 0, sizeof(switch_api_capability_t));

  // Create Default VLAN
  api_switch_info->default_vlan = SWITCH_API_DEFAULT_VLAN;
  switch_info->default_vlan_handle =
      switch_api_vlan_create(device, SWITCH_API_DEFAULT_VLAN);

  // Create Default Vrf
  api_switch_info->default_vrf = SWITCH_API_DEFAULT_VRF;
  switch_info->default_vrf_handle =
      switch_api_vrf_create(device, SWITCH_API_DEFAULT_VRF);

  api_switch_info->max_ports = switch_max_configured_ports;
  for (index = 0; index < SWITCH_API_MAX_PORTS; index++) {
    port_info = switch_api_port_get_internal((switch_port_t)index);
    api_switch_info->port_list[index] = port_info->port_handle;
  }
  return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 4
0
switch_status_t switch_api_l3_interface_address_add(
    switch_device_t device,
    switch_handle_t interface_handle,
    switch_handle_t vrf_handle,
    switch_ip_addr_t *ip_addr) {
  switch_interface_info_t *info = NULL;
  switch_ip_addr_info_t *ip_info = NULL;
  switch_status_t status = SWITCH_STATUS_SUCCESS;

  UNUSED(device);
  info = switch_api_interface_get(interface_handle);
  if (!info) {
    return SWITCH_STATUS_INVALID_INTERFACE;
  }

  ip_info = switch_malloc(sizeof(switch_ip_addr_info_t), 1);
  if (!ip_info) {
    return SWITCH_STATUS_NO_MEMORY;
  }

  ip_info->vrf_handle = vrf_handle;
  ip_info->default_ip = TRUE;
  ip_info->ip = *ip_addr;

  // append to list and increment member count
  tommy_list_insert_head(&(info->ip_addr), &(ip_info->node), ip_info);
  info->ip_addr_count++;

  return status;
}
Ejemplo n.º 5
0
switch_status_t
switch_smac_rewrite_add_entry(switch_mac_addr_t *mac)
{
    switch_smac_entry_t               *smac_entry = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;
    uint16_t                           smac_index = 0;
    switch_device_t                    device = SWITCH_DEV_ID;

    smac_entry = switch_smac_rewrite_search_entry(mac);
    if (smac_entry) {
        smac_entry->ref_count++;
        return SWITCH_STATUS_SUCCESS;
    }
    smac_entry = switch_malloc(sizeof(switch_smac_entry_t), 1);
    if (!smac_entry) {
        return SWITCH_STATUS_NO_MEMORY;
    }
    memset(smac_entry, 0, sizeof(switch_smac_entry_t));
    smac_index = switch_api_id_allocator_allocate(smac_rewrite_index_allocator);
    memcpy(&smac_entry->mac, mac, ETH_LEN);
    smac_entry->smac_index = smac_index;
    smac_entry->ref_count = 1;
    switch_smac_rewrite_hash_insert(smac_entry);
    status = switch_pd_smac_rewrite_table_add_entry(device, smac_entry);
    return status;
}
Ejemplo n.º 6
0
/*
 * @function: switch_api_router_mac_add
 * Add Router mac to rmac group
 * @param device - Device to be programmed
 * @param rmac_handle - ID of the RMAC group
 * @param mac - Router mac address to be added to the group
 * @return: Returns success if mac is added successfully
 */
switch_status_t
switch_api_router_mac_add(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac)
{
    switch_rmac_info_t                *rmac_info = NULL;
    switch_rmac_entry_t               *rmac_entry = NULL;
    tommy_node                        *node = NULL;
    switch_status_t                    status = SWITCH_STATUS_SUCCESS;

    if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }

    rmac_info = switch_api_rmac_info_get_internal(rmac_handle);
    if (!rmac_info) {
        return SWITCH_STATUS_INVALID_HANDLE;
    }
    node = tommy_list_head(&(rmac_info->rmac_list));
    while (node) {
        rmac_entry = node->data;
        if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) {
            return SWITCH_STATUS_SUCCESS;
        }
        node = node->next;
    }
    rmac_entry = switch_malloc(sizeof(switch_rmac_entry_t), 1);
    if (!rmac_entry) {
        return SWITCH_STATUS_NO_MEMORY;
    }
    memcpy(&rmac_entry->mac, mac, sizeof(switch_mac_addr_t));
    tommy_list_insert_head(&(rmac_info->rmac_list), &(rmac_entry->node), rmac_entry);
    status = switch_smac_rewrite_add_entry(mac);
    if (status != SWITCH_STATUS_SUCCESS) {
        printf("MAC rewrite table add failed with error code %d\n", status);
        return status;
    }
#ifdef SWITCH_PD
    
    status = switch_pd_inner_rmac_table_add_entry(device,
                                              handle_to_id(rmac_handle), mac,
                                              &rmac_entry->inner_rmac_entry);
    if(status != SWITCH_STATUS_SUCCESS) {
        printf("Inner RMAC table add failed with error code %d\n", status);
        return status;
    }

    status = switch_pd_outer_rmac_table_add_entry(device,
                                              handle_to_id(rmac_handle), mac,
                                              &rmac_entry->outer_rmac_entry);
    if(status != SWITCH_STATUS_SUCCESS) {
        printf("Outer RMAC table add failed with error code %d\n", status);
    }
#endif
    return status; 
}
Ejemplo n.º 7
0
switch_lpm_trie_t *switch_lpm_trie_create(size_t key_width_bytes,
                                          bool auto_shrink) {
  assert(key_width_bytes <= 64);
  switch_lpm_trie_t *trie =
      (switch_lpm_trie_t *)switch_malloc(sizeof(switch_lpm_trie_t), 1);
  trie->key_width_bytes = key_width_bytes;
  trie->release_memory = auto_shrink;
  allocate_node(&trie->root);
  trie->num_entries = 0;
  return trie;
}
Ejemplo n.º 8
0
switch_status_t add_fetch_handler(ei_node_t *ei_node, erlang_pid *from, switch_xml_binding_t *binding) {
    ei_xml_agent_t *agent;
    ei_xml_client_t *client;
    fetch_handler_t *fetch_handler;

    agent = (ei_xml_agent_t *)switch_xml_get_binding_user_data(binding);

    /* write-lock the agent */
    switch_thread_rwlock_wrlock(agent->lock);

    if (!(client = find_xml_client(ei_node, agent))) {
        client = add_xml_client(ei_node, agent);
    }

    fetch_handler = client->fetch_handlers;
    while (fetch_handler != NULL) {
        if (ei_compare_pids(&fetch_handler->pid, from) == SWITCH_STATUS_SUCCESS) {
            switch_thread_rwlock_unlock(agent->lock);
            return SWITCH_STATUS_SUCCESS;
        }
        fetch_handler = fetch_handler->next;
    }

    switch_malloc(fetch_handler, sizeof(*fetch_handler));

    memcpy(&fetch_handler->pid, from, sizeof(erlang_pid));;

    fetch_handler->next = NULL;
    if (client->fetch_handlers) {
        fetch_handler->next = client->fetch_handlers;
    }

    client->fetch_handlers = fetch_handler;

    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added %s XML handler %s <%d.%d.%d>\n"
                      ,xml_section_to_string(agent->section)
                      ,fetch_handler->pid.node
                      ,fetch_handler->pid.creation
                      ,fetch_handler->pid.num
                      ,fetch_handler->pid.serial);

    switch_thread_rwlock_unlock(agent->lock);

    ei_link(ei_node, ei_self(&globals.ei_cnode), from);

    return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 9
0
static ei_xml_client_t *add_xml_client(ei_node_t *ei_node, ei_xml_agent_t *agent) {
    ei_xml_client_t *client;

    switch_malloc(client, sizeof(*client));

    client->ei_node = ei_node;
    client->fetch_handlers = NULL;
    client->next = NULL;

    if (agent->clients) {
        client->next = agent->clients;
    }

    agent->clients = client;

    return client;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
static switch_status_t switch_neighbor_dmac_insert_hash(
    switch_device_t device,
    switch_handle_t bd_handle,
    switch_mac_addr_t *mac,
    switch_handle_t neighbor_handle) {
  unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE];
  unsigned int len = 0;
  uint32_t hash = 0;
  uint16_t mac_index = 0;
  switch_neighbor_dmac_t *neighbor_dmac = NULL;

  switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash);
  neighbor_dmac = switch_malloc(sizeof(switch_neighbor_dmac_t), 1);
  if (!neighbor_dmac) {
    return mac_index;
  }
  memcpy(&neighbor_dmac->mac, mac, sizeof(switch_mac_addr_t));
  neighbor_dmac->handle = bd_handle;
  neighbor_dmac->neighbor_handle = neighbor_handle;
  tommy_hashtable_insert(
      &switch_neighbor_dmac_table, &(neighbor_dmac->node), neighbor_dmac, hash);
  return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
switch_status_t mod_amqp_logging_recv(const switch_log_node_t *node, switch_log_level_t level)
{
	switch_hash_index_t *hi = NULL;
	mod_amqp_message_t *msg = NULL;
	mod_amqp_logging_profile_t *logging = NULL;
	char *json = NULL;

	if (!strcmp(node->file, "mod_amqp_logging.c")) {
		return SWITCH_STATUS_SUCCESS;
	}

	/*
	  1. Loop through logging hash of profiles. Check for a profile that accepts this logging level, and file regex.
	  2. If event not already parsed/created, then create it now
	  3. Queue copy of event into logging profile send queue
	  4. Destroy local event copy
	*/
	for (hi = switch_core_hash_first(globals.logging_hash); hi; hi = switch_core_hash_next(&hi)) {
		switch_core_hash_this(hi, NULL, NULL, (void **)&logging);

		if ( logging && switch_log_check_mask(logging->log_level_mask, level) ) {
			char file[128] = {0};
			if ( !json ) {
				cJSON *body = NULL;
				char date[80] = "";
				switch_time_exp_t tm;

				switch_time_exp_lt(&tm, node->timestamp);
				switch_snprintf(date, sizeof(date), "%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d.%0.6d",
								tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec);

				/* Create cJSON body */
				body = cJSON_CreateObject();

				cJSON_AddItemToObject(body, "file", cJSON_CreateString((const char *) node->file));
				cJSON_AddItemToObject(body, "function", cJSON_CreateString((const char *) node->func));
				cJSON_AddItemToObject(body, "line", cJSON_CreateNumber((double) node->line));
				cJSON_AddItemToObject(body, "level", cJSON_CreateString(switch_log_level2str(node->level)));
				cJSON_AddItemToObject(body, "timestamp", cJSON_CreateString((const char *)date));
				cJSON_AddItemToObject(body, "timestamp_epoch", cJSON_CreateNumber((double) node->timestamp / 1000000));
				cJSON_AddItemToObject(body, "content", cJSON_CreateString(node->content ));

				json = cJSON_Print(body);
				cJSON_Delete(body);
			}

			/* Create message */
			switch_malloc(msg, sizeof(mod_amqp_message_t));
			msg->pjson = strdup(json);
			strcpy(file, node->file);
			switch_replace_char(file, '.', '_', 0);

			snprintf(msg->routing_key, sizeof(msg->routing_key), "%s.%s.%s.%s", switch_core_get_hostname(), node->userdata, switch_log_level2str(node->level), file);

			if (switch_queue_trypush(logging->send_queue, msg) != SWITCH_STATUS_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP logging message queue full. Messages will be dropped!\n");
				return SWITCH_STATUS_SUCCESS;
			}
		}
	}


	switch_safe_free(json);
	return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 14
0
static inline void allocate_node(node_t **node) {
  *node = (node_t *)switch_malloc(sizeof(node_t), 1);
  memset(*node, 0, sizeof(node_t));
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
static switch_status_t config(void) {
	char *cf = "kazoo.conf";
	switch_xml_t cfg, xml, child, param;
	globals.send_all_headers = globals.send_all_private_headers = 0;
	globals.connection_timeout = 500;
	globals.receive_timeout = 200;
	globals.receive_msg_preallocate = 2000;
	globals.event_stream_preallocate = 4000;
	globals.send_msg_batch = 10;
	globals.event_stream_framing = 2;
	globals.port = 0;
	
	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf);
		return SWITCH_STATUS_FALSE;
	} else {
		if ((child = switch_xml_child(cfg, "settings"))) {
			for (param = switch_xml_child(child, "param"); param; param = param->next) {
				char *var = (char *) switch_xml_attr_soft(param, "name");
				char *val = (char *) switch_xml_attr_soft(param, "value");
				
				if (!strcmp(var, "listen-ip")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val);
					set_pref_ip(val);
				} else if (!strcmp(var, "listen-port")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind port: %s\n", val);
					globals.port = atoi(val);
				} else if (!strcmp(var, "cookie")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie: %s\n", val);
					set_pref_ei_cookie(val);
				} else if (!strcmp(var, "cookie-file")) {
					if (read_cookie_from_file(val) == 1) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie from %s\n", val);
					}
				} else if (!strcmp(var, "nodename")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set node name: %s\n", val);
					set_pref_ei_nodename(val);
				} else if (!strcmp(var, "shortname")) {
					globals.ei_shortname = switch_true(val);
				} else if (!strcmp(var, "kazoo-var-prefix")) {
					set_pref_kazoo_var_prefix(val);
				} else if (!strcmp(var, "compat-rel")) {
					if (atoi(val) >= 7)
						globals.ei_compat_rel = atoi(val);
					else
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid compatibility release '%s' specified\n", val);
				} else if (!strcmp(var, "nat-map")) {
					globals.nat_map = switch_true(val);
				} else if (!strcmp(var, "send-all-headers")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-headers: %s\n", val);
					globals.send_all_headers = switch_true(val);
				} else if (!strcmp(var, "send-all-private-headers")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-all-private-headers: %s\n", val);
					globals.send_all_private_headers = switch_true(val);
				} else if (!strcmp(var, "connection-timeout")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set connection-timeout: %s\n", val);
					globals.connection_timeout = atoi(val);
				} else if (!strcmp(var, "receive-timeout")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-timeout: %s\n", val);
					globals.receive_timeout = atoi(val);
				} else if (!strcmp(var, "receive-msg-preallocate")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set receive-msg-preallocate: %s\n", val);
					globals.receive_msg_preallocate = atoi(val);
				} else if (!strcmp(var, "event-stream-preallocate")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-preallocate: %s\n", val);
					globals.event_stream_preallocate = atoi(val);
				} else if (!strcmp(var, "send-msg-batch-size")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set send-msg-batch-size: %s\n", val);
					globals.send_msg_batch = atoi(val);
				} else if (!strcmp(var, "event-stream-framing")) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set event-stream-framing: %s\n", val);
					globals.event_stream_framing = atoi(val);
				}
			}
		}
		
		if ((child = switch_xml_child(cfg, "event-filter"))) {
			switch_hash_t *filter;
			
			switch_core_hash_init(&filter);
			for (param = switch_xml_child(child, "header"); param; param = param->next) {
				char *var = (char *) switch_xml_attr_soft(param, "name");
				switch_core_hash_insert(filter, var, "1");
			}
			
			globals.event_filter = filter;
		}
		
		switch_xml_free(xml);
	}

	if (globals.receive_msg_preallocate < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n");
		globals.receive_msg_preallocate = 0;
	}
	
	if (globals.event_stream_preallocate < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n");
		globals.event_stream_preallocate = 0;
	}
	
	if (globals.send_msg_batch < 1) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n");
		globals.send_msg_batch = 10;
	}
	
	if (!globals.event_filter) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n");
		globals.event_filter = create_default_filter();
	}

	if (globals.event_stream_framing < 1 || globals.event_stream_framing > 4) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n");
		globals.event_stream_framing = 2;
	}
	
	if (zstr(globals.kazoo_var_prefix)) {
		set_pref_kazoo_var_prefix("variable_ecallmgr*");
		globals.var_prefix_length = 17; //ignore the *
	} else {
		/* we could use the global pool but then we would have to conditionally
		 * free the pointer if it was not drawn from the XML */
		char *buf;
		int size = switch_snprintf(NULL, 0, "variable_%s*", globals.kazoo_var_prefix) + 1;
		
		switch_malloc(buf, size);
		switch_snprintf(buf, size, "variable_%s*", globals.kazoo_var_prefix);
		switch_safe_free(globals.kazoo_var_prefix);
		globals.kazoo_var_prefix = buf;
		globals.var_prefix_length = size - 2; //ignore the *
	}
	
	if (!globals.num_worker_threads) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of worker threads not found in configuration, using default\n");
		globals.num_worker_threads = 10;
	}
	
	if (zstr(globals.ip)) {
		set_pref_ip("0.0.0.0");
	}
	
	if (zstr(globals.ei_cookie)) {
		int res;
		char *home_dir = getenv("HOME");
		char path_buf[1024];
		
		if (!zstr(home_dir)) {
			/* $HOME/.erlang.cookie */
			switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie");
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf);
			
			res = read_cookie_from_file(path_buf);
			if (res) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n");
				set_pref_ei_cookie("ClueCon");
			}
		}
	}
	
	if (!globals.ei_nodename) {
		set_pref_ei_nodename("freeswitch");
	}
	
	if (!globals.nat_map) {
		globals.nat_map = 0;
	}
	
	return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
static switch_xml_t fetch_handler(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) {
    switch_xml_t xml = NULL;
    switch_uuid_t uuid;
    switch_time_t now = 0;
    ei_xml_agent_t *agent = (ei_xml_agent_t *) user_data;
    ei_xml_client_t *client;
    fetch_handler_t *fetch_handler;
    xml_fetch_reply_t reply, *pending, *prev = NULL;

    now = switch_micro_time_now();

    if (!switch_test_flag(&globals, LFLAG_RUNNING)) {
        return xml;
    }

    /* read-lock the agent */
    switch_thread_rwlock_rdlock(agent->lock);

    /* serialize access to current, used to round-robin requests */
    /* TODO: check globals for round-robin boolean or loop all clients */
    switch_mutex_lock(agent->current_client_mutex);
    if (!agent->current_client) {
        client = agent->clients;
    } else {
        client = agent->current_client;
    }
    if (client) {
        agent->current_client = client->next;
    }
    switch_mutex_unlock(agent->current_client_mutex);

    /* no client, no work required */
    if (!client || !client->fetch_handlers) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No %s XML erlang handler currently available\n"
                          ,section);
        switch_thread_rwlock_unlock(agent->lock);
        return xml;
    }

    /* prepare the reply collector */
    switch_uuid_get(&uuid);
    switch_uuid_format(reply.uuid_str, &uuid);
    reply.next = NULL;
    reply.xml_str = NULL;

    /* add our reply placeholder to the replies list */
    switch_mutex_lock(agent->replies_mutex);
    if (!agent->replies) {
        agent->replies = &reply;
    } else {
        reply.next = agent->replies;
        agent->replies = &reply;
    }
    switch_mutex_unlock(agent->replies_mutex);

    fetch_handler = client->fetch_handlers;
    while (fetch_handler != NULL) {
        ei_send_msg_t *send_msg;

        switch_malloc(send_msg, sizeof(*send_msg));
        memcpy(&send_msg->pid, &fetch_handler->pid, sizeof(erlang_pid));

        ei_x_new_with_version(&send_msg->buf);

        ei_x_encode_tuple_header(&send_msg->buf, 7);
        ei_x_encode_atom(&send_msg->buf, "fetch");
        ei_x_encode_atom(&send_msg->buf, section);
        _ei_x_encode_string(&send_msg->buf, tag_name ? tag_name : "undefined");
        _ei_x_encode_string(&send_msg->buf, key_name ? key_name : "undefined");
        _ei_x_encode_string(&send_msg->buf, key_value ? key_value : "undefined");
        _ei_x_encode_string(&send_msg->buf, reply.uuid_str);

        if (params) {
            ei_encode_switch_event_headers(&send_msg->buf, params);
        } else {
            ei_x_encode_empty_list(&send_msg->buf);
        }

        if (switch_queue_trypush(client->ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send %s XML request to %s <%d.%d.%d>\n"
                              ,section
                              ,fetch_handler->pid.node
                              ,fetch_handler->pid.creation
                              ,fetch_handler->pid.num
                              ,fetch_handler->pid.serial);
            ei_x_free(&send_msg->buf);
            switch_safe_free(send_msg);
        } else {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending %s XML request (%s) to %s <%d.%d.%d>\n"
                              ,section
                              ,reply.uuid_str
                              ,fetch_handler->pid.node
                              ,fetch_handler->pid.creation
                              ,fetch_handler->pid.num
                              ,fetch_handler->pid.serial);
        }

        fetch_handler = fetch_handler->next;
    }

    /* wait for a reply (if there isnt already one...amazingly improbable but lets not take shortcuts */
    switch_mutex_lock(agent->replies_mutex);

    switch_thread_rwlock_unlock(agent->lock);

    if (!reply.xml_str) {
        switch_time_t timeout;

        timeout = switch_micro_time_now() + 3000000;
        while (switch_micro_time_now() < timeout) {
            /* unlock the replies list and go to sleep, calculate a three second timeout before we started the loop
             * plus 100ms to add a little hysteresis between the timeout and the while loop */
            switch_thread_cond_timedwait(agent->new_reply, agent->replies_mutex, (timeout - switch_micro_time_now() + 100000));

            /* if we woke up (and therefore have locked replies again) check if we got our reply
             * otherwise we either timed-out (the while condition will fail) or one of
             * our sibling processes got a reply and we should go back to sleep */
            if (reply.xml_str) {
                break;
            }
        }
    }

    /* find our reply placeholder in the linked list and remove it */
    pending = agent->replies;
    while (pending != NULL) {
        if (pending->uuid_str == reply.uuid_str) {
            break;
        }

        prev = pending;
        pending = pending->next;
    }

    if (pending) {
        if (!prev) {
            agent->replies = reply.next;
        } else {
            prev->next = reply.next;
        }
    }

    /* we are done with the replies link-list */
    switch_mutex_unlock(agent->replies_mutex);

    /* after all that did we get what we were after?! */
    if (reply.xml_str) {
        /* HELL YA WE DID */
        reply.xml_str = expand_vars(reply.xml_str);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received %s XML (%s) after %dms: %s\n"
                          ,section
                          ,reply.uuid_str
                          ,(unsigned int) (switch_micro_time_now() - now) / 1000
                          ,reply.xml_str);

        xml = switch_xml_parse_str_dynamic(reply.xml_str, SWITCH_FALSE);
    } else {
        /* facepalm */
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Request for %s XML (%s) timed-out after %dms\n"
                          ,section
                          ,reply.uuid_str
                          ,(unsigned int) (switch_micro_time_now() - now) / 1000);
    }

    return xml;
}
Ejemplo n.º 19
0
static switch_handle_t sai_ipmc_tree_create(
    _In_ switch_handle_t vrf_handle,
    _In_ switch_ip_addr_t *src_addr,
    _In_ switch_ip_addr_t *grp_addr,
    _In_ int oif_list_count,
    _In_ switch_handle_t *oif_list_handle) {
  switch_handle_t mcast_handle;
  switch_status_t status;

  uint16_t mbr_count_max = oif_list_count;
  uint16_t mbr_count = 0;
  switch_vlan_interface_t *mbrs = NULL;
  mbrs = switch_malloc(sizeof(switch_vlan_interface_t), oif_list_count);

  mcast_handle = switch_api_multicast_tree_create(device);
  int i = 0;
  for (i = 0; i < oif_list_count; i++) {
    switch_handle_t intf_handle = oif_list_handle[i];
    switch_interface_type_t type;
    status = switch_api_interface_get_type(intf_handle, &type);
    assert(status == SWITCH_STATUS_SUCCESS);
    if (type == SWITCH_API_INTERFACE_L3) {
      mbrs[mbr_count].vlan_handle = 0;
      mbrs[mbr_count].intf_handle = intf_handle;
      mbr_count++;
    } else {
      uint64_t snooping_enabled = true;
      switch_handle_t vlan_handle;
      status = switch_api_interface_get_vlan_handle(intf_handle, &vlan_handle);
      assert(status == SWITCH_STATUS_SUCCESS);
      if (grp_addr->type == SWITCH_API_IP_ADDR_V4) {
        status = switch_api_vlan_igmp_snooping_enabled_get(vlan_handle,
                                                           &snooping_enabled);
        assert(status == SWITCH_STATUS_SUCCESS);
      } else {
        status = switch_api_vlan_mld_snooping_enabled_get(vlan_handle,
                                                          &snooping_enabled);
        assert(status == SWITCH_STATUS_SUCCESS);
      }
      if (snooping_enabled) {
        switch_handle_t l2mcast_handle;
        status = switch_api_multicast_l2route_tree_get(
            device, vlan_handle, src_addr, grp_addr, &l2mcast_handle);
        if (status != SWITCH_STATUS_SUCCESS) {
          continue;
        }
        uint16_t l2mbr_count = 0;
        switch_vlan_interface_t *l2mbrs = NULL;
        status = switch_api_multicast_member_get(
            device, l2mcast_handle, &l2mbr_count, &l2mbrs);
        if (status != SWITCH_STATUS_SUCCESS) {
          continue;
        }
        mbr_count_max += l2mbr_count;
        mbrs = switch_realloc(
            mbrs, (sizeof(switch_vlan_interface_t) * mbr_count_max));
        memcpy(mbrs + mbr_count,
               l2mbrs,
               (sizeof(switch_vlan_interface_t) * l2mbr_count));
        mbr_count += l2mbr_count;

        switch_free(l2mbrs);
      } else {
        uint16_t l2mbr_count = 0;
        switch_vlan_interface_t *l2mbrs = NULL;
        status = switch_api_vlan_interfaces_get(
            device, vlan_handle, &l2mbr_count, &l2mbrs);
        if (status != SWITCH_STATUS_SUCCESS) {
          continue;
        }

        mbr_count_max += l2mbr_count;
        mbrs = switch_realloc(
            mbrs, (sizeof(switch_vlan_interface_t) * mbr_count_max));
        memcpy(mbrs + mbr_count,
               l2mbrs,
               (sizeof(switch_vlan_interface_t) * l2mbr_count));
        mbr_count += l2mbr_count;
      }
    }
  }
  status =
      switch_api_multicast_member_add(device, mcast_handle, mbr_count, mbrs);
  assert(status == SWITCH_STATUS_SUCCESS);

  switch_free(mbrs);
  return mcast_handle;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
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;
}