@@ -119,7 +119,14 @@ static const struct role roles[] = {
119
119
},
120
120
};
121
121
122
+ enum discovery_state {
123
+ DISCOVERY_UNSUPPORTED ,
124
+ DISCOVERY_DISCOVERED ,
125
+ DISCOVERY_UNDISCOVERED ,
126
+ };
127
+
122
128
struct link {
129
+ enum discovery_state discovered ;
123
130
bool published ;
124
131
int ifindex ;
125
132
enum endpoint_role role ;
@@ -786,6 +793,9 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
786
793
warnx ("ERR: cannot add bus owner to object lists" );
787
794
}
788
795
796
+ if (link_data -> discovered != DISCOVERY_UNSUPPORTED ) {
797
+ link_data -> discovered = DISCOVERY_DISCOVERED ;
798
+ }
789
799
resp -> status =
790
800
SET_MCTP_EID_ASSIGNMENT_STATUS (MCTP_SET_EID_ACCEPTED ) |
791
801
SET_MCTP_EID_ALLOCATION_STATUS (MCTP_SET_EID_POOL_NONE );
@@ -795,6 +805,20 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
795
805
return reply_message (ctx , sd , resp , resp_len , addr );
796
806
797
807
case MCTP_SET_EID_DISCOVERED :
808
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
809
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
810
+ resp_len = sizeof (struct mctp_ctrl_resp );
811
+ return reply_message (ctx , sd , resp , resp_len , addr );
812
+ }
813
+
814
+ link_data -> discovered = DISCOVERY_DISCOVERED ;
815
+ resp -> status =
816
+ SET_MCTP_EID_ASSIGNMENT_STATUS (MCTP_SET_EID_REJECTED ) |
817
+ SET_MCTP_EID_ALLOCATION_STATUS (MCTP_SET_EID_POOL_NONE );
818
+ resp -> eid_set = req -> eid ;
819
+ resp -> eid_pool_size = 0 ;
820
+ return reply_message (ctx , sd , resp , resp_len , addr );
821
+
798
822
case MCTP_SET_EID_RESET :
799
823
// unsupported
800
824
resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
@@ -957,6 +981,97 @@ handle_control_resolve_endpoint_id(struct ctx *ctx, int sd,
957
981
return reply_message (ctx , sd , resp , resp_len , addr );
958
982
}
959
983
984
+ static int handle_control_prepare_endpoint_discovery (
985
+ struct ctx * ctx , int sd , const struct sockaddr_mctp_ext * addr ,
986
+ const uint8_t * buf , const size_t buf_size )
987
+ {
988
+ struct mctp_ctrl_msg_hdr * req = NULL ;
989
+ struct mctp_ctrl_resp_prepare_discovery respi = { 0 }, * resp = & respi ;
990
+ struct link * link_data ;
991
+
992
+ if (buf_size < sizeof (* req )) {
993
+ warnx ("short Prepare for Endpoint Discovery message" );
994
+ return - ENOMSG ;
995
+ }
996
+
997
+ link_data = mctp_nl_get_link_userdata (ctx -> nl , addr -> smctp_ifindex );
998
+ if (!link_data ) {
999
+ bug_warn ("unconfigured interface %d" , addr -> smctp_ifindex );
1000
+ return - ENOENT ;
1001
+ }
1002
+
1003
+ if (link_data -> role == ENDPOINT_ROLE_BUS_OWNER ) {
1004
+ // ignore message if we are bus owner
1005
+ return 0 ;
1006
+ }
1007
+
1008
+ req = (void * )buf ;
1009
+ resp = (void * )resp ;
1010
+ mctp_ctrl_msg_hdr_init_resp (& resp -> ctrl_hdr , * req );
1011
+
1012
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
1013
+ warnx ("received prepare for discovery request to unsupported interface %d" ,
1014
+ addr -> smctp_ifindex );
1015
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_UNSUPPORTED_CMD ;
1016
+ return reply_message_phys (ctx , sd , resp ,
1017
+ sizeof (struct mctp_ctrl_resp ), addr );
1018
+ }
1019
+
1020
+ if (link_data -> discovered == DISCOVERY_DISCOVERED ) {
1021
+ link_data -> discovered = DISCOVERY_UNDISCOVERED ;
1022
+ warnx ("clear discovered flag of interface %d" ,
1023
+ addr -> smctp_ifindex );
1024
+ }
1025
+
1026
+ // we need to send using physical addressing, no entry in routing table yet
1027
+ resp -> completion_code = MCTP_CTRL_CC_SUCCESS ;
1028
+ return reply_message_phys (ctx , sd , resp , sizeof (* resp ), addr );
1029
+ }
1030
+
1031
+ static int
1032
+ handle_control_endpoint_discovery (struct ctx * ctx , int sd ,
1033
+ const struct sockaddr_mctp_ext * addr ,
1034
+ const uint8_t * buf , const size_t buf_size )
1035
+ {
1036
+ struct mctp_ctrl_msg_hdr * req = NULL ;
1037
+ struct mctp_ctrl_resp_endpoint_discovery respi = { 0 }, * resp = & respi ;
1038
+ struct link * link_data ;
1039
+
1040
+ if (buf_size < sizeof (* req )) {
1041
+ warnx ("short Endpoint Discovery message" );
1042
+ return - ENOMSG ;
1043
+ }
1044
+
1045
+ link_data = mctp_nl_get_link_userdata (ctx -> nl , addr -> smctp_ifindex );
1046
+ if (!link_data ) {
1047
+ bug_warn ("unconfigured interface %d" , addr -> smctp_ifindex );
1048
+ return - ENOENT ;
1049
+ }
1050
+
1051
+ if (link_data -> role == ENDPOINT_ROLE_BUS_OWNER ) {
1052
+ // ignore message if we are bus owner
1053
+ return 0 ;
1054
+ }
1055
+
1056
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
1057
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
1058
+ return reply_message (ctx , sd , resp ,
1059
+ sizeof (struct mctp_ctrl_resp ), addr );
1060
+ }
1061
+
1062
+ if (link_data -> discovered == DISCOVERY_DISCOVERED ) {
1063
+ // if we are already discovered (i.e, assigned an EID), then no reply
1064
+ return 0 ;
1065
+ }
1066
+
1067
+ req = (void * )buf ;
1068
+ resp = (void * )resp ;
1069
+ mctp_ctrl_msg_hdr_init_resp (& resp -> ctrl_hdr , * req );
1070
+
1071
+ // we need to send using physical addressing, no entry in routing table yet
1072
+ return reply_message_phys (ctx , sd , resp , sizeof (* resp ), addr );
1073
+ }
1074
+
960
1075
static int handle_control_unsupported (struct ctx * ctx , int sd ,
961
1076
const struct sockaddr_mctp_ext * addr ,
962
1077
const uint8_t * buf , const size_t buf_size )
@@ -1039,6 +1154,14 @@ static int cb_listen_control_msg(sd_event_source *s, int sd, uint32_t revents,
1039
1154
rc = handle_control_resolve_endpoint_id (ctx , sd , & addr , buf ,
1040
1155
buf_size );
1041
1156
break ;
1157
+ case MCTP_CTRL_CMD_PREPARE_ENDPOINT_DISCOVERY :
1158
+ rc = handle_control_prepare_endpoint_discovery (ctx , sd , & addr ,
1159
+ buf , buf_size );
1160
+ break ;
1161
+ case MCTP_CTRL_CMD_ENDPOINT_DISCOVERY :
1162
+ rc = handle_control_endpoint_discovery (ctx , sd , & addr , buf ,
1163
+ buf_size );
1164
+ break ;
1042
1165
default :
1043
1166
if (ctx -> verbose ) {
1044
1167
warnx ("Ignoring unsupported command code 0x%02x" ,
@@ -4150,10 +4273,13 @@ static int add_interface(struct ctx *ctx, int ifindex)
4150
4273
return - ENOENT ;
4151
4274
}
4152
4275
4276
+ uint8_t phys_binding = mctp_nl_phys_binding_byindex (ctx -> nl , ifindex );
4277
+
4153
4278
struct link * link = calloc (1 , sizeof (* link ));
4154
4279
if (!link )
4155
4280
return - ENOMEM ;
4156
4281
4282
+ link -> discovered = DISCOVERY_UNSUPPORTED ;
4157
4283
link -> published = false;
4158
4284
link -> ifindex = ifindex ;
4159
4285
link -> ctx = ctx ;
@@ -4182,6 +4308,10 @@ static int add_interface(struct ctx *ctx, int ifindex)
4182
4308
bus_link_owner_vtable , link );
4183
4309
}
4184
4310
4311
+ if (phys_binding == MCTP_PHYS_BINDING_PCIE_VDM ) {
4312
+ link -> discovered = DISCOVERY_UNDISCOVERED ;
4313
+ }
4314
+
4185
4315
link -> published = true;
4186
4316
rc = emit_interface_added (link );
4187
4317
if (rc < 0 ) {
0 commit comments