Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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
Show 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,10 +981,22 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
...
@@ -915,10 +981,22 @@ 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
);
break
;
}
if
(
cmd
!=
SIOCGETPRL
)
netdev_state_change
(
dev
);
netdev_state_change
(
dev
);
break
;
break
;
...
...
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