ncsi-rsp.c (188de5dd80b2b7986e75821374efb67081049b6e) | ncsi-rsp.c (9771b8ccdfa6dcb1ac5128ca7fe8649f3092d392) |
---|---|
1/* 2 * Copyright Gavin Shan, IBM Corporation 2016. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10#include <linux/module.h> 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/netdevice.h> 14#include <linux/skbuff.h> 15 16#include <net/ncsi.h> 17#include <net/net_namespace.h> 18#include <net/sock.h> | 1/* 2 * Copyright Gavin Shan, IBM Corporation 2016. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10#include <linux/module.h> 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/netdevice.h> 14#include <linux/skbuff.h> 15 16#include <net/ncsi.h> 17#include <net/net_namespace.h> 18#include <net/sock.h> |
19#include <net/genetlink.h> |
|
19 20#include "internal.h" 21#include "ncsi-pkt.h" | 20 21#include "internal.h" 22#include "ncsi-pkt.h" |
23#include "ncsi-netlink.h" |
|
22 23static int ncsi_validate_rsp_pkt(struct ncsi_request *nr, 24 unsigned short payload) 25{ 26 struct ncsi_rsp_pkt_hdr *h; 27 u32 checksum; 28 __be32 *pchecksum; 29 30 /* Check NCSI packet header. We don't need validate 31 * the packet type, which should have been checked 32 * before calling this function. 33 */ 34 h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp); | 24 25static int ncsi_validate_rsp_pkt(struct ncsi_request *nr, 26 unsigned short payload) 27{ 28 struct ncsi_rsp_pkt_hdr *h; 29 u32 checksum; 30 __be32 *pchecksum; 31 32 /* Check NCSI packet header. We don't need validate 33 * the packet type, which should have been checked 34 * before calling this function. 35 */ 36 h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp); |
35 if (h->common.revision != NCSI_PKT_REVISION) | 37 38 if (h->common.revision != NCSI_PKT_REVISION) { 39 netdev_dbg(nr->ndp->ndev.dev, 40 "NCSI: unsupported header revision\n"); |
36 return -EINVAL; | 41 return -EINVAL; |
37 if (ntohs(h->common.length) != payload) | 42 } 43 if (ntohs(h->common.length) != payload) { 44 netdev_dbg(nr->ndp->ndev.dev, 45 "NCSI: payload length mismatched\n"); |
38 return -EINVAL; | 46 return -EINVAL; |
47 } |
|
39 40 /* Check on code and reason */ 41 if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED || | 48 49 /* Check on code and reason */ 50 if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED || |
42 ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) 43 return -EINVAL; | 51 ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) { 52 netdev_dbg(nr->ndp->ndev.dev, 53 "NCSI: non zero response/reason code\n"); 54 return -EPERM; 55 } |
44 45 /* Validate checksum, which might be zeroes if the 46 * sender doesn't support checksum according to NCSI 47 * specification. 48 */ 49 pchecksum = (__be32 *)((void *)(h + 1) + payload - 4); 50 if (ntohl(*pchecksum) == 0) 51 return 0; 52 53 checksum = ncsi_calculate_checksum((unsigned char *)h, 54 sizeof(*h) + payload - 4); | 56 57 /* Validate checksum, which might be zeroes if the 58 * sender doesn't support checksum according to NCSI 59 * specification. 60 */ 61 pchecksum = (__be32 *)((void *)(h + 1) + payload - 4); 62 if (ntohl(*pchecksum) == 0) 63 return 0; 64 65 checksum = ncsi_calculate_checksum((unsigned char *)h, 66 sizeof(*h) + payload - 4); |
55 if (*pchecksum != htonl(checksum)) | 67 68 if (*pchecksum != htonl(checksum)) { 69 netdev_dbg(nr->ndp->ndev.dev, "NCSI: checksum mismatched\n"); |
56 return -EINVAL; | 70 return -EINVAL; |
71 } |
|
57 58 return 0; 59} 60 61static int ncsi_rsp_handler_cis(struct ncsi_request *nr) 62{ 63 struct ncsi_rsp_pkt *rsp; 64 struct ncsi_dev_priv *ndp = nr->ndp; --- 871 unchanged lines hidden (view full) --- 936 if (!np) 937 return -ENODEV; 938 939 memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid)); 940 941 return 0; 942} 943 | 72 73 return 0; 74} 75 76static int ncsi_rsp_handler_cis(struct ncsi_request *nr) 77{ 78 struct ncsi_rsp_pkt *rsp; 79 struct ncsi_dev_priv *ndp = nr->ndp; --- 871 unchanged lines hidden (view full) --- 951 if (!np) 952 return -ENODEV; 953 954 memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid)); 955 956 return 0; 957} 958 |
959static int ncsi_rsp_handler_netlink(struct ncsi_request *nr) 960{ 961 struct ncsi_dev_priv *ndp = nr->ndp; 962 struct ncsi_rsp_pkt *rsp; 963 struct ncsi_package *np; 964 struct ncsi_channel *nc; 965 int ret; 966 967 /* Find the package */ 968 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp); 969 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, 970 &np, &nc); 971 if (!np) 972 return -ENODEV; 973 974 ret = ncsi_send_netlink_rsp(nr, np, nc); 975 976 return ret; 977} 978 |
|
944static struct ncsi_rsp_handler { 945 unsigned char type; 946 int payload; 947 int (*handler)(struct ncsi_request *nr); 948} ncsi_rsp_handlers[] = { 949 { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis }, 950 { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp }, 951 { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp }, --- 86 unchanged lines hidden (view full) --- 1038 payload = nrh->payload; 1039 if (payload < 0) 1040 payload = ntohs(hdr->length); 1041 ret = ncsi_validate_rsp_pkt(nr, payload); 1042 if (ret) { 1043 netdev_warn(ndp->ndev.dev, 1044 "NCSI: 'bad' packet ignored for type 0x%x\n", 1045 hdr->type); | 979static struct ncsi_rsp_handler { 980 unsigned char type; 981 int payload; 982 int (*handler)(struct ncsi_request *nr); 983} ncsi_rsp_handlers[] = { 984 { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis }, 985 { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp }, 986 { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp }, --- 86 unchanged lines hidden (view full) --- 1073 payload = nrh->payload; 1074 if (payload < 0) 1075 payload = ntohs(hdr->length); 1076 ret = ncsi_validate_rsp_pkt(nr, payload); 1077 if (ret) { 1078 netdev_warn(ndp->ndev.dev, 1079 "NCSI: 'bad' packet ignored for type 0x%x\n", 1080 hdr->type); |
1081 1082 if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) { 1083 if (ret == -EPERM) 1084 goto out_netlink; 1085 else 1086 ncsi_send_netlink_err(ndp->ndev.dev, 1087 nr->snd_seq, 1088 nr->snd_portid, 1089 &nr->nlhdr, 1090 ret); 1091 } |
|
1046 goto out; 1047 } 1048 1049 /* Process the packet */ 1050 ret = nrh->handler(nr); 1051 if (ret) 1052 netdev_err(ndp->ndev.dev, 1053 "NCSI: Handler for packet type 0x%x returned %d\n", 1054 hdr->type, ret); | 1092 goto out; 1093 } 1094 1095 /* Process the packet */ 1096 ret = nrh->handler(nr); 1097 if (ret) 1098 netdev_err(ndp->ndev.dev, 1099 "NCSI: Handler for packet type 0x%x returned %d\n", 1100 hdr->type, ret); |
1101 1102out_netlink: 1103 if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) { 1104 ret = ncsi_rsp_handler_netlink(nr); 1105 if (ret) { 1106 netdev_err(ndp->ndev.dev, 1107 "NCSI: Netlink handler for packet type 0x%x returned %d\n", 1108 hdr->type, ret); 1109 } 1110 } 1111 |
|
1055out: 1056 ncsi_free_request(nr); 1057 return ret; 1058} | 1112out: 1113 ncsi_free_request(nr); 1114 return ret; 1115} |