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_with_addr(mctp_eid_t addr) 84 { 85 struct mctp_test_dev *dev; 86 87 dev = __mctp_test_create_dev(0, NULL); 88 if (!dev) 89 return NULL; 90 91 dev->mdev->addrs = kmalloc_objs(u8, 1, GFP_KERNEL); 92 if (!dev->mdev->addrs) { 93 mctp_test_destroy_dev(dev); 94 return NULL; 95 } 96 97 dev->mdev->num_addrs = 1; 98 dev->mdev->addrs[0] = 8; 99 100 return dev; 101 } 102 103 struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len, 104 const unsigned char *lladdr) 105 { 106 return __mctp_test_create_dev(lladdr_len, lladdr); 107 } 108 109 void mctp_test_destroy_dev(struct mctp_test_dev *dev) 110 { 111 skb_queue_purge(&dev->pkts); 112 mctp_dev_put(dev->mdev); 113 unregister_netdev(dev->ndev); 114 } 115 116 static int mctp_test_dst_output(struct mctp_dst *dst, struct sk_buff *skb) 117 { 118 skb->dev = dst->dev->dev; 119 dev_queue_xmit(skb); 120 121 return 0; 122 } 123 124 /* local version of mctp_route_alloc() */ 125 static struct mctp_test_route *mctp_route_test_alloc(void) 126 { 127 struct mctp_test_route *rt; 128 129 rt = kzalloc_obj(*rt); 130 if (!rt) 131 return NULL; 132 133 INIT_LIST_HEAD(&rt->rt.list); 134 refcount_set(&rt->rt.refs, 1); 135 rt->rt.output = mctp_test_dst_output; 136 137 return rt; 138 } 139 140 struct mctp_test_route *mctp_test_create_route_direct(struct net *net, 141 struct mctp_dev *dev, 142 mctp_eid_t eid, 143 unsigned int mtu) 144 { 145 struct mctp_test_route *rt; 146 147 rt = mctp_route_test_alloc(); 148 if (!rt) 149 return NULL; 150 151 rt->rt.min = eid; 152 rt->rt.max = eid; 153 rt->rt.mtu = mtu; 154 rt->rt.type = RTN_UNSPEC; 155 rt->rt.dst_type = MCTP_ROUTE_DIRECT; 156 if (dev) 157 mctp_dev_hold(dev); 158 rt->rt.dev = dev; 159 160 list_add_rcu(&rt->rt.list, &net->mctp.routes); 161 162 return rt; 163 } 164 165 struct mctp_test_route *mctp_test_create_route_gw(struct net *net, 166 unsigned int netid, 167 mctp_eid_t eid, 168 mctp_eid_t gw, 169 unsigned int mtu) 170 { 171 struct mctp_test_route *rt; 172 173 rt = mctp_route_test_alloc(); 174 if (!rt) 175 return NULL; 176 177 rt->rt.min = eid; 178 rt->rt.max = eid; 179 rt->rt.mtu = mtu; 180 rt->rt.type = RTN_UNSPEC; 181 rt->rt.dst_type = MCTP_ROUTE_GATEWAY; 182 rt->rt.gateway.eid = gw; 183 rt->rt.gateway.net = netid; 184 185 list_add_rcu(&rt->rt.list, &net->mctp.routes); 186 187 return rt; 188 } 189 190 /* Convenience function for our test dst; release with mctp_dst_release() */ 191 void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst, 192 struct mctp_test_dev *dev, unsigned int mtu) 193 { 194 unsigned long flags; 195 196 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); 197 198 memset(dst, 0, sizeof(*dst)); 199 200 dst->dev = dev->mdev; 201 __mctp_dev_get(dst->dev->dev); 202 dst->mtu = mtu; 203 dst->output = mctp_test_dst_output; 204 dst->saddr = MCTP_ADDR_NULL; 205 spin_lock_irqsave(&dev->mdev->addrs_lock, flags); 206 if (dev->mdev->num_addrs) 207 dst->saddr = dev->mdev->addrs[0]; 208 spin_unlock_irqrestore(&dev->mdev->addrs_lock, flags); 209 } 210 211 void mctp_test_route_destroy(struct kunit *test, struct mctp_test_route *rt) 212 { 213 unsigned int refs; 214 215 rtnl_lock(); 216 list_del_rcu(&rt->rt.list); 217 rtnl_unlock(); 218 219 if (rt->rt.dst_type == MCTP_ROUTE_DIRECT && rt->rt.dev) 220 mctp_dev_put(rt->rt.dev); 221 222 refs = refcount_read(&rt->rt.refs); 223 KUNIT_ASSERT_EQ_MSG(test, refs, 1, "route ref imbalance"); 224 225 kfree_rcu(&rt->rt, rcu); 226 } 227 228 void mctp_test_skb_set_dev(struct sk_buff *skb, struct mctp_test_dev *dev) 229 { 230 struct mctp_skb_cb *cb; 231 232 cb = mctp_cb(skb); 233 cb->net = READ_ONCE(dev->mdev->net); 234 skb->dev = dev->ndev; 235 } 236 237 struct sk_buff *mctp_test_create_skb(const struct mctp_hdr *hdr, 238 unsigned int data_len) 239 { 240 size_t hdr_len = sizeof(*hdr); 241 struct sk_buff *skb; 242 unsigned int i; 243 u8 *buf; 244 245 skb = alloc_skb(hdr_len + data_len, GFP_KERNEL); 246 if (!skb) 247 return NULL; 248 249 __mctp_cb(skb); 250 memcpy(skb_put(skb, hdr_len), hdr, hdr_len); 251 252 buf = skb_put(skb, data_len); 253 for (i = 0; i < data_len; i++) 254 buf[i] = i & 0xff; 255 256 return skb; 257 } 258 259 struct sk_buff *__mctp_test_create_skb_data(const struct mctp_hdr *hdr, 260 const void *data, size_t data_len) 261 { 262 size_t hdr_len = sizeof(*hdr); 263 struct sk_buff *skb; 264 265 skb = alloc_skb(hdr_len + data_len, GFP_KERNEL); 266 if (!skb) 267 return NULL; 268 269 __mctp_cb(skb); 270 memcpy(skb_put(skb, hdr_len), hdr, hdr_len); 271 memcpy(skb_put(skb, data_len), data, data_len); 272 273 return skb; 274 } 275 276 void mctp_test_bind_run(struct kunit *test, 277 const struct mctp_test_bind_setup *setup, 278 int *ret_bind_errno, struct socket **sock) 279 { 280 struct sockaddr_mctp addr; 281 int rc; 282 283 *ret_bind_errno = -EIO; 284 285 rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, sock); 286 KUNIT_ASSERT_EQ(test, rc, 0); 287 288 /* connect() if requested */ 289 if (setup->have_peer) { 290 memset(&addr, 0x0, sizeof(addr)); 291 addr.smctp_family = AF_MCTP; 292 addr.smctp_network = setup->peer_net; 293 addr.smctp_addr.s_addr = setup->peer_addr; 294 /* connect() type must match bind() type */ 295 addr.smctp_type = setup->bind_type; 296 rc = kernel_connect(*sock, (struct sockaddr_unsized *)&addr, 297 sizeof(addr), 0); 298 KUNIT_EXPECT_EQ(test, rc, 0); 299 } 300 301 /* bind() */ 302 memset(&addr, 0x0, sizeof(addr)); 303 addr.smctp_family = AF_MCTP; 304 addr.smctp_network = setup->bind_net; 305 addr.smctp_addr.s_addr = setup->bind_addr; 306 addr.smctp_type = setup->bind_type; 307 308 *ret_bind_errno = 309 kernel_bind(*sock, (struct sockaddr_unsized *)&addr, 310 sizeof(addr)); 311 } 312