1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/netdevice.h> 4 #include <linux/mctp.h> 5 #include <linux/if_arp.h> 6 7 #include <net/mctp.h> 8 #include <net/mctpdevice.h> 9 #include <net/pkt_sched.h> 10 11 #include "utils.h" 12 13 static netdev_tx_t mctp_test_dev_tx(struct sk_buff *skb, 14 struct net_device *ndev) 15 { 16 struct mctp_test_dev *dev = netdev_priv(ndev); 17 18 skb_queue_tail(&dev->pkts, skb); 19 20 return NETDEV_TX_OK; 21 } 22 23 static const struct net_device_ops mctp_test_netdev_ops = { 24 .ndo_start_xmit = mctp_test_dev_tx, 25 }; 26 27 static void mctp_test_dev_setup(struct net_device *ndev) 28 { 29 ndev->type = ARPHRD_MCTP; 30 ndev->mtu = MCTP_DEV_TEST_MTU; 31 ndev->hard_header_len = 0; 32 ndev->tx_queue_len = 0; 33 ndev->flags = IFF_NOARP; 34 ndev->netdev_ops = &mctp_test_netdev_ops; 35 ndev->needs_free_netdev = true; 36 } 37 38 static struct mctp_test_dev *__mctp_test_create_dev(unsigned short lladdr_len, 39 const unsigned char *lladdr) 40 { 41 struct mctp_test_dev *dev; 42 struct net_device *ndev; 43 int rc; 44 45 if (WARN_ON(lladdr_len > MAX_ADDR_LEN)) 46 return NULL; 47 48 ndev = alloc_netdev(sizeof(*dev), "mctptest%d", NET_NAME_ENUM, 49 mctp_test_dev_setup); 50 if (!ndev) 51 return NULL; 52 53 dev = netdev_priv(ndev); 54 dev->ndev = ndev; 55 ndev->addr_len = lladdr_len; 56 dev_addr_set(ndev, lladdr); 57 skb_queue_head_init(&dev->pkts); 58 59 rc = register_netdev(ndev); 60 if (rc) { 61 free_netdev(ndev); 62 return NULL; 63 } 64 65 rcu_read_lock(); 66 dev->mdev = __mctp_dev_get(ndev); 67 dev->mdev->net = mctp_default_net(dev_net(ndev)); 68 rcu_read_unlock(); 69 70 /* bring the device up; we want to be able to TX immediately */ 71 rtnl_lock(); 72 dev_open(ndev, NULL); 73 rtnl_unlock(); 74 75 return dev; 76 } 77 78 struct mctp_test_dev *mctp_test_create_dev(void) 79 { 80 return __mctp_test_create_dev(0, NULL); 81 } 82 83 struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len, 84 const unsigned char *lladdr) 85 { 86 return __mctp_test_create_dev(lladdr_len, lladdr); 87 } 88 89 void mctp_test_destroy_dev(struct mctp_test_dev *dev) 90 { 91 skb_queue_purge(&dev->pkts); 92 mctp_dev_put(dev->mdev); 93 unregister_netdev(dev->ndev); 94 } 95 96 static int mctp_test_dst_output(struct mctp_dst *dst, struct sk_buff *skb) 97 { 98 skb->dev = dst->dev->dev; 99 dev_queue_xmit(skb); 100 101 return 0; 102 } 103 104 /* local version of mctp_route_alloc() */ 105 static struct mctp_test_route *mctp_route_test_alloc(void) 106 { 107 struct mctp_test_route *rt; 108 109 rt = kzalloc(sizeof(*rt), GFP_KERNEL); 110 if (!rt) 111 return NULL; 112 113 INIT_LIST_HEAD(&rt->rt.list); 114 refcount_set(&rt->rt.refs, 1); 115 rt->rt.output = mctp_test_dst_output; 116 117 return rt; 118 } 119 120 struct mctp_test_route *mctp_test_create_route_direct(struct net *net, 121 struct mctp_dev *dev, 122 mctp_eid_t eid, 123 unsigned int mtu) 124 { 125 struct mctp_test_route *rt; 126 127 rt = mctp_route_test_alloc(); 128 if (!rt) 129 return NULL; 130 131 rt->rt.min = eid; 132 rt->rt.max = eid; 133 rt->rt.mtu = mtu; 134 rt->rt.type = RTN_UNSPEC; 135 rt->rt.dst_type = MCTP_ROUTE_DIRECT; 136 if (dev) 137 mctp_dev_hold(dev); 138 rt->rt.dev = dev; 139 140 list_add_rcu(&rt->rt.list, &net->mctp.routes); 141 142 return rt; 143 } 144 145 struct mctp_test_route *mctp_test_create_route_gw(struct net *net, 146 unsigned int netid, 147 mctp_eid_t eid, 148 mctp_eid_t gw, 149 unsigned int mtu) 150 { 151 struct mctp_test_route *rt; 152 153 rt = mctp_route_test_alloc(); 154 if (!rt) 155 return NULL; 156 157 rt->rt.min = eid; 158 rt->rt.max = eid; 159 rt->rt.mtu = mtu; 160 rt->rt.type = RTN_UNSPEC; 161 rt->rt.dst_type = MCTP_ROUTE_GATEWAY; 162 rt->rt.gateway.eid = gw; 163 rt->rt.gateway.net = netid; 164 165 list_add_rcu(&rt->rt.list, &net->mctp.routes); 166 167 return rt; 168 } 169 170 /* Convenience function for our test dst; release with mctp_dst_release() */ 171 void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst, 172 struct mctp_test_dev *dev, unsigned int mtu) 173 { 174 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); 175 176 memset(dst, 0, sizeof(*dst)); 177 178 dst->dev = dev->mdev; 179 __mctp_dev_get(dst->dev->dev); 180 dst->mtu = mtu; 181 dst->output = mctp_test_dst_output; 182 } 183 184 void mctp_test_route_destroy(struct kunit *test, struct mctp_test_route *rt) 185 { 186 unsigned int refs; 187 188 rtnl_lock(); 189 list_del_rcu(&rt->rt.list); 190 rtnl_unlock(); 191 192 if (rt->rt.dst_type == MCTP_ROUTE_DIRECT && rt->rt.dev) 193 mctp_dev_put(rt->rt.dev); 194 195 refs = refcount_read(&rt->rt.refs); 196 KUNIT_ASSERT_EQ_MSG(test, refs, 1, "route ref imbalance"); 197 198 kfree_rcu(&rt->rt, rcu); 199 } 200 201 void mctp_test_skb_set_dev(struct sk_buff *skb, struct mctp_test_dev *dev) 202 { 203 struct mctp_skb_cb *cb; 204 205 cb = mctp_cb(skb); 206 cb->net = READ_ONCE(dev->mdev->net); 207 skb->dev = dev->ndev; 208 } 209 210 struct sk_buff *mctp_test_create_skb(const struct mctp_hdr *hdr, 211 unsigned int data_len) 212 { 213 size_t hdr_len = sizeof(*hdr); 214 struct sk_buff *skb; 215 unsigned int i; 216 u8 *buf; 217 218 skb = alloc_skb(hdr_len + data_len, GFP_KERNEL); 219 if (!skb) 220 return NULL; 221 222 __mctp_cb(skb); 223 memcpy(skb_put(skb, hdr_len), hdr, hdr_len); 224 225 buf = skb_put(skb, data_len); 226 for (i = 0; i < data_len; i++) 227 buf[i] = i & 0xff; 228 229 return skb; 230 } 231 232 struct sk_buff *__mctp_test_create_skb_data(const struct mctp_hdr *hdr, 233 const void *data, size_t data_len) 234 { 235 size_t hdr_len = sizeof(*hdr); 236 struct sk_buff *skb; 237 238 skb = alloc_skb(hdr_len + data_len, GFP_KERNEL); 239 if (!skb) 240 return NULL; 241 242 __mctp_cb(skb); 243 memcpy(skb_put(skb, hdr_len), hdr, hdr_len); 244 memcpy(skb_put(skb, data_len), data, data_len); 245 246 return skb; 247 } 248 249 void mctp_test_bind_run(struct kunit *test, 250 const struct mctp_test_bind_setup *setup, 251 int *ret_bind_errno, struct socket **sock) 252 { 253 struct sockaddr_mctp addr; 254 int rc; 255 256 *ret_bind_errno = -EIO; 257 258 rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, sock); 259 KUNIT_ASSERT_EQ(test, rc, 0); 260 261 /* connect() if requested */ 262 if (setup->have_peer) { 263 memset(&addr, 0x0, sizeof(addr)); 264 addr.smctp_family = AF_MCTP; 265 addr.smctp_network = setup->peer_net; 266 addr.smctp_addr.s_addr = setup->peer_addr; 267 /* connect() type must match bind() type */ 268 addr.smctp_type = setup->bind_type; 269 rc = kernel_connect(*sock, (struct sockaddr_unsized *)&addr, 270 sizeof(addr), 0); 271 KUNIT_EXPECT_EQ(test, rc, 0); 272 } 273 274 /* bind() */ 275 memset(&addr, 0x0, sizeof(addr)); 276 addr.smctp_family = AF_MCTP; 277 addr.smctp_network = setup->bind_net; 278 addr.smctp_addr.s_addr = setup->bind_addr; 279 addr.smctp_type = setup->bind_type; 280 281 *ret_bind_errno = 282 kernel_bind(*sock, (struct sockaddr_unsized *)&addr, 283 sizeof(addr)); 284 } 285