1 /* Copyright 2005 Renzo Davoli - VDE-2
2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004.
3 * Licensed under the GPLv2
4 * Modified by Ludovico Gardenghi 2005
5 * -g option (group management) by Daniel P. Berrange
6 * dir permission patch by Alessio Caprari 2006
18 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <sys/types.h>
33 #include <vdecommon.h>
35 #include "../vde_switch/switch.h"
36 #include "sockutils.h"
39 /* will be inserted in a af_ipn.h include */
41 #define AF_IPN 34 /* IPN sockets */
46 #define AF_NETBEUI PF_NETBEUI
51 #define AF_IPN_STOLEN AF_NETBEUI /* IPN temporary sockets */
52 #define PF_IPN_STOLEN AF_IPN_STOLEN
55 #define IPN_BROADCAST 1
57 #define IPN_VDESWITCH 2
58 #define IPN_VDESWITCH_L3 3
60 #define IPN_SO_PREBIND 0x80
62 #define IPN_SO_DESCR 1
63 #define IPN_SO_CHANGE_NUMNODES 2
64 #define IPN_SO_HANDLE_OOB 3
65 #define IPN_SO_WANT_OOB_NUMNODES 4
66 #define IPN_SO_MTU (IPN_SO_PREBIND | 0)
67 #define IPN_SO_NUMNODES (IPN_SO_PREBIND | 1)
68 #define IPN_SO_MSGPOOLSIZE (IPN_SO_PREBIND | 2)
69 #define IPN_SO_FLAGS (IPN_SO_PREBIND | 3)
70 #define IPN_SO_MODE (IPN_SO_PREBIND | 4)
72 #define IPN_PORTNO_ANY -1
74 #define IPN_DESCRLEN 128
76 #define IPN_FLAG_LOSSLESS 1
77 #define IPN_FLAG_TERMINATED 0x1000
79 #define IPN_NODEFLAG_TAP 0x10 /* This is a tap interface */
80 #define IPN_NODEFLAG_GRAB 0x20 /* This is a grab of a real interface */
83 #define IPN_SETPERSIST_NETDEV _IOW('I', 200, int)
84 #define IPN_CLRPERSIST_NETDEV _IOW('I', 201, int)
85 #define IPN_CONN_NETDEV _IOW('I', 202, int)
86 #define IPN_JOIN_NETDEV _IOW('I', 203, int)
87 #define IPN_SETPERSIST _IOW('I', 204, int)
89 static struct swmodule swmi
;
90 static unsigned int ctl_type
;
91 static int mode
= 0700;
93 static char real_ctl_socket
[PATH_MAX
];
94 static char *ctl_socket
= real_ctl_socket
;
95 static gid_t grp_owner
= -1;
97 #define MODULENAME "kernel module interface"
99 static void handle_input(unsigned char type
,int fd
,int revents
,int *arg
)
101 /*here OOB messages will be delivered for debug options */
104 static void cleanup(unsigned char type
,int fd
,int arg
)
109 static struct option long_options
[] = {
111 {"vdesock", 1, 0, 's'},
114 {"group", 1, 0, 'g'},
120 #define Nlong_options (sizeof(long_options)/sizeof(struct option));
122 static void usage(void)
125 "(opts from datasock module)\n"
126 " -s, --sock SOCK control directory pathname\n"
127 " -s, --vdesock SOCK Same as --sock SOCK\n"
128 " -s, --unix SOCK Same as --sock SOCK\n"
129 " -m, --mod MODE Standard access mode for comm sockets (octal)\n"
130 " -g, --group GROUP Group owner for comm sockets\n"
131 " -t, --tap TAP Enable routing through TAP tap interface\n"
132 " -G, --grab INT Enable routing grabbing an existing interface\n");
135 struct extinterface
{
138 struct extinterface
*next
;
141 static struct extinterface
*extifhead
;
142 static struct extinterface
**extiftail
=&extifhead
;
144 static void addextinterface(char type
,char *name
)
146 struct extinterface
*new=malloc(sizeof (struct extinterface
));
149 new->name
=strdup(name
);
152 extiftail
=&(new->next
);
156 static void runextinterfaces(int kvdefd
)
158 struct extinterface
*iface
,*oldiface
;
160 for (iface
=extifhead
;iface
!= NULL
;iface
=oldiface
)
162 memset(&ifr
, 0, sizeof(ifr
));
163 strncpy(ifr
.ifr_name
,iface
->name
,IFNAMSIZ
);
164 if (iface
->type
== 't')
165 ifr
.ifr_flags
=IPN_NODEFLAG_TAP
;
167 ifr
.ifr_flags
=IPN_NODEFLAG_GRAB
;
168 // printf("ioctl\n");
169 if (ioctl(kvdefd
, IPN_CONN_NETDEV
, (void *) &ifr
) < 0) {
170 printlog(LOG_ERR
, "%s interface %s error: %s", iface
->name
,
171 (iface
->type
== 't')?"tap":"grab",strerror(errno
));
175 oldiface
=iface
->next
;
181 static int parseopt(int c
, char *optarg
)
187 /* This should returns NULL as the path probably does not exist */
188 vde_realpath(optarg
, ctl_socket
);
191 sscanf(optarg
,"%o",&mode
);
194 if (!(grp
= getgrnam(optarg
))) {
195 printlog(LOG_ERR
, "No such group '%s'", optarg
);
198 grp_owner
=grp
->gr_gid
;
202 addextinterface(c
,optarg
);
210 static void init(void)
213 struct sockaddr_un sun
;
215 kvdefd
= socket(AF_IPN
,SOCK_RAW
,IPN_VDESWITCH
);
217 family
=AF_IPN_STOLEN
;
218 kvdefd
= socket(AF_IPN_STOLEN
,SOCK_RAW
,IPN_VDESWITCH
);
220 printlog(LOG_ERR
,"kvde_switch requires ipn and kvde_switch kernel modules loaded");
224 sun
.sun_family
= family
;
225 snprintf(sun
.sun_path
,sizeof(sun
.sun_path
),"%s",ctl_socket
);
226 if(bind(kvdefd
, (struct sockaddr
*) &sun
, sizeof(sun
)) < 0) {
227 printlog(LOG_ERR
,"cannot bind socket %s",ctl_socket
);
230 if(chmod(ctl_socket
, mode
) <0) {
231 printlog(LOG_ERR
, "chmod: %s", strerror(errno
));
234 if(chown(ctl_socket
,-1,grp_owner
) < 0) {
235 printlog(LOG_ERR
, "chown: %s", strerror(errno
));
238 runextinterfaces(kvdefd
);
239 add_fd(kvdefd
,ctl_type
,-1);
242 static int showinfo(FILE *fd
)
244 printoutc(fd
,"ctl dir %s",ctl_socket
);
245 printoutc(fd
,"std mode 0%03o",mode
);
249 static struct comlist cl
[]={
250 {"ds","============","DATA SOCKET MENU",NULL
,NOARG
},
251 {"ds/showinfo","","show ds info",showinfo
,NOARG
|WITHFILE
},
255 static void delep (int fd, void* data, void *descr)
257 if (fd>=0) remove_fd(fd);
258 if (data) free(data);
259 if (descr) free(descr);
263 void start_datasock(void)
265 strcpy(ctl_socket
,(geteuid()==0)?VDESTDSOCK
:VDETMPSOCK
);
266 swmi
.swmnopts
=Nlong_options
;
267 swmi
.swmopts
=long_options
;
269 swmi
.parseopt
=parseopt
;
271 swmi
.handle_input
=handle_input
;
272 swmi
.cleanup
=cleanup
;