slirp: associate slirp_output callback with the Slirp context

Let's make the slirp interface a bit more library-like.
Associate the slirp_output() with a Slirp context.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
This commit is contained in:
Marc-André Lureau 2018-11-10 17:45:36 +04:00 committed by Samuel Thibault
parent 27df21ca38
commit 62c1d2c483
5 changed files with 17 additions and 11 deletions

View File

@ -99,7 +99,7 @@ static void slirp_smb_cleanup(SlirpState *s);
static inline void slirp_smb_cleanup(SlirpState *s) { } static inline void slirp_smb_cleanup(SlirpState *s) { }
#endif #endif
void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len) static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
{ {
SlirpState *s = opaque; SlirpState *s = opaque;
@ -378,7 +378,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
ipv6, ip6_prefix, vprefix6_len, ip6_host, ipv6, ip6_prefix, vprefix6_len, ip6_host,
vhostname, tftp_server_name, vhostname, tftp_server_name,
tftp_export, bootfile, dhcp, tftp_export, bootfile, dhcp,
dns, ip6_dns, dnssearch, vdomainname, s); dns, ip6_dns, dnssearch, vdomainname,
net_slirp_output, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
for (config = slirp_configs; config; config = config->next) { for (config = slirp_configs; config; config = config->next) {

View File

@ -5,6 +5,8 @@
typedef struct Slirp Slirp; typedef struct Slirp Slirp;
typedef void (*slirp_output)(void *opaque, const uint8_t *pkt, int pkt_len);
int get_dns_addr(struct in_addr *pdns_addr); int get_dns_addr(struct in_addr *pdns_addr);
int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id); int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
@ -17,7 +19,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
const char *tftp_path, const char *bootfile, const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver, struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch, struct in6_addr vnameserver6, const char **vdnssearch,
const char *vdomainname, void *opaque); const char *vdomainname,
slirp_output output,
void *opaque);
void slirp_cleanup(Slirp *slirp); void slirp_cleanup(Slirp *slirp);
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout); void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
@ -26,9 +30,6 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error);
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
/* you must provide the following functions: */
void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
int slirp_add_hostfwd(Slirp *slirp, int is_udp, int slirp_add_hostfwd(Slirp *slirp, int is_udp,
struct in_addr host_addr, int host_port, struct in_addr host_addr, int host_port,
struct in_addr guest_addr, int guest_port); struct in_addr guest_addr, int guest_port);

View File

@ -163,5 +163,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
*pchecksum = htonl(checksum); *pchecksum = htonl(checksum);
ncsi_rsp_len += 4; ncsi_rsp_len += 4;
slirp_output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len); slirp->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
} }

View File

@ -287,12 +287,15 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
const char *tftp_path, const char *bootfile, const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver, struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch, struct in6_addr vnameserver6, const char **vdnssearch,
const char *vdomainname, void *opaque) const char *vdomainname,
slirp_output output,
void *opaque)
{ {
Slirp *slirp = g_malloc0(sizeof(Slirp)); Slirp *slirp = g_malloc0(sizeof(Slirp));
slirp_init_once(); slirp_init_once();
slirp->output = output;
slirp->grand = g_rand_new(); slirp->grand = g_rand_new();
slirp->restricted = restricted; slirp->restricted = restricted;
@ -832,7 +835,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
rah->ar_sip = ah->ar_tip; rah->ar_sip = ah->ar_tip;
memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
rah->ar_tip = ah->ar_sip; rah->ar_tip = ah->ar_sip;
slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply)); slirp->output(slirp->opaque, arp_reply, sizeof(arp_reply));
} }
break; break;
case ARPOP_REPLY: case ARPOP_REPLY:
@ -932,7 +935,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
/* target IP */ /* target IP */
rah->ar_tip = iph->ip_dst.s_addr; rah->ar_tip = iph->ip_dst.s_addr;
slirp->client_ipaddr = iph->ip_dst; slirp->client_ipaddr = iph->ip_dst;
slirp_output(slirp->opaque, arp_req, sizeof(arp_req)); slirp->output(slirp->opaque, arp_req, sizeof(arp_req));
ifm->resolution_requested = true; ifm->resolution_requested = true;
/* Expire request and drop outgoing packet after 1 second */ /* Expire request and drop outgoing packet after 1 second */
@ -1018,7 +1021,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
eh->h_dest[0], eh->h_dest[1], eh->h_dest[2], eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
eh->h_dest[3], eh->h_dest[4], eh->h_dest[5])); eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN); slirp->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
return 1; return 1;
} }

View File

@ -220,6 +220,7 @@ struct Slirp {
GRand *grand; GRand *grand;
QEMUTimer *ra_timer; QEMUTimer *ra_timer;
slirp_output output;
void *opaque; void *opaque;
}; };