LASSERTF (0, "checksums for forwarded packets not implemented\n");
#endif
- if (kqswnal_nid2elanid (dest_nid) >= 0) /* should have gone direct to peer */
- {
+ if (PTL_NIDNET(dest_nid) == PTL_NIDNET(kqswnal_data.kqn_ni->ni_nid)) {
+ /* should have gone direct to peer */
CERROR("dropping packet from %s for %s: target is peer\n",
libcfs_nid2str(le64_to_cpu(hdr->src_nid)),
libcfs_nid2str(dest_nid));
spin_unlock_irqrestore (&kqswnal_data.kqn_sched_lock, flags);
/* If we're shutting down, this will just requeue fwd on kqn_idletxd_fwdq */
- kqswnal_fwd_packet (NULL, fwd);
+ kqswnal_fwd_packet (kqswnal_data.kqn_ni, fwd);
did_something = 1;
spin_lock_irqsave (&kqswnal_data.kqn_sched_lock, flags);
return;
}
- if (body_len > PTL_MTU) { /* too big to forward */
+ if (PTL_NIDNET(conn->ksnc_hdr.dest_nid) ==
+ PTL_NIDNET(ksocknal_data.ksnd_ni->ni_nid)) {
+ /* should have gone direct */
CERROR ("dropping packet from %s for %s: "
- "packet size %d too big\n",
+ "target is a peer\n",
libcfs_nid2str(src_nid),
- libcfs_nid2str(dest_nid),
- body_len);
- /* on to new packet (skip this one's body) */
+ libcfs_nid2str(dest_nid));
+
+ /* on to next packet (skip this one's body) */
ksocknal_new_packet (conn, body_len);
return;
}
ksocknal_new_packet (conn, body_len); /* on to new packet */
return;
}
-
- /* should have gone direct */
- peer = ksocknal_find_peer (conn->ksnc_hdr.dest_nid);
- if (peer != NULL) {
+
+ if (body_len > PTL_MTU) { /* too big to forward */
CERROR ("dropping packet from %s for %s: "
- "target is a peer\n",
+ "packet size %d too big\n",
libcfs_nid2str(src_nid),
- libcfs_nid2str(dest_nid));
- ksocknal_peer_decref(peer); /* drop ref from get above */
-
- /* on to next packet (skip this one's body) */
+ libcfs_nid2str(dest_nid),
+ body_len);
+ /* on to new packet (skip this one's body) */
ksocknal_new_packet (conn, body_len);
return;
}
CFS_MODULE_PARM(networks, "s", charp, 0444,
"local networks (default='"DEFAULT_NETWORKS"')");
-static int nal_load_timeout = 10;
-CFS_MODULE_PARM(nal_load_timeout, "i", int, 0444,
- "seconds to wait for a NAL to load");
-
ptl_apini_t ptl_apini; /* THE network interface (at the API) */
void ptl_assert_wire_constants (void)
#define DEBUG_SUBSYSTEM S_PORTALS
#include <portals/lib-p30.h>
+static int config_on_load = 1;
+CFS_MODULE_PARM(config_on_load, "i", int, 0444,
+ "configure network at module load");
+
static int kportal_ioctl(unsigned int cmd, struct portal_ioctl_data *data)
{
ptl_err_t initrc;
initrc = PtlNIInit(PTL_IFACE_DEFAULT, LUSTRE_SRV_PTL_PID,
NULL, NULL, &nih);
if (!(initrc == PTL_OK || initrc == PTL_IFACE_DUP))
- RETURN (-EINVAL);
+ RETURN (-ENETDOWN);
rc = PtlNICtl(nih, cmd, data);
RETURN(rc);
}
+ if (config_on_load) {
+ ptl_handle_ni_t nih;
+
+ PTL_MUTEX_DOWN(&ptl_apini.apini_api_mutex);
+ ptl_apini.apini_niinit_self = 1;
+ PTL_MUTEX_UP(&ptl_apini.apini_api_mutex);
+
+ rc = PtlNIInit(PTL_IFACE_DEFAULT, LUSTRE_SRV_PTL_PID,
+ NULL, NULL, &nih);
+ if (rc != PTL_OK) {
+ PtlFini();
+ return -ENETDOWN;
+ }
+ }
+
rc = libcfs_register_ioctl(&kportal_ioctl_handler);
LASSERT (rc == 0);
#include "router.h"
#include <linux/seq_file.h>
-#define KPR_PROC_ROUTER "sys/portals/router"
+#define KPR_PROC_STATS "sys/portals/router_stats"
#define KPR_PROC_ROUTES "sys/portals/routes"
static int
struct proc_dir_entry *stats;
struct proc_dir_entry *routes;
- /* Initialize KPR_PROC_ROUTER */
- stats = create_proc_entry (KPR_PROC_ROUTER, 0644, NULL);
+ /* Initialize KPR_PROC_STATS */
+ stats = create_proc_entry (KPR_PROC_STATS, 0644, NULL);
if (stats == NULL) {
- CERROR("couldn't create proc entry %s\n", KPR_PROC_ROUTER);
+ CERROR("couldn't create proc entry %s\n", KPR_PROC_STATS);
return;
}
void
kpr_proc_fini(void)
{
- remove_proc_entry(KPR_PROC_ROUTER, 0);
+ remove_proc_entry(KPR_PROC_STATS, 0);
remove_proc_entry(KPR_PROC_ROUTES, 0);
}
int rc = -ENOENT;
__u32 target_net = PTL_NIDNET(target_nid);
- /* Caller wants to know if 'target_nid' can be reached via a gateway
- * ON HER OWN NETWORK */
-
CDEBUG (D_NET, "lookup "LPX64" from %s\n", target_nid,
(ni == NULL) ? "<>" : libcfs_nid2str(ni->ni_nid));
return gwni->ni_nid;
}
} else if (target_net == PTL_NIDNET(ni->ni_nid)) {
- ptl_ni_addref(ni); /* extra ref so caller can drop blindly */
+ /* Caller wants to know if 'target_nid' can be reached via a
+ * gateway ON HER OWN NETWORK */
+ ptl_ni_addref(ni); /* extra ref so caller can drop blindly */
return ni->ni_nid;
}
+ CDEBUG(D_NET, "%s from %s\n", libcfs_nid2str(target_nid),
+ (ni == NULL) ? "<none>" : libcfs_nid2str(ni->ni_nid));
+
read_lock_irqsave(&kpr_state.kpr_rwlock, flags);
if (ni != NULL && ni->ni_shutdown) {
if (PTL_NIDNET(ni->ni_nid) != /* gateway not on ni's net */
PTL_NIDNET(re->kpre_gateway->kpge_nid))
continue;
- tmpni = NULL;
+
+ if (ge != NULL &&
+ kpr_ge_isbetter (ge, re->kpre_gateway))
+ continue;
+
+ } else if (gwni != NULL &&
+ PTL_NIDNET(gwni->ni_nid) ==
+ PTL_NIDNET(ge->kpge_nid)) {
+ /* another gateway on the same net */
+
+ if (kpr_ge_isbetter(ge, re->kpre_gateway))
+ continue;
} else {
- tmpni = ptl_net2ni(PTL_NIDNET(ge->kpge_nid));
+ /* another gateway on a new/different net */
+
+ tmpni = ptl_net2ni(PTL_NIDNET(re->kpre_gateway->kpge_nid));
if (tmpni == NULL) /* gateway not on a local net */
continue;
- }
- if (ge == NULL ||
- kpr_ge_isbetter (re->kpre_gateway, ge)) {
+ if (ge != NULL &&
+ kpr_ge_isbetter(ge, re->kpre_gateway)) {
+ ptl_ni_decref(tmpni);
+ continue;
+ }
+
if (gwni != NULL)
ptl_ni_decref(gwni);
- ge = re->kpre_gateway;
gwni = tmpni;
- } else if (tmpni != NULL) {
- ptl_ni_decref(tmpni);
}
+
+ ge = re->kpre_gateway;
}
if (ge == NULL) {
return PTL_NID_ANY;
}
- kpr_update_weight (ge, nob);
+ kpr_update_weight(ge, nob);
gwnid = ge->kpge_nid;
read_unlock_irqrestore(&kpr_state.kpr_rwlock, flags);
__u32 target_net = PTL_NIDNET(target_nid);
__u32 source_net = PTL_NIDNET(src_ni->ni_nid);
int nob = fwd->kprfd_nob;
- kpr_gateway_entry_t *ge = NULL;
- ptl_ni_t *dst_ni = NULL;
+ kpr_gateway_entry_t *ge;
+ ptl_ni_t *dst_ni;
ptl_ni_t *tmp_ni;
unsigned long flags;
struct list_head *e;
CDEBUG (D_NET, "forward [%p] %s from %s\n", fwd,
libcfs_nid2str(target_nid), libcfs_nid2str(src_ni->ni_nid));
+ LASSERT (target_net != source_net);
LASSERT (nob == ptl_kiov_nob (fwd->kprfd_niov, fwd->kprfd_kiov));
fwd->kprfd_src_ni = src_ni; /* stash calling ni */
goto out;
}
- /* Search routes for one that has a gateway to target_nid NOT on the caller's network */
+ /* Is the target_nid on a local network? */
+ dst_ni = ptl_net2ni(target_net);
+ if (dst_ni != NULL) {
+ if (dst_ni->ni_nal->nal_fwd == NULL) {
+ rc = -EHOSTUNREACH;
+ goto out;
+ }
+
+ fwd->kprfd_gateway_nid = dst_ni->ni_nid;
+ atomic_inc (&kpr_state.kpr_queue_depth);
+
+ read_unlock_irqrestore(&kpr_state.kpr_rwlock, flags);
+
+ CDEBUG (D_NET, "forward [%p] %s: src ni %s dst ni %s\n",
+ fwd, libcfs_nid2str(target_nid),
+ libcfs_nid2str(src_ni->ni_nid),
+ libcfs_nid2str(dst_ni->ni_nid));
+ dst_ni->ni_nal->nal_fwd(dst_ni, fwd);
+ ptl_ni_decref(dst_ni);
+ return;
+ }
+
+ /* Search routes for one that has a gateway to target_nid NOT on the caller's network */
+ dst_ni = NULL;
+ ge = NULL;
list_for_each (e, &kpr_state.kpr_routes) {
re = list_entry (e, kpr_route_entry_t, kpre_list);
continue;
}
- if (ge == NULL ||
- kpr_ge_isbetter (re->kpre_gateway, ge)) {
- if (dst_ni != NULL)
- ptl_ni_decref(dst_ni);
-
- dst_ni = tmp_ni;
- ge = re->kpre_gateway;
+ if (ge != NULL &&
+ kpr_ge_isbetter(ge, re->kpre_gateway)) {
+ ptl_ni_decref(tmp_ni);
+ continue;
}
+
+ if (dst_ni != NULL)
+ ptl_ni_decref(dst_ni);
+
+ dst_ni = tmp_ni;
+ ge = re->kpre_gateway;
}
if (ge != NULL) {