Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-mctp-improvements-for-null-eid-addressing'

Jeremy Kerr says:

====================
net: mctp: improvements for NULL-EID addressing

Currently, our focus for the MCTP routing implementation has been for
MCTP bus-owner devices. In this case, we will generally have an EID
assigned during local transmit, and have routes established before
expecting to receive.

We also want to handle non-bus-owner cases, where:

- we may need to send control protocol messages (like Discovery Notify)
before any local addresses have been assigned, particularly as part
of acquiring a local address assignment; and

- we will likely want to receive incoming messages before we have
routing established.

This series improves handling for these cases, by handling NULL EIDs
as source / destination addresses where possible.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
====================

Link: https://patch.msgid.link/20260331-dev-mctp-null-eids-v1-0-b4d047372eaf@codeconstruct.com.au
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+243 -60
+1
include/net/mctp.h
··· 270 270 struct mctp_dev *dev; 271 271 unsigned int mtu; 272 272 mctp_eid_t nexthop; 273 + mctp_eid_t saddr; 273 274 274 275 /* set for direct addressing */ 275 276 unsigned char halen;
+45 -49
net/mctp/route.c
··· 880 880 rt1->max == rt2->max; 881 881 } 882 882 883 + static mctp_eid_t mctp_dev_saddr(struct mctp_dev *dev) 884 + { 885 + mctp_eid_t addr = MCTP_ADDR_NULL; 886 + unsigned long flags; 887 + 888 + spin_lock_irqsave(&dev->addrs_lock, flags); 889 + if (dev->num_addrs) { 890 + /* use the outbound interface's first address as our source */ 891 + addr = dev->addrs[0]; 892 + } 893 + spin_unlock_irqrestore(&dev->addrs_lock, flags); 894 + 895 + return addr; 896 + } 897 + 883 898 /* must only be called on a direct route, as the final output hop */ 884 899 static void mctp_dst_from_route(struct mctp_dst *dst, mctp_eid_t eid, 885 900 unsigned int mtu, struct mctp_route *route) ··· 907 892 dst->mtu = min(dst->mtu, mtu); 908 893 dst->halen = 0; 909 894 dst->output = route->output; 895 + dst->saddr = mctp_dev_saddr(route->dev); 910 896 } 911 897 912 898 int mctp_dst_from_extaddr(struct mctp_dst *dst, struct net *net, int ifindex, ··· 940 924 dst->halen = halen; 941 925 dst->output = mctp_dst_output; 942 926 dst->nexthop = 0; 927 + dst->saddr = mctp_dev_saddr(dev); 943 928 memcpy(dst->haddr, haddr, halen); 944 929 945 930 rc = 0; ··· 975 958 { 976 959 const unsigned int max_depth = 32; 977 960 unsigned int depth, mtu = 0; 961 + struct mctp_dst dst_tmp; 978 962 int rc = -EHOSTUNREACH; 979 963 980 964 rcu_read_lock(); ··· 996 978 mtu = mtu ?: rt->mtu; 997 979 998 980 if (rt->dst_type == MCTP_ROUTE_DIRECT) { 999 - if (dst) 1000 - mctp_dst_from_route(dst, daddr, mtu, rt); 1001 - rc = 0; 981 + mctp_dst_from_route(&dst_tmp, daddr, mtu, rt); 982 + /* cannot do gateway-ed routes without a src */ 983 + if (dst_tmp.saddr == MCTP_ADDR_NULL && depth != 0) { 984 + mctp_dst_release(&dst_tmp); 985 + } else { 986 + if (dst) 987 + *dst = dst_tmp; 988 + rc = 0; 989 + } 1002 990 break; 1003 991 1004 992 } else if (rt->dst_type == MCTP_ROUTE_GATEWAY) { ··· 1017 993 return rc; 1018 994 } 1019 995 1020 - static int mctp_route_lookup_null(struct net *net, struct net_device *dev, 1021 - struct mctp_dst *dst) 996 + static int mctp_dst_input_null(struct net *net, struct net_device *dev, 997 + struct mctp_dst *dst) 1022 998 { 1023 - int rc = -EHOSTUNREACH; 1024 - struct mctp_route *rt; 1025 - 1026 999 rcu_read_lock(); 1027 - 1028 - list_for_each_entry_rcu(rt, &net->mctp.routes, list) { 1029 - if (rt->dst_type != MCTP_ROUTE_DIRECT || rt->type != RTN_LOCAL) 1030 - continue; 1031 - 1032 - if (rt->dev->dev != dev) 1033 - continue; 1034 - 1035 - mctp_dst_from_route(dst, 0, 0, rt); 1036 - rc = 0; 1037 - break; 1038 - } 1039 - 1000 + dst->dev = __mctp_dev_get(dev); 1040 1001 rcu_read_unlock(); 1041 1002 1042 - return rc; 1003 + if (!dst->dev) 1004 + return -EHOSTUNREACH; 1005 + 1006 + dst->mtu = READ_ONCE(dev->mtu); 1007 + dst->halen = 0; 1008 + dst->output = mctp_dst_input; 1009 + dst->nexthop = 0; 1010 + 1011 + return 0; 1043 1012 } 1044 1013 1045 1014 static int mctp_do_fragment_route(struct mctp_dst *dst, struct sk_buff *skb, ··· 1133 1116 struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk); 1134 1117 struct mctp_sk_key *key; 1135 1118 struct mctp_hdr *hdr; 1136 - unsigned long flags; 1137 1119 unsigned int netid; 1138 - mctp_eid_t saddr; 1139 - int rc; 1140 1120 u8 tag; 1141 1121 1142 1122 KUNIT_STATIC_STUB_REDIRECT(mctp_local_output, sk, dst, skb, daddr, 1143 1123 req_tag); 1144 1124 1145 - rc = -ENODEV; 1146 - 1147 - spin_lock_irqsave(&dst->dev->addrs_lock, flags); 1148 - if (dst->dev->num_addrs == 0) { 1149 - rc = -EHOSTUNREACH; 1150 - } else { 1151 - /* use the outbound interface's first address as our source */ 1152 - saddr = dst->dev->addrs[0]; 1153 - rc = 0; 1154 - } 1155 - spin_unlock_irqrestore(&dst->dev->addrs_lock, flags); 1156 1125 netid = READ_ONCE(dst->dev->net); 1157 - 1158 - if (rc) 1159 - goto err_free; 1160 1126 1161 1127 if (req_tag & MCTP_TAG_OWNER) { 1162 1128 if (req_tag & MCTP_TAG_PREALLOC) 1163 1129 key = mctp_lookup_prealloc_tag(msk, netid, daddr, 1164 1130 req_tag, &tag); 1165 1131 else 1166 - key = mctp_alloc_local_tag(msk, netid, saddr, daddr, 1167 - false, &tag); 1132 + key = mctp_alloc_local_tag(msk, netid, dst->saddr, 1133 + daddr, false, &tag); 1168 1134 1169 1135 if (IS_ERR(key)) { 1170 - rc = PTR_ERR(key); 1171 - goto err_free; 1136 + kfree_skb(skb); 1137 + return PTR_ERR(key); 1172 1138 } 1173 1139 mctp_skb_set_flow(skb, key); 1174 1140 /* done with the key in this scope */ ··· 1174 1174 hdr = mctp_hdr(skb); 1175 1175 hdr->ver = 1; 1176 1176 hdr->dest = daddr; 1177 - hdr->src = saddr; 1177 + hdr->src = dst->saddr; 1178 1178 1179 1179 /* route output functions consume the skb, even on error */ 1180 1180 return mctp_do_fragment_route(dst, skb, dst->mtu, tag); 1181 - 1182 - err_free: 1183 - kfree_skb(skb); 1184 - return rc; 1185 1181 } 1186 1182 1187 1183 /* route management */ ··· 1362 1366 1363 1367 /* NULL EID, but addressed to our physical address */ 1364 1368 if (rc && mh->dest == MCTP_ADDR_NULL && skb->pkt_type == PACKET_HOST) 1365 - rc = mctp_route_lookup_null(net, dev, &dst); 1369 + rc = mctp_dst_input_null(net, dev, &dst); 1366 1370 1367 1371 if (rc) 1368 1372 goto err_drop;
+169 -11
net/mctp/test/route-test.c
··· 174 174 KUNIT_ARRAY_PARAM(mctp_rx_input, mctp_rx_input_tests, 175 175 mctp_rx_input_test_to_desc); 176 176 177 - /* set up a local dev, route on EID 8, and a socket listening on type 0 */ 177 + /* set up a local dev (with addr 8), route on EID 8, and a socket listening on 178 + * type 0 179 + */ 178 180 static void __mctp_route_test_init(struct kunit *test, 179 181 struct mctp_test_dev **devp, 180 182 struct mctp_dst *dst, ··· 192 190 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 193 191 if (netid != MCTP_NET_ANY) 194 192 WRITE_ONCE(dev->mdev->net, netid); 193 + 194 + dev->mdev->addrs = kmalloc_objs(u8, 1, GFP_KERNEL); 195 + dev->mdev->num_addrs = 1; 196 + dev->mdev->addrs[0] = 8; 195 197 196 198 mctp_test_dst_setup(test, dst, dev, 68); 197 199 ··· 914 908 __mctp_route_test_fini(test, dev, &dst, sock); 915 909 } 916 910 911 + /* check we can receive an incoming packet with the null EID as daddr, when 912 + * no RTN_LOCAL routes are present. 913 + */ 914 + static void mctp_test_route_input_null_eid(struct kunit *test) 915 + { 916 + struct mctp_hdr hdr = RX_HDR(1, 10, 0, FL_S | FL_E | FL_TO); 917 + struct sk_buff *skb_pkt, *skb_sk; 918 + struct mctp_test_dev *dev; 919 + struct sockaddr_mctp addr; 920 + struct socket *sock; 921 + u8 type = 0; 922 + int rc; 923 + 924 + dev = mctp_test_create_dev(); 925 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 926 + 927 + rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); 928 + KUNIT_ASSERT_EQ(test, rc, 0); 929 + 930 + addr.smctp_family = AF_MCTP; 931 + addr.smctp_network = MCTP_NET_ANY; 932 + addr.smctp_addr.s_addr = MCTP_ADDR_ANY; 933 + addr.smctp_type = type; 934 + rc = kernel_bind(sock, (struct sockaddr_unsized *)&addr, sizeof(addr)); 935 + KUNIT_ASSERT_EQ(test, rc, 0); 936 + 937 + skb_pkt = mctp_test_create_skb_data(&hdr, &type); 938 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb_pkt); 939 + 940 + skb_pkt->dev = dev->ndev; 941 + skb_pkt->pkt_type = PACKET_HOST; 942 + 943 + mctp_pkttype_receive(skb_pkt, dev->ndev, &mctp_packet_type, NULL); 944 + 945 + skb_sk = skb_recv_datagram(sock->sk, MSG_DONTWAIT, &rc); 946 + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, skb_sk); 947 + 948 + skb_free_datagram(sock->sk, skb_sk); 949 + sock_release(sock); 950 + mctp_test_destroy_dev(dev); 951 + } 952 + 917 953 #if IS_ENABLED(CONFIG_MCTP_FLOWS) 918 954 919 955 static void mctp_test_flow_init(struct kunit *test, ··· 975 927 * route we provide 976 928 */ 977 929 __mctp_route_test_init(test, &dev, dst, sock, MCTP_NET_ANY); 978 - 979 - /* Assign a single EID. ->addrs is freed on mctp netdev release */ 980 - dev->mdev->addrs = kmalloc(sizeof(u8), GFP_KERNEL); 981 - dev->mdev->num_addrs = 1; 982 - dev->mdev->addrs[0] = 8; 983 930 984 931 skb = alloc_skb(len + sizeof(struct mctp_hdr) + 1, GFP_KERNEL); 985 932 KUNIT_ASSERT_TRUE(test, skb); ··· 1101 1058 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1102 1059 WRITE_ONCE(dev->mdev->net, netid); 1103 1060 1104 - mctp_test_dst_setup(test, &dst, dev, 68); 1105 - 1106 1061 rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); 1107 1062 KUNIT_ASSERT_EQ(test, rc, 0); 1108 1063 1109 1064 dev->mdev->addrs = kmalloc(sizeof(u8), GFP_KERNEL); 1110 1065 dev->mdev->num_addrs = 1; 1111 1066 dev->mdev->addrs[0] = src_eid; 1067 + 1068 + mctp_test_dst_setup(test, &dst, dev, 68); 1112 1069 1113 1070 skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL); 1114 1071 KUNIT_ASSERT_TRUE(test, skb); ··· 1208 1165 struct mctp_test_dev *dev; 1209 1166 int rc; 1210 1167 1211 - dev = mctp_test_create_dev(); 1168 + dev = mctp_test_create_dev_with_addr(8); 1212 1169 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1213 1170 1214 1171 /* 8 (local) -> 10 (gateway) via 9 (direct) */ ··· 1238 1195 struct mctp_test_dev *dev; 1239 1196 int rc; 1240 1197 1241 - dev = mctp_test_create_dev(); 1198 + dev = mctp_test_create_dev_with_addr(8); 1242 1199 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1243 1200 1244 1201 /* two routes using each other as the gw */ ··· 1297 1254 unsigned int netid; 1298 1255 int rc; 1299 1256 1300 - dev = mctp_test_create_dev(); 1257 + dev = mctp_test_create_dev_with_addr(8); 1301 1258 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1302 1259 dev->ndev->mtu = mtus->dev; 1303 1260 mdev = dev->mdev; ··· 1612 1569 __mctp_route_test_fini(test, dev, &dst, sock_ty0); 1613 1570 } 1614 1571 1572 + static void mctp_test_route_output_direct_no_eids(struct kunit *test) 1573 + { 1574 + struct mctp_dst dst = { 0 }; 1575 + struct sk_buff *skb, *skb2; 1576 + struct mctp_test_route *rt; 1577 + struct mctp_test_dev *dev; 1578 + struct socket *sock; 1579 + const int len = 2; 1580 + int rc; 1581 + 1582 + dev = mctp_test_create_dev(); 1583 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1584 + 1585 + rt = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68); 1586 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt); 1587 + 1588 + rc = mctp_route_lookup(&init_net, dev->mdev->net, 9, &dst); 1589 + KUNIT_ASSERT_EQ(test, rc, 0); 1590 + 1591 + rc = sock_create_kern(&init_net, AF_MCTP, SOCK_DGRAM, 0, &sock); 1592 + KUNIT_ASSERT_EQ(test, rc, 0); 1593 + 1594 + skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL); 1595 + KUNIT_ASSERT_TRUE(test, skb); 1596 + __mctp_cb(skb); 1597 + skb_reserve(skb, sizeof(struct mctp_hdr) + 1 + len); 1598 + memset(skb_put(skb, len), 0, len); 1599 + 1600 + rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER); 1601 + KUNIT_ASSERT_EQ(test, rc, 0); 1602 + 1603 + KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1); 1604 + 1605 + skb2 = skb_dequeue(&dev->pkts); 1606 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2); 1607 + 1608 + kfree_skb(skb2); 1609 + sock_release(sock); 1610 + mctp_dst_release(&dst); 1611 + mctp_test_route_destroy(test, rt); 1612 + mctp_test_destroy_dev(dev); 1613 + } 1614 + 1615 + static void mctp_test_route_output_gw_no_eids(struct kunit *test) 1616 + { 1617 + struct mctp_test_route *rt1, *rt2; 1618 + struct mctp_test_dev *dev; 1619 + struct mctp_dst dst = { 0 }; 1620 + int rc; 1621 + 1622 + dev = mctp_test_create_dev(); 1623 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1624 + 1625 + /* route: direct to bridge */ 1626 + rt1 = mctp_test_create_route_direct(&init_net, dev->mdev, 9, 68); 1627 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt1); 1628 + 1629 + /* route: bridge gw to final dest */ 1630 + rt2 = mctp_test_create_route_gw(&init_net, dev->mdev->net, 10, 9, 0); 1631 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, rt2); 1632 + 1633 + /* route lookup should fail, due to no source address on dev */ 1634 + rc = mctp_route_lookup(&init_net, dev->mdev->net, 10, &dst); 1635 + KUNIT_ASSERT_NE(test, rc, 0); 1636 + 1637 + mctp_test_route_destroy(test, rt1); 1638 + mctp_test_route_destroy(test, rt2); 1639 + mctp_test_destroy_dev(dev); 1640 + } 1641 + 1642 + static void mctp_test_route_output_extaddr_no_eids(struct kunit *test) 1643 + { 1644 + struct mctp_dst dst = { 0 }; 1645 + struct sk_buff *skb, *skb2; 1646 + struct mctp_test_dev *dev; 1647 + struct socket *sock; 1648 + const int len = 1; 1649 + struct net *net; 1650 + int rc; 1651 + 1652 + dev = mctp_test_create_dev(); 1653 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1654 + 1655 + net = dev_net(dev->ndev); 1656 + 1657 + rc = mctp_dst_from_extaddr(&dst, net, dev->ndev->ifindex, 0, NULL); 1658 + KUNIT_ASSERT_EQ(test, rc, 0); 1659 + 1660 + rc = sock_create_kern(net, AF_MCTP, SOCK_DGRAM, 0, &sock); 1661 + KUNIT_ASSERT_EQ(test, rc, 0); 1662 + 1663 + skb = alloc_skb(sizeof(struct mctp_hdr) + 1 + len, GFP_KERNEL); 1664 + KUNIT_ASSERT_TRUE(test, skb); 1665 + __mctp_cb(skb); 1666 + skb_reserve(skb, sizeof(struct mctp_hdr) + 1 + len); 1667 + memset(skb_put(skb, len), 0, len); 1668 + 1669 + rc = mctp_local_output(sock->sk, &dst, skb, 9, MCTP_TAG_OWNER); 1670 + KUNIT_ASSERT_EQ(test, rc, 0); 1671 + 1672 + KUNIT_ASSERT_EQ(test, dev->pkts.qlen, 1); 1673 + 1674 + skb2 = skb_dequeue(&dev->pkts); 1675 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, skb2); 1676 + 1677 + kfree_skb(skb2); 1678 + sock_release(sock); 1679 + mctp_dst_release(&dst); 1680 + mctp_test_destroy_dev(dev); 1681 + } 1682 + 1615 1683 static struct kunit_case mctp_test_cases[] = { 1616 1684 KUNIT_CASE_PARAM(mctp_test_fragment, mctp_frag_gen_params), 1617 1685 KUNIT_CASE_PARAM(mctp_test_rx_input, mctp_rx_input_gen_params), ··· 1735 1581 KUNIT_CASE(mctp_test_route_input_sk_fail_frag), 1736 1582 KUNIT_CASE(mctp_test_route_input_multiple_nets_bind), 1737 1583 KUNIT_CASE(mctp_test_route_input_multiple_nets_key), 1584 + KUNIT_CASE(mctp_test_route_input_null_eid), 1738 1585 KUNIT_CASE(mctp_test_packet_flow), 1739 1586 KUNIT_CASE(mctp_test_fragment_flow), 1740 1587 KUNIT_CASE(mctp_test_route_output_key_create), ··· 1746 1591 KUNIT_CASE_PARAM(mctp_test_route_gw_mtu, mctp_route_gw_mtu_gen_params), 1747 1592 KUNIT_CASE(mctp_test_route_gw_output), 1748 1593 KUNIT_CASE_PARAM(mctp_test_bind_lookup, mctp_bind_lookup_gen_params), 1594 + KUNIT_CASE(mctp_test_route_output_direct_no_eids), 1595 + KUNIT_CASE(mctp_test_route_output_gw_no_eids), 1596 + KUNIT_CASE(mctp_test_route_output_extaddr_no_eids), 1749 1597 {} 1750 1598 }; 1751 1599
+27
net/mctp/test/utils.c
··· 80 80 return __mctp_test_create_dev(0, NULL); 81 81 } 82 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 + 83 103 struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len, 84 104 const unsigned char *lladdr) 85 105 { ··· 191 171 void mctp_test_dst_setup(struct kunit *test, struct mctp_dst *dst, 192 172 struct mctp_test_dev *dev, unsigned int mtu) 193 173 { 174 + unsigned long flags; 175 + 194 176 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev); 195 177 196 178 memset(dst, 0, sizeof(*dst)); ··· 201 179 __mctp_dev_get(dst->dev->dev); 202 180 dst->mtu = mtu; 203 181 dst->output = mctp_test_dst_output; 182 + dst->saddr = MCTP_ADDR_NULL; 183 + spin_lock_irqsave(&dev->mdev->addrs_lock, flags); 184 + if (dev->mdev->num_addrs) 185 + dst->saddr = dev->mdev->addrs[0]; 186 + spin_unlock_irqrestore(&dev->mdev->addrs_lock, flags); 204 187 } 205 188 206 189 void mctp_test_route_destroy(struct kunit *test, struct mctp_test_route *rt)
+1
net/mctp/test/utils.h
··· 42 42 }; 43 43 44 44 struct mctp_test_dev *mctp_test_create_dev(void); 45 + struct mctp_test_dev *mctp_test_create_dev_with_addr(mctp_eid_t eid); 45 46 struct mctp_test_dev *mctp_test_create_dev_lladdr(unsigned short lladdr_len, 46 47 const unsigned char *lladdr); 47 48 void mctp_test_destroy_dev(struct mctp_test_dev *dev);