xref: /openbmc/qemu/net/dgram.c (revision 25657fc6)
1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  * Copyright (c) 2022 Red Hat, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #include "qemu/osdep.h"
27 
28 #include "net/net.h"
29 #include "clients.h"
30 #include "monitor/monitor.h"
31 #include "qapi/error.h"
32 #include "qemu/error-report.h"
33 #include "qemu/option.h"
34 #include "qemu/sockets.h"
35 #include "qemu/iov.h"
36 #include "qemu/main-loop.h"
37 #include "qemu/cutils.h"
38 
39 typedef struct NetDgramState {
40     NetClientState nc;
41     int fd;
42     SocketReadState rs;
43     bool read_poll;               /* waiting to receive data? */
44     bool write_poll;              /* waiting to transmit data? */
45     /* contains destination iff connectionless */
46     struct sockaddr *dest_addr;
47     socklen_t dest_len;
48 } NetDgramState;
49 
50 static void net_dgram_send(void *opaque);
51 static void net_dgram_writable(void *opaque);
52 
net_dgram_update_fd_handler(NetDgramState * s)53 static void net_dgram_update_fd_handler(NetDgramState *s)
54 {
55     qemu_set_fd_handler(s->fd,
56                         s->read_poll ? net_dgram_send : NULL,
57                         s->write_poll ? net_dgram_writable : NULL,
58                         s);
59 }
60 
net_dgram_read_poll(NetDgramState * s,bool enable)61 static void net_dgram_read_poll(NetDgramState *s, bool enable)
62 {
63     s->read_poll = enable;
64     net_dgram_update_fd_handler(s);
65 }
66 
net_dgram_write_poll(NetDgramState * s,bool enable)67 static void net_dgram_write_poll(NetDgramState *s, bool enable)
68 {
69     s->write_poll = enable;
70     net_dgram_update_fd_handler(s);
71 }
72 
net_dgram_writable(void * opaque)73 static void net_dgram_writable(void *opaque)
74 {
75     NetDgramState *s = opaque;
76 
77     net_dgram_write_poll(s, false);
78 
79     qemu_flush_queued_packets(&s->nc);
80 }
81 
net_dgram_receive(NetClientState * nc,const uint8_t * buf,size_t size)82 static ssize_t net_dgram_receive(NetClientState *nc,
83                                  const uint8_t *buf, size_t size)
84 {
85     NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
86     ssize_t ret;
87 
88     do {
89         if (s->dest_addr) {
90             ret = sendto(s->fd, buf, size, 0, s->dest_addr, s->dest_len);
91         } else {
92             ret = send(s->fd, buf, size, 0);
93         }
94     } while (ret == -1 && errno == EINTR);
95 
96     if (ret == -1 && errno == EAGAIN) {
97         net_dgram_write_poll(s, true);
98         return 0;
99     }
100     return ret;
101 }
102 
net_dgram_send_completed(NetClientState * nc,ssize_t len)103 static void net_dgram_send_completed(NetClientState *nc, ssize_t len)
104 {
105     NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
106 
107     if (!s->read_poll) {
108         net_dgram_read_poll(s, true);
109     }
110 }
111 
net_dgram_rs_finalize(SocketReadState * rs)112 static void net_dgram_rs_finalize(SocketReadState *rs)
113 {
114     NetDgramState *s = container_of(rs, NetDgramState, rs);
115 
116     if (qemu_send_packet_async(&s->nc, rs->buf,
117                                rs->packet_len,
118                                net_dgram_send_completed) == 0) {
119         net_dgram_read_poll(s, false);
120     }
121 }
122 
net_dgram_send(void * opaque)123 static void net_dgram_send(void *opaque)
124 {
125     NetDgramState *s = opaque;
126     int size;
127 
128     size = recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0);
129     if (size < 0) {
130         return;
131     }
132     if (size == 0) {
133         /* end of connection */
134         net_dgram_read_poll(s, false);
135         net_dgram_write_poll(s, false);
136         return;
137     }
138     if (qemu_send_packet_async(&s->nc, s->rs.buf, size,
139                                net_dgram_send_completed) == 0) {
140         net_dgram_read_poll(s, false);
141     }
142 }
143 
net_dgram_mcast_create(struct sockaddr_in * mcastaddr,struct in_addr * localaddr,Error ** errp)144 static int net_dgram_mcast_create(struct sockaddr_in *mcastaddr,
145                                   struct in_addr *localaddr,
146                                   Error **errp)
147 {
148     struct ip_mreq imr;
149     int fd;
150     int val, ret;
151 #ifdef __OpenBSD__
152     unsigned char loop;
153 #else
154     int loop;
155 #endif
156 
157     if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
158         error_setg(errp, "specified mcastaddr %s (0x%08x) "
159                    "does not contain a multicast address",
160                    inet_ntoa(mcastaddr->sin_addr),
161                    (int)ntohl(mcastaddr->sin_addr.s_addr));
162         return -1;
163     }
164 
165     fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
166     if (fd < 0) {
167         error_setg_errno(errp, errno, "can't create datagram socket");
168         return -1;
169     }
170 
171     /*
172      * Allow multiple sockets to bind the same multicast ip and port by setting
173      * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
174      * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
175      * only on posix systems.
176      */
177     val = 1;
178     ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
179     if (ret < 0) {
180         error_setg_errno(errp, errno, "can't set socket option SO_REUSEADDR");
181         goto fail;
182     }
183 
184     ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
185     if (ret < 0) {
186         error_setg_errno(errp, errno, "can't bind ip=%s to socket",
187                          inet_ntoa(mcastaddr->sin_addr));
188         goto fail;
189     }
190 
191     /* Add host to multicast group */
192     imr.imr_multiaddr = mcastaddr->sin_addr;
193     if (localaddr) {
194         imr.imr_interface = *localaddr;
195     } else {
196         imr.imr_interface.s_addr = htonl(INADDR_ANY);
197     }
198 
199     ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
200                      &imr, sizeof(struct ip_mreq));
201     if (ret < 0) {
202         error_setg_errno(errp, errno,
203                          "can't add socket to multicast group %s",
204                          inet_ntoa(imr.imr_multiaddr));
205         goto fail;
206     }
207 
208     /* Force mcast msgs to loopback (eg. several QEMUs in same host */
209     loop = 1;
210     ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
211                      &loop, sizeof(loop));
212     if (ret < 0) {
213         error_setg_errno(errp, errno,
214                          "can't force multicast message to loopback");
215         goto fail;
216     }
217 
218     /* If a bind address is given, only send packets from that address */
219     if (localaddr != NULL) {
220         ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
221                          localaddr, sizeof(*localaddr));
222         if (ret < 0) {
223             error_setg_errno(errp, errno,
224                              "can't set the default network send interface");
225             goto fail;
226         }
227     }
228 
229     qemu_socket_set_nonblock(fd);
230     return fd;
231 fail:
232     if (fd >= 0) {
233         close(fd);
234     }
235     return -1;
236 }
237 
net_dgram_cleanup(NetClientState * nc)238 static void net_dgram_cleanup(NetClientState *nc)
239 {
240     NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
241     if (s->fd != -1) {
242         net_dgram_read_poll(s, false);
243         net_dgram_write_poll(s, false);
244         close(s->fd);
245         s->fd = -1;
246     }
247     g_free(s->dest_addr);
248     s->dest_addr = NULL;
249     s->dest_len = 0;
250 }
251 
252 static NetClientInfo net_dgram_socket_info = {
253     .type = NET_CLIENT_DRIVER_DGRAM,
254     .size = sizeof(NetDgramState),
255     .receive = net_dgram_receive,
256     .cleanup = net_dgram_cleanup,
257 };
258 
net_dgram_fd_init(NetClientState * peer,const char * model,const char * name,int fd,Error ** errp)259 static NetDgramState *net_dgram_fd_init(NetClientState *peer,
260                                         const char *model,
261                                         const char *name,
262                                         int fd,
263                                         Error **errp)
264 {
265     NetClientState *nc;
266     NetDgramState *s;
267 
268     nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
269 
270     s = DO_UPCAST(NetDgramState, nc, nc);
271 
272     s->fd = fd;
273     net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false);
274     net_dgram_read_poll(s, true);
275 
276     return s;
277 }
278 
net_dgram_mcast_init(NetClientState * peer,const char * model,const char * name,SocketAddress * remote,SocketAddress * local,Error ** errp)279 static int net_dgram_mcast_init(NetClientState *peer,
280                                 const char *model,
281                                 const char *name,
282                                 SocketAddress *remote,
283                                 SocketAddress *local,
284                                 Error **errp)
285 {
286     NetDgramState *s;
287     int fd, ret;
288     struct sockaddr_in *saddr;
289 
290     if (remote->type != SOCKET_ADDRESS_TYPE_INET) {
291         error_setg(errp, "multicast only support inet type");
292         return -1;
293     }
294 
295     saddr = g_new(struct sockaddr_in, 1);
296     if (convert_host_port(saddr, remote->u.inet.host, remote->u.inet.port,
297                           errp) < 0) {
298         g_free(saddr);
299         return -1;
300     }
301 
302     if (!local) {
303         fd = net_dgram_mcast_create(saddr, NULL, errp);
304         if (fd < 0) {
305             g_free(saddr);
306             return -1;
307         }
308     } else {
309         switch (local->type) {
310         case SOCKET_ADDRESS_TYPE_INET: {
311             struct in_addr localaddr;
312 
313             if (inet_aton(local->u.inet.host, &localaddr) == 0) {
314                 g_free(saddr);
315                 error_setg(errp, "localaddr '%s' is not a valid IPv4 address",
316                            local->u.inet.host);
317                 return -1;
318             }
319 
320             fd = net_dgram_mcast_create(saddr, &localaddr, errp);
321             if (fd < 0) {
322                 g_free(saddr);
323                 return -1;
324             }
325             break;
326         }
327         case SOCKET_ADDRESS_TYPE_FD: {
328             int newfd;
329 
330             fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
331             if (fd == -1) {
332                 g_free(saddr);
333                 return -1;
334             }
335             ret = qemu_socket_try_set_nonblock(fd);
336             if (ret < 0) {
337                 g_free(saddr);
338                 error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
339                                  name, fd);
340                 return -1;
341             }
342 
343             /*
344              * fd passed: multicast: "learn" dest_addr address from bound
345              * address and save it. Because this may be "shared" socket from a
346              * "master" process, datagrams would be recv() by ONLY ONE process:
347              * we must "clone" this dgram socket --jjo
348              */
349 
350             saddr = g_new(struct sockaddr_in, 1);
351 
352             if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port,
353                                   errp) < 0) {
354                 g_free(saddr);
355                 close(fd);
356                 return -1;
357             }
358 
359             /* must be bound */
360             if (saddr->sin_addr.s_addr == 0) {
361                 error_setg(errp, "can't setup multicast destination address");
362                 g_free(saddr);
363                 close(fd);
364                 return -1;
365             }
366             /* clone dgram socket */
367             newfd = net_dgram_mcast_create(saddr, NULL, errp);
368             if (newfd < 0) {
369                 g_free(saddr);
370                 close(fd);
371                 return -1;
372             }
373             /* clone newfd to fd, close newfd */
374             dup2(newfd, fd);
375             close(newfd);
376             break;
377         }
378         default:
379             g_free(saddr);
380             error_setg(errp, "only support inet or fd type for local");
381             return -1;
382         }
383     }
384 
385     s = net_dgram_fd_init(peer, model, name, fd, errp);
386     if (!s) {
387         g_free(saddr);
388         return -1;
389     }
390 
391     g_assert(s->dest_addr == NULL);
392     s->dest_addr = (struct sockaddr *)saddr;
393     s->dest_len = sizeof(*saddr);
394 
395     if (!local) {
396         qemu_set_info_str(&s->nc, "mcast=%s:%d",
397                           inet_ntoa(saddr->sin_addr),
398                           ntohs(saddr->sin_port));
399     } else {
400         switch (local->type) {
401         case SOCKET_ADDRESS_TYPE_INET:
402             qemu_set_info_str(&s->nc, "mcast=%s:%d",
403                               inet_ntoa(saddr->sin_addr),
404                               ntohs(saddr->sin_port));
405             break;
406         case SOCKET_ADDRESS_TYPE_FD:
407             qemu_set_info_str(&s->nc, "fd=%d (cloned mcast=%s:%d)",
408                               fd, inet_ntoa(saddr->sin_addr),
409                               ntohs(saddr->sin_port));
410             break;
411         default:
412             g_assert_not_reached();
413         }
414     }
415 
416     return 0;
417 
418 }
419 
420 
net_init_dgram(const Netdev * netdev,const char * name,NetClientState * peer,Error ** errp)421 int net_init_dgram(const Netdev *netdev, const char *name,
422                    NetClientState *peer, Error **errp)
423 {
424     NetDgramState *s;
425     int fd, ret;
426     SocketAddress *remote, *local;
427     struct sockaddr *dest_addr;
428     struct sockaddr_in laddr_in, raddr_in;
429     struct sockaddr_un laddr_un, raddr_un;
430     socklen_t dest_len;
431 
432     assert(netdev->type == NET_CLIENT_DRIVER_DGRAM);
433 
434     remote = netdev->u.dgram.remote;
435     local = netdev->u.dgram.local;
436 
437     /* detect multicast address */
438     if (remote && remote->type == SOCKET_ADDRESS_TYPE_INET) {
439         struct sockaddr_in mcastaddr;
440 
441         if (convert_host_port(&mcastaddr, remote->u.inet.host,
442                               remote->u.inet.port, errp) < 0) {
443             return -1;
444         }
445 
446         if (IN_MULTICAST(ntohl(mcastaddr.sin_addr.s_addr))) {
447             return net_dgram_mcast_init(peer, "dram", name, remote, local,
448                                            errp);
449         }
450     }
451 
452     /* unicast address */
453     if (!local) {
454         error_setg(errp, "dgram requires local= parameter");
455         return -1;
456     }
457 
458     if (remote) {
459         if (local->type == SOCKET_ADDRESS_TYPE_FD) {
460             error_setg(errp, "don't set remote with local.fd");
461             return -1;
462         }
463         if (remote->type != local->type) {
464             error_setg(errp, "remote and local types must be the same");
465             return -1;
466         }
467     } else {
468         if (local->type != SOCKET_ADDRESS_TYPE_FD) {
469             error_setg(errp,
470                        "type=inet or type=unix requires remote parameter");
471             return -1;
472         }
473     }
474 
475     switch (local->type) {
476     case SOCKET_ADDRESS_TYPE_INET:
477         if (convert_host_port(&laddr_in, local->u.inet.host, local->u.inet.port,
478                               errp) < 0) {
479             return -1;
480         }
481 
482         if (convert_host_port(&raddr_in, remote->u.inet.host,
483                               remote->u.inet.port, errp) < 0) {
484             return -1;
485         }
486 
487         fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
488         if (fd < 0) {
489             error_setg_errno(errp, errno, "can't create datagram socket");
490             return -1;
491         }
492 
493         ret = socket_set_fast_reuse(fd);
494         if (ret < 0) {
495             error_setg_errno(errp, errno,
496                              "can't set socket option SO_REUSEADDR");
497             close(fd);
498             return -1;
499         }
500         ret = bind(fd, (struct sockaddr *)&laddr_in, sizeof(laddr_in));
501         if (ret < 0) {
502             error_setg_errno(errp, errno, "can't bind ip=%s to socket",
503                              inet_ntoa(laddr_in.sin_addr));
504             close(fd);
505             return -1;
506         }
507         qemu_socket_set_nonblock(fd);
508 
509         dest_len = sizeof(raddr_in);
510         dest_addr = g_malloc(dest_len);
511         memcpy(dest_addr, &raddr_in, dest_len);
512         break;
513     case SOCKET_ADDRESS_TYPE_UNIX:
514         ret = unlink(local->u.q_unix.path);
515         if (ret < 0 && errno != ENOENT) {
516             error_setg_errno(errp, errno, "failed to unlink socket %s",
517                              local->u.q_unix.path);
518             return -1;
519         }
520 
521         laddr_un.sun_family = PF_UNIX;
522         ret = snprintf(laddr_un.sun_path, sizeof(laddr_un.sun_path), "%s",
523                        local->u.q_unix.path);
524         if (ret < 0 || ret >= sizeof(laddr_un.sun_path)) {
525             error_setg(errp, "UNIX socket path '%s' is too long",
526                        local->u.q_unix.path);
527             error_append_hint(errp, "Path must be less than %zu bytes\n",
528                               sizeof(laddr_un.sun_path));
529         }
530 
531         raddr_un.sun_family = PF_UNIX;
532         ret = snprintf(raddr_un.sun_path, sizeof(raddr_un.sun_path), "%s",
533                        remote->u.q_unix.path);
534         if (ret < 0 || ret >= sizeof(raddr_un.sun_path)) {
535             error_setg(errp, "UNIX socket path '%s' is too long",
536                        remote->u.q_unix.path);
537             error_append_hint(errp, "Path must be less than %zu bytes\n",
538                               sizeof(raddr_un.sun_path));
539         }
540 
541         fd = qemu_socket(PF_UNIX, SOCK_DGRAM, 0);
542         if (fd < 0) {
543             error_setg_errno(errp, errno, "can't create datagram socket");
544             return -1;
545         }
546 
547         ret = bind(fd, (struct sockaddr *)&laddr_un, sizeof(laddr_un));
548         if (ret < 0) {
549             error_setg_errno(errp, errno, "can't bind unix=%s to socket",
550                              laddr_un.sun_path);
551             close(fd);
552             return -1;
553         }
554         qemu_socket_set_nonblock(fd);
555 
556         dest_len = sizeof(raddr_un);
557         dest_addr = g_malloc(dest_len);
558         memcpy(dest_addr, &raddr_un, dest_len);
559         break;
560     case SOCKET_ADDRESS_TYPE_FD:
561         fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
562         if (fd == -1) {
563             return -1;
564         }
565         ret = qemu_socket_try_set_nonblock(fd);
566         if (ret < 0) {
567             error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
568                              name, fd);
569             return -1;
570         }
571         dest_addr = NULL;
572         dest_len = 0;
573         break;
574     default:
575         error_setg(errp, "only support inet or fd type for local");
576         return -1;
577     }
578 
579     s = net_dgram_fd_init(peer, "dgram", name, fd, errp);
580     if (!s) {
581         return -1;
582     }
583 
584     if (remote) {
585         g_assert(s->dest_addr == NULL);
586         s->dest_addr = dest_addr;
587         s->dest_len = dest_len;
588     }
589 
590     switch (local->type) {
591     case SOCKET_ADDRESS_TYPE_INET:
592         qemu_set_info_str(&s->nc, "udp=%s:%d/%s:%d",
593                           inet_ntoa(laddr_in.sin_addr),
594                           ntohs(laddr_in.sin_port),
595                           inet_ntoa(raddr_in.sin_addr),
596                           ntohs(raddr_in.sin_port));
597         break;
598     case SOCKET_ADDRESS_TYPE_UNIX:
599         qemu_set_info_str(&s->nc, "udp=%s:%s",
600                           laddr_un.sun_path, raddr_un.sun_path);
601         break;
602     case SOCKET_ADDRESS_TYPE_FD: {
603         SocketAddress *sa;
604         SocketAddressType sa_type;
605 
606         sa = socket_local_address(fd, errp);
607         if (sa) {
608             sa_type = sa->type;
609             qapi_free_SocketAddress(sa);
610 
611             qemu_set_info_str(&s->nc, "fd=%d %s", fd,
612                               SocketAddressType_str(sa_type));
613         } else {
614             qemu_set_info_str(&s->nc, "fd=%d", fd);
615         }
616         break;
617     }
618     default:
619         g_assert_not_reached();
620     }
621 
622     return 0;
623 }
624