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