@@ -117,7 +117,14 @@ static const struct role roles[] = {
117
117
},
118
118
};
119
119
120
+ enum discovery_state {
121
+ DISCOVERY_UNSUPPORTED ,
122
+ DISCOVERY_DISCOVERED ,
123
+ DISCOVERY_UNDISCOVERED ,
124
+ };
125
+
120
126
struct link {
127
+ enum discovery_state discovered ;
121
128
bool published ;
122
129
int ifindex ;
123
130
enum endpoint_role role ;
@@ -777,6 +784,9 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
777
784
warnx ("ERR: cannot add bus owner to object lists" );
778
785
}
779
786
787
+ if (link_data -> discovered != DISCOVERY_UNSUPPORTED ) {
788
+ link_data -> discovered = DISCOVERY_DISCOVERED ;
789
+ }
780
790
resp -> status =
781
791
SET_MCTP_EID_ASSIGNMENT_STATUS (MCTP_SET_EID_ACCEPTED ) |
782
792
SET_MCTP_EID_ALLOCATION_STATUS (MCTP_SET_EID_POOL_NONE );
@@ -786,6 +796,20 @@ static int handle_control_set_endpoint_id(struct ctx *ctx, int sd,
786
796
return reply_message (ctx , sd , resp , resp_len , addr );
787
797
788
798
case MCTP_SET_EID_DISCOVERED :
799
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
800
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
801
+ resp_len = sizeof (struct mctp_ctrl_resp );
802
+ return reply_message (ctx , sd , resp , resp_len , addr );
803
+ }
804
+
805
+ link_data -> discovered = DISCOVERY_DISCOVERED ;
806
+ resp -> status =
807
+ SET_MCTP_EID_ASSIGNMENT_STATUS (MCTP_SET_EID_REJECTED ) |
808
+ SET_MCTP_EID_ALLOCATION_STATUS (MCTP_SET_EID_POOL_NONE );
809
+ resp -> eid_set = req -> eid ;
810
+ resp -> eid_pool_size = 0 ;
811
+ return reply_message (ctx , sd , resp , resp_len , addr );
812
+
789
813
case MCTP_SET_EID_RESET :
790
814
// unsupported
791
815
resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
@@ -948,6 +972,97 @@ handle_control_resolve_endpoint_id(struct ctx *ctx, int sd,
948
972
return reply_message (ctx , sd , resp , resp_len , addr );
949
973
}
950
974
975
+ static int handle_control_prepare_endpoint_discovery (
976
+ struct ctx * ctx , int sd , const struct sockaddr_mctp_ext * addr ,
977
+ const uint8_t * buf , const size_t buf_size )
978
+ {
979
+ struct mctp_ctrl_msg_hdr * req = NULL ;
980
+ struct mctp_ctrl_resp_prepare_discovery respi = { 0 }, * resp = & respi ;
981
+ struct link * link_data ;
982
+
983
+ if (buf_size < sizeof (* req )) {
984
+ warnx ("short Prepare for Endpoint Discovery message" );
985
+ return - ENOMSG ;
986
+ }
987
+
988
+ link_data = mctp_nl_get_link_userdata (ctx -> nl , addr -> smctp_ifindex );
989
+ if (!link_data ) {
990
+ bug_warn ("unconfigured interface %d" , addr -> smctp_ifindex );
991
+ return - ENOENT ;
992
+ }
993
+
994
+ if (link_data -> role == ENDPOINT_ROLE_BUS_OWNER ) {
995
+ // ignore message if we are bus owner
996
+ return 0 ;
997
+ }
998
+
999
+ req = (void * )buf ;
1000
+ resp = (void * )resp ;
1001
+ mctp_ctrl_msg_hdr_init_resp (& resp -> ctrl_hdr , * req );
1002
+
1003
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
1004
+ warnx ("received prepare for discovery request to unsupported interface %d" ,
1005
+ addr -> smctp_ifindex );
1006
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_UNSUPPORTED_CMD ;
1007
+ return reply_message_phys (ctx , sd , resp ,
1008
+ sizeof (struct mctp_ctrl_resp ), addr );
1009
+ }
1010
+
1011
+ if (link_data -> discovered == DISCOVERY_DISCOVERED ) {
1012
+ link_data -> discovered = DISCOVERY_UNDISCOVERED ;
1013
+ warnx ("clear discovered flag of interface %d" ,
1014
+ addr -> smctp_ifindex );
1015
+ }
1016
+
1017
+ // we need to send using physical addressing, no entry in routing table yet
1018
+ resp -> completion_code = MCTP_CTRL_CC_SUCCESS ;
1019
+ return reply_message_phys (ctx , sd , resp , sizeof (* resp ), addr );
1020
+ }
1021
+
1022
+ static int
1023
+ handle_control_endpoint_discovery (struct ctx * ctx , int sd ,
1024
+ const struct sockaddr_mctp_ext * addr ,
1025
+ const uint8_t * buf , const size_t buf_size )
1026
+ {
1027
+ struct mctp_ctrl_msg_hdr * req = NULL ;
1028
+ struct mctp_ctrl_resp_endpoint_discovery respi = { 0 }, * resp = & respi ;
1029
+ struct link * link_data ;
1030
+
1031
+ if (buf_size < sizeof (* req )) {
1032
+ warnx ("short Endpoint Discovery message" );
1033
+ return - ENOMSG ;
1034
+ }
1035
+
1036
+ link_data = mctp_nl_get_link_userdata (ctx -> nl , addr -> smctp_ifindex );
1037
+ if (!link_data ) {
1038
+ bug_warn ("unconfigured interface %d" , addr -> smctp_ifindex );
1039
+ return - ENOENT ;
1040
+ }
1041
+
1042
+ if (link_data -> role == ENDPOINT_ROLE_BUS_OWNER ) {
1043
+ // ignore message if we are bus owner
1044
+ return 0 ;
1045
+ }
1046
+
1047
+ if (link_data -> discovered == DISCOVERY_UNSUPPORTED ) {
1048
+ resp -> completion_code = MCTP_CTRL_CC_ERROR_INVALID_DATA ;
1049
+ return reply_message (ctx , sd , resp ,
1050
+ sizeof (struct mctp_ctrl_resp ), addr );
1051
+ }
1052
+
1053
+ if (link_data -> discovered == DISCOVERY_DISCOVERED ) {
1054
+ // if we are already discovered (i.e, assigned an EID), then no reply
1055
+ return 0 ;
1056
+ }
1057
+
1058
+ req = (void * )buf ;
1059
+ resp = (void * )resp ;
1060
+ mctp_ctrl_msg_hdr_init_resp (& resp -> ctrl_hdr , * req );
1061
+
1062
+ // we need to send using physical addressing, no entry in routing table yet
1063
+ return reply_message_phys (ctx , sd , resp , sizeof (* resp ), addr );
1064
+ }
1065
+
951
1066
static int handle_control_unsupported (struct ctx * ctx , int sd ,
952
1067
const struct sockaddr_mctp_ext * addr ,
953
1068
const uint8_t * buf , const size_t buf_size )
@@ -1030,6 +1145,14 @@ static int cb_listen_control_msg(sd_event_source *s, int sd, uint32_t revents,
1030
1145
rc = handle_control_resolve_endpoint_id (ctx , sd , & addr , buf ,
1031
1146
buf_size );
1032
1147
break ;
1148
+ case MCTP_CTRL_CMD_PREPARE_ENDPOINT_DISCOVERY :
1149
+ rc = handle_control_prepare_endpoint_discovery (ctx , sd , & addr ,
1150
+ buf , buf_size );
1151
+ break ;
1152
+ case MCTP_CTRL_CMD_ENDPOINT_DISCOVERY :
1153
+ rc = handle_control_endpoint_discovery (ctx , sd , & addr , buf ,
1154
+ buf_size );
1155
+ break ;
1033
1156
default :
1034
1157
if (ctx -> verbose ) {
1035
1158
warnx ("Ignoring unsupported command code 0x%02x" ,
@@ -3905,10 +4028,14 @@ static int add_interface(struct ctx *ctx, int ifindex)
3905
4028
return - ENOENT ;
3906
4029
}
3907
4030
4031
+ enum mctp_phys_binding phys_binding =
4032
+ mctp_nl_phys_binding_byindex (ctx -> nl , ifindex );
4033
+
3908
4034
struct link * link = calloc (1 , sizeof (* link ));
3909
4035
if (!link )
3910
4036
return - ENOMEM ;
3911
4037
4038
+ link -> discovered = DISCOVERY_UNSUPPORTED ;
3912
4039
link -> published = false;
3913
4040
link -> ifindex = ifindex ;
3914
4041
link -> ctx = ctx ;
@@ -3937,6 +4064,11 @@ static int add_interface(struct ctx *ctx, int ifindex)
3937
4064
bus_link_owner_vtable , link );
3938
4065
}
3939
4066
4067
+ if (phys_binding == MCTP_PHYS_BINDING_PCIE_VDM ||
4068
+ phys_binding == MCTP_PHYS_BINDING_I3C ) {
4069
+ link -> discovered = DISCOVERY_UNDISCOVERED ;
4070
+ }
4071
+
3940
4072
link -> published = true;
3941
4073
rc = emit_interface_added (link );
3942
4074
if (rc < 0 ) {
0 commit comments