diff options
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 122 | ||||
| -rw-r--r-- | include/scsi/iscsi_if.h | 42 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 5 |
3 files changed, 133 insertions, 36 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index d69a53aa406f..f3e664628d7a 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #define ISCSI_TRANSPORT_VERSION "2.0-870" | 37 | #define ISCSI_TRANSPORT_VERSION "2.0-870" |
| 38 | 38 | ||
| 39 | struct iscsi_internal { | 39 | struct iscsi_internal { |
| 40 | int daemon_pid; | ||
| 41 | struct scsi_transport_template t; | 40 | struct scsi_transport_template t; |
| 42 | struct iscsi_transport *iscsi_transport; | 41 | struct iscsi_transport *iscsi_transport; |
| 43 | struct list_head list; | 42 | struct list_head list; |
| @@ -938,23 +937,9 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt) | |||
| 938 | } | 937 | } |
| 939 | 938 | ||
| 940 | static int | 939 | static int |
| 941 | iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) | 940 | iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp) |
| 942 | { | 941 | { |
| 943 | return netlink_broadcast(nls, skb, 0, 1, gfp); | 942 | return nlmsg_multicast(nls, skb, 0, group, gfp); |
| 944 | } | ||
| 945 | |||
| 946 | static int | ||
| 947 | iscsi_unicast_skb(struct sk_buff *skb, int pid) | ||
| 948 | { | ||
| 949 | int rc; | ||
| 950 | |||
| 951 | rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); | ||
| 952 | if (rc < 0) { | ||
| 953 | printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); | ||
| 954 | return rc; | ||
| 955 | } | ||
| 956 | |||
| 957 | return 0; | ||
| 958 | } | 943 | } |
| 959 | 944 | ||
| 960 | int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | 945 | int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, |
| @@ -980,7 +965,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | |||
| 980 | return -ENOMEM; | 965 | return -ENOMEM; |
| 981 | } | 966 | } |
| 982 | 967 | ||
| 983 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | 968 | nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); |
| 984 | ev = NLMSG_DATA(nlh); | 969 | ev = NLMSG_DATA(nlh); |
| 985 | memset(ev, 0, sizeof(*ev)); | 970 | memset(ev, 0, sizeof(*ev)); |
| 986 | ev->transport_handle = iscsi_handle(conn->transport); | 971 | ev->transport_handle = iscsi_handle(conn->transport); |
| @@ -991,10 +976,45 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | |||
| 991 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); | 976 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); |
| 992 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); | 977 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); |
| 993 | 978 | ||
| 994 | return iscsi_unicast_skb(skb, priv->daemon_pid); | 979 | return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC); |
| 995 | } | 980 | } |
| 996 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); | 981 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); |
| 997 | 982 | ||
| 983 | int iscsi_offload_mesg(struct Scsi_Host *shost, | ||
| 984 | struct iscsi_transport *transport, uint32_t type, | ||
| 985 | char *data, uint16_t data_size) | ||
| 986 | { | ||
| 987 | struct nlmsghdr *nlh; | ||
| 988 | struct sk_buff *skb; | ||
| 989 | struct iscsi_uevent *ev; | ||
| 990 | int len = NLMSG_SPACE(sizeof(*ev) + data_size); | ||
| 991 | |||
| 992 | skb = alloc_skb(len, GFP_NOIO); | ||
| 993 | if (!skb) { | ||
| 994 | printk(KERN_ERR "can not deliver iscsi offload message:OOM\n"); | ||
| 995 | return -ENOMEM; | ||
| 996 | } | ||
| 997 | |||
| 998 | nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); | ||
| 999 | ev = NLMSG_DATA(nlh); | ||
| 1000 | memset(ev, 0, sizeof(*ev)); | ||
| 1001 | ev->type = type; | ||
| 1002 | ev->transport_handle = iscsi_handle(transport); | ||
| 1003 | switch (type) { | ||
| 1004 | case ISCSI_KEVENT_PATH_REQ: | ||
| 1005 | ev->r.req_path.host_no = shost->host_no; | ||
| 1006 | break; | ||
| 1007 | case ISCSI_KEVENT_IF_DOWN: | ||
| 1008 | ev->r.notify_if_down.host_no = shost->host_no; | ||
| 1009 | break; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | memcpy((char *)ev + sizeof(*ev), data, data_size); | ||
| 1013 | |||
| 1014 | return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO); | ||
| 1015 | } | ||
| 1016 | EXPORT_SYMBOL_GPL(iscsi_offload_mesg); | ||
| 1017 | |||
| 998 | void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) | 1018 | void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) |
| 999 | { | 1019 | { |
| 1000 | struct nlmsghdr *nlh; | 1020 | struct nlmsghdr *nlh; |
| @@ -1014,7 +1034,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
| 1014 | return; | 1034 | return; |
| 1015 | } | 1035 | } |
| 1016 | 1036 | ||
| 1017 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | 1037 | nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); |
| 1018 | ev = NLMSG_DATA(nlh); | 1038 | ev = NLMSG_DATA(nlh); |
| 1019 | ev->transport_handle = iscsi_handle(conn->transport); | 1039 | ev->transport_handle = iscsi_handle(conn->transport); |
| 1020 | ev->type = ISCSI_KEVENT_CONN_ERROR; | 1040 | ev->type = ISCSI_KEVENT_CONN_ERROR; |
| @@ -1022,7 +1042,7 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
| 1022 | ev->r.connerror.cid = conn->cid; | 1042 | ev->r.connerror.cid = conn->cid; |
| 1023 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); | 1043 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); |
| 1024 | 1044 | ||
| 1025 | iscsi_broadcast_skb(skb, GFP_ATOMIC); | 1045 | iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC); |
| 1026 | 1046 | ||
| 1027 | iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", | 1047 | iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", |
| 1028 | error); | 1048 | error); |
| @@ -1030,8 +1050,8 @@ void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
| 1030 | EXPORT_SYMBOL_GPL(iscsi_conn_error_event); | 1050 | EXPORT_SYMBOL_GPL(iscsi_conn_error_event); |
| 1031 | 1051 | ||
| 1032 | static int | 1052 | static int |
| 1033 | iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, | 1053 | iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, |
| 1034 | void *payload, int size) | 1054 | void *payload, int size) |
| 1035 | { | 1055 | { |
| 1036 | struct sk_buff *skb; | 1056 | struct sk_buff *skb; |
| 1037 | struct nlmsghdr *nlh; | 1057 | struct nlmsghdr *nlh; |
| @@ -1045,10 +1065,10 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, | |||
| 1045 | return -ENOMEM; | 1065 | return -ENOMEM; |
| 1046 | } | 1066 | } |
| 1047 | 1067 | ||
| 1048 | nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); | 1068 | nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0); |
| 1049 | nlh->nlmsg_flags = flags; | 1069 | nlh->nlmsg_flags = flags; |
| 1050 | memcpy(NLMSG_DATA(nlh), payload, size); | 1070 | memcpy(NLMSG_DATA(nlh), payload, size); |
| 1051 | return iscsi_unicast_skb(skb, pid); | 1071 | return iscsi_multicast_skb(skb, group, GFP_ATOMIC); |
| 1052 | } | 1072 | } |
| 1053 | 1073 | ||
| 1054 | static int | 1074 | static int |
| @@ -1085,7 +1105,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
| 1085 | return -ENOMEM; | 1105 | return -ENOMEM; |
| 1086 | } | 1106 | } |
| 1087 | 1107 | ||
| 1088 | nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0, | 1108 | nlhstat = __nlmsg_put(skbstat, 0, 0, 0, |
| 1089 | (len - sizeof(*nlhstat)), 0); | 1109 | (len - sizeof(*nlhstat)), 0); |
| 1090 | evstat = NLMSG_DATA(nlhstat); | 1110 | evstat = NLMSG_DATA(nlhstat); |
| 1091 | memset(evstat, 0, sizeof(*evstat)); | 1111 | memset(evstat, 0, sizeof(*evstat)); |
| @@ -1109,7 +1129,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
| 1109 | skb_trim(skbstat, NLMSG_ALIGN(actual_size)); | 1129 | skb_trim(skbstat, NLMSG_ALIGN(actual_size)); |
| 1110 | nlhstat->nlmsg_len = actual_size; | 1130 | nlhstat->nlmsg_len = actual_size; |
| 1111 | 1131 | ||
| 1112 | err = iscsi_unicast_skb(skbstat, priv->daemon_pid); | 1132 | err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID, |
| 1133 | GFP_ATOMIC); | ||
| 1113 | } while (err < 0 && err != -ECONNREFUSED); | 1134 | } while (err < 0 && err != -ECONNREFUSED); |
| 1114 | 1135 | ||
| 1115 | return err; | 1136 | return err; |
| @@ -1143,7 +1164,7 @@ int iscsi_session_event(struct iscsi_cls_session *session, | |||
| 1143 | return -ENOMEM; | 1164 | return -ENOMEM; |
| 1144 | } | 1165 | } |
| 1145 | 1166 | ||
| 1146 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | 1167 | nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); |
| 1147 | ev = NLMSG_DATA(nlh); | 1168 | ev = NLMSG_DATA(nlh); |
| 1148 | ev->transport_handle = iscsi_handle(session->transport); | 1169 | ev->transport_handle = iscsi_handle(session->transport); |
| 1149 | 1170 | ||
| @@ -1172,7 +1193,7 @@ int iscsi_session_event(struct iscsi_cls_session *session, | |||
| 1172 | * this will occur if the daemon is not up, so we just warn | 1193 | * this will occur if the daemon is not up, so we just warn |
| 1173 | * the user and when the daemon is restarted it will handle it | 1194 | * the user and when the daemon is restarted it will handle it |
| 1174 | */ | 1195 | */ |
| 1175 | rc = iscsi_broadcast_skb(skb, GFP_KERNEL); | 1196 | rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL); |
| 1176 | if (rc == -ESRCH) | 1197 | if (rc == -ESRCH) |
| 1177 | iscsi_cls_session_printk(KERN_ERR, session, | 1198 | iscsi_cls_session_printk(KERN_ERR, session, |
| 1178 | "Cannot notify userspace of session " | 1199 | "Cannot notify userspace of session " |
| @@ -1393,7 +1414,31 @@ iscsi_set_host_param(struct iscsi_transport *transport, | |||
| 1393 | } | 1414 | } |
| 1394 | 1415 | ||
| 1395 | static int | 1416 | static int |
| 1396 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1417 | iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
| 1418 | { | ||
| 1419 | struct Scsi_Host *shost; | ||
| 1420 | struct iscsi_path *params; | ||
| 1421 | int err; | ||
| 1422 | |||
| 1423 | if (!transport->set_path) | ||
| 1424 | return -ENOSYS; | ||
| 1425 | |||
| 1426 | shost = scsi_host_lookup(ev->u.set_path.host_no); | ||
| 1427 | if (!shost) { | ||
| 1428 | printk(KERN_ERR "set path could not find host no %u\n", | ||
| 1429 | ev->u.set_path.host_no); | ||
| 1430 | return -ENODEV; | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | params = (struct iscsi_path *)((char *)ev + sizeof(*ev)); | ||
| 1434 | err = transport->set_path(shost, params); | ||
| 1435 | |||
| 1436 | scsi_host_put(shost); | ||
| 1437 | return err; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | static int | ||
| 1441 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) | ||
| 1397 | { | 1442 | { |
| 1398 | int err = 0; | 1443 | int err = 0; |
| 1399 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); | 1444 | struct iscsi_uevent *ev = NLMSG_DATA(nlh); |
| @@ -1403,6 +1448,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1403 | struct iscsi_cls_conn *conn; | 1448 | struct iscsi_cls_conn *conn; |
| 1404 | struct iscsi_endpoint *ep = NULL; | 1449 | struct iscsi_endpoint *ep = NULL; |
| 1405 | 1450 | ||
| 1451 | if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE) | ||
| 1452 | *group = ISCSI_NL_GRP_UIP; | ||
| 1453 | else | ||
| 1454 | *group = ISCSI_NL_GRP_ISCSID; | ||
| 1455 | |||
| 1406 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); | 1456 | priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); |
| 1407 | if (!priv) | 1457 | if (!priv) |
| 1408 | return -EINVAL; | 1458 | return -EINVAL; |
| @@ -1411,8 +1461,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1411 | if (!try_module_get(transport->owner)) | 1461 | if (!try_module_get(transport->owner)) |
| 1412 | return -EINVAL; | 1462 | return -EINVAL; |
| 1413 | 1463 | ||
| 1414 | priv->daemon_pid = NETLINK_CREDS(skb)->pid; | ||
| 1415 | |||
| 1416 | switch (nlh->nlmsg_type) { | 1464 | switch (nlh->nlmsg_type) { |
| 1417 | case ISCSI_UEVENT_CREATE_SESSION: | 1465 | case ISCSI_UEVENT_CREATE_SESSION: |
| 1418 | err = iscsi_if_create_session(priv, ep, ev, | 1466 | err = iscsi_if_create_session(priv, ep, ev, |
| @@ -1506,6 +1554,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1506 | case ISCSI_UEVENT_SET_HOST_PARAM: | 1554 | case ISCSI_UEVENT_SET_HOST_PARAM: |
| 1507 | err = iscsi_set_host_param(transport, ev); | 1555 | err = iscsi_set_host_param(transport, ev); |
| 1508 | break; | 1556 | break; |
| 1557 | case ISCSI_UEVENT_PATH_UPDATE: | ||
| 1558 | err = iscsi_set_path(transport, ev); | ||
| 1559 | break; | ||
| 1509 | default: | 1560 | default: |
| 1510 | err = -ENOSYS; | 1561 | err = -ENOSYS; |
| 1511 | break; | 1562 | break; |
| @@ -1528,6 +1579,7 @@ iscsi_if_rx(struct sk_buff *skb) | |||
| 1528 | uint32_t rlen; | 1579 | uint32_t rlen; |
| 1529 | struct nlmsghdr *nlh; | 1580 | struct nlmsghdr *nlh; |
| 1530 | struct iscsi_uevent *ev; | 1581 | struct iscsi_uevent *ev; |
| 1582 | uint32_t group; | ||
| 1531 | 1583 | ||
| 1532 | nlh = nlmsg_hdr(skb); | 1584 | nlh = nlmsg_hdr(skb); |
| 1533 | if (nlh->nlmsg_len < sizeof(*nlh) || | 1585 | if (nlh->nlmsg_len < sizeof(*nlh) || |
| @@ -1540,7 +1592,7 @@ iscsi_if_rx(struct sk_buff *skb) | |||
| 1540 | if (rlen > skb->len) | 1592 | if (rlen > skb->len) |
| 1541 | rlen = skb->len; | 1593 | rlen = skb->len; |
| 1542 | 1594 | ||
| 1543 | err = iscsi_if_recv_msg(skb, nlh); | 1595 | err = iscsi_if_recv_msg(skb, nlh, &group); |
| 1544 | if (err) { | 1596 | if (err) { |
| 1545 | ev->type = ISCSI_KEVENT_IF_ERROR; | 1597 | ev->type = ISCSI_KEVENT_IF_ERROR; |
| 1546 | ev->iferror = err; | 1598 | ev->iferror = err; |
| @@ -1554,8 +1606,7 @@ iscsi_if_rx(struct sk_buff *skb) | |||
| 1554 | */ | 1606 | */ |
| 1555 | if (ev->type == ISCSI_UEVENT_GET_STATS && !err) | 1607 | if (ev->type == ISCSI_UEVENT_GET_STATS && !err) |
| 1556 | break; | 1608 | break; |
| 1557 | err = iscsi_if_send_reply( | 1609 | err = iscsi_if_send_reply(group, nlh->nlmsg_seq, |
| 1558 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, | ||
| 1559 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); | 1610 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); |
| 1560 | } while (err < 0 && err != -ECONNREFUSED); | 1611 | } while (err < 0 && err != -ECONNREFUSED); |
| 1561 | skb_pull(skb, rlen); | 1612 | skb_pull(skb, rlen); |
| @@ -1803,7 +1854,6 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1803 | if (!priv) | 1854 | if (!priv) |
| 1804 | return NULL; | 1855 | return NULL; |
| 1805 | INIT_LIST_HEAD(&priv->list); | 1856 | INIT_LIST_HEAD(&priv->list); |
| 1806 | priv->daemon_pid = -1; | ||
| 1807 | priv->iscsi_transport = tt; | 1857 | priv->iscsi_transport = tt; |
| 1808 | priv->t.user_scan = iscsi_user_scan; | 1858 | priv->t.user_scan = iscsi_user_scan; |
| 1809 | priv->t.create_work_queue = 1; | 1859 | priv->t.create_work_queue = 1; |
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 2c1a4af9eafb..4426f00da5ff 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
| @@ -22,6 +22,11 @@ | |||
| 22 | #define ISCSI_IF_H | 22 | #define ISCSI_IF_H |
| 23 | 23 | ||
| 24 | #include <scsi/iscsi_proto.h> | 24 | #include <scsi/iscsi_proto.h> |
| 25 | #include <linux/in.h> | ||
| 26 | #include <linux/in6.h> | ||
| 27 | |||
| 28 | #define ISCSI_NL_GRP_ISCSID 1 | ||
| 29 | #define ISCSI_NL_GRP_UIP 2 | ||
| 25 | 30 | ||
| 26 | #define UEVENT_BASE 10 | 31 | #define UEVENT_BASE 10 |
| 27 | #define KEVENT_BASE 100 | 32 | #define KEVENT_BASE 100 |
| @@ -53,6 +58,8 @@ enum iscsi_uevent_e { | |||
| 53 | ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, | 58 | ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18, |
| 54 | ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 19, | 59 | ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST = UEVENT_BASE + 19, |
| 55 | 60 | ||
| 61 | ISCSI_UEVENT_PATH_UPDATE = UEVENT_BASE + 20, | ||
| 62 | |||
| 56 | /* up events */ | 63 | /* up events */ |
| 57 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, | 64 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, |
| 58 | ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, | 65 | ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, |
| @@ -60,6 +67,9 @@ enum iscsi_uevent_e { | |||
| 60 | ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, | 67 | ISCSI_KEVENT_DESTROY_SESSION = KEVENT_BASE + 4, |
| 61 | ISCSI_KEVENT_UNBIND_SESSION = KEVENT_BASE + 5, | 68 | ISCSI_KEVENT_UNBIND_SESSION = KEVENT_BASE + 5, |
| 62 | ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6, | 69 | ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6, |
| 70 | |||
| 71 | ISCSI_KEVENT_PATH_REQ = KEVENT_BASE + 7, | ||
| 72 | ISCSI_KEVENT_IF_DOWN = KEVENT_BASE + 8, | ||
| 63 | }; | 73 | }; |
| 64 | 74 | ||
| 65 | enum iscsi_tgt_dscvr { | 75 | enum iscsi_tgt_dscvr { |
| @@ -159,6 +169,9 @@ struct iscsi_uevent { | |||
| 159 | uint32_t param; /* enum iscsi_host_param */ | 169 | uint32_t param; /* enum iscsi_host_param */ |
| 160 | uint32_t len; | 170 | uint32_t len; |
| 161 | } set_host_param; | 171 | } set_host_param; |
| 172 | struct msg_set_path { | ||
| 173 | uint32_t host_no; | ||
| 174 | } set_path; | ||
| 162 | } u; | 175 | } u; |
| 163 | union { | 176 | union { |
| 164 | /* messages k -> u */ | 177 | /* messages k -> u */ |
| @@ -192,10 +205,39 @@ struct iscsi_uevent { | |||
| 192 | struct msg_transport_connect_ret { | 205 | struct msg_transport_connect_ret { |
| 193 | uint64_t handle; | 206 | uint64_t handle; |
| 194 | } ep_connect_ret; | 207 | } ep_connect_ret; |
| 208 | struct msg_req_path { | ||
| 209 | uint32_t host_no; | ||
| 210 | } req_path; | ||
| 211 | struct msg_notify_if_down { | ||
| 212 | uint32_t host_no; | ||
| 213 | } notify_if_down; | ||
| 195 | } r; | 214 | } r; |
| 196 | } __attribute__ ((aligned (sizeof(uint64_t)))); | 215 | } __attribute__ ((aligned (sizeof(uint64_t)))); |
| 197 | 216 | ||
| 198 | /* | 217 | /* |
| 218 | * To keep the struct iscsi_uevent size the same for userspace code | ||
| 219 | * compatibility, the main structure for ISCSI_UEVENT_PATH_UPDATE and | ||
| 220 | * ISCSI_KEVENT_PATH_REQ is defined separately and comes after the | ||
| 221 | * struct iscsi_uevent in the NETLINK_ISCSI message. | ||
| 222 | */ | ||
| 223 | struct iscsi_path { | ||
| 224 | uint64_t handle; | ||
| 225 | uint8_t mac_addr[6]; | ||
| 226 | uint8_t mac_addr_old[6]; | ||
| 227 | uint32_t ip_addr_len; /* 4 or 16 */ | ||
| 228 | union { | ||
| 229 | struct in_addr v4_addr; | ||
| 230 | struct in6_addr v6_addr; | ||
| 231 | } src; | ||
| 232 | union { | ||
| 233 | struct in_addr v4_addr; | ||
| 234 | struct in6_addr v6_addr; | ||
| 235 | } dst; | ||
| 236 | uint16_t vlan_id; | ||
| 237 | uint16_t pmtu; | ||
| 238 | } __attribute__ ((aligned (sizeof(uint64_t)))); | ||
| 239 | |||
| 240 | /* | ||
| 199 | * Common error codes | 241 | * Common error codes |
| 200 | */ | 242 | */ |
| 201 | enum iscsi_err { | 243 | enum iscsi_err { |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 8cb7a31d9961..349c7f30720d 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -133,6 +133,7 @@ struct iscsi_transport { | |||
| 133 | void (*ep_disconnect) (struct iscsi_endpoint *ep); | 133 | void (*ep_disconnect) (struct iscsi_endpoint *ep); |
| 134 | int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type, | 134 | int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type, |
| 135 | uint32_t enable, struct sockaddr *dst_addr); | 135 | uint32_t enable, struct sockaddr *dst_addr); |
| 136 | int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params); | ||
| 136 | }; | 137 | }; |
| 137 | 138 | ||
| 138 | /* | 139 | /* |
| @@ -149,6 +150,10 @@ extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn, | |||
| 149 | extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | 150 | extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, |
| 150 | char *data, uint32_t data_size); | 151 | char *data, uint32_t data_size); |
| 151 | 152 | ||
| 153 | extern int iscsi_offload_mesg(struct Scsi_Host *shost, | ||
| 154 | struct iscsi_transport *transport, uint32_t type, | ||
| 155 | char *data, uint16_t data_size); | ||
| 156 | |||
| 152 | struct iscsi_cls_conn { | 157 | struct iscsi_cls_conn { |
| 153 | struct list_head conn_list; /* item in connlist */ | 158 | struct list_head conn_list; /* item in connlist */ |
| 154 | void *dd_data; /* LLD private data */ | 159 | void *dd_data; /* LLD private data */ |
