ACM_ROUTE_PRELOAD_OSM_FULL_V1
};
+enum acm_addr_preload {
+ ACM_ADDR_PRELOAD_NONE,
+ ACM_ADDR_PRELOAD_HOSTS
+};
+
/*
* Nested locking order: dest -> ep, dest -> port
*/
static char *opts_file = ACM_CONF_DIR "/" ACM_OPTS_FILE;
static char *addr_file = ACM_CONF_DIR "/" ACM_ADDR_FILE;
static char route_data_file[128] = ACM_CONF_DIR "/ibacm_route.data";
+static char addr_data_file[128] = ACM_CONF_DIR "/ibacm_hosts.data";
static char log_file[128] = "/var/log/ibacm.log";
static int log_level = 0;
static char lock_file[128] = "/var/run/ibacm.pid";
static uint8_t min_mtu = IBV_MTU_2048;
static uint8_t min_rate = IBV_RATE_10_GBPS;
static enum acm_route_preload route_preload;
+static enum acm_addr_preload addr_preload;
#define acm_log(level, format, ...) \
acm_write(level, "%s: "format, __func__, ## __VA_ARGS__)
return route_preload;
}
+static enum acm_route_preload acm_convert_addr_preload(char *param)
+{
+ if (!stricmp("none", param) || !stricmp("no", param))
+ return ACM_ADDR_PRELOAD_NONE;
+ else if (!stricmp("acm_hosts", param))
+ return ACM_ADDR_PRELOAD_HOSTS;
+
+ return addr_preload;
+}
+
static enum ibv_rate acm_get_rate(uint8_t width, uint8_t speed)
{
switch (width) {
return ret;
}
+static void acm_parse_hosts_file(struct acm_ep *ep)
+{
+ FILE *f;
+ char s[120];
+ char addr[INET6_ADDRSTRLEN], gid[INET6_ADDRSTRLEN];
+ uint8_t name[ACM_MAX_ADDRESS];
+ struct in6_addr ip_addr, ib_addr;
+ struct acm_dest *dest, *new_dest;
+ uint8_t addr_type;
+
+ if (!(f = fopen(addr_data_file, "r"))) {
+ acm_log(0, "ERROR - couldn't open %s\n", addr_data_file);
+ return;
+ }
+
+ while (fgets(s, sizeof s, f)) {
+ if (s[0] == '#')
+ continue;
+
+ if (sscanf(s, "%46s%46s", addr, gid) != 2)
+ continue;
+
+ acm_log(2, "%s", s);
+ if (inet_pton(AF_INET6, gid, &ib_addr) <= 0) {
+ acm_log(0, "ERROR - %s is not IB GID\n", gid);
+ continue;
+ }
+ if (inet_pton(AF_INET, addr, &ip_addr) > 0)
+ addr_type = ACM_ADDRESS_IP;
+ else if (inet_pton(AF_INET6, addr, &ip_addr) > 0)
+ addr_type = ACM_ADDRESS_IP6;
+ else {
+ acm_log(0, "ERROR - %s is not IP address\n", addr);
+ continue;
+ }
+
+ memset(name, 0, ACM_MAX_ADDRESS);
+ memcpy(name, &ib_addr, sizeof(ib_addr));
+ dest = acm_get_dest(ep, ACM_ADDRESS_GID, name);
+ if (!dest) {
+ acm_log(0, "ERROR - IB GID %s not found in cache\n", gid);
+ continue;
+ }
+
+ memset(name, 0, ACM_MAX_ADDRESS);
+ if (addr_type == ACM_ADDRESS_IP)
+ memcpy(name, &ip_addr, 4);
+ else
+ memcpy(name, &ip_addr, sizeof(ip_addr));
+ new_dest = acm_acquire_dest(ep, addr_type, name);
+ if (!new_dest) {
+ acm_log(0, "ERROR - unable to create dest %s\n", addr);
+ continue;
+ }
+ new_dest->path = dest->path;
+ new_dest->remote_qpn = dest->remote_qpn;
+ new_dest->addr_timeout = dest->addr_timeout;
+ new_dest->route_timeout = dest->route_timeout;
+ new_dest->state = dest->state;
+ acm_put_dest(new_dest);
+ acm_put_dest(dest);
+ acm_log(1, "added host %s address type %d IB GID %s\n",
+ addr, addr_type, gid);
+ }
+
+ fclose(f);
+}
+
static int acm_assign_ep_names(struct acm_ep *ep)
{
FILE *faddr;
return !index;
}
+/*
+ * We currently require that the routing data be preloaded in order to
+ * load the address data. This is backwards from normal operation, which
+ * usually resolves the address before the route.
+ */
static void acm_ep_preload(struct acm_ep *ep)
{
switch (route_preload) {
if (acm_parse_osm_fullv1(ep))
acm_log(0, "ERROR - failed to preload EP\n");
break;
+ default:
+ return;
+ }
+
+ switch (addr_preload) {
+ case ACM_ADDR_PRELOAD_HOSTS:
+ acm_parse_hosts_file(ep);
+ break;
default:
break;
}
route_preload = acm_convert_route_preload(value);
else if (!stricmp("route_data_file", opt))
strcpy(route_data_file, value);
+ else if (!stricmp("addr_preload", opt))
+ addr_preload = acm_convert_addr_preload(value);
+ else if (!stricmp("addr_data_file", opt))
+ strcpy(addr_data_file, value);
}
fclose(f);
acm_log(0, "minimum rate %d\n", min_rate);
acm_log(0, "route preload %d\n", route_preload);
acm_log(0, "route data file %s\n", route_data_file);
+ acm_log(0, "address preload %d\n", addr_preload);
+ acm_log(0, "address data file %s\n", addr_data_file);
}
static FILE *acm_open_log(void)
fprintf(f, "# Default is ACM_CONF_DIR/ibacm_route.data\n");
fprintf(f, "# route_data_file /etc/rdma/ibacm_route.data\n");
fprintf(f, "\n");
+ fprintf(f, "# addr_preload:\n");
+ fprintf(f, "# Specifies if the ACM address cache should be preloaded, or built on demand.\n");
+ fprintf(f, "# If preloaded, indicates the method used to build the cache.\n");
+ fprintf(f, "# Supported preload values are:\n");
+ fprintf(f, "# none - The address cache is not pre-built (default)\n");
+ fprintf(f, "# acm_hosts - ACM address to GID file format\n");
+ fprintf(f, "\n");
+ fprintf(f, "addr_preload none\n");
+ fprintf(f, "\n");
+ fprintf(f, "# addr_data_file:\n");
+ fprintf(f, "# Specifies the location of the address data file to use when preloading\n");
+ fprintf(f, "# the ACM cache. This option is only valid if addr_preload\n");
+ fprintf(f, "# indicates that address data should be read from a file.\n");
+ fprintf(f, "# Default is ACM_CONF_DIR/ibacm_hosts.data\n");
+ fprintf(f, "# addr_data_file /etc/rdma/ibacm_hosts.data\n");
+ fprintf(f, "\n");
}
static int open_dir(void)