diff mbox series

net/slirp: Use newer slirp_*_hostxfwd API

Message ID 20210925214820.18078-1-nicholas@ngai.me (mailing list archive)
State New, archived
Headers show
Series net/slirp: Use newer slirp_*_hostxfwd API | expand

Commit Message

Nicholas Ngai Sept. 25, 2021, 9:48 p.m. UTC
libslirp provides a newer slirp_*_hostxfwd API meant for
address-agnostic forwarding instead of the is_udp parameter which is
limited to just TCP/UDP.

Signed-off-by: Nicholas Ngai <nicholas@ngai.me>
---
 net/slirp.c | 64 +++++++++++++++++++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 22 deletions(-)

Comments

Nicholas Ngai Sept. 25, 2021, 11:22 p.m. UTC | #1
Hi,

Sorry for the duplicate email. The cc’s for the maintainers on the email 
didn’t go through the first time.

Nicholas Ngai

On 9/25/21 2:48 PM, Nicholas Ngai wrote:
> libslirp provides a newer slirp_*_hostxfwd API meant for
> address-agnostic forwarding instead of the is_udp parameter which is
> limited to just TCP/UDP.
>
> Signed-off-by: Nicholas Ngai <nicholas@ngai.me>
> ---
>   net/slirp.c | 64 +++++++++++++++++++++++++++++++++++------------------
>   1 file changed, 42 insertions(+), 22 deletions(-)
>
> diff --git a/net/slirp.c b/net/slirp.c
> index ad3a838e0b..49ae01a2f0 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -643,12 +643,17 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
>   
>   void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>   {
> -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
> -    int host_port;
> +    struct sockaddr_in host_addr = {
> +        .sin_family = AF_INET,
> +        .sin_addr = {
> +            .s_addr = INADDR_ANY,
> +        },
> +    };
> +    int port;
> +    int flags = 0;
>       char buf[256];
>       const char *src_str, *p;
>       SlirpState *s;
> -    int is_udp = 0;
>       int err;
>       const char *arg1 = qdict_get_str(qdict, "arg1");
>       const char *arg2 = qdict_get_try_str(qdict, "arg2");
> @@ -670,9 +675,9 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>       }
>   
>       if (!strcmp(buf, "tcp") || buf[0] == '\0') {
> -        is_udp = 0;
> +        /* Do nothing; already TCP. */
>       } else if (!strcmp(buf, "udp")) {
> -        is_udp = 1;
> +        flags |= SLIRP_HOSTFWD_UDP;
>       } else {
>           goto fail_syntax;
>       }
> @@ -680,15 +685,17 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>       if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
>           goto fail_syntax;
>       }
> -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
> +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
>           goto fail_syntax;
>       }
>   
> -    if (qemu_strtoi(p, NULL, 10, &host_port)) {
> +    if (qemu_strtoi(p, NULL, 10, &port)) {
>           goto fail_syntax;
>       }
> +    host_addr.sin_port = htons(port);
>   
> -    err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port);
> +    err = slirp_remove_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
> +            sizeof(host_addr), flags);
>   
>       monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
>                      err ? "not found" : "removed");
> @@ -700,12 +707,22 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>   
>   static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>   {
> -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
> -    struct in_addr guest_addr = { .s_addr = 0 };
> -    int host_port, guest_port;
> +    struct sockaddr_in host_addr = {
> +        .sin_family = AF_INET,
> +        .sin_addr = {
> +            .s_addr = INADDR_ANY,
> +        },
> +    };
> +    struct sockaddr_in guest_addr = {
> +        .sin_family = AF_INET,
> +        .sin_addr = {
> +            .s_addr = 0,
> +        },
> +    };
> +    int flags = 0;
> +    int port;
>       const char *p;
>       char buf[256];
> -    int is_udp;
>       char *end;
>       const char *fail_reason = "Unknown reason";
>   
> @@ -715,9 +732,9 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>           goto fail_syntax;
>       }
>       if (!strcmp(buf, "tcp") || buf[0] == '\0') {
> -        is_udp = 0;
> +        /* Do nothing; already TCP. */
>       } else if (!strcmp(buf, "udp")) {
> -        is_udp = 1;
> +        flags |= SLIRP_HOSTFWD_UDP;
>       } else {
>           fail_reason = "Bad protocol name";
>           goto fail_syntax;
> @@ -727,7 +744,7 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>           fail_reason = "Missing : separator";
>           goto fail_syntax;
>       }
> -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
> +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
>           fail_reason = "Bad host address";
>           goto fail_syntax;
>       }
> @@ -736,29 +753,32 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>           fail_reason = "Bad host port separator";
>           goto fail_syntax;
>       }
> -    host_port = strtol(buf, &end, 0);
> -    if (*end != '\0' || host_port < 0 || host_port > 65535) {
> +    port = strtol(buf, &end, 0);
> +    if (*end != '\0' || port < 0 || port > 65535) {
>           fail_reason = "Bad host port";
>           goto fail_syntax;
>       }
> +    host_addr.sin_port = htons(port);
>   
>       if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
>           fail_reason = "Missing guest address";
>           goto fail_syntax;
>       }
> -    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
> +    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr.sin_addr)) {
>           fail_reason = "Bad guest address";
>           goto fail_syntax;
>       }
>   
> -    guest_port = strtol(p, &end, 0);
> -    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
> +    port = strtol(p, &end, 0);
> +    if (*end != '\0' || port < 1 || port > 65535) {
>           fail_reason = "Bad guest port";
>           goto fail_syntax;
>       }
> +    guest_addr.sin_port = htons(port);
>   
> -    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
> -                          guest_port) < 0) {
> +    if (slirp_add_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
> +                           sizeof(host_addr), (struct sockaddr *) &guest_addr,
> +                           sizeof(guest_addr), flags) < 0) {
>           error_setg(errp, "Could not set up host forwarding rule '%s'",
>                      redir_str);
>           return -1;
Samuel Thibault Oct. 5, 2021, 11:56 p.m. UTC | #2
Nicholas Ngai, le sam. 25 sept. 2021 16:22:02 -0700, a ecrit:
> Sorry for the duplicate email. The cc’s for the maintainers on the email
> didn’t go through the first time.
> 
> Nicholas Ngai
> 
> On 9/25/21 2:48 PM, Nicholas Ngai wrote:
> > libslirp provides a newer slirp_*_hostxfwd API meant for
> > address-agnostic forwarding instead of the is_udp parameter which is
> > limited to just TCP/UDP.
> > 
> > Signed-off-by: Nicholas Ngai <nicholas@ngai.me>

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

> > ---
> >   net/slirp.c | 64 +++++++++++++++++++++++++++++++++++------------------
> >   1 file changed, 42 insertions(+), 22 deletions(-)
> > 
> > diff --git a/net/slirp.c b/net/slirp.c
> > index ad3a838e0b..49ae01a2f0 100644
> > --- a/net/slirp.c
> > +++ b/net/slirp.c
> > @@ -643,12 +643,17 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
> >   void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
> >   {
> > -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
> > -    int host_port;
> > +    struct sockaddr_in host_addr = {
> > +        .sin_family = AF_INET,
> > +        .sin_addr = {
> > +            .s_addr = INADDR_ANY,
> > +        },
> > +    };
> > +    int port;
> > +    int flags = 0;
> >       char buf[256];
> >       const char *src_str, *p;
> >       SlirpState *s;
> > -    int is_udp = 0;
> >       int err;
> >       const char *arg1 = qdict_get_str(qdict, "arg1");
> >       const char *arg2 = qdict_get_try_str(qdict, "arg2");
> > @@ -670,9 +675,9 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
> >       }
> >       if (!strcmp(buf, "tcp") || buf[0] == '\0') {
> > -        is_udp = 0;
> > +        /* Do nothing; already TCP. */
> >       } else if (!strcmp(buf, "udp")) {
> > -        is_udp = 1;
> > +        flags |= SLIRP_HOSTFWD_UDP;
> >       } else {
> >           goto fail_syntax;
> >       }
> > @@ -680,15 +685,17 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
> >       if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> >           goto fail_syntax;
> >       }
> > -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
> > +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
> >           goto fail_syntax;
> >       }
> > -    if (qemu_strtoi(p, NULL, 10, &host_port)) {
> > +    if (qemu_strtoi(p, NULL, 10, &port)) {
> >           goto fail_syntax;
> >       }
> > +    host_addr.sin_port = htons(port);
> > -    err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port);
> > +    err = slirp_remove_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
> > +            sizeof(host_addr), flags);
> >       monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
> >                      err ? "not found" : "removed");
> > @@ -700,12 +707,22 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
> >   static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
> >   {
> > -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
> > -    struct in_addr guest_addr = { .s_addr = 0 };
> > -    int host_port, guest_port;
> > +    struct sockaddr_in host_addr = {
> > +        .sin_family = AF_INET,
> > +        .sin_addr = {
> > +            .s_addr = INADDR_ANY,
> > +        },
> > +    };
> > +    struct sockaddr_in guest_addr = {
> > +        .sin_family = AF_INET,
> > +        .sin_addr = {
> > +            .s_addr = 0,
> > +        },
> > +    };
> > +    int flags = 0;
> > +    int port;
> >       const char *p;
> >       char buf[256];
> > -    int is_udp;
> >       char *end;
> >       const char *fail_reason = "Unknown reason";
> > @@ -715,9 +732,9 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
> >           goto fail_syntax;
> >       }
> >       if (!strcmp(buf, "tcp") || buf[0] == '\0') {
> > -        is_udp = 0;
> > +        /* Do nothing; already TCP. */
> >       } else if (!strcmp(buf, "udp")) {
> > -        is_udp = 1;
> > +        flags |= SLIRP_HOSTFWD_UDP;
> >       } else {
> >           fail_reason = "Bad protocol name";
> >           goto fail_syntax;
> > @@ -727,7 +744,7 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
> >           fail_reason = "Missing : separator";
> >           goto fail_syntax;
> >       }
> > -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
> > +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
> >           fail_reason = "Bad host address";
> >           goto fail_syntax;
> >       }
> > @@ -736,29 +753,32 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
> >           fail_reason = "Bad host port separator";
> >           goto fail_syntax;
> >       }
> > -    host_port = strtol(buf, &end, 0);
> > -    if (*end != '\0' || host_port < 0 || host_port > 65535) {
> > +    port = strtol(buf, &end, 0);
> > +    if (*end != '\0' || port < 0 || port > 65535) {
> >           fail_reason = "Bad host port";
> >           goto fail_syntax;
> >       }
> > +    host_addr.sin_port = htons(port);
> >       if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
> >           fail_reason = "Missing guest address";
> >           goto fail_syntax;
> >       }
> > -    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
> > +    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr.sin_addr)) {
> >           fail_reason = "Bad guest address";
> >           goto fail_syntax;
> >       }
> > -    guest_port = strtol(p, &end, 0);
> > -    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
> > +    port = strtol(p, &end, 0);
> > +    if (*end != '\0' || port < 1 || port > 65535) {
> >           fail_reason = "Bad guest port";
> >           goto fail_syntax;
> >       }
> > +    guest_addr.sin_port = htons(port);
> > -    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
> > -                          guest_port) < 0) {
> > +    if (slirp_add_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
> > +                           sizeof(host_addr), (struct sockaddr *) &guest_addr,
> > +                           sizeof(guest_addr), flags) < 0) {
> >           error_setg(errp, "Could not set up host forwarding rule '%s'",
> >                      redir_str);
> >           return -1;
>
Nicholas Ngai March 23, 2022, 1:58 a.m. UTC | #3
Hi,

Pinging this. It’s a bit old, though the patch still applies cleanly to 
master as far as I can tell.

Link to patchew is 
https://patchew.org/QEMU/20210925214820.18078-1-nicholas@ngai.me/.

I’d love to get https://gitlab.com/qemu-project/qemu/-/issues/347 
addressed once libslirp makes a release with added Unix-to-TCP support 
in the hostxfwd API, but this patch is a requirement for that first.

Thanks!

Nicholas Ngai

On 10/5/21 4:56 PM, Samuel Thibault wrote:
> Nicholas Ngai, le sam. 25 sept. 2021 16:22:02 -0700, a ecrit:
>> Sorry for the duplicate email. The cc’s for the maintainers on the email
>> didn’t go through the first time.
>>
>> Nicholas Ngai
>>
>> On 9/25/21 2:48 PM, Nicholas Ngai wrote:
>>> libslirp provides a newer slirp_*_hostxfwd API meant for
>>> address-agnostic forwarding instead of the is_udp parameter which is
>>> limited to just TCP/UDP.
>>>
>>> Signed-off-by: Nicholas Ngai <nicholas@ngai.me>
> Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
>
>>> ---
>>>    net/slirp.c | 64 +++++++++++++++++++++++++++++++++++------------------
>>>    1 file changed, 42 insertions(+), 22 deletions(-)
>>>
>>> diff --git a/net/slirp.c b/net/slirp.c
>>> index ad3a838e0b..49ae01a2f0 100644
>>> --- a/net/slirp.c
>>> +++ b/net/slirp.c
>>> @@ -643,12 +643,17 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
>>>    void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>>>    {
>>> -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
>>> -    int host_port;
>>> +    struct sockaddr_in host_addr = {
>>> +        .sin_family = AF_INET,
>>> +        .sin_addr = {
>>> +            .s_addr = INADDR_ANY,
>>> +        },
>>> +    };
>>> +    int port;
>>> +    int flags = 0;
>>>        char buf[256];
>>>        const char *src_str, *p;
>>>        SlirpState *s;
>>> -    int is_udp = 0;
>>>        int err;
>>>        const char *arg1 = qdict_get_str(qdict, "arg1");
>>>        const char *arg2 = qdict_get_try_str(qdict, "arg2");
>>> @@ -670,9 +675,9 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>>>        }
>>>        if (!strcmp(buf, "tcp") || buf[0] == '\0') {
>>> -        is_udp = 0;
>>> +        /* Do nothing; already TCP. */
>>>        } else if (!strcmp(buf, "udp")) {
>>> -        is_udp = 1;
>>> +        flags |= SLIRP_HOSTFWD_UDP;
>>>        } else {
>>>            goto fail_syntax;
>>>        }
>>> @@ -680,15 +685,17 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>>>        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
>>>            goto fail_syntax;
>>>        }
>>> -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
>>> +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
>>>            goto fail_syntax;
>>>        }
>>> -    if (qemu_strtoi(p, NULL, 10, &host_port)) {
>>> +    if (qemu_strtoi(p, NULL, 10, &port)) {
>>>            goto fail_syntax;
>>>        }
>>> +    host_addr.sin_port = htons(port);
>>> -    err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port);
>>> +    err = slirp_remove_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
>>> +            sizeof(host_addr), flags);
>>>        monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
>>>                       err ? "not found" : "removed");
>>> @@ -700,12 +707,22 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
>>>    static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>>>    {
>>> -    struct in_addr host_addr = { .s_addr = INADDR_ANY };
>>> -    struct in_addr guest_addr = { .s_addr = 0 };
>>> -    int host_port, guest_port;
>>> +    struct sockaddr_in host_addr = {
>>> +        .sin_family = AF_INET,
>>> +        .sin_addr = {
>>> +            .s_addr = INADDR_ANY,
>>> +        },
>>> +    };
>>> +    struct sockaddr_in guest_addr = {
>>> +        .sin_family = AF_INET,
>>> +        .sin_addr = {
>>> +            .s_addr = 0,
>>> +        },
>>> +    };
>>> +    int flags = 0;
>>> +    int port;
>>>        const char *p;
>>>        char buf[256];
>>> -    int is_udp;
>>>        char *end;
>>>        const char *fail_reason = "Unknown reason";
>>> @@ -715,9 +732,9 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>>>            goto fail_syntax;
>>>        }
>>>        if (!strcmp(buf, "tcp") || buf[0] == '\0') {
>>> -        is_udp = 0;
>>> +        /* Do nothing; already TCP. */
>>>        } else if (!strcmp(buf, "udp")) {
>>> -        is_udp = 1;
>>> +        flags |= SLIRP_HOSTFWD_UDP;
>>>        } else {
>>>            fail_reason = "Bad protocol name";
>>>            goto fail_syntax;
>>> @@ -727,7 +744,7 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>>>            fail_reason = "Missing : separator";
>>>            goto fail_syntax;
>>>        }
>>> -    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
>>> +    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
>>>            fail_reason = "Bad host address";
>>>            goto fail_syntax;
>>>        }
>>> @@ -736,29 +753,32 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>>>            fail_reason = "Bad host port separator";
>>>            goto fail_syntax;
>>>        }
>>> -    host_port = strtol(buf, &end, 0);
>>> -    if (*end != '\0' || host_port < 0 || host_port > 65535) {
>>> +    port = strtol(buf, &end, 0);
>>> +    if (*end != '\0' || port < 0 || port > 65535) {
>>>            fail_reason = "Bad host port";
>>>            goto fail_syntax;
>>>        }
>>> +    host_addr.sin_port = htons(port);
>>>        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
>>>            fail_reason = "Missing guest address";
>>>            goto fail_syntax;
>>>        }
>>> -    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
>>> +    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr.sin_addr)) {
>>>            fail_reason = "Bad guest address";
>>>            goto fail_syntax;
>>>        }
>>> -    guest_port = strtol(p, &end, 0);
>>> -    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
>>> +    port = strtol(p, &end, 0);
>>> +    if (*end != '\0' || port < 1 || port > 65535) {
>>>            fail_reason = "Bad guest port";
>>>            goto fail_syntax;
>>>        }
>>> +    guest_addr.sin_port = htons(port);
>>> -    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
>>> -                          guest_port) < 0) {
>>> +    if (slirp_add_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
>>> +                           sizeof(host_addr), (struct sockaddr *) &guest_addr,
>>> +                           sizeof(guest_addr), flags) < 0) {
>>>            error_setg(errp, "Could not set up host forwarding rule '%s'",
>>>                       redir_str);
>>>            return -1;
Breno Leitao May 2, 2022, 7:58 a.m. UTC | #4
On 9/25/21 22:48, Nicholas Ngai wrote:
> libslirp provides a newer slirp_*_hostxfwd API meant for
> address-agnostic forwarding instead of the is_udp parameter which is
> limited to just TCP/UDP.
> 
> Signed-off-by: Nicholas Ngai <nicholas@ngai.me>
> Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

Tested-by: Breno Leitao <leitao@debian.org>
Thomas Weißschuh Feb. 22, 2024, 10:44 a.m. UTC | #5
Hi Nicholas,

On Tue, Mar 22, 2022 at 06:58:36PM -0700, Nicholas Ngai wrote:
> Pinging this. It’s a bit old, though the patch still applies cleanly to
> master as far as I can tell.
> 
> Link to patchew is
> https://patchew.org/QEMU/20210925214820.18078-1-nicholas@ngai.me/.
> 
> I’d love to get https://gitlab.com/qemu-project/qemu/-/issues/347 addressed
> once libslirp makes a release with added Unix-to-TCP support in the hostxfwd
> API, but this patch is a requirement for that first.

I'm also interested in this PATCH and a resolution to issue 347.

FYI your patch triggers checkpatch warnings, see [0].
Maybe you can resend the patch with the review tags and the checkpatch
warnings cleaned up.

Also it would be useful to know how the patch changes the version
requirements of the libslirp dependency.
(The version requirement should also be enforced in meson.build)
Also the commit in subprojects/slirp.wrap should be high enough,
which seems to already be the case however.

It seems it requires libslirp 4.6.0 from 2021-06-14, which is only
available from Debian 12 or Ubuntu 22.04 and no release of RHEL.


Thomas

[0] https://patchew.org/QEMU/20210925214820.18078-1-nicholas@ngai.me/logs/testing.checkpatch/
diff mbox series

Patch

diff --git a/net/slirp.c b/net/slirp.c
index ad3a838e0b..49ae01a2f0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -643,12 +643,17 @@  static SlirpState *slirp_lookup(Monitor *mon, const char *id)
 
 void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
 {
-    struct in_addr host_addr = { .s_addr = INADDR_ANY };
-    int host_port;
+    struct sockaddr_in host_addr = {
+        .sin_family = AF_INET,
+        .sin_addr = {
+            .s_addr = INADDR_ANY,
+        },
+    };
+    int port;
+    int flags = 0;
     char buf[256];
     const char *src_str, *p;
     SlirpState *s;
-    int is_udp = 0;
     int err;
     const char *arg1 = qdict_get_str(qdict, "arg1");
     const char *arg2 = qdict_get_try_str(qdict, "arg2");
@@ -670,9 +675,9 @@  void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
     }
 
     if (!strcmp(buf, "tcp") || buf[0] == '\0') {
-        is_udp = 0;
+        /* Do nothing; already TCP. */
     } else if (!strcmp(buf, "udp")) {
-        is_udp = 1;
+        flags |= SLIRP_HOSTFWD_UDP;
     } else {
         goto fail_syntax;
     }
@@ -680,15 +685,17 @@  void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
     if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
         goto fail_syntax;
     }
-    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
+    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
         goto fail_syntax;
     }
 
-    if (qemu_strtoi(p, NULL, 10, &host_port)) {
+    if (qemu_strtoi(p, NULL, 10, &port)) {
         goto fail_syntax;
     }
+    host_addr.sin_port = htons(port);
 
-    err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port);
+    err = slirp_remove_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
+            sizeof(host_addr), flags);
 
     monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
                    err ? "not found" : "removed");
@@ -700,12 +707,22 @@  void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
 {
-    struct in_addr host_addr = { .s_addr = INADDR_ANY };
-    struct in_addr guest_addr = { .s_addr = 0 };
-    int host_port, guest_port;
+    struct sockaddr_in host_addr = {
+        .sin_family = AF_INET,
+        .sin_addr = {
+            .s_addr = INADDR_ANY,
+        },
+    };
+    struct sockaddr_in guest_addr = {
+        .sin_family = AF_INET,
+        .sin_addr = {
+            .s_addr = 0,
+        },
+    };
+    int flags = 0;
+    int port;
     const char *p;
     char buf[256];
-    int is_udp;
     char *end;
     const char *fail_reason = "Unknown reason";
 
@@ -715,9 +732,9 @@  static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
         goto fail_syntax;
     }
     if (!strcmp(buf, "tcp") || buf[0] == '\0') {
-        is_udp = 0;
+        /* Do nothing; already TCP. */
     } else if (!strcmp(buf, "udp")) {
-        is_udp = 1;
+        flags |= SLIRP_HOSTFWD_UDP;
     } else {
         fail_reason = "Bad protocol name";
         goto fail_syntax;
@@ -727,7 +744,7 @@  static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
         fail_reason = "Missing : separator";
         goto fail_syntax;
     }
-    if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
+    if (buf[0] != '\0' && !inet_aton(buf, &host_addr.sin_addr)) {
         fail_reason = "Bad host address";
         goto fail_syntax;
     }
@@ -736,29 +753,32 @@  static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
         fail_reason = "Bad host port separator";
         goto fail_syntax;
     }
-    host_port = strtol(buf, &end, 0);
-    if (*end != '\0' || host_port < 0 || host_port > 65535) {
+    port = strtol(buf, &end, 0);
+    if (*end != '\0' || port < 0 || port > 65535) {
         fail_reason = "Bad host port";
         goto fail_syntax;
     }
+    host_addr.sin_port = htons(port);
 
     if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
         fail_reason = "Missing guest address";
         goto fail_syntax;
     }
-    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
+    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr.sin_addr)) {
         fail_reason = "Bad guest address";
         goto fail_syntax;
     }
 
-    guest_port = strtol(p, &end, 0);
-    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
+    port = strtol(p, &end, 0);
+    if (*end != '\0' || port < 1 || port > 65535) {
         fail_reason = "Bad guest port";
         goto fail_syntax;
     }
+    guest_addr.sin_port = htons(port);
 
-    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
-                          guest_port) < 0) {
+    if (slirp_add_hostxfwd(s->slirp, (struct sockaddr *) &host_addr,
+                           sizeof(host_addr), (struct sockaddr *) &guest_addr,
+                           sizeof(guest_addr), flags) < 0) {
         error_setg(errp, "Could not set up host forwarding rule '%s'",
                    redir_str);
         return -1;