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
nexedi
linux
Commits
66d2856c
Commit
66d2856c
authored
Apr 11, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPSEC]: Add ipv4 tunnel transformer.
parent
925511b7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
250 additions
and
14 deletions
+250
-14
include/net/xfrm.h
include/net/xfrm.h
+8
-0
net/ipv4/Makefile
net/ipv4/Makefile
+1
-1
net/ipv4/ipip.c
net/ipv4/ipip.c
+14
-13
net/ipv4/xfrm4_tunnel.c
net/ipv4/xfrm4_tunnel.c
+225
-0
net/netsyms.c
net/netsyms.c
+2
-0
No files found.
include/net/xfrm.h
View file @
66d2856c
...
...
@@ -723,6 +723,12 @@ struct xfrm_algo_desc {
struct
sadb_alg
desc
;
};
/* XFRM tunnel handlers. */
struct
xfrm_tunnel
{
int
(
*
handler
)(
struct
sk_buff
*
skb
);
void
(
*
err_handler
)(
struct
sk_buff
*
skb
,
void
*
info
);
};
extern
void
xfrm_init
(
void
);
extern
void
xfrm4_init
(
void
);
extern
void
xfrm4_fini
(
void
);
...
...
@@ -752,6 +758,8 @@ extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
extern
int
xfrm_check_selectors
(
struct
xfrm_state
**
x
,
int
n
,
struct
flowi
*
fl
);
extern
int
xfrm4_rcv
(
struct
sk_buff
*
skb
);
extern
int
xfrm4_rcv_encap
(
struct
sk_buff
*
skb
,
__u16
encap_type
);
extern
int
xfrm4_tunnel_register
(
struct
xfrm_tunnel
*
handler
);
extern
int
xfrm4_tunnel_deregister
(
struct
xfrm_tunnel
*
handler
);
extern
int
xfrm6_rcv
(
struct
sk_buff
**
pskb
);
extern
int
xfrm6_clear_mutable_options
(
struct
sk_buff
*
skb
,
u16
*
nh_offset
,
int
dir
);
extern
int
xfrm_user_policy
(
struct
sock
*
sk
,
int
optname
,
u8
*
optval
,
int
optlen
);
...
...
net/ipv4/Makefile
View file @
66d2856c
...
...
@@ -22,4 +22,4 @@ obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
obj-$(CONFIG_IP_PNP)
+=
ipconfig.o
obj-$(CONFIG_NETFILTER)
+=
netfilter/
obj-y
+=
xfrm4_policy.o xfrm4_state.o xfrm4_input.o
obj-y
+=
xfrm4_policy.o xfrm4_state.o xfrm4_input.o
xfrm4_tunnel.o
net/ipv4/ipip.c
View file @
66d2856c
...
...
@@ -115,6 +115,7 @@
#include <net/protocol.h>
#include <net/ipip.h>
#include <net/inet_ecn.h>
#include <net/xfrm.h>
#define HASH_SIZE 16
#define HASH(addr) ((addr^(addr>>4))&0xF)
...
...
@@ -285,7 +286,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
dev_put
(
dev
);
}
void
ipip_err
(
struct
sk_buff
*
skb
,
u32
info
)
void
ipip_err
(
struct
sk_buff
*
skb
,
void
*
__unused
)
{
#ifndef I_WISH_WORLD_WERE_PERFECT
...
...
@@ -468,11 +469,13 @@ void ipip_err(struct sk_buff *skb, u32 info)
#endif
}
static
inline
void
ipip_ecn_decapsulate
(
struct
iphdr
*
iph
,
struct
sk_buff
*
skb
)
static
inline
void
ipip_ecn_decapsulate
(
struct
iphdr
*
outer_
iph
,
struct
sk_buff
*
skb
)
{
if
(
INET_ECN_is_ce
(
iph
->
tos
)
&&
INET_ECN_is_not_ce
(
skb
->
nh
.
iph
->
tos
))
IP_ECN_set_ce
(
iph
);
struct
iphdr
*
inner_iph
=
skb
->
nh
.
iph
;
if
(
INET_ECN_is_ce
(
outer_iph
->
tos
)
&&
INET_ECN_is_not_ce
(
inner_iph
->
tos
))
IP_ECN_set_ce
(
inner_iph
);
}
int
ipip_rcv
(
struct
sk_buff
*
skb
)
...
...
@@ -511,10 +514,8 @@ int ipip_rcv(struct sk_buff *skb)
}
read_unlock
(
&
ipip_lock
);
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_PROT_UNREACH
,
0
);
out:
kfree_skb
(
skb
);
return
0
;
return
-
1
;
}
/*
...
...
@@ -867,7 +868,7 @@ int __init ipip_fb_tunnel_init(struct net_device *dev)
return
0
;
}
static
struct
inet_protocol
ipip_protocol
=
{
static
struct
xfrm_tunnel
ipip_handler
=
{
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
};
...
...
@@ -879,8 +880,8 @@ int __init ipip_init(void)
{
printk
(
banner
);
if
(
inet_add_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't
add protoco
l
\n
"
);
if
(
xfrm4_tunnel_register
(
&
ipip_handler
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't
register tunne
l
\n
"
);
return
-
EAGAIN
;
}
...
...
@@ -892,8 +893,8 @@ int __init ipip_init(void)
static
void
__exit
ipip_fini
(
void
)
{
if
(
inet_del_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't
remove protoco
l
\n
"
);
if
(
xfrm4_tunnel_deregister
(
&
ipip_handler
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't
deregister tunne
l
\n
"
);
unregister_netdev
(
&
ipip_fb_tunnel_dev
);
}
...
...
net/ipv4/xfrm4_tunnel.c
0 → 100644
View file @
66d2856c
/* xfrm4_tunnel.c: Generic IP tunnel transformer.
*
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
*/
#include <linux/skbuff.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/inet_ecn.h>
static
int
ipip_output
(
struct
sk_buff
*
skb
)
{
struct
dst_entry
*
dst
=
skb
->
dst
;
struct
xfrm_state
*
x
=
dst
->
xfrm
;
struct
iphdr
*
iph
,
*
top_iph
;
int
tos
;
iph
=
skb
->
nh
.
iph
;
spin_lock_bh
(
&
x
->
lock
);
tos
=
iph
->
tos
;
top_iph
=
(
struct
iphdr
*
)
skb_push
(
skb
,
x
->
props
.
header_len
);
top_iph
->
ihl
=
5
;
top_iph
->
version
=
4
;
top_iph
->
tos
=
INET_ECN_encapsulate
(
tos
,
iph
->
tos
);
top_iph
->
tot_len
=
htons
(
skb
->
len
);
top_iph
->
frag_off
=
iph
->
frag_off
&
~
htons
(
IP_MF
|
IP_OFFSET
);
if
(
!
(
iph
->
frag_off
&
htons
(
IP_DF
)))
__ip_select_ident
(
top_iph
,
dst
,
0
);
top_iph
->
ttl
=
iph
->
ttl
;
top_iph
->
protocol
=
IPPROTO_IPIP
;
top_iph
->
check
=
0
;
top_iph
->
saddr
=
x
->
props
.
saddr
.
a4
;
top_iph
->
daddr
=
x
->
id
.
daddr
.
a4
;
memset
(
&
(
IPCB
(
skb
)
->
opt
),
0
,
sizeof
(
struct
ip_options
));
ip_send_check
(
top_iph
);
skb
->
nh
.
raw
=
skb
->
data
;
x
->
curlft
.
bytes
+=
skb
->
len
;
x
->
curlft
.
packets
++
;
spin_unlock_bh
(
&
x
->
lock
);
if
((
skb
->
dst
=
dst_pop
(
dst
))
==
NULL
)
{
kfree_skb
(
skb
);
return
-
EHOSTUNREACH
;
}
return
NET_XMIT_BYPASS
;
}
static
inline
void
ipip_ecn_decapsulate
(
struct
iphdr
*
outer_iph
,
struct
sk_buff
*
skb
)
{
struct
iphdr
*
inner_iph
=
skb
->
nh
.
iph
;
if
(
INET_ECN_is_ce
(
outer_iph
->
tos
)
&&
INET_ECN_is_not_ce
(
inner_iph
->
tos
))
IP_ECN_set_ce
(
inner_iph
);
}
static
int
ipip_xfrm_rcv
(
struct
xfrm_state
*
x
,
struct
xfrm_decap_state
*
decap
,
struct
sk_buff
*
skb
)
{
struct
iphdr
*
outer_iph
=
skb
->
nh
.
iph
;
if
(
!
pskb_may_pull
(
skb
,
sizeof
(
struct
iphdr
)))
return
-
EINVAL
;
skb
->
mac
.
raw
=
skb
->
nh
.
raw
;
skb
->
nh
.
raw
=
skb
->
data
;
memset
(
&
(
IPCB
(
skb
)
->
opt
),
0
,
sizeof
(
struct
ip_options
));
dst_release
(
skb
->
dst
);
skb
->
dst
=
NULL
;
skb
->
protocol
=
htons
(
ETH_P_IP
);
skb
->
pkt_type
=
PACKET_HOST
;
ipip_ecn_decapsulate
(
outer_iph
,
skb
);
netif_rx
(
skb
);
return
0
;
}
static
struct
xfrm_tunnel
*
ipip_handler
;
static
DECLARE_MUTEX
(
xfrm4_tunnel_sem
);
int
xfrm4_tunnel_register
(
struct
xfrm_tunnel
*
handler
)
{
int
ret
;
down
(
&
xfrm4_tunnel_sem
);
ret
=
0
;
if
(
ipip_handler
!=
NULL
)
ret
=
-
EINVAL
;
if
(
!
ret
)
ipip_handler
=
handler
;
up
(
&
xfrm4_tunnel_sem
);
return
ret
;
}
int
xfrm4_tunnel_deregister
(
struct
xfrm_tunnel
*
handler
)
{
int
ret
;
down
(
&
xfrm4_tunnel_sem
);
ret
=
0
;
if
(
ipip_handler
!=
handler
)
ret
=
-
EINVAL
;
if
(
!
ret
)
ipip_handler
=
NULL
;
up
(
&
xfrm4_tunnel_sem
);
synchronize_net
();
return
ret
;
}
static
int
ipip_rcv
(
struct
sk_buff
*
skb
)
{
struct
xfrm_tunnel
*
handler
=
ipip_handler
;
struct
xfrm_state
*
x
=
NULL
;
int
err
;
/* Tunnel devices take precedence. */
if
(
handler
)
{
err
=
handler
->
handler
(
skb
);
if
(
!
err
)
goto
out
;
}
x
=
xfrm_state_lookup
((
xfrm_address_t
*
)
&
skb
->
nh
.
iph
->
daddr
,
skb
->
nh
.
iph
->
saddr
,
IPPROTO_IPIP
,
AF_INET
);
if
(
x
)
{
spin_lock
(
&
x
->
lock
);
if
(
unlikely
(
x
->
km
.
state
!=
XFRM_STATE_VALID
))
goto
drop_unlock
;
}
err
=
ipip_xfrm_rcv
(
x
,
NULL
,
skb
);
if
(
err
)
goto
drop_unlock
;
if
(
x
)
{
x
->
curlft
.
bytes
+=
skb
->
len
;
x
->
curlft
.
packets
++
;
spin_unlock
(
&
x
->
lock
);
xfrm_state_put
(
x
);
}
return
0
;
drop_unlock:
if
(
x
)
{
spin_unlock
(
&
x
->
lock
);
xfrm_state_put
(
x
);
}
kfree_skb
(
skb
);
out:
return
0
;
}
void
ipip_err
(
struct
sk_buff
*
skb
,
u32
info
)
{
struct
xfrm_tunnel
*
handler
=
ipip_handler
;
u32
arg
=
info
;
if
(
handler
)
handler
->
err_handler
(
skb
,
&
arg
);
}
static
int
ipip_init_state
(
struct
xfrm_state
*
x
,
void
*
args
)
{
x
->
props
.
header_len
=
sizeof
(
struct
iphdr
);
return
0
;
}
static
void
ipip_destroy
(
struct
xfrm_state
*
x
)
{
}
static
struct
xfrm_type
ipip_type
=
{
.
description
=
"IPIP"
,
.
proto
=
IPPROTO_IPIP
,
.
init_state
=
ipip_init_state
,
.
destructor
=
ipip_destroy
,
.
input
=
ipip_xfrm_rcv
,
.
output
=
ipip_output
};
static
struct
inet_protocol
ipip_protocol
=
{
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
};
static
int
__init
ipip_init
(
void
)
{
SET_MODULE_OWNER
(
&
ipip_type
);
if
(
xfrm_register_type
(
&
ipip_type
,
AF_INET
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't add xfrm type
\n
"
);
return
-
EAGAIN
;
}
if
(
inet_add_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't add protocol
\n
"
);
xfrm_unregister_type
(
&
ipip_type
,
AF_INET
);
return
-
EAGAIN
;
}
return
0
;
}
static
void
__exit
ipip_fini
(
void
)
{
if
(
inet_del_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't remove protocol
\n
"
);
if
(
xfrm_unregister_type
(
&
ipip_type
,
AF_INET
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't remove xfrm type
\n
"
);
}
module_init
(
ipip_init
);
module_exit
(
ipip_fini
);
MODULE_LICENSE
(
"GPL"
);
net/netsyms.c
View file @
66d2856c
...
...
@@ -318,6 +318,8 @@ EXPORT_SYMBOL(__secpath_destroy);
EXPORT_SYMBOL
(
xfrm_get_acqseq
);
EXPORT_SYMBOL
(
xfrm_parse_spi
);
EXPORT_SYMBOL
(
xfrm4_rcv
);
EXPORT_SYMBOL
(
xfrm4_tunnel_register
);
EXPORT_SYMBOL
(
xfrm4_tunnel_deregister
);
EXPORT_SYMBOL
(
xfrm_register_type
);
EXPORT_SYMBOL
(
xfrm_unregister_type
);
EXPORT_SYMBOL
(
xfrm_get_type
);
...
...
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