2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL.
11 #include <sys/socket.h>
16 #include "kern_util.h"
17 #include "user_util.h"
21 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
23 enum request_type
{ REQ_NEW_CONTROL
};
25 #define SWITCH_MAGIC 0xfeedface
30 enum request_type type
;
31 struct sockaddr_un sock
;
34 static struct sockaddr_un
*new_addr(void *name
, int len
)
36 struct sockaddr_un
*sun
;
38 sun
= um_kmalloc(sizeof(struct sockaddr_un
));
40 printk("new_addr: allocation of sockaddr_un failed\n");
43 sun
->sun_family
= AF_UNIX
;
44 memcpy(sun
->sun_path
, name
, len
);
48 static int connect_to_switch(struct daemon_data
*pri
)
50 struct sockaddr_un
*ctl_addr
= pri
->ctl_addr
;
51 struct sockaddr_un
*local_addr
= pri
->local_addr
;
52 struct sockaddr_un
*sun
;
53 struct request_v3 req
;
56 pri
->control
= socket(AF_UNIX
, SOCK_STREAM
, 0);
58 printk("daemon_open : control socket failed, errno = %d\n",
63 if(connect(pri
->control
, (struct sockaddr
*) ctl_addr
,
64 sizeof(*ctl_addr
)) < 0){
65 printk("daemon_open : control connect failed, errno = %d\n",
71 fd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
73 printk("daemon_open : data socket failed, errno = %d\n",
78 if(bind(fd
, (struct sockaddr
*) local_addr
, sizeof(*local_addr
)) < 0){
79 printk("daemon_open : data bind failed, errno = %d\n",
85 sun
= um_kmalloc(sizeof(struct sockaddr_un
));
87 printk("new_addr: allocation of sockaddr_un failed\n");
92 req
.magic
= SWITCH_MAGIC
;
93 req
.version
= SWITCH_VERSION
;
94 req
.type
= REQ_NEW_CONTROL
;
95 req
.sock
= *local_addr
;
96 n
= os_write_file(pri
->control
, &req
, sizeof(req
));
98 printk("daemon_open : control setup request failed, err = %d\n",
104 n
= os_read_file(pri
->control
, sun
, sizeof(*sun
));
105 if(n
!= sizeof(*sun
)){
106 printk("daemon_open : read of data socket failed, err = %d\n",
112 pri
->data_addr
= sun
;
120 os_close_file(pri
->control
);
124 static void daemon_user_init(void *data
, void *dev
)
126 struct daemon_data
*pri
= data
;
134 if(!strcmp(pri
->sock_type
, "unix"))
135 pri
->ctl_addr
= new_addr(pri
->ctl_sock
,
136 strlen(pri
->ctl_sock
) + 1);
138 name
.pid
= os_getpid();
139 gettimeofday(&tv
, NULL
);
140 name
.usecs
= tv
.tv_usec
;
141 pri
->local_addr
= new_addr(&name
, sizeof(name
));
143 pri
->fd
= connect_to_switch(pri
);
145 kfree(pri
->local_addr
);
146 pri
->local_addr
= NULL
;
150 static int daemon_open(void *data
)
152 struct daemon_data
*pri
= data
;
156 static void daemon_remove(void *data
)
158 struct daemon_data
*pri
= data
;
160 os_close_file(pri
->fd
);
162 os_close_file(pri
->control
);
165 kfree(pri
->data_addr
);
166 pri
->data_addr
= NULL
;
167 kfree(pri
->ctl_addr
);
168 pri
->ctl_addr
= NULL
;
169 kfree(pri
->local_addr
);
170 pri
->local_addr
= NULL
;
173 int daemon_user_write(int fd
, void *buf
, int len
, struct daemon_data
*pri
)
175 struct sockaddr_un
*data_addr
= pri
->data_addr
;
177 return(net_sendto(fd
, buf
, len
, data_addr
, sizeof(*data_addr
)));
180 static int daemon_set_mtu(int mtu
, void *data
)
185 struct net_user_info daemon_user_info
= {
186 .init
= daemon_user_init
,
189 .remove
= daemon_remove
,
190 .set_mtu
= daemon_set_mtu
,
192 .delete_address
= NULL
,
193 .max_packet
= MAX_PACKET
- ETH_HEADER_OTHER
197 * Overrides for Emacs so that we follow Linus's tabbing style.
198 * Emacs will notice this stuff at the end of the file and automatically
199 * adjust the settings for this buffer only. This must remain at the end
201 * ---------------------------------------------------------------------------
203 * c-file-style: "linux"