Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
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
linux
Commits
300aaeea
Commit
300aaeea
authored
Mar 24, 2008
by
YOSHIFUJI Hideaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV6] SIT: Add SIOCGETPRL ioctl to get/dump PRL.
Signed-off-by:
YOSHIFUJI Hideaki
<
yoshfuji@linux-ipv6.org
>
parent
0009ae1f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
10 deletions
+95
-10
include/linux/if_tunnel.h
include/linux/if_tunnel.h
+4
-0
include/net/ipip.h
include/net/ipip.h
+4
-1
net/ipv6/sit.c
net/ipv6/sit.c
+87
-9
No files found.
include/linux/if_tunnel.h
View file @
300aaeea
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
...
@@ -38,6 +39,9 @@ struct ip_tunnel_prl {
...
@@ -38,6 +39,9 @@ struct ip_tunnel_prl {
__be32
addr
;
__be32
addr
;
__u16
flags
;
__u16
flags
;
__u16
__reserved
;
__u16
__reserved
;
__u32
datalen
;
__u32
__reserved2
;
void
__user
*
data
;
};
};
/* PRL flags */
/* PRL flags */
...
...
include/net/ipip.h
View file @
300aaeea
...
@@ -24,13 +24,16 @@ struct ip_tunnel
...
@@ -24,13 +24,16 @@ struct ip_tunnel
int
mlink
;
int
mlink
;
struct
ip_tunnel_parm
parms
;
struct
ip_tunnel_parm
parms
;
struct
ip_tunnel_prl_entry
*
prl
;
/* potential router list */
struct
ip_tunnel_prl_entry
*
prl
;
/* potential router list */
unsigned
int
prl_count
;
/* # of entries in PRL */
};
};
struct
ip_tunnel_prl_entry
struct
ip_tunnel_prl_entry
{
{
struct
ip_tunnel_prl_entry
*
next
;
struct
ip_tunnel_prl_entry
*
next
;
struct
ip_tunnel_prl
entry
;
__be32
addr
;
u16
flags
;
};
};
#define IPTUNNEL_XMIT() do { \
#define IPTUNNEL_XMIT() do { \
...
...
net/ipv6/sit.c
View file @
300aaeea
...
@@ -203,12 +203,73 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
...
@@ -203,12 +203,73 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
struct
ip_tunnel_prl_entry
*
p
=
(
struct
ip_tunnel_prl_entry
*
)
NULL
;
struct
ip_tunnel_prl_entry
*
p
=
(
struct
ip_tunnel_prl_entry
*
)
NULL
;
for
(
p
=
t
->
prl
;
p
;
p
=
p
->
next
)
for
(
p
=
t
->
prl
;
p
;
p
=
p
->
next
)
if
(
p
->
entry
.
addr
==
addr
)
if
(
p
->
addr
==
addr
)
break
;
break
;
return
p
;
return
p
;
}
}
static
int
ipip6_tunnel_get_prl
(
struct
ip_tunnel
*
t
,
struct
ip_tunnel_prl
*
a
)
{
struct
ip_tunnel_prl
*
kp
;
struct
ip_tunnel_prl_entry
*
prl
;
unsigned
int
cmax
,
c
=
0
,
ca
,
len
;
int
ret
=
0
;
cmax
=
a
->
datalen
/
sizeof
(
*
a
);
if
(
cmax
>
1
&&
a
->
addr
!=
htonl
(
INADDR_ANY
))
cmax
=
1
;
/* For simple GET or for root users,
* we try harder to allocate.
*/
kp
=
(
cmax
<=
1
||
capable
(
CAP_NET_ADMIN
))
?
kcalloc
(
cmax
,
sizeof
(
*
kp
),
GFP_KERNEL
)
:
NULL
;
read_lock
(
&
ipip6_lock
);
ca
=
t
->
prl_count
<
cmax
?
t
->
prl_count
:
cmax
;
if
(
!
kp
)
{
/* We don't try hard to allocate much memory for
* non-root users.
* For root users, retry allocating enough memory for
* the answer.
*/
kp
=
kcalloc
(
ca
,
sizeof
(
*
kp
),
GFP_ATOMIC
);
if
(
!
kp
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
}
c
=
0
;
for
(
prl
=
t
->
prl
;
prl
;
prl
=
prl
->
next
)
{
if
(
c
>
cmax
)
break
;
if
(
a
->
addr
!=
htonl
(
INADDR_ANY
)
&&
prl
->
addr
!=
a
->
addr
)
continue
;
kp
[
c
].
addr
=
prl
->
addr
;
kp
[
c
].
flags
=
prl
->
flags
;
c
++
;
if
(
a
->
addr
!=
htonl
(
INADDR_ANY
))
break
;
}
out:
read_unlock
(
&
ipip6_lock
);
len
=
sizeof
(
*
kp
)
*
c
;
ret
=
len
?
copy_to_user
(
a
->
data
,
kp
,
len
)
:
0
;
kfree
(
kp
);
if
(
ret
)
return
-
EFAULT
;
a
->
datalen
=
len
;
return
0
;
}
static
int
static
int
ipip6_tunnel_add_prl
(
struct
ip_tunnel
*
t
,
struct
ip_tunnel_prl
*
a
,
int
chg
)
ipip6_tunnel_add_prl
(
struct
ip_tunnel
*
t
,
struct
ip_tunnel_prl
*
a
,
int
chg
)
{
{
...
@@ -221,7 +282,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
...
@@ -221,7 +282,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
write_lock
(
&
ipip6_lock
);
write_lock
(
&
ipip6_lock
);
for
(
p
=
t
->
prl
;
p
;
p
=
p
->
next
)
{
for
(
p
=
t
->
prl
;
p
;
p
=
p
->
next
)
{
if
(
p
->
entry
.
addr
==
a
->
addr
)
{
if
(
p
->
addr
==
a
->
addr
)
{
if
(
chg
)
if
(
chg
)
goto
update
;
goto
update
;
err
=
-
EEXIST
;
err
=
-
EEXIST
;
...
@@ -242,8 +303,10 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
...
@@ -242,8 +303,10 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
p
->
next
=
t
->
prl
;
p
->
next
=
t
->
prl
;
t
->
prl
=
p
;
t
->
prl
=
p
;
t
->
prl_count
++
;
update:
update:
p
->
entry
=
*
a
;
p
->
addr
=
a
->
addr
;
p
->
flags
=
a
->
flags
;
out:
out:
write_unlock
(
&
ipip6_lock
);
write_unlock
(
&
ipip6_lock
);
return
err
;
return
err
;
...
@@ -259,10 +322,11 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
...
@@ -259,10 +322,11 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
if
(
a
&&
a
->
addr
!=
htonl
(
INADDR_ANY
))
{
if
(
a
&&
a
->
addr
!=
htonl
(
INADDR_ANY
))
{
for
(
p
=
&
t
->
prl
;
*
p
;
p
=
&
(
*
p
)
->
next
)
{
for
(
p
=
&
t
->
prl
;
*
p
;
p
=
&
(
*
p
)
->
next
)
{
if
((
*
p
)
->
entry
.
addr
==
a
->
addr
)
{
if
((
*
p
)
->
addr
==
a
->
addr
)
{
x
=
*
p
;
x
=
*
p
;
*
p
=
x
->
next
;
*
p
=
x
->
next
;
kfree
(
x
);
kfree
(
x
);
t
->
prl_count
--
;
goto
out
;
goto
out
;
}
}
}
}
...
@@ -272,6 +336,7 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
...
@@ -272,6 +336,7 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
x
=
t
->
prl
;
x
=
t
->
prl
;
t
->
prl
=
t
->
prl
->
next
;
t
->
prl
=
t
->
prl
->
next
;
kfree
(
x
);
kfree
(
x
);
t
->
prl_count
--
;
}
}
}
}
out:
out:
...
@@ -313,7 +378,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
...
@@ -313,7 +378,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
read_lock
(
&
ipip6_lock
);
read_lock
(
&
ipip6_lock
);
p
=
__ipip6_tunnel_locate_prl
(
t
,
iph
->
saddr
);
p
=
__ipip6_tunnel_locate_prl
(
t
,
iph
->
saddr
);
if
(
p
)
{
if
(
p
)
{
if
(
p
->
entry
.
flags
&
PRL_DEFAULT
)
if
(
p
->
flags
&
PRL_DEFAULT
)
skb
->
ndisc_nodetype
=
NDISC_NODETYPE_DEFAULT
;
skb
->
ndisc_nodetype
=
NDISC_NODETYPE_DEFAULT
;
else
else
skb
->
ndisc_nodetype
=
NDISC_NODETYPE_NODEFAULT
;
skb
->
ndisc_nodetype
=
NDISC_NODETYPE_NODEFAULT
;
...
@@ -899,11 +964,12 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
...
@@ -899,11 +964,12 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
err
=
0
;
err
=
0
;
break
;
break
;
case
SIOCGETPRL
:
case
SIOCADDPRL
:
case
SIOCADDPRL
:
case
SIOCDELPRL
:
case
SIOCDELPRL
:
case
SIOCCHGPRL
:
case
SIOCCHGPRL
:
err
=
-
EPERM
;
err
=
-
EPERM
;
if
(
!
capable
(
CAP_NET_ADMIN
))
if
(
cmd
!=
SIOCGETPRL
&&
!
capable
(
CAP_NET_ADMIN
))
goto
done
;
goto
done
;
err
=
-
EINVAL
;
err
=
-
EINVAL
;
if
(
dev
==
ipip6_fb_tunnel_dev
)
if
(
dev
==
ipip6_fb_tunnel_dev
)
...
@@ -915,11 +981,23 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
...
@@ -915,11 +981,23 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
if
(
!
(
t
=
netdev_priv
(
dev
)))
if
(
!
(
t
=
netdev_priv
(
dev
)))
goto
done
;
goto
done
;
if
(
cmd
==
SIOCDELPRL
)
switch
(
cmd
)
{
case
SIOCGETPRL
:
err
=
ipip6_tunnel_get_prl
(
t
,
&
prl
);
if
(
!
err
&&
copy_to_user
(
ifr
->
ifr_ifru
.
ifru_data
,
&
prl
,
sizeof
(
prl
)))
err
=
-
EFAULT
;
break
;
case
SIOCDELPRL
:
err
=
ipip6_tunnel_del_prl
(
t
,
&
prl
);
err
=
ipip6_tunnel_del_prl
(
t
,
&
prl
);
else
break
;
case
SIOCADDPRL
:
case
SIOCCHGPRL
:
err
=
ipip6_tunnel_add_prl
(
t
,
&
prl
,
cmd
==
SIOCCHGPRL
);
err
=
ipip6_tunnel_add_prl
(
t
,
&
prl
,
cmd
==
SIOCCHGPRL
);
netdev_state_change
(
dev
);
break
;
}
if
(
cmd
!=
SIOCGETPRL
)
netdev_state_change
(
dev
);
break
;
break
;
default:
default:
...
...
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