Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
iproute2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
iproute2
Commits
f411a628
Commit
f411a628
authored
Mar 29, 2010
by
Stephen Hemminger
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/shemminger/iproute2
parents
12ddfff7
1db61e02
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
417 additions
and
4 deletions
+417
-4
include/linux/if_tun.h
include/linux/if_tun.h
+87
-0
ip/Makefile
ip/Makefile
+1
-1
ip/ip.c
ip/ip.c
+3
-1
ip/ip_common.h
ip/ip_common.h
+1
-0
ip/ipaddress.c
ip/ipaddress.c
+2
-2
ip/iptuntap.c
ip/iptuntap.c
+323
-0
No files found.
include/linux/if_tun.h
0 → 100644
View file @
f411a628
/*
* Universal TUN/TAP device driver.
* Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __IF_TUN_H
#define __IF_TUN_H
#include <linux/types.h>
#include <linux/if_ether.h>
/* Read queue size */
#define TUN_READQ_SIZE 500
/* TUN device flags */
#define TUN_TUN_DEV 0x0001
#define TUN_TAP_DEV 0x0002
#define TUN_TYPE_MASK 0x000f
#define TUN_FASYNC 0x0010
#define TUN_NOCHECKSUM 0x0020
#define TUN_NO_PI 0x0040
#define TUN_ONE_QUEUE 0x0080
#define TUN_PERSIST 0x0100
#define TUN_VNET_HDR 0x0200
/* Ioctl defines */
#define TUNSETNOCSUM _IOW('T', 200, int)
#define TUNSETDEBUG _IOW('T', 201, int)
#define TUNSETIFF _IOW('T', 202, int)
#define TUNSETPERSIST _IOW('T', 203, int)
#define TUNSETOWNER _IOW('T', 204, int)
#define TUNSETLINK _IOW('T', 205, int)
#define TUNSETGROUP _IOW('T', 206, int)
#define TUNGETFEATURES _IOR('T', 207, unsigned int)
#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
#define TUNGETIFF _IOR('T', 210, unsigned int)
#define TUNGETSNDBUF _IOR('T', 211, int)
#define TUNSETSNDBUF _IOW('T', 212, int)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
#define IFF_VNET_HDR 0x4000
/* Features for GSO (TUNSETOFFLOAD). */
#define TUN_F_CSUM 0x01
/* You can hand me unchecksummed packets. */
#define TUN_F_TSO4 0x02
/* I can handle TSO for IPv4 packets */
#define TUN_F_TSO6 0x04
/* I can handle TSO for IPv6 packets */
#define TUN_F_TSO_ECN 0x08
/* I can handle TSO with ECN bits. */
/* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
#define TUN_PKT_STRIP 0x0001
struct
tun_pi
{
__u16
flags
;
__be16
proto
;
};
/*
* Filter spec (used for SETXXFILTER ioctls)
* This stuff is applicable only to the TAP (Ethernet) devices.
* If the count is zero the filter is disabled and the driver accepts
* all packets (promisc mode).
* If the filter is enabled in order to accept broadcast packets
* broadcast addr must be explicitly included in the addr list.
*/
#define TUN_FLT_ALLMULTI 0x0001
/* Accept all multicast packets */
struct
tun_filter
{
__u16
flags
;
/* TUN_FLT_ flags see above */
__u16
count
;
/* Number of addresses */
__u8
addr
[
0
][
ETH_ALEN
];
};
#endif
/* __IF_TUN_H */
ip/Makefile
View file @
f411a628
IPOBJ
=
ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o
\
rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o ipntable.o iplink.o
\
ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o
\
ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o
iptuntap.o
\
ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o
\
iplink_vlan.o link_veth.o link_gre.o iplink_can.o
\
iplink_macvlan.o
...
...
ip/ip.c
View file @
f411a628
...
...
@@ -42,7 +42,7 @@ static void usage(void)
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
\n
"
" ip [ -force ] -batch filename
\n
"
"where OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |
\n
"
" tunnel | maddr | mroute | monitor | xfrm }
\n
"
" tunnel |
tuntap |
maddr | mroute | monitor | xfrm }
\n
"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
\n
"
" -f[amily] { inet | inet6 | ipx | dnet | link } |
\n
"
" -o[neline] | -t[imestamp] | -b[atch] [filename] |
\n
"
...
...
@@ -71,6 +71,8 @@ static const struct cmd {
{
"link"
,
do_iplink
},
{
"tunnel"
,
do_iptunnel
},
{
"tunl"
,
do_iptunnel
},
{
"tuntap"
,
do_iptuntap
},
{
"tap"
,
do_iptuntap
},
{
"monitor"
,
do_ipmonitor
},
{
"xfrm"
,
do_xfrm
},
{
"mroute"
,
do_multiroute
},
...
...
ip/ip_common.h
View file @
f411a628
...
...
@@ -32,6 +32,7 @@ extern int do_ipneigh(int argc, char **argv);
extern
int
do_ipntable
(
int
argc
,
char
**
argv
);
extern
int
do_iptunnel
(
int
argc
,
char
**
argv
);
extern
int
do_ip6tunnel
(
int
argc
,
char
**
argv
);
extern
int
do_iptuntap
(
int
argc
,
char
**
argv
);
extern
int
do_iplink
(
int
argc
,
char
**
argv
);
extern
int
do_ipmonitor
(
int
argc
,
char
**
argv
);
extern
int
do_multiaddr
(
int
argc
,
char
**
argv
);
...
...
ip/ipaddress.c
View file @
f411a628
...
...
@@ -1039,7 +1039,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
if
(
l
&&
matches
(
d
,
l
)
!=
0
)
{
fprintf
(
stderr
,
"
\"
dev
\"
(%s) must match
\"
label
\"
(%s).
\n
"
,
d
,
l
);
exit
(
1
)
;
return
-
1
;
}
if
(
peer_len
==
0
&&
local_len
)
{
...
...
@@ -1104,7 +1104,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
if
(
rtnl_talk
(
&
rth
,
&
req
.
n
,
0
,
0
,
NULL
,
NULL
,
NULL
)
<
0
)
exit
(
2
)
;
return
-
2
;
return
0
;
}
...
...
ip/iptuntap.c
0 → 100644
View file @
f411a628
/*
* iptunnel.c "ip tuntap"
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: David Woodhouse <David.Woodhouse@intel.com>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
#define TUNDEV "/dev/net/tun"
static
void
usage
(
void
)
__attribute__
((
noreturn
));
static
void
usage
(
void
)
{
fprintf
(
stderr
,
"Usage: ip tuntap { add | del } [ dev PHYS_DEV ]
\n
"
);
fprintf
(
stderr
,
" [ mode { tun | tap } ] [ user USER ] [ group GROUP ]
\n
"
);
fprintf
(
stderr
,
" [ one_queue ] [ pi ] [ vnet_hdr ]
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"Where: USER := { STRING | NUMBER }
\n
"
);
fprintf
(
stderr
,
" GROUP := { STRING | NUMBER }
\n
"
);
exit
(
-
1
);
}
static
int
tap_add_ioctl
(
struct
ifreq
*
ifr
,
uid_t
uid
,
gid_t
gid
)
{
int
fd
=
open
(
TUNDEV
,
O_RDWR
);
int
ret
=
-
1
;
#ifdef IFF_TUN_EXCL
ifr
->
ifr_flags
|=
IFF_TUN_EXCL
;
#endif
fd
=
open
(
TUNDEV
,
O_RDWR
);
if
(
fd
<
0
)
{
perror
(
"open"
);
return
-
1
;
}
if
(
ioctl
(
fd
,
TUNSETIFF
,
ifr
))
{
perror
(
"ioctl(TUNSETIFF)"
);
goto
out
;
}
if
(
uid
!=
-
1
&&
ioctl
(
fd
,
TUNSETOWNER
,
uid
))
{
perror
(
"ioctl(TUNSETOWNER)"
);
goto
out
;
}
if
(
gid
!=
-
1
&&
ioctl
(
fd
,
TUNSETGROUP
,
gid
))
{
perror
(
"ioctl(TUNSETGROUP)"
);
goto
out
;
}
if
(
ioctl
(
fd
,
TUNSETPERSIST
,
1
))
{
perror
(
"ioctl(TUNSETPERSIST)"
);
goto
out
;
}
ret
=
0
;
out:
close
(
fd
);
return
ret
;
}
static
int
tap_del_ioctl
(
struct
ifreq
*
ifr
)
{
int
fd
=
open
(
TUNDEV
,
O_RDWR
);
int
ret
=
-
1
;
if
(
fd
<
0
)
{
perror
(
"open"
);
return
-
1
;
}
if
(
ioctl
(
fd
,
TUNSETIFF
,
ifr
))
{
perror
(
"ioctl(TUNSETIFF)"
);
goto
out
;
}
if
(
ioctl
(
fd
,
TUNSETPERSIST
,
0
))
{
perror
(
"ioctl(TUNSETPERSIST)"
);
goto
out
;
}
ret
=
0
;
out:
close
(
fd
);
return
ret
;
}
static
int
parse_args
(
int
argc
,
char
**
argv
,
struct
ifreq
*
ifr
,
uid_t
*
uid
,
gid_t
*
gid
)
{
int
count
=
0
;
memset
(
ifr
,
0
,
sizeof
(
*
ifr
));
ifr
->
ifr_flags
|=
IFF_NO_PI
;
while
(
argc
>
0
)
{
if
(
matches
(
*
argv
,
"mode"
)
==
0
)
{
NEXT_ARG
();
if
(
matches
(
*
argv
,
"tun"
)
==
0
)
{
if
(
ifr
->
ifr_flags
&
IFF_TAP
)
{
fprintf
(
stderr
,
"You managed to ask for more than one tunnel mode.
\n
"
);
exit
(
-
1
);
}
ifr
->
ifr_flags
|=
IFF_TUN
;
}
else
if
(
matches
(
*
argv
,
"tap"
)
==
0
)
{
if
(
ifr
->
ifr_flags
&
IFF_TUN
)
{
fprintf
(
stderr
,
"You managed to ask for more than one tunnel mode.
\n
"
);
exit
(
-
1
);
}
ifr
->
ifr_flags
|=
IFF_TAP
;
}
else
{
fprintf
(
stderr
,
"Cannot guess tunnel mode.
\n
"
);
exit
(
-
1
);
}
}
else
if
(
uid
&&
matches
(
*
argv
,
"user"
)
==
0
)
{
char
*
end
;
unsigned
long
user
;
NEXT_ARG
();
if
(
**
argv
&&
((
user
=
strtol
(
*
argv
,
&
end
,
10
)),
!*
end
))
*
uid
=
user
;
else
{
struct
passwd
*
pw
=
getpwnam
(
*
argv
);
if
(
!
pw
)
{
fprintf
(
stderr
,
"invalid user
\"
%s
\"\n
"
,
*
argv
);
exit
(
-
1
);
}
*
uid
=
pw
->
pw_uid
;
}
}
else
if
(
gid
&&
matches
(
*
argv
,
"group"
)
==
0
)
{
char
*
end
;
unsigned
long
group
;
NEXT_ARG
();
if
(
**
argv
&&
((
group
=
strtol
(
*
argv
,
&
end
,
10
)),
!*
end
))
*
gid
=
group
;
else
{
struct
group
*
gr
=
getgrnam
(
*
argv
);
if
(
!
gr
)
{
fprintf
(
stderr
,
"invalid group
\"
%s
\"\n
"
,
*
argv
);
exit
(
-
1
);
}
*
gid
=
gr
->
gr_gid
;
}
}
else
if
(
matches
(
*
argv
,
"pi"
)
==
0
)
{
ifr
->
ifr_flags
&=
~
IFF_NO_PI
;
}
else
if
(
matches
(
*
argv
,
"one_queue"
)
==
0
)
{
ifr
->
ifr_flags
|=
IFF_ONE_QUEUE
;
}
else
if
(
matches
(
*
argv
,
"vnet_hdr"
)
==
0
)
{
ifr
->
ifr_flags
|=
IFF_VNET_HDR
;
}
else
if
(
matches
(
*
argv
,
"dev"
)
==
0
)
{
NEXT_ARG
();
strncpy
(
ifr
->
ifr_name
,
*
argv
,
IFNAMSIZ
-
1
);
}
else
{
if
(
matches
(
*
argv
,
"name"
)
==
0
)
{
NEXT_ARG
();
}
else
if
(
matches
(
*
argv
,
"help"
)
==
0
)
usage
();
if
(
ifr
->
ifr_name
[
0
])
duparg2
(
"name"
,
*
argv
);
strncpy
(
ifr
->
ifr_name
,
*
argv
,
IFNAMSIZ
);
}
count
++
;
argc
--
;
argv
++
;
}
return
0
;
}
static
int
do_add
(
int
argc
,
char
**
argv
)
{
struct
ifreq
ifr
;
uid_t
uid
=
-
1
;
gid_t
gid
=
-
1
;
if
(
parse_args
(
argc
,
argv
,
&
ifr
,
&
uid
,
&
gid
)
<
0
)
return
-
1
;
if
(
!
(
ifr
.
ifr_flags
&
TUN_TYPE_MASK
))
{
fprintf
(
stderr
,
"You failed to specify a tunnel mode
\n
"
);
return
-
1
;
}
return
tap_add_ioctl
(
&
ifr
,
uid
,
gid
);
}
static
int
do_del
(
int
argc
,
char
**
argv
)
{
struct
ifreq
ifr
;
if
(
parse_args
(
argc
,
argv
,
&
ifr
,
NULL
,
NULL
)
<
0
)
return
-
1
;
return
tap_del_ioctl
(
&
ifr
);
}
static
int
read_prop
(
char
*
dev
,
char
*
prop
,
long
*
value
)
{
char
fname
[
IFNAMSIZ
+
25
],
buf
[
80
],
*
endp
;
ssize_t
len
;
int
fd
;
long
result
;
sprintf
(
fname
,
"/sys/class/net/%s/%s"
,
dev
,
prop
);
fd
=
open
(
fname
,
O_RDONLY
);
if
(
fd
<
0
)
{
if
(
strcmp
(
prop
,
"tun_flags"
))
fprintf
(
stderr
,
"open %s: %s
\n
"
,
fname
,
strerror
(
errno
));
return
-
1
;
}
len
=
read
(
fd
,
buf
,
sizeof
(
buf
)
-
1
);
close
(
fd
);
if
(
len
<
0
)
{
fprintf
(
stderr
,
"read %s: %s"
,
fname
,
strerror
(
errno
));
return
-
1
;
}
buf
[
len
]
=
0
;
result
=
strtol
(
buf
,
&
endp
,
0
);
if
(
*
endp
!=
'\n'
)
{
fprintf
(
stderr
,
"Failed to parse %s
\n
"
,
fname
);
return
-
1
;
}
*
value
=
result
;
return
0
;
}
static
void
print_flags
(
long
flags
)
{
if
(
flags
&
IFF_TUN
)
printf
(
" tun"
);
if
(
flags
&
IFF_TAP
)
printf
(
" tap"
);
if
(
!
(
flags
&
IFF_NO_PI
))
printf
(
" pi"
);
if
(
flags
&
IFF_ONE_QUEUE
)
printf
(
" one_queue"
);
if
(
flags
&
IFF_VNET_HDR
)
printf
(
" vnet_hdr"
);
flags
&=
~
(
IFF_TUN
|
IFF_TAP
|
IFF_NO_PI
|
IFF_ONE_QUEUE
|
IFF_VNET_HDR
);
if
(
flags
)
printf
(
" UNKNOWN_FLAGS:%lx"
,
flags
);
}
static
int
do_show
(
int
argc
,
char
**
argv
)
{
DIR
*
dir
;
struct
dirent
*
d
;
long
flags
,
owner
=
-
1
,
group
=
-
1
;
dir
=
opendir
(
"/sys/class/net"
);
if
(
!
dir
)
{
perror
(
"opendir"
);
return
-
1
;
}
while
((
d
=
readdir
(
dir
)))
{
if
(
d
->
d_name
[
0
]
==
'.'
&&
(
d
->
d_name
[
1
]
==
0
||
d
->
d_name
[
1
]
==
'.'
))
continue
;
if
(
read_prop
(
d
->
d_name
,
"tun_flags"
,
&
flags
))
continue
;
read_prop
(
d
->
d_name
,
"owner"
,
&
owner
);
read_prop
(
d
->
d_name
,
"group"
,
&
group
);
printf
(
"%s:"
,
d
->
d_name
);
print_flags
(
flags
);
if
(
owner
!=
-
1
)
printf
(
" user %ld"
,
owner
);
if
(
group
!=
-
1
)
printf
(
" group %ld"
,
group
);
printf
(
"
\n
"
);
}
return
0
;
}
int
do_iptuntap
(
int
argc
,
char
**
argv
)
{
if
(
argc
>
0
)
{
if
(
matches
(
*
argv
,
"add"
)
==
0
)
return
do_add
(
argc
-
1
,
argv
+
1
);
if
(
matches
(
*
argv
,
"del"
)
==
0
)
return
do_del
(
argc
-
1
,
argv
+
1
);
if
(
matches
(
*
argv
,
"show"
)
==
0
||
matches
(
*
argv
,
"lst"
)
==
0
||
matches
(
*
argv
,
"list"
)
==
0
)
return
do_show
(
argc
-
1
,
argv
+
1
);
if
(
matches
(
*
argv
,
"help"
)
==
0
)
usage
();
}
else
return
do_show
(
0
,
NULL
);
fprintf
(
stderr
,
"Command
\"
%s
\"
is unknown, try
\"
ip tuntap help
\"
.
\n
"
,
*
argv
);
exit
(
-
1
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment