@@ -8,10 +8,10 @@ use core::{
88} ;
99
1010use axerrno:: { AxError , AxResult , LinuxError } ;
11- use axnet:: { SocketAddrEx , unix:: UnixSocketAddr } ;
11+ use axnet:: { SocketAddrEx , unix:: UnixSocketAddr , vsock :: VsocketAddr } ;
1212use linux_raw_sys:: net:: {
13- __kernel_sa_family_t, AF_INET , AF_INET6 , AF_UNIX , in_addr, in6_addr, sockaddr, sockaddr_in ,
14- sockaddr_in6, socklen_t,
13+ __kernel_sa_family_t, AF_INET , AF_INET6 , AF_UNIX , AF_VSOCK , in_addr, in6_addr, sockaddr,
14+ sockaddr_in , sockaddr_in6, socklen_t,
1515} ;
1616
1717use crate :: mm:: { UserConstPtr , UserPtr } ;
@@ -195,11 +195,54 @@ impl SocketAddrExt for UnixSocketAddr {
195195 }
196196}
197197
198+ // Linux sockaddr_vm is not public in linux_raw_sys crate.
199+ // its struct is like below:
200+ // struct sockaddr_vm {
201+ // __kernel_sa_family_t svm_family; /* Address family */
202+ // unsigned short svm_reserved1;
203+ // __u32 svm_port; /* Port # */
204+ // __u32 svm_cid; /* Context ID */
205+ // unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(__kernel_sa_family_t) - 2 * sizeof(__u32)];
206+ // };
207+ impl SocketAddrExt for VsocketAddr {
208+ fn read_from_user ( addr : UserConstPtr < sockaddr > , addrlen : socklen_t ) -> AxResult < Self > {
209+ if read_family ( addr, addrlen) ? as u32 != AF_VSOCK {
210+ return Err ( AxError :: Other ( LinuxError :: EAFNOSUPPORT ) ) ;
211+ }
212+ let addr_vm_ptr: UserConstPtr < u8 > = addr. cast :: < u8 > ( ) ;
213+ let addr_vm: & ' static [ u8 ] = addr_vm_ptr. get_as_slice ( addrlen as usize ) ?;
214+ // sockaddr_vm at least has 12 bytes for family, reserved1, port and cid.
215+ if addr_vm. len ( ) < 12 {
216+ return Err ( AxError :: InvalidInput ) ;
217+ }
218+ let port: u32 = u32:: from_le_bytes ( [ addr_vm[ 4 ] , addr_vm[ 5 ] , addr_vm[ 6 ] , addr_vm[ 7 ] ] ) ;
219+ let cid: u32 = u32:: from_le_bytes ( [ addr_vm[ 8 ] , addr_vm[ 9 ] , addr_vm[ 10 ] , addr_vm[ 11 ] ] ) ;
220+
221+ info ! ( "read_from_user: port={}, cid={}" , port, cid) ;
222+ Ok ( VsocketAddr { cid, port } )
223+ }
224+
225+ fn write_to_user ( & self , addr : UserPtr < sockaddr > , addrlen : & mut socklen_t ) -> AxResult < ( ) > {
226+ let mut buf: Vec < u8 > = Vec :: with_capacity ( 16 ) ; // size of sockaddr_vm
227+ buf. extend_from_slice ( & ( AF_VSOCK as u16 ) . to_le_bytes ( ) ) ; // family
228+ buf. extend_from_slice ( & 0u16 . to_le_bytes ( ) ) ; // reserved1
229+ buf. extend_from_slice ( & self . port . to_le_bytes ( ) ) ;
230+ buf. extend_from_slice ( & self . cid . to_le_bytes ( ) ) ;
231+ buf. extend_from_slice ( & [ 0u8 ; 4 ] ) ; // padding = 16 - 2 - 2 - 4 - 4 = 4
232+ fill_addr ( addr, addrlen, & buf)
233+ }
234+
235+ fn family ( & self ) -> u16 {
236+ AF_VSOCK as u16
237+ }
238+ }
239+
198240impl SocketAddrExt for SocketAddrEx {
199241 fn read_from_user ( addr : UserConstPtr < sockaddr > , addrlen : socklen_t ) -> AxResult < Self > {
200242 match read_family ( addr, addrlen) ? as u32 {
201243 AF_INET | AF_INET6 => SocketAddr :: read_from_user ( addr, addrlen) . map ( Self :: Ip ) ,
202244 AF_UNIX => UnixSocketAddr :: read_from_user ( addr, addrlen) . map ( Self :: Unix ) ,
245+ AF_VSOCK => VsocketAddr :: read_from_user ( addr, addrlen) . map ( Self :: Vsock ) ,
203246 _ => Err ( AxError :: Other ( LinuxError :: EAFNOSUPPORT ) ) ,
204247 }
205248 }
@@ -208,6 +251,7 @@ impl SocketAddrExt for SocketAddrEx {
208251 match self {
209252 SocketAddrEx :: Ip ( ip_addr) => ip_addr. write_to_user ( addr, addrlen) ,
210253 SocketAddrEx :: Unix ( unix_addr) => unix_addr. write_to_user ( addr, addrlen) ,
254+ SocketAddrEx :: Vsock ( vsock_addr) => vsock_addr. write_to_user ( addr, addrlen) ,
211255 }
212256 }
213257
0 commit comments