|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* OSM QoS Policy functions.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Author:
|
|
Packit |
13e616 |
* Yevgeny Kliteynik, Mellanox
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdio.h>
|
|
Packit |
13e616 |
#include <assert.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <ctype.h>
|
|
Packit |
13e616 |
#include <arpa/inet.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_QOS_POLICY_C
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <opensm/osm_node.h>
|
|
Packit |
13e616 |
#include <opensm/osm_port.h>
|
|
Packit |
13e616 |
#include <opensm/osm_partition.h>
|
|
Packit |
13e616 |
#include <opensm/osm_opensm.h>
|
|
Packit |
13e616 |
#include <opensm/osm_qos_policy.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
extern osm_qos_level_t __default_simple_qos_level;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void
|
|
Packit |
13e616 |
__build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_node_t * p_node;
|
|
Packit |
13e616 |
cl_qmap_t * p_node_guid_tbl = &p_qos_policy->p_subn->node_guid_tbl;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_qos_policy->p_node_hash = st_init_strtable();
|
|
Packit |
13e616 |
CL_ASSERT(p_qos_policy->p_node_hash);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_node_guid_tbl || !cl_qmap_count(p_node_guid_tbl))
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (p_node = (osm_node_t *) cl_qmap_head(p_node_guid_tbl);
|
|
Packit |
13e616 |
p_node != (osm_node_t *) cl_qmap_end(p_node_guid_tbl);
|
|
Packit |
13e616 |
p_node = (osm_node_t *) cl_qmap_next(&p_node->map_item)) {
|
|
Packit |
13e616 |
if (!st_lookup(p_qos_policy->p_node_hash,
|
|
Packit |
13e616 |
(st_data_t)p_node->print_desc, NULL))
|
|
Packit |
13e616 |
st_insert(p_qos_policy->p_node_hash,
|
|
Packit |
13e616 |
(st_data_t)p_node->print_desc,
|
|
Packit |
13e616 |
(st_data_t)p_node);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static boolean_t
|
|
Packit |
13e616 |
__is_num_in_range_arr(uint64_t ** range_arr,
|
|
Packit |
13e616 |
unsigned range_arr_len, uint64_t num)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
unsigned ind_1 = 0;
|
|
Packit |
13e616 |
unsigned ind_2 = range_arr_len - 1;
|
|
Packit |
13e616 |
unsigned ind_mid;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!range_arr || !range_arr_len)
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (ind_1 <= ind_2) {
|
|
Packit |
13e616 |
if (num < range_arr[ind_1][0] || num > range_arr[ind_2][1])
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
else if (num <= range_arr[ind_1][1] || num >= range_arr[ind_2][0])
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ind_mid = ind_1 + (ind_2 - ind_1 + 1)/2;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (num < range_arr[ind_mid][0])
|
|
Packit |
13e616 |
ind_2 = ind_mid;
|
|
Packit |
13e616 |
else if (num > range_arr[ind_mid][1])
|
|
Packit |
13e616 |
ind_1 = ind_mid;
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ind_1++;
|
|
Packit |
13e616 |
ind_2--;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __free_single_element(void *p_element, void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (p_element)
|
|
Packit |
13e616 |
free(p_element);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_port_t *osm_qos_policy_port_create(osm_physp_t *p_physp)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_port_t *p =
|
|
Packit |
13e616 |
(osm_qos_port_t *) calloc(1, sizeof(osm_qos_port_t));
|
|
Packit |
13e616 |
if (p)
|
|
Packit |
13e616 |
p->p_physp = p_physp;
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_port_group_t *osm_qos_policy_port_group_create()
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_port_group_t *p =
|
|
Packit |
13e616 |
(osm_qos_port_group_t *) calloc(1, sizeof(osm_qos_port_group_t));
|
|
Packit |
13e616 |
if (p)
|
|
Packit |
13e616 |
cl_qmap_init(&p->port_map);
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_port_t * p_port;
|
|
Packit |
13e616 |
osm_qos_port_t * p_old_port;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->name)
|
|
Packit |
13e616 |
free(p->name);
|
|
Packit |
13e616 |
if (p->use)
|
|
Packit |
13e616 |
free(p->use);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_port = (osm_qos_port_t *) cl_qmap_head(&p->port_map);
|
|
Packit |
13e616 |
while (p_port != (osm_qos_port_t *) cl_qmap_end(&p->port_map))
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
p_old_port = p_port;
|
|
Packit |
13e616 |
p_port = (osm_qos_port_t *) cl_qmap_next(&p_port->map_item);
|
|
Packit |
13e616 |
free(p_old_port);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_qmap_remove_all(&p->port_map);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_vlarb_scope_t *osm_qos_policy_vlarb_scope_create()
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_vlarb_scope_t *p =
|
|
Packit |
13e616 |
(osm_qos_vlarb_scope_t *) calloc(1, sizeof(osm_qos_vlarb_scope_t));
|
|
Packit |
13e616 |
if (p) {
|
|
Packit |
13e616 |
cl_list_init(&p->group_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->across_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->vlarb_high_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->vlarb_low_list, 10);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_vlarb_scope_destroy(osm_qos_vlarb_scope_t * p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_apply_func(&p->group_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_apply_func(&p->across_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_apply_func(&p->vlarb_high_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_apply_func(&p->vlarb_low_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_remove_all(&p->group_list);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->across_list);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->vlarb_high_list);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->vlarb_low_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_destroy(&p->group_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->across_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->vlarb_high_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->vlarb_low_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_sl2vl_scope_t *osm_qos_policy_sl2vl_scope_create()
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_sl2vl_scope_t *p =
|
|
Packit |
13e616 |
(osm_qos_sl2vl_scope_t *) calloc(1, sizeof(osm_qos_sl2vl_scope_t));
|
|
Packit |
13e616 |
if (p) {
|
|
Packit |
13e616 |
cl_list_init(&p->group_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->across_from_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->across_to_list, 10);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_sl2vl_scope_destroy(osm_qos_sl2vl_scope_t * p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_apply_func(&p->group_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_apply_func(&p->across_from_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_apply_func(&p->across_to_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_remove_all(&p->group_list);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->across_from_list);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->across_to_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_destroy(&p->group_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->across_from_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->across_to_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_level_t *osm_qos_policy_qos_level_create()
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_level_t *p =
|
|
Packit |
13e616 |
(osm_qos_level_t *) calloc(1, sizeof(osm_qos_level_t));
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_qos_level_destroy(osm_qos_level_t * p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
unsigned i;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p->name);
|
|
Packit |
13e616 |
free(p->use);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (i = 0; i < p->path_bits_range_len; i++)
|
|
Packit |
13e616 |
free(p->path_bits_range_arr[i]);
|
|
Packit |
13e616 |
free(p->path_bits_range_arr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for(i = 0; i < p->pkey_range_len; i++)
|
|
Packit |
13e616 |
free((p->pkey_range_arr[i]));
|
|
Packit |
13e616 |
free(p->pkey_range_arr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
boolean_t osm_qos_level_has_pkey(IN const osm_qos_level_t * p_qos_level,
|
|
Packit |
13e616 |
IN ib_net16_t pkey)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (!p_qos_level || !p_qos_level->pkey_range_len)
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
return __is_num_in_range_arr(p_qos_level->pkey_range_arr,
|
|
Packit |
13e616 |
p_qos_level->pkey_range_len,
|
|
Packit |
13e616 |
cl_ntoh16(ib_pkey_get_base(pkey)));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_net16_t osm_qos_level_get_shared_pkey(IN const osm_qos_level_t * p_qos_level,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_src_physp,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_dest_physp,
|
|
Packit |
13e616 |
IN const boolean_t allow_both_pkeys)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
unsigned i;
|
|
Packit |
13e616 |
uint16_t pkey_ho = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_level || !p_qos_level->pkey_range_len)
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* ToDo: This approach is not optimal.
|
|
Packit |
13e616 |
* Think how to find shared pkey that also exists
|
|
Packit |
13e616 |
* in QoS level in less runtime.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (i = 0; i < p_qos_level->pkey_range_len; i++) {
|
|
Packit |
13e616 |
for (pkey_ho = p_qos_level->pkey_range_arr[i][0];
|
|
Packit |
13e616 |
pkey_ho <= p_qos_level->pkey_range_arr[i][1]; pkey_ho++) {
|
|
Packit |
13e616 |
if (osm_physp_share_this_pkey
|
|
Packit |
13e616 |
(p_src_physp, p_dest_physp, cl_hton16(pkey_ho),
|
|
Packit |
13e616 |
allow_both_pkeys))
|
|
Packit |
13e616 |
return cl_hton16(pkey_ho);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_match_rule_t *osm_qos_policy_match_rule_create()
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_match_rule_t *p =
|
|
Packit |
13e616 |
(osm_qos_match_rule_t *) calloc(1, sizeof(osm_qos_match_rule_t));
|
|
Packit |
13e616 |
if (p) {
|
|
Packit |
13e616 |
cl_list_init(&p->source_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->source_group_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->destination_list, 10);
|
|
Packit |
13e616 |
cl_list_init(&p->destination_group_list, 10);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_match_rule_destroy(osm_qos_match_rule_t * p)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
unsigned i;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->qos_level_name)
|
|
Packit |
13e616 |
free(p->qos_level_name);
|
|
Packit |
13e616 |
if (p->use)
|
|
Packit |
13e616 |
free(p->use);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->service_id_range_arr) {
|
|
Packit |
13e616 |
for (i = 0; i < p->service_id_range_len; i++)
|
|
Packit |
13e616 |
free(p->service_id_range_arr[i]);
|
|
Packit |
13e616 |
free(p->service_id_range_arr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->qos_class_range_arr) {
|
|
Packit |
13e616 |
for (i = 0; i < p->qos_class_range_len; i++)
|
|
Packit |
13e616 |
free(p->qos_class_range_arr[i]);
|
|
Packit |
13e616 |
free(p->qos_class_range_arr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->pkey_range_arr) {
|
|
Packit |
13e616 |
for (i = 0; i < p->pkey_range_len; i++)
|
|
Packit |
13e616 |
free(p->pkey_range_arr[i]);
|
|
Packit |
13e616 |
free(p->pkey_range_arr);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_apply_func(&p->source_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->source_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->source_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_remove_all(&p->source_group_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->source_group_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_apply_func(&p->destination_list, __free_single_element, NULL);
|
|
Packit |
13e616 |
cl_list_remove_all(&p->destination_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->destination_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_remove_all(&p->destination_group_list);
|
|
Packit |
13e616 |
cl_list_destroy(&p->destination_group_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_policy_t * osm_qos_policy_create(osm_subn_t * p_subn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_policy_t * p_qos_policy = (osm_qos_policy_t *)calloc(1, sizeof(osm_qos_policy_t));
|
|
Packit |
13e616 |
if (!p_qos_policy)
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&p_qos_policy->port_groups);
|
|
Packit |
13e616 |
cl_list_init(&p_qos_policy->port_groups, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&p_qos_policy->vlarb_tables);
|
|
Packit |
13e616 |
cl_list_init(&p_qos_policy->vlarb_tables, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&p_qos_policy->sl2vl_tables);
|
|
Packit |
13e616 |
cl_list_init(&p_qos_policy->sl2vl_tables, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&p_qos_policy->qos_levels);
|
|
Packit |
13e616 |
cl_list_init(&p_qos_policy->qos_levels, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
cl_list_init(&p_qos_policy->qos_match_rules, 10);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_qos_policy->p_subn = p_subn;
|
|
Packit |
13e616 |
__build_nodebyname_hash(p_qos_policy);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p_qos_policy;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_qos_policy_destroy(osm_qos_policy_t * p_qos_policy)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
osm_qos_port_group_t *p_port_group = NULL;
|
|
Packit |
13e616 |
osm_qos_vlarb_scope_t *p_vlarb_scope = NULL;
|
|
Packit |
13e616 |
osm_qos_sl2vl_scope_t *p_sl2vl_scope = NULL;
|
|
Packit |
13e616 |
osm_qos_level_t *p_qos_level = NULL;
|
|
Packit |
13e616 |
osm_qos_match_rule_t *p_qos_match_rule = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_policy)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->port_groups);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
|
|
Packit |
13e616 |
p_port_group =
|
|
Packit |
13e616 |
(osm_qos_port_group_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_port_group)
|
|
Packit |
13e616 |
osm_qos_policy_port_group_destroy(p_port_group);
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_remove_all(&p_qos_policy->port_groups);
|
|
Packit |
13e616 |
cl_list_destroy(&p_qos_policy->port_groups);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->vlarb_tables);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->vlarb_tables)) {
|
|
Packit |
13e616 |
p_vlarb_scope =
|
|
Packit |
13e616 |
(osm_qos_vlarb_scope_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_vlarb_scope)
|
|
Packit |
13e616 |
osm_qos_policy_vlarb_scope_destroy(p_vlarb_scope);
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_remove_all(&p_qos_policy->vlarb_tables);
|
|
Packit |
13e616 |
cl_list_destroy(&p_qos_policy->vlarb_tables);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->sl2vl_tables);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->sl2vl_tables)) {
|
|
Packit |
13e616 |
p_sl2vl_scope =
|
|
Packit |
13e616 |
(osm_qos_sl2vl_scope_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_sl2vl_scope)
|
|
Packit |
13e616 |
osm_qos_policy_sl2vl_scope_destroy(p_sl2vl_scope);
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_remove_all(&p_qos_policy->sl2vl_tables);
|
|
Packit |
13e616 |
cl_list_destroy(&p_qos_policy->sl2vl_tables);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->qos_levels);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
|
|
Packit |
13e616 |
p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_qos_level)
|
|
Packit |
13e616 |
osm_qos_policy_qos_level_destroy(p_qos_level);
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_remove_all(&p_qos_policy->qos_levels);
|
|
Packit |
13e616 |
cl_list_destroy(&p_qos_policy->qos_levels);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
|
|
Packit |
13e616 |
p_qos_match_rule =
|
|
Packit |
13e616 |
(osm_qos_match_rule_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_qos_match_rule)
|
|
Packit |
13e616 |
osm_qos_policy_match_rule_destroy(p_qos_match_rule);
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_list_remove_all(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
cl_list_destroy(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_qos_policy->p_node_hash)
|
|
Packit |
13e616 |
st_free_table(p_qos_policy->p_node_hash);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_qos_policy);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_qos_policy = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static boolean_t
|
|
Packit |
13e616 |
__qos_policy_is_port_in_group(osm_subn_t * p_subn,
|
|
Packit |
13e616 |
const osm_physp_t * p_physp,
|
|
Packit |
13e616 |
osm_qos_port_group_t * p_port_group)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit |
13e616 |
ib_net64_t port_guid = osm_physp_get_port_guid(p_physp);
|
|
Packit |
13e616 |
uint64_t port_guid_ho = cl_ntoh64(port_guid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* check whether this port's type matches any of group's types */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if ( p_port_group->node_types &
|
|
Packit |
13e616 |
(((uint8_t)1)<
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* check whether this port's guid is in group's port map */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_qmap_get(&p_port_group->port_map, port_guid_ho) !=
|
|
Packit |
13e616 |
cl_qmap_end(&p_port_group->port_map))
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
} /* __qos_policy_is_port_in_group() */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static boolean_t
|
|
Packit |
13e616 |
__qos_policy_is_port_in_group_list(const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
const osm_physp_t * p_physp,
|
|
Packit |
13e616 |
cl_list_t * p_port_group_list)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_port_group_t *p_port_group;
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(p_port_group_list);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(p_port_group_list)) {
|
|
Packit |
13e616 |
p_port_group =
|
|
Packit |
13e616 |
(osm_qos_port_group_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (p_port_group) {
|
|
Packit |
13e616 |
if (__qos_policy_is_port_in_group
|
|
Packit |
13e616 |
(p_qos_policy->p_subn, p_physp, p_port_group))
|
|
Packit |
13e616 |
return TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
|
|
Packit |
13e616 |
const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
uint64_t service_id,
|
|
Packit |
13e616 |
uint16_t qos_class,
|
|
Packit |
13e616 |
uint16_t pkey,
|
|
Packit |
13e616 |
const osm_physp_t * p_src_physp,
|
|
Packit |
13e616 |
const osm_physp_t * p_dest_physp,
|
|
Packit |
13e616 |
ib_net64_t comp_mask)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_match_rule_t *p_qos_match_rule = NULL;
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
osm_log_t * p_log = &p_qos_policy->p_subn->p_osm->log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
boolean_t matched_by_sguid = FALSE,
|
|
Packit |
13e616 |
matched_by_dguid = FALSE,
|
|
Packit |
13e616 |
matched_by_sordguid = FALSE,
|
|
Packit |
13e616 |
matched_by_class = FALSE,
|
|
Packit |
13e616 |
matched_by_sid = FALSE,
|
|
Packit |
13e616 |
matched_by_pkey = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!cl_list_count(&p_qos_policy->qos_match_rules))
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Go over all QoS match rules and find the one that matches the request */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
|
|
Packit |
13e616 |
p_qos_match_rule =
|
|
Packit |
13e616 |
(osm_qos_match_rule_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (!p_qos_match_rule) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has Source groups and no Destination groups,
|
|
Packit |
13e616 |
* PR request source has to be in this list */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_list_count(&p_qos_match_rule->source_group_list)
|
|
Packit |
13e616 |
&& !cl_list_count(&p_qos_match_rule->destination_group_list)) {
|
|
Packit |
13e616 |
if (!__qos_policy_is_port_in_group_list(p_qos_policy,
|
|
Packit |
13e616 |
p_src_physp,
|
|
Packit |
13e616 |
&p_qos_match_rule->
|
|
Packit |
13e616 |
source_group_list))
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
matched_by_sguid = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has Destination groups and no Source groups,
|
|
Packit |
13e616 |
* PR request dest. has to be in this list */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_list_count(&p_qos_match_rule->destination_group_list)
|
|
Packit |
13e616 |
&& !cl_list_count(&p_qos_match_rule->source_group_list)) {
|
|
Packit |
13e616 |
if (!__qos_policy_is_port_in_group_list(p_qos_policy,
|
|
Packit |
13e616 |
p_dest_physp,
|
|
Packit |
13e616 |
&p_qos_match_rule->
|
|
Packit |
13e616 |
destination_group_list))
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
matched_by_dguid = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has both Source and Destination groups,
|
|
Packit |
13e616 |
* PR request source or dest. must be in respective list
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (cl_list_count(&p_qos_match_rule->source_group_list)
|
|
Packit |
13e616 |
&& cl_list_count(&p_qos_match_rule->destination_group_list)) {
|
|
Packit |
13e616 |
if (__qos_policy_is_port_in_group_list(p_qos_policy,
|
|
Packit |
13e616 |
p_src_physp,
|
|
Packit |
13e616 |
&p_qos_match_rule->
|
|
Packit |
13e616 |
source_group_list)
|
|
Packit |
13e616 |
&& __qos_policy_is_port_in_group_list(p_qos_policy,
|
|
Packit |
13e616 |
p_dest_physp,
|
|
Packit |
13e616 |
&p_qos_match_rule->
|
|
Packit |
13e616 |
destination_group_list))
|
|
Packit |
13e616 |
matched_by_sordguid = TRUE;
|
|
Packit |
13e616 |
else {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has QoS classes, PR request HAS
|
|
Packit |
13e616 |
to have a matching QoS class to match the rule */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_qos_match_rule->qos_class_range_len) {
|
|
Packit |
13e616 |
if (!(comp_mask & IB_PR_COMPMASK_QOS_CLASS)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!__is_num_in_range_arr
|
|
Packit |
13e616 |
(p_qos_match_rule->qos_class_range_arr,
|
|
Packit |
13e616 |
p_qos_match_rule->qos_class_range_len,
|
|
Packit |
13e616 |
qos_class)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
matched_by_class = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has Service IDs, PR request HAS
|
|
Packit |
13e616 |
to have a matching Service ID to match the rule */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_qos_match_rule->service_id_range_len) {
|
|
Packit |
13e616 |
if (!(comp_mask & IB_PR_COMPMASK_SERVICEID_MSB) ||
|
|
Packit |
13e616 |
!(comp_mask & IB_PR_COMPMASK_SERVICEID_LSB)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!__is_num_in_range_arr
|
|
Packit |
13e616 |
(p_qos_match_rule->service_id_range_arr,
|
|
Packit |
13e616 |
p_qos_match_rule->service_id_range_len,
|
|
Packit |
13e616 |
service_id)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
matched_by_sid = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If a match rule has PKeys, PR request HAS
|
|
Packit |
13e616 |
to have a matching PKey to match the rule */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_qos_match_rule->pkey_range_len) {
|
|
Packit |
13e616 |
if (!(comp_mask & IB_PR_COMPMASK_PKEY)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!__is_num_in_range_arr
|
|
Packit |
13e616 |
(p_qos_match_rule->pkey_range_arr,
|
|
Packit |
13e616 |
p_qos_match_rule->pkey_range_len,
|
|
Packit |
13e616 |
pkey & 0x7FFF)) {
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
matched_by_pkey = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* if we got here, then this match-rule matched this PR request */
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (list_iterator == cl_list_end(&p_qos_policy->qos_match_rules))
|
|
Packit |
13e616 |
p_qos_match_rule = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_qos_match_rule)
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"request matched rule (%s) by:%s%s%s%s%s%s\n",
|
|
Packit |
13e616 |
(p_qos_match_rule->use) ?
|
|
Packit |
13e616 |
p_qos_match_rule->use : "no description",
|
|
Packit |
13e616 |
(matched_by_sguid) ? " SGUID" : "",
|
|
Packit |
13e616 |
(matched_by_dguid) ? " DGUID" : "",
|
|
Packit |
13e616 |
(matched_by_sordguid) ? "SorDGUID" : "",
|
|
Packit |
13e616 |
(matched_by_class) ? " QoS_Class" : "",
|
|
Packit |
13e616 |
(matched_by_sid) ? " ServiceID" : "",
|
|
Packit |
13e616 |
(matched_by_pkey) ? " PKey" : "");
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"request not matched any rule\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return p_qos_match_rule;
|
|
Packit |
13e616 |
} /* __qos_policy_get_match_rule_by_params() */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static osm_qos_level_t *__qos_policy_get_qos_level_by_name(
|
|
Packit |
13e616 |
const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
const char *name)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_level_t *p_qos_level = NULL;
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->qos_levels);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
|
|
Packit |
13e616 |
p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (!p_qos_level)
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* names are case INsensitive */
|
|
Packit |
13e616 |
if (strcasecmp(name, p_qos_level->name) == 0)
|
|
Packit |
13e616 |
return p_qos_level;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(
|
|
Packit |
13e616 |
const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
const char *const name)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_port_group_t *p_port_group = NULL;
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_head(&p_qos_policy->port_groups);
|
|
Packit |
13e616 |
while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
|
|
Packit |
13e616 |
p_port_group =
|
|
Packit |
13e616 |
(osm_qos_port_group_t *) cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
if (!p_port_group)
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* names are case INsensitive */
|
|
Packit |
13e616 |
if (strcasecmp(name, p_port_group->name) == 0)
|
|
Packit |
13e616 |
return p_port_group;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __qos_policy_validate_pkey(
|
|
Packit |
13e616 |
osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
osm_qos_match_rule_t * p_qos_match_rule,
|
|
Packit |
13e616 |
osm_prtn_t * p_prtn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
if (!p_qos_policy || !p_qos_match_rule || !p_prtn)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_match_rule->p_qos_level->sl_set ||
|
|
Packit |
13e616 |
p_prtn->sl == p_qos_match_rule->p_qos_level->sl)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"QoS Level SL (%u) for Pkey 0x%04X in match rule "
|
|
Packit |
13e616 |
"differs from partition SL (%u)\n",
|
|
Packit |
13e616 |
p_qos_match_rule->p_qos_level->sl,
|
|
Packit |
13e616 |
cl_ntoh16(p_prtn->pkey), p_prtn->sl);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
osm_log_t *p_log)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_iterator_t match_rules_list_iterator;
|
|
Packit |
13e616 |
cl_list_iterator_t list_iterator;
|
|
Packit |
13e616 |
osm_qos_port_group_t *p_port_group = NULL;
|
|
Packit |
13e616 |
osm_qos_match_rule_t *p_qos_match_rule = NULL;
|
|
Packit |
13e616 |
char *str;
|
|
Packit |
13e616 |
unsigned i, j;
|
|
Packit |
13e616 |
int res = 0;
|
|
Packit |
13e616 |
uint64_t pkey_64;
|
|
Packit |
13e616 |
ib_net16_t pkey;
|
|
Packit |
13e616 |
osm_prtn_t * p_prtn;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* set default qos level */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_qos_policy->p_default_qos_level =
|
|
Packit |
13e616 |
__qos_policy_get_qos_level_by_name(p_qos_policy, OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
|
|
Packit |
13e616 |
if (!p_qos_policy->p_default_qos_level) {
|
|
Packit |
13e616 |
/* There's no default QoS level in the usual qos-level section.
|
|
Packit |
13e616 |
Check whether the 'simple' default QoS level that can be
|
|
Packit |
13e616 |
defined in the qos-ulp section exists */
|
|
Packit |
13e616 |
if (__default_simple_qos_level.sl_set) {
|
|
Packit |
13e616 |
p_qos_policy->p_default_qos_level = &__default_simple_qos_level;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
else {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC10: "
|
|
Packit |
13e616 |
"Default qos-level (%s) not defined.\n",
|
|
Packit |
13e616 |
OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* scan all the match rules, and fill the lists of pointers to
|
|
Packit |
13e616 |
relevant qos levels and port groups to speed up PR matching */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
i = 1;
|
|
Packit |
13e616 |
match_rules_list_iterator =
|
|
Packit |
13e616 |
cl_list_head(&p_qos_policy->qos_match_rules);
|
|
Packit |
13e616 |
while (match_rules_list_iterator !=
|
|
Packit |
13e616 |
cl_list_end(&p_qos_policy->qos_match_rules)) {
|
|
Packit |
13e616 |
p_qos_match_rule =
|
|
Packit |
13e616 |
(osm_qos_match_rule_t *)
|
|
Packit |
13e616 |
cl_list_obj(match_rules_list_iterator);
|
|
Packit |
13e616 |
CL_ASSERT(p_qos_match_rule);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* find the matching qos-level for each match-rule */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_match_rule->p_qos_level)
|
|
Packit |
13e616 |
p_qos_match_rule->p_qos_level =
|
|
Packit |
13e616 |
__qos_policy_get_qos_level_by_name(p_qos_policy,
|
|
Packit |
13e616 |
p_qos_match_rule->qos_level_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_match_rule->p_qos_level) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC11: "
|
|
Packit |
13e616 |
"qos-match-rule num %u: qos-level '%s' not found\n",
|
|
Packit |
13e616 |
i, p_qos_match_rule->qos_level_name);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* find the matching port-group for element of source_list */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_list_count(&p_qos_match_rule->source_list)) {
|
|
Packit |
13e616 |
list_iterator =
|
|
Packit |
13e616 |
cl_list_head(&p_qos_match_rule->source_list);
|
|
Packit |
13e616 |
while (list_iterator !=
|
|
Packit |
13e616 |
cl_list_end(&p_qos_match_rule->source_list)) {
|
|
Packit |
13e616 |
str = (char *)cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
CL_ASSERT(str);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_port_group =
|
|
Packit |
13e616 |
__qos_policy_get_port_group_by_name(p_qos_policy, str);
|
|
Packit |
13e616 |
if (!p_port_group) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC12: "
|
|
Packit |
13e616 |
"qos-match-rule num %u: source port-group '%s' not found\n",
|
|
Packit |
13e616 |
i, str);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_insert_tail(&p_qos_match_rule->
|
|
Packit |
13e616 |
source_group_list,
|
|
Packit |
13e616 |
p_port_group);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* find the matching port-group for element of destination_list */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_list_count(&p_qos_match_rule->destination_list)) {
|
|
Packit |
13e616 |
list_iterator =
|
|
Packit |
13e616 |
cl_list_head(&p_qos_match_rule->destination_list);
|
|
Packit |
13e616 |
while (list_iterator !=
|
|
Packit |
13e616 |
cl_list_end(&p_qos_match_rule->
|
|
Packit |
13e616 |
destination_list)) {
|
|
Packit |
13e616 |
str = (char *)cl_list_obj(list_iterator);
|
|
Packit |
13e616 |
CL_ASSERT(str);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_port_group =
|
|
Packit |
13e616 |
__qos_policy_get_port_group_by_name(p_qos_policy,str);
|
|
Packit |
13e616 |
if (!p_port_group) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC13: "
|
|
Packit |
13e616 |
"qos-match-rule num %u: destination port-group '%s' not found\n",
|
|
Packit |
13e616 |
i, str);
|
|
Packit |
13e616 |
res = 1;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_insert_tail(&p_qos_match_rule->
|
|
Packit |
13e616 |
destination_group_list,
|
|
Packit |
13e616 |
p_port_group);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
list_iterator = cl_list_next(list_iterator);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Scan all the pkeys in matching rule, and if the
|
|
Packit |
13e616 |
* partition for these pkeys exists, set the SL
|
|
Packit |
13e616 |
* according to the QoS Level.
|
|
Packit |
13e616 |
* Warn if there's mismatch between QoS level SL
|
|
Packit |
13e616 |
* and Partition SL.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (j = 0; j < p_qos_match_rule->pkey_range_len; j++) {
|
|
Packit |
13e616 |
for ( pkey_64 = p_qos_match_rule->pkey_range_arr[j][0];
|
|
Packit |
13e616 |
pkey_64 <= p_qos_match_rule->pkey_range_arr[j][1];
|
|
Packit |
13e616 |
pkey_64++) {
|
|
Packit |
13e616 |
pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
|
|
Packit |
13e616 |
p_prtn = (osm_prtn_t *)cl_qmap_get(
|
|
Packit |
13e616 |
&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_prtn == (osm_prtn_t *)cl_qmap_end(
|
|
Packit |
13e616 |
&p_qos_policy->p_subn->prtn_pkey_tbl))
|
|
Packit |
13e616 |
/* partition for this pkey not found */
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC14: "
|
|
Packit |
13e616 |
"pkey 0x%04X in match rule - "
|
|
Packit |
13e616 |
"partition doesn't exist\n",
|
|
Packit |
13e616 |
cl_ntoh16(pkey));
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
__qos_policy_validate_pkey(p_qos_policy,
|
|
Packit |
13e616 |
p_qos_match_rule,
|
|
Packit |
13e616 |
p_prtn);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* done with the current match-rule */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
match_rules_list_iterator =
|
|
Packit |
13e616 |
cl_list_next(match_rules_list_iterator);
|
|
Packit |
13e616 |
i++;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return res;
|
|
Packit |
13e616 |
} /* osm_qos_policy_validate() */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static osm_qos_level_t * __qos_policy_get_qos_level_by_params(
|
|
Packit |
13e616 |
IN const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_src_physp,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_dest_physp,
|
|
Packit |
13e616 |
IN uint64_t service_id,
|
|
Packit |
13e616 |
IN uint16_t qos_class,
|
|
Packit |
13e616 |
IN uint16_t pkey,
|
|
Packit |
13e616 |
IN ib_net64_t comp_mask)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_qos_match_rule_t *p_qos_match_rule = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_policy)
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_qos_match_rule = __qos_policy_get_match_rule_by_params(
|
|
Packit |
13e616 |
p_qos_policy, service_id, qos_class, pkey,
|
|
Packit |
13e616 |
p_src_physp, p_dest_physp, comp_mask);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p_qos_match_rule ? p_qos_match_rule->p_qos_level :
|
|
Packit |
13e616 |
p_qos_policy->p_default_qos_level;
|
|
Packit |
13e616 |
} /* __qos_policy_get_qos_level_by_params() */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_level_t * osm_qos_policy_get_qos_level_by_pr(
|
|
Packit |
13e616 |
IN const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
IN const ib_path_rec_t * p_pr,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_src_physp,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_dest_physp,
|
|
Packit |
13e616 |
IN ib_net64_t comp_mask)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
return __qos_policy_get_qos_level_by_params(
|
|
Packit |
13e616 |
p_qos_policy, p_src_physp, p_dest_physp,
|
|
Packit |
13e616 |
cl_ntoh64(p_pr->service_id), ib_path_rec_qos_class(p_pr),
|
|
Packit |
13e616 |
cl_ntoh16(p_pr->pkey), comp_mask);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_qos_level_t * osm_qos_policy_get_qos_level_by_mpr(
|
|
Packit |
13e616 |
IN const osm_qos_policy_t * p_qos_policy,
|
|
Packit |
13e616 |
IN const ib_multipath_rec_t * p_mpr,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_src_physp,
|
|
Packit |
13e616 |
IN const osm_physp_t * p_dest_physp,
|
|
Packit |
13e616 |
IN ib_net64_t comp_mask)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_net64_t pr_comp_mask = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_qos_policy)
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Converting MultiPathRecord compmask to the PathRecord
|
|
Packit |
13e616 |
* compmask. Note that only relevant bits are set.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
pr_comp_mask =
|
|
Packit |
13e616 |
((comp_mask & IB_MPR_COMPMASK_QOS_CLASS) ?
|
|
Packit |
13e616 |
IB_PR_COMPMASK_QOS_CLASS : 0) |
|
|
Packit |
13e616 |
((comp_mask & IB_MPR_COMPMASK_PKEY) ?
|
|
Packit |
13e616 |
IB_PR_COMPMASK_PKEY : 0) |
|
|
Packit |
13e616 |
((comp_mask & IB_MPR_COMPMASK_SERVICEID_MSB) ?
|
|
Packit |
13e616 |
IB_PR_COMPMASK_SERVICEID_MSB : 0) |
|
|
Packit |
13e616 |
((comp_mask & IB_MPR_COMPMASK_SERVICEID_LSB) ?
|
|
Packit |
13e616 |
IB_PR_COMPMASK_SERVICEID_LSB : 0);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return __qos_policy_get_qos_level_by_params(
|
|
Packit |
13e616 |
p_qos_policy, p_src_physp, p_dest_physp,
|
|
Packit |
13e616 |
cl_ntoh64(ib_multipath_rec_service_id(p_mpr)),
|
|
Packit |
13e616 |
ib_multipath_rec_qos_class(p_mpr),
|
|
Packit |
13e616 |
cl_ntoh16(p_mpr->pkey), pr_comp_mask);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/***************************************************
|
|
Packit |
13e616 |
***************************************************/
|