2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4 * James Leu (jleu@mindspring.net).
5 * Copyright (C) 2001 by various other people who didn't put their name here.
6 * Licensed under the GPL.
12 #include <sys/types.h>
13 #include <sys/socket.h>
19 #include "um_malloc.h"
22 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
24 enum request_type
{ REQ_NEW_CONTROL
};
26 #define SWITCH_MAGIC 0xfeedface
31 enum request_type type
;
32 struct sockaddr_un sock
;
35 static struct sockaddr_un
*new_addr(void *name
, int len
)
37 struct sockaddr_un
*sun
;
39 sun
= kmalloc(sizeof(struct sockaddr_un
), UM_GFP_KERNEL
);
41 printk(UM_KERN_ERR
"new_addr: allocation of sockaddr_un "
45 sun
->sun_family
= AF_UNIX
;
46 memcpy(sun
->sun_path
, name
, len
);
50 static int connect_to_switch(struct daemon_data
*pri
)
52 struct sockaddr_un
*ctl_addr
= pri
->ctl_addr
;
53 struct sockaddr_un
*local_addr
= pri
->local_addr
;
54 struct sockaddr_un
*sun
;
55 struct request_v3 req
;
58 pri
->control
= socket(AF_UNIX
, SOCK_STREAM
, 0);
59 if (pri
->control
< 0) {
61 printk(UM_KERN_ERR
"daemon_open : control socket failed, "
62 "errno = %d\n", -err
);
66 if (connect(pri
->control
, (struct sockaddr
*) ctl_addr
,
67 sizeof(*ctl_addr
)) < 0) {
69 printk(UM_KERN_ERR
"daemon_open : control connect failed, "
70 "errno = %d\n", -err
);
74 fd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
77 printk(UM_KERN_ERR
"daemon_open : data socket failed, "
78 "errno = %d\n", -err
);
81 if (bind(fd
, (struct sockaddr
*) local_addr
, sizeof(*local_addr
)) < 0) {
83 printk(UM_KERN_ERR
"daemon_open : data bind failed, "
84 "errno = %d\n", -err
);
88 sun
= kmalloc(sizeof(struct sockaddr_un
), UM_GFP_KERNEL
);
90 printk(UM_KERN_ERR
"new_addr: allocation of sockaddr_un "
96 req
.magic
= SWITCH_MAGIC
;
97 req
.version
= SWITCH_VERSION
;
98 req
.type
= REQ_NEW_CONTROL
;
99 req
.sock
= *local_addr
;
100 n
= write(pri
->control
, &req
, sizeof(req
));
101 if (n
!= sizeof(req
)) {
102 printk(UM_KERN_ERR
"daemon_open : control setup request "
103 "failed, err = %d\n", -errno
);
108 n
= read(pri
->control
, sun
, sizeof(*sun
));
109 if (n
!= sizeof(*sun
)) {
110 printk(UM_KERN_ERR
"daemon_open : read of data socket failed, "
111 "err = %d\n", -errno
);
116 pri
->data_addr
= sun
;
128 static int daemon_user_init(void *data
, void *dev
)
130 struct daemon_data
*pri
= data
;
138 if (!strcmp(pri
->sock_type
, "unix"))
139 pri
->ctl_addr
= new_addr(pri
->ctl_sock
,
140 strlen(pri
->ctl_sock
) + 1);
142 name
.pid
= os_getpid();
143 gettimeofday(&tv
, NULL
);
144 name
.usecs
= tv
.tv_usec
;
145 pri
->local_addr
= new_addr(&name
, sizeof(name
));
147 pri
->fd
= connect_to_switch(pri
);
149 kfree(pri
->local_addr
);
150 pri
->local_addr
= NULL
;
157 static int daemon_open(void *data
)
159 struct daemon_data
*pri
= data
;
163 static void daemon_remove(void *data
)
165 struct daemon_data
*pri
= data
;
172 kfree(pri
->data_addr
);
173 pri
->data_addr
= NULL
;
174 kfree(pri
->ctl_addr
);
175 pri
->ctl_addr
= NULL
;
176 kfree(pri
->local_addr
);
177 pri
->local_addr
= NULL
;
180 int daemon_user_write(int fd
, void *buf
, int len
, struct daemon_data
*pri
)
182 struct sockaddr_un
*data_addr
= pri
->data_addr
;
184 return net_sendto(fd
, buf
, len
, data_addr
, sizeof(*data_addr
));
187 static int daemon_set_mtu(int mtu
, void *data
)
192 const struct net_user_info daemon_user_info
= {
193 .init
= daemon_user_init
,
196 .remove
= daemon_remove
,
197 .set_mtu
= daemon_set_mtu
,
199 .delete_address
= NULL
,
200 .max_packet
= MAX_PACKET
- ETH_HEADER_OTHER