@@ -77,6 +77,7 @@ static int mctp_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
7777 const int hlen = MCTP_HEADER_MAXLEN + sizeof (struct mctp_hdr );
7878 int rc , addrlen = msg -> msg_namelen ;
7979 struct sock * sk = sock -> sk ;
80+ struct mctp_sock * msk = container_of (sk , struct mctp_sock , sk );
8081 struct mctp_skb_cb * cb ;
8182 struct mctp_route * rt ;
8283 struct sk_buff * skb ;
@@ -100,11 +101,6 @@ static int mctp_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
100101 if (addr -> smctp_network == MCTP_NET_ANY )
101102 addr -> smctp_network = mctp_default_net (sock_net (sk ));
102103
103- rt = mctp_route_lookup (sock_net (sk ), addr -> smctp_network ,
104- addr -> smctp_addr .s_addr );
105- if (!rt )
106- return - EHOSTUNREACH ;
107-
108104 skb = sock_alloc_send_skb (sk , hlen + 1 + len ,
109105 msg -> msg_flags & MSG_DONTWAIT , & rc );
110106 if (!skb )
@@ -116,26 +112,53 @@ static int mctp_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
116112 * (u8 * )skb_put (skb , 1 ) = addr -> smctp_type ;
117113
118114 rc = memcpy_from_msg ((void * )skb_put (skb , len ), msg , len );
119- if (rc < 0 ) {
120- kfree_skb (skb );
121- return rc ;
122- }
115+ if (rc < 0 )
116+ goto err_free ;
123117
124118 /* set up cb */
125119 cb = __mctp_cb (skb );
126120 cb -> net = addr -> smctp_network ;
127121
122+ /* direct addressing */
123+ if (msk -> addr_ext && addrlen >= sizeof (struct sockaddr_mctp_ext )) {
124+ DECLARE_SOCKADDR (struct sockaddr_mctp_ext * ,
125+ extaddr , msg -> msg_name );
126+
127+ if (extaddr -> smctp_halen > sizeof (cb -> haddr )) {
128+ rc = - EINVAL ;
129+ goto err_free ;
130+ }
131+
132+ cb -> ifindex = extaddr -> smctp_ifindex ;
133+ cb -> halen = extaddr -> smctp_halen ;
134+ memcpy (cb -> haddr , extaddr -> smctp_haddr , cb -> halen );
135+
136+ rt = NULL ;
137+ } else {
138+ rt = mctp_route_lookup (sock_net (sk ), addr -> smctp_network ,
139+ addr -> smctp_addr .s_addr );
140+ if (!rt ) {
141+ rc = - EHOSTUNREACH ;
142+ goto err_free ;
143+ }
144+ }
145+
128146 rc = mctp_local_output (sk , rt , skb , addr -> smctp_addr .s_addr ,
129147 addr -> smctp_tag );
130148
131149 return rc ? : len ;
150+
151+ err_free :
152+ kfree_skb (skb );
153+ return rc ;
132154}
133155
134156static int mctp_recvmsg (struct socket * sock , struct msghdr * msg , size_t len ,
135157 int flags )
136158{
137159 DECLARE_SOCKADDR (struct sockaddr_mctp * , addr , msg -> msg_name );
138160 struct sock * sk = sock -> sk ;
161+ struct mctp_sock * msk = container_of (sk , struct mctp_sock , sk );
139162 struct sk_buff * skb ;
140163 size_t msglen ;
141164 u8 type ;
@@ -181,6 +204,16 @@ static int mctp_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
181204 addr -> smctp_tag = hdr -> flags_seq_tag &
182205 (MCTP_HDR_TAG_MASK | MCTP_HDR_FLAG_TO );
183206 msg -> msg_namelen = sizeof (* addr );
207+
208+ if (msk -> addr_ext ) {
209+ DECLARE_SOCKADDR (struct sockaddr_mctp_ext * , ae ,
210+ msg -> msg_name );
211+ msg -> msg_namelen = sizeof (* ae );
212+ ae -> smctp_ifindex = cb -> ifindex ;
213+ ae -> smctp_halen = cb -> halen ;
214+ memset (ae -> smctp_haddr , 0x0 , sizeof (ae -> smctp_haddr ));
215+ memcpy (ae -> smctp_haddr , cb -> haddr , cb -> halen );
216+ }
184217 }
185218
186219 rc = len ;
@@ -196,12 +229,45 @@ static int mctp_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
196229static int mctp_setsockopt (struct socket * sock , int level , int optname ,
197230 sockptr_t optval , unsigned int optlen )
198231{
199- return - EINVAL ;
232+ struct mctp_sock * msk = container_of (sock -> sk , struct mctp_sock , sk );
233+ int val ;
234+
235+ if (level != SOL_MCTP )
236+ return - EINVAL ;
237+
238+ if (optname == MCTP_OPT_ADDR_EXT ) {
239+ if (optlen != sizeof (int ))
240+ return - EINVAL ;
241+ if (copy_from_sockptr (& val , optval , sizeof (int )))
242+ return - EFAULT ;
243+ msk -> addr_ext = val ;
244+ return 0 ;
245+ }
246+
247+ return - ENOPROTOOPT ;
200248}
201249
202250static int mctp_getsockopt (struct socket * sock , int level , int optname ,
203251 char __user * optval , int __user * optlen )
204252{
253+ struct mctp_sock * msk = container_of (sock -> sk , struct mctp_sock , sk );
254+ int len , val ;
255+
256+ if (level != SOL_MCTP )
257+ return - EINVAL ;
258+
259+ if (get_user (len , optlen ))
260+ return - EFAULT ;
261+
262+ if (optname == MCTP_OPT_ADDR_EXT ) {
263+ if (len != sizeof (int ))
264+ return - EINVAL ;
265+ val = !!msk -> addr_ext ;
266+ if (copy_to_user (optval , & val , len ))
267+ return - EFAULT ;
268+ return 0 ;
269+ }
270+
205271 return - EINVAL ;
206272}
207273
0 commit comments