18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 48c2ecf20Sopenharmony_ci * James Leu (jleu@mindspring.net). 58c2ecf20Sopenharmony_ci * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 68c2ecf20Sopenharmony_ci * Copyright (C) 2001 by various other people who didn't put their name here. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/init.h> 108c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 118c2ecf20Sopenharmony_ci#include <net_kern.h> 128c2ecf20Sopenharmony_ci#include "daemon.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistruct daemon_init { 158c2ecf20Sopenharmony_ci char *sock_type; 168c2ecf20Sopenharmony_ci char *ctl_sock; 178c2ecf20Sopenharmony_ci}; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic void daemon_init(struct net_device *dev, void *data) 208c2ecf20Sopenharmony_ci{ 218c2ecf20Sopenharmony_ci struct uml_net_private *pri; 228c2ecf20Sopenharmony_ci struct daemon_data *dpri; 238c2ecf20Sopenharmony_ci struct daemon_init *init = data; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci pri = netdev_priv(dev); 268c2ecf20Sopenharmony_ci dpri = (struct daemon_data *) pri->user; 278c2ecf20Sopenharmony_ci dpri->sock_type = init->sock_type; 288c2ecf20Sopenharmony_ci dpri->ctl_sock = init->ctl_sock; 298c2ecf20Sopenharmony_ci dpri->fd = -1; 308c2ecf20Sopenharmony_ci dpri->control = -1; 318c2ecf20Sopenharmony_ci dpri->dev = dev; 328c2ecf20Sopenharmony_ci /* We will free this pointer. If it contains crap we're burned. */ 338c2ecf20Sopenharmony_ci dpri->ctl_addr = NULL; 348c2ecf20Sopenharmony_ci dpri->data_addr = NULL; 358c2ecf20Sopenharmony_ci dpri->local_addr = NULL; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci printk("daemon backend (uml_switch version %d) - %s:%s", 388c2ecf20Sopenharmony_ci SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); 398c2ecf20Sopenharmony_ci printk("\n"); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci return net_recvfrom(fd, skb_mac_header(skb), 458c2ecf20Sopenharmony_ci skb->dev->mtu + ETH_HEADER_OTHER); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci return daemon_user_write(fd, skb->data, skb->len, 518c2ecf20Sopenharmony_ci (struct daemon_data *) &lp->user); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic const struct net_kern_info daemon_kern_info = { 558c2ecf20Sopenharmony_ci .init = daemon_init, 568c2ecf20Sopenharmony_ci .protocol = eth_protocol, 578c2ecf20Sopenharmony_ci .read = daemon_read, 588c2ecf20Sopenharmony_ci .write = daemon_write, 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic int daemon_setup(char *str, char **mac_out, void *data) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci struct daemon_init *init = data; 648c2ecf20Sopenharmony_ci char *remain; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci *init = ((struct daemon_init) 678c2ecf20Sopenharmony_ci { .sock_type = "unix", 688c2ecf20Sopenharmony_ci .ctl_sock = "/tmp/uml.ctl" }); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, 718c2ecf20Sopenharmony_ci NULL); 728c2ecf20Sopenharmony_ci if (remain != NULL) 738c2ecf20Sopenharmony_ci printk(KERN_WARNING "daemon_setup : Ignoring data socket " 748c2ecf20Sopenharmony_ci "specification\n"); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci return 1; 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic struct transport daemon_transport = { 808c2ecf20Sopenharmony_ci .list = LIST_HEAD_INIT(daemon_transport.list), 818c2ecf20Sopenharmony_ci .name = "daemon", 828c2ecf20Sopenharmony_ci .setup = daemon_setup, 838c2ecf20Sopenharmony_ci .user = &daemon_user_info, 848c2ecf20Sopenharmony_ci .kern = &daemon_kern_info, 858c2ecf20Sopenharmony_ci .private_size = sizeof(struct daemon_data), 868c2ecf20Sopenharmony_ci .setup_size = sizeof(struct daemon_init), 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic int register_daemon(void) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci register_transport(&daemon_transport); 928c2ecf20Sopenharmony_ci return 0; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cilate_initcall(register_daemon); 96