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
e442c99d
Commit
e442c99d
authored
Oct 08, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV4/IPV6]: Cleanup inet{,6}_protocol.
parent
8f6174bf
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
207 additions
and
416 deletions
+207
-416
include/net/protocol.h
include/net/protocol.h
+5
-15
include/net/raw.h
include/net/raw.h
+1
-1
include/net/rawv6.h
include/net/rawv6.h
+1
-3
net/ipv4/af_inet.c
net/ipv4/af_inet.c
+30
-9
net/ipv4/icmp.c
net/ipv4/icmp.c
+3
-16
net/ipv4/ip_gre.c
net/ipv4/ip_gre.c
+8
-9
net/ipv4/ip_input.c
net/ipv4/ip_input.c
+19
-54
net/ipv4/ipip.c
net/ipv4/ipip.c
+8
-6
net/ipv4/ipmr.c
net/ipv4/ipmr.c
+12
-14
net/ipv4/protocol.c
net/ipv4/protocol.c
+24
-106
net/ipv4/raw.c
net/ipv4/raw.c
+8
-18
net/ipv6/icmp.c
net/ipv6/icmp.c
+12
-20
net/ipv6/ip6_input.c
net/ipv6/ip6_input.c
+15
-31
net/ipv6/protocol.c
net/ipv6/protocol.c
+20
-55
net/ipv6/raw.c
net/ipv6/raw.c
+11
-21
net/ipv6/sit.c
net/ipv6/sit.c
+8
-9
net/ipv6/tcp_ipv6.c
net/ipv6/tcp_ipv6.c
+5
-7
net/ipv6/udp.c
net/ipv6/udp.c
+4
-5
net/sctp/ipv6.c
net/sctp/ipv6.c
+5
-8
net/sctp/protocol.c
net/sctp/protocol.c
+8
-9
No files found.
include/net/protocol.h
View file @
e442c99d
...
...
@@ -30,7 +30,7 @@
#include <linux/ipv6.h>
#endif
#define MAX_INET_PROTOS
32
/* Must be a power of 2 */
#define MAX_INET_PROTOS
256
/* Must be a power of 2 */
/* This is used to register protocols. */
...
...
@@ -38,11 +38,6 @@ struct inet_protocol
{
int
(
*
handler
)(
struct
sk_buff
*
skb
);
void
(
*
err_handler
)(
struct
sk_buff
*
skb
,
u32
info
);
struct
inet_protocol
*
next
;
unsigned
char
protocol
;
unsigned
char
copy
:
1
;
void
*
data
;
const
char
*
name
;
};
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
...
...
@@ -54,11 +49,6 @@ struct inet6_protocol
struct
inet6_skb_parm
*
opt
,
int
type
,
int
code
,
int
offset
,
__u32
info
);
struct
inet6_protocol
*
next
;
unsigned
char
protocol
;
unsigned
char
copy
:
1
;
void
*
data
;
const
char
*
name
;
};
#endif
...
...
@@ -93,14 +83,14 @@ extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
extern
struct
list_head
inetsw6
[
SOCK_MAX
];
#endif
extern
void
inet_add_protocol
(
struct
inet_protocol
*
prot
);
extern
int
inet_del_protocol
(
struct
inet_protocol
*
prot
);
extern
int
inet_add_protocol
(
struct
inet_protocol
*
prot
,
unsigned
char
num
);
extern
int
inet_del_protocol
(
struct
inet_protocol
*
prot
,
unsigned
char
num
);
extern
void
inet_register_protosw
(
struct
inet_protosw
*
p
);
extern
void
inet_unregister_protosw
(
struct
inet_protosw
*
p
);
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern
void
inet6_add_protocol
(
struct
inet6_protocol
*
prot
);
extern
int
inet6_del_protocol
(
struct
inet6_protocol
*
prot
);
extern
int
inet6_add_protocol
(
struct
inet6_protocol
*
prot
,
unsigned
char
num
);
extern
int
inet6_del_protocol
(
struct
inet6_protocol
*
prot
,
unsigned
char
num
);
extern
void
inet6_register_protosw
(
struct
inet_protosw
*
p
);
extern
void
inet6_unregister_protosw
(
struct
inet_protosw
*
p
);
#endif
...
...
include/net/raw.h
View file @
e442c99d
...
...
@@ -37,6 +37,6 @@ extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
unsigned
long
raddr
,
unsigned
long
laddr
,
int
dif
);
extern
struct
sock
*
raw_v4_input
(
struct
sk_buff
*
skb
,
struct
iphdr
*
iph
,
int
hash
);
extern
void
raw_v4_input
(
struct
sk_buff
*
skb
,
struct
iphdr
*
iph
,
int
hash
);
#endif
/* _RAW_H */
include/net/rawv6.h
View file @
e442c99d
...
...
@@ -7,9 +7,7 @@
extern
struct
sock
*
raw_v6_htable
[
RAWV6_HTABLE_SIZE
];
extern
rwlock_t
raw_v6_lock
;
extern
struct
sock
*
ipv6_raw_deliver
(
struct
sk_buff
*
skb
,
int
nexthdr
);
extern
void
ipv6_raw_deliver
(
struct
sk_buff
*
skb
,
int
nexthdr
);
extern
struct
sock
*
__raw_v6_lookup
(
struct
sock
*
sk
,
unsigned
short
num
,
struct
in6_addr
*
loc_addr
,
struct
in6_addr
*
rmt_addr
);
...
...
net/ipv4/af_inet.c
View file @
e442c99d
...
...
@@ -1093,6 +1093,25 @@ void inet_unregister_protosw(struct inet_protosw *p)
}
}
#ifdef CONFIG_IP_MULTICAST
static
struct
inet_protocol
igmp_protocol
=
{
.
handler
=
igmp_rcv
,
};
#endif
static
struct
inet_protocol
tcp_protocol
=
{
.
handler
=
tcp_v4_rcv
,
.
err_handler
=
tcp_v4_err
,
};
static
struct
inet_protocol
udp_protocol
=
{
.
handler
=
udp_rcv
,
.
err_handler
=
udp_err
,
};
static
struct
inet_protocol
icmp_protocol
=
{
.
handler
=
icmp_rcv
,
};
/*
* Called by socket.c on kernel startup.
...
...
@@ -1101,7 +1120,6 @@ void inet_unregister_protosw(struct inet_protosw *p)
static
int
__init
inet_init
(
void
)
{
struct
sk_buff
*
dummy_skb
;
struct
inet_protocol
*
p
;
struct
inet_protosw
*
q
;
struct
list_head
*
r
;
...
...
@@ -1131,16 +1149,19 @@ static int __init inet_init(void)
(
void
)
sock_register
(
&
inet_family_ops
);
/*
* Add all the
protocols.
* Add all the
base protocols.
*/
printk
(
KERN_INFO
"IP Protocols: "
);
for
(
p
=
inet_protocol_base
;
p
;)
{
struct
inet_protocol
*
tmp
=
(
struct
inet_protocol
*
)
p
->
next
;
inet_add_protocol
(
p
);
printk
(
"%s%s"
,
p
->
name
,
tmp
?
", "
:
"
\n
"
);
p
=
tmp
;
}
if
(
inet_add_protocol
(
&
icmp_protocol
,
IPPROTO_ICMP
)
<
0
)
printk
(
KERN_CRIT
"inet_init: Cannot add ICMP protocol
\n
"
);
if
(
inet_add_protocol
(
&
udp_protocol
,
IPPROTO_UDP
)
<
0
)
printk
(
KERN_CRIT
"inet_init: Cannot add UDP protocol
\n
"
);
if
(
inet_add_protocol
(
&
tcp_protocol
,
IPPROTO_TCP
)
<
0
)
printk
(
KERN_CRIT
"inet_init: Cannot add TCP protocol
\n
"
);
#ifdef CONFIG_IP_MULTICAST
if
(
inet_add_protocol
(
&
igmp_protocol
,
IPPROTO_IGMP
)
<
0
)
printk
(
KERN_CRIT
"inet_init: Cannot add TCP protocol
\n
"
);
#endif
/* Register the socket-side information for inet_create. */
for
(
r
=
&
inetsw
[
0
];
r
<
&
inetsw
[
SOCK_MAX
];
++
r
)
...
...
net/ipv4/icmp.c
View file @
e442c99d
...
...
@@ -719,23 +719,10 @@ static void icmp_unreach(struct sk_buff *skb)
* we are OK.
*/
ipprot
=
(
struct
inet_protocol
*
)
inet_protos
[
hash
];
while
(
ipprot
)
{
struct
inet_protocol
*
nextip
;
ipprot
=
inet_protos
[
hash
];
if
(
ipprot
&&
ipprot
->
err_handler
)
ipprot
->
err_handler
(
skb
,
info
)
;
nextip
=
(
struct
inet_protocol
*
)
ipprot
->
next
;
/*
* Pass it off to everyone who wants it.
*/
/* RFC1122: OK. Passes appropriate ICMP errors to the */
/* appropriate protocol layer (MUST), as per 3.2.2. */
if
(
protocol
==
ipprot
->
protocol
&&
ipprot
->
err_handler
)
ipprot
->
err_handler
(
skb
,
info
);
ipprot
=
nextip
;
}
out:
return
;
out_err:
...
...
net/ipv4/ip_gre.c
View file @
e442c99d
...
...
@@ -1259,13 +1259,8 @@ int __init ipgre_fb_tunnel_init(struct net_device *dev)
static
struct
inet_protocol
ipgre_protocol
=
{
ipgre_rcv
,
/* GRE handler */
ipgre_err
,
/* TUNNEL error control */
0
,
/* next */
IPPROTO_GRE
,
/* protocol ID */
0
,
/* copy */
NULL
,
/* data */
"GRE"
/* name */
.
handler
=
ipgre_rcv
,
.
err_handler
=
ipgre_err
,
};
...
...
@@ -1281,9 +1276,13 @@ int __init ipgre_init(void)
{
printk
(
KERN_INFO
"GRE over IPv4 tunneling driver
\n
"
);
if
(
inet_add_protocol
(
&
ipgre_protocol
,
IPPROTO_GRE
)
<
0
)
{
printk
(
KERN_INFO
"ipgre init: can't add protocol
\n
"
);
return
-
EAGAIN
;
}
ipgre_fb_tunnel_dev
.
priv
=
(
void
*
)
&
ipgre_fb_tunnel
;
register_netdev
(
&
ipgre_fb_tunnel_dev
);
inet_add_protocol
(
&
ipgre_protocol
);
return
0
;
}
...
...
@@ -1291,7 +1290,7 @@ int __init ipgre_init(void)
void
cleanup_module
(
void
)
{
if
(
inet_del_protocol
(
&
ipgre_protocol
)
<
0
)
if
(
inet_del_protocol
(
&
ipgre_protocol
,
IPPROTO_GRE
)
<
0
)
printk
(
KERN_INFO
"ipgre close: can't remove protocol
\n
"
);
unregister_netdev
(
&
ipgre_fb_tunnel_dev
);
...
...
net/ipv4/ip_input.c
View file @
e442c99d
...
...
@@ -194,28 +194,6 @@ int ip_call_ra_chain(struct sk_buff *skb)
return
0
;
}
/* Handle this out of line, it is rare. */
static
int
ip_run_ipprot
(
struct
sk_buff
*
skb
,
struct
iphdr
*
iph
,
struct
inet_protocol
*
ipprot
,
int
force_copy
)
{
int
ret
=
0
;
do
{
if
(
ipprot
->
protocol
==
iph
->
protocol
)
{
struct
sk_buff
*
skb2
=
skb
;
if
(
ipprot
->
copy
||
force_copy
)
skb2
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
skb2
!=
NULL
)
{
ret
=
1
;
ipprot
->
handler
(
skb2
);
}
}
ipprot
=
(
struct
inet_protocol
*
)
ipprot
->
next
;
}
while
(
ipprot
!=
NULL
);
return
ret
;
}
static
inline
int
ip_local_deliver_finish
(
struct
sk_buff
*
skb
)
{
int
ihl
=
skb
->
nh
.
iph
->
ihl
*
4
;
...
...
@@ -239,44 +217,31 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
{
/* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */
int
protocol
=
skb
->
nh
.
iph
->
protocol
;
int
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
)
;
struct
sock
*
raw_sk
=
raw_v4_htable
[
hash
]
;
int
hash
;
struct
sock
*
raw_sk
;
struct
inet_protocol
*
ipprot
;
int
flag
;
resubmit:
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
);
raw_sk
=
raw_v4_htable
[
hash
];
/* If there maybe a raw socket we must check - if not we
* don't care less
*/
if
(
raw_sk
!=
NULL
)
raw_sk
=
raw_v4_input
(
skb
,
skb
->
nh
.
iph
,
hash
);
ipprot
=
(
struct
inet_protocol
*
)
inet_protos
[
hash
];
flag
=
0
;
if
(
ipprot
!=
NULL
)
{
if
(
raw_sk
==
NULL
&&
ipprot
->
next
==
NULL
&&
ipprot
->
protocol
==
protocol
)
{
int
ret
;
/* Fast path... */
ret
=
ipprot
->
handler
(
skb
);
return
ret
;
}
else
{
flag
=
ip_run_ipprot
(
skb
,
skb
->
nh
.
iph
,
ipprot
,
(
raw_sk
!=
NULL
));
if
(
raw_sk
)
raw_v4_input
(
skb
,
skb
->
nh
.
iph
,
hash
);
if
((
ipprot
=
inet_protos
[
hash
])
!=
NULL
)
{
int
ret
=
ipprot
->
handler
(
skb
);
if
(
ret
<
0
)
{
protocol
=
-
ret
;
goto
resubmit
;
}
}
else
{
if
(
!
raw_sk
)
{
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_PROT_UNREACH
,
0
);
}
}
/* All protocols checked.
* If this packet was a broadcast, we may *not* reply to it, since that
* causes (proven, grin) ARP storms and a leakage of memory (i.e. all
* ICMP reply messages get queued up for transmission...)
*/
if
(
raw_sk
!=
NULL
)
{
/* Shift to last raw user */
raw_rcv
(
raw_sk
,
skb
);
sock_put
(
raw_sk
);
}
else
if
(
!
flag
)
{
/* Free and report errors */
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_PROT_UNREACH
,
0
);
kfree_skb
(
skb
);
}
}
...
...
net/ipv4/ipip.c
View file @
e442c99d
...
...
@@ -877,10 +877,8 @@ int __init ipip_fb_tunnel_init(struct net_device *dev)
}
static
struct
inet_protocol
ipip_protocol
=
{
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
.
protocol
=
IPPROTO_IPIP
,
.
name
=
"IPIP"
.
handler
=
ipip_rcv
,
.
err_handler
=
ipip_err
,
};
static
char
banner
[]
__initdata
=
...
...
@@ -890,15 +888,19 @@ int __init ipip_init(void)
{
printk
(
banner
);
if
(
inet_add_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
{
printk
(
KERN_INFO
"ipip init: can't add protocol
\n
"
);
return
-
EAGAIN
;
}
ipip_fb_tunnel_dev
.
priv
=
(
void
*
)
&
ipip_fb_tunnel
;
register_netdev
(
&
ipip_fb_tunnel_dev
);
inet_add_protocol
(
&
ipip_protocol
);
return
0
;
}
static
void
__exit
ipip_fini
(
void
)
{
if
(
inet_del_protocol
(
&
ipip_protocol
)
<
0
)
if
(
inet_del_protocol
(
&
ipip_protocol
,
IPPROTO_IPIP
)
<
0
)
printk
(
KERN_INFO
"ipip close: can't remove protocol
\n
"
);
unregister_netdev
(
&
ipip_fb_tunnel_dev
);
...
...
net/ipv4/ipmr.c
View file @
e442c99d
...
...
@@ -108,7 +108,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
static
int
ipmr_cache_report
(
struct
sk_buff
*
pkt
,
vifi_t
vifi
,
int
assert
);
static
int
ipmr_fill_mroute
(
struct
sk_buff
*
skb
,
struct
mfc_cache
*
c
,
struct
rtmsg
*
rtm
);
extern
struct
inet_protocol
pim_protocol
;
static
struct
inet_protocol
pim_protocol
;
static
struct
timer_list
ipmr_expire_timer
;
...
...
@@ -928,23 +928,28 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char *optval,int optlen)
#ifdef CONFIG_IP_PIMSM
case
MRT_PIM
:
{
int
v
;
int
v
,
ret
;
if
(
get_user
(
v
,(
int
*
)
optval
))
return
-
EFAULT
;
v
=
(
v
)
?
1
:
0
;
rtnl_lock
();
ret
=
0
;
if
(
v
!=
mroute_do_pim
)
{
mroute_do_pim
=
v
;
mroute_do_assert
=
v
;
#ifdef CONFIG_IP_PIMSM_V2
if
(
mroute_do_pim
)
inet_add_protocol
(
&
pim_protocol
);
ret
=
inet_add_protocol
(
&
pim_protocol
,
IPPROTO_PIM
);
else
inet_del_protocol
(
&
pim_protocol
);
ret
=
inet_del_protocol
(
&
pim_protocol
,
IPPROTO_PIM
);
if
(
ret
<
0
)
ret
=
-
EAGAIN
;
#endif
}
rtnl_unlock
();
return
0
;
return
ret
;
}
#endif
/*
...
...
@@ -1727,15 +1732,8 @@ static int ipmr_mfc_info(char *buffer, char **start, off_t offset, int length)
#endif
#ifdef CONFIG_IP_PIMSM_V2
struct
inet_protocol
pim_protocol
=
{
pim_rcv
,
/* PIM handler */
NULL
,
/* PIM error control */
NULL
,
/* next */
IPPROTO_PIM
,
/* protocol ID */
0
,
/* copy */
NULL
,
/* data */
"PIM"
/* name */
static
struct
inet_protocol
pim_protocol
=
{
.
handler
=
pim_rcv
,
};
#endif
...
...
net/ipv4/protocol.c
View file @
e442c99d
...
...
@@ -48,134 +48,52 @@
#include <net/ipip.h>
#include <linux/igmp.h>
#define IPPROTO_PREVIOUS NULL
#ifdef CONFIG_IP_MULTICAST
static
struct
inet_protocol
igmp_protocol
=
{
.
handler
=
igmp_rcv
,
.
next
=
IPPROTO_PREVIOUS
,
.
protocol
=
IPPROTO_IGMP
,
.
name
=
"IGMP"
};
#undef IPPROTO_PREVIOUS
#define IPPROTO_PREVIOUS &igmp_protocol
#endif
static
struct
inet_protocol
tcp_protocol
=
{
.
handler
=
tcp_v4_rcv
,
.
err_handler
=
tcp_v4_err
,
.
next
=
IPPROTO_PREVIOUS
,
.
protocol
=
IPPROTO_TCP
,
.
name
=
"TCP"
};
#undef IPPROTO_PREVIOUS
#define IPPROTO_PREVIOUS &tcp_protocol
static
struct
inet_protocol
udp_protocol
=
{
.
handler
=
udp_rcv
,
.
err_handler
=
udp_err
,
.
next
=
IPPROTO_PREVIOUS
,
.
protocol
=
IPPROTO_UDP
,
.
name
=
"UDP"
};
#undef IPPROTO_PREVIOUS
#define IPPROTO_PREVIOUS &udp_protocol
static
struct
inet_protocol
icmp_protocol
=
{
.
handler
=
icmp_rcv
,
.
next
=
IPPROTO_PREVIOUS
,
.
protocol
=
IPPROTO_ICMP
,
.
name
=
"ICMP"
};
#undef IPPROTO_PREVIOUS
#define IPPROTO_PREVIOUS &icmp_protocol
struct
inet_protocol
*
inet_protocol_base
=
IPPROTO_PREVIOUS
;
struct
inet_protocol
*
inet_protos
[
MAX_INET_PROTOS
];
/*
* Add a protocol handler to the hash tables
*/
void
inet_add_protocol
(
struct
inet_protocol
*
prot
)
int
inet_add_protocol
(
struct
inet_protocol
*
prot
,
unsigned
char
protocol
)
{
unsigned
char
hash
;
struct
inet_protocol
*
p2
;
int
hash
,
ret
;
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
);
hash
=
prot
->
protocol
&
(
MAX_INET_PROTOS
-
1
);
br_write_lock_bh
(
BR_NETPROTO_LOCK
);
prot
->
next
=
inet_protos
[
hash
];
inet_protos
[
hash
]
=
prot
;
prot
->
copy
=
0
;
/*
* Set the copy bit if we need to.
*/
p2
=
(
struct
inet_protocol
*
)
prot
->
next
;
while
(
p2
)
{
if
(
p2
->
protocol
==
prot
->
protocol
)
{
prot
->
copy
=
1
;
break
;
}
p2
=
(
struct
inet_protocol
*
)
p2
->
next
;
if
(
inet_protos
[
hash
])
{
ret
=
-
1
;
}
else
{
inet_protos
[
hash
]
=
prot
;
ret
=
0
;
}
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
ret
;
}
/*
* Remove a protocol from the hash tables.
*/
int
inet_del_protocol
(
struct
inet_protocol
*
prot
)
int
inet_del_protocol
(
struct
inet_protocol
*
prot
,
unsigned
char
protocol
)
{
struct
inet_protocol
*
p
;
struct
inet_protocol
*
lp
=
NULL
;
unsigned
char
hash
;
int
hash
,
ret
;
hash
=
prot
->
protocol
&
(
MAX_INET_PROTOS
-
1
);
br_write_lock_bh
(
BR_NETPROTO_LOCK
);
if
(
prot
==
inet_protos
[
hash
])
{
inet_protos
[
hash
]
=
(
struct
inet_protocol
*
)
inet_protos
[
hash
]
->
next
;
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
0
;
}
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
);
p
=
(
struct
inet_protocol
*
)
inet_protos
[
hash
];
if
(
p
!=
NULL
&&
p
->
protocol
==
prot
->
protocol
)
lp
=
p
;
while
(
p
)
{
/*
* We have to worry if the protocol being deleted is
* the last one on the list, then we may need to reset
* someone's copied bit.
*/
if
(
p
->
next
&&
p
->
next
==
prot
)
{
/*
* if we are the last one with this protocol and
* there is a previous one, reset its copy bit.
*/
if
(
prot
->
copy
==
0
&&
lp
!=
NULL
)
lp
->
copy
=
0
;
p
->
next
=
prot
->
next
;
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
0
;
}
if
(
p
->
next
!=
NULL
&&
p
->
next
->
protocol
==
prot
->
protocol
)
lp
=
p
->
next
;
br_write_lock_bh
(
BR_NETPROTO_LOCK
);
p
=
(
struct
inet_protocol
*
)
p
->
next
;
if
(
inet_protos
[
hash
]
==
prot
)
{
inet_protos
[
hash
]
=
NULL
;
ret
=
0
;
}
else
{
ret
=
-
1
;
}
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
-
1
;
return
ret
;
}
net/ipv4/raw.c
View file @
e442c99d
...
...
@@ -135,13 +135,12 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
}
/* IP input processing comes here for RAW socket delivery.
* This is fun as to avoid copies we want to make no surplus
* copies.
* Caller owns SKB, so we must make clones.
*
* RFC 1122: SHOULD pass TOS value up to the transport layer.
* -> It does. And not only TOS, but all IP header.
*/
struct
sock
*
raw_v4_input
(
struct
sk_buff
*
skb
,
struct
iphdr
*
iph
,
int
hash
)
void
raw_v4_input
(
struct
sk_buff
*
skb
,
struct
iphdr
*
iph
,
int
hash
)
{
struct
sock
*
sk
;
...
...
@@ -153,28 +152,19 @@ struct sock *raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
skb
->
dev
->
ifindex
);
while
(
sk
)
{
struct
sock
*
sknext
=
__raw_v4_lookup
(
sk
->
next
,
iph
->
protocol
,
iph
->
saddr
,
iph
->
daddr
,
skb
->
dev
->
ifindex
);
if
(
iph
->
protocol
!=
IPPROTO_ICMP
||
!
icmp_filter
(
sk
,
skb
))
{
struct
sk_buff
*
clone
;
if
(
!
sknext
)
break
;
clone
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
iph
->
protocol
!=
IPPROTO_ICMP
||
!
icmp_filter
(
sk
,
skb
))
{
struct
sk_buff
*
clone
=
skb_clone
(
skb
,
GFP_ATOMIC
);
/* Not releasing hash table! */
if
(
clone
)
raw_rcv
(
sk
,
clone
);
}
sk
=
sknext
;
sk
=
__raw_v4_lookup
(
sk
->
next
,
iph
->
protocol
,
iph
->
saddr
,
iph
->
daddr
,
skb
->
dev
->
ifindex
);
}
out:
if
(
sk
)
sock_hold
(
sk
);
read_unlock
(
&
raw_v4_lock
);
return
sk
;
}
void
raw_err
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
u32
info
)
...
...
net/ipv6/icmp.c
View file @
e442c99d
...
...
@@ -70,15 +70,8 @@ struct socket *icmpv6_socket;
static
int
icmpv6_rcv
(
struct
sk_buff
*
skb
);
static
struct
inet6_protocol
icmpv6_protocol
=
{
icmpv6_rcv
,
/* handler */
NULL
,
/* error control */
NULL
,
/* next */
IPPROTO_ICMPV6
,
/* protocol ID */
0
,
/* copy */
NULL
,
/* data */
"ICMPv6"
/* name */
static
struct
inet6_protocol
icmpv6_protocol
=
{
.
handler
=
icmpv6_rcv
,
};
struct
icmpv6_msg
{
...
...
@@ -467,15 +460,9 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
hash
=
nexthdr
&
(
MAX_INET_PROTOS
-
1
);
for
(
ipprot
=
(
struct
inet6_protocol
*
)
inet6_protos
[
hash
];
ipprot
!=
NULL
;
ipprot
=
(
struct
inet6_protocol
*
)
ipprot
->
next
)
{
if
(
ipprot
->
protocol
!=
nexthdr
)
continue
;
if
(
ipprot
->
err_handler
)
ipprot
->
err_handler
(
skb
,
NULL
,
type
,
code
,
inner_offset
,
info
);
}
ipprot
=
inet6_protos
[
hash
];
if
(
ipprot
&&
ipprot
->
err_handler
)
ipprot
->
err_handler
(
skb
,
NULL
,
type
,
code
,
inner_offset
,
info
);
read_lock
(
&
raw_v6_lock
);
if
((
sk
=
raw_v6_htable
[
hash
])
!=
NULL
)
{
...
...
@@ -651,7 +638,12 @@ int __init icmpv6_init(struct net_proto_family *ops)
sk
->
sndbuf
=
SK_WMEM_MAX
*
2
;
sk
->
prot
->
unhash
(
sk
);
inet6_add_protocol
(
&
icmpv6_protocol
);
if
(
inet6_add_protocol
(
&
icmpv6_protocol
,
IPPROTO_ICMPV6
)
<
0
)
{
printk
(
KERN_ERR
"Failed to register ICMP6 protocol
\n
"
);
sock_release
(
icmpv6_socket
);
icmpv6_socket
=
NULL
;
return
-
EAGAIN
;
}
return
0
;
}
...
...
@@ -660,7 +652,7 @@ void icmpv6_cleanup(void)
{
sock_release
(
icmpv6_socket
);
icmpv6_socket
=
NULL
;
/* For safety. */
inet6_del_protocol
(
&
icmpv6_protocol
);
inet6_del_protocol
(
&
icmpv6_protocol
,
IPPROTO_ICMPV6
);
}
static
struct
icmp6_err
{
...
...
net/ipv6/ip6_input.c
View file @
e442c99d
...
...
@@ -126,7 +126,6 @@ static inline int ip6_input_finish(struct sk_buff *skb)
struct
sock
*
raw_sk
;
int
nhoff
;
int
nexthdr
;
int
found
=
0
;
u8
hash
;
skb
->
h
.
raw
=
skb
->
nh
.
raw
+
sizeof
(
struct
ipv6hdr
);
...
...
@@ -164,39 +163,24 @@ static inline int ip6_input_finish(struct sk_buff *skb)
skb
->
csum
=
csum_sub
(
skb
->
csum
,
csum_partial
(
skb
->
nh
.
raw
,
skb
->
h
.
raw
-
skb
->
nh
.
raw
,
0
));
raw_sk
=
raw_v6_htable
[
nexthdr
&
(
MAX_INET_PROTOS
-
1
)];
resubmit:
raw_sk
=
raw_v6_htable
[
nexthdr
&
(
MAX_INET_PROTOS
-
1
)];
if
(
raw_sk
)
raw_sk
=
ipv6_raw_deliver
(
skb
,
nexthdr
);
ipv6_raw_deliver
(
skb
,
nexthdr
);
hash
=
nexthdr
&
(
MAX_INET_PROTOS
-
1
);
for
(
ipprot
=
(
struct
inet6_protocol
*
)
inet6_protos
[
hash
];
ipprot
!=
NULL
;
ipprot
=
(
struct
inet6_protocol
*
)
ipprot
->
next
)
{
struct
sk_buff
*
buff
=
skb
;
if
(
ipprot
->
protocol
!=
nexthdr
)
continue
;
if
(
ipprot
->
copy
||
raw_sk
)
buff
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
buff
)
ipprot
->
handler
(
buff
);
found
=
1
;
}
if
(
raw_sk
)
{
rawv6_rcv
(
raw_sk
,
skb
);
sock_put
(
raw_sk
);
found
=
1
;
}
/*
* not found: send ICMP parameter problem back
*/
if
(
!
found
)
{
IP6_INC_STATS_BH
(
Ip6InUnknownProtos
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
nhoff
);
if
((
ipprot
=
inet6_protos
[
hash
])
!=
NULL
)
{
int
ret
=
ipprot
->
handler
(
skb
);
if
(
ret
<
0
)
{
nexthdr
=
-
ret
;
goto
resubmit
;
}
}
else
{
if
(
!
raw_sk
)
{
IP6_INC_STATS_BH
(
Ip6InUnknownProtos
);
icmpv6_param_prob
(
skb
,
ICMPV6_UNK_NEXTHDR
,
nhoff
);
}
kfree_skb
(
skb
);
}
return
0
;
...
...
net/ipv6/protocol.c
View file @
e442c99d
...
...
@@ -42,77 +42,42 @@
struct
inet6_protocol
*
inet6_protos
[
MAX_INET_PROTOS
];
void
inet6_add_protocol
(
struct
inet6_protocol
*
prot
)
int
inet6_add_protocol
(
struct
inet6_protocol
*
prot
,
unsigned
char
protocol
)
{
unsigned
char
hash
;
struct
inet6_protocol
*
p2
;
int
ret
,
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
);
hash
=
prot
->
protocol
&
(
MAX_INET_PROTOS
-
1
);
br_write_lock_bh
(
BR_NETPROTO_LOCK
);
prot
->
next
=
inet6_protos
[
hash
];
inet6_protos
[
hash
]
=
prot
;
prot
->
copy
=
0
;
/*
* Set the copy bit if we need to.
*/
p2
=
(
struct
inet6_protocol
*
)
prot
->
next
;
while
(
p2
!=
NULL
)
{
if
(
p2
->
protocol
==
prot
->
protocol
)
{
prot
->
copy
=
1
;
break
;
}
p2
=
(
struct
inet6_protocol
*
)
p2
->
next
;
if
(
inet6_protos
[
hash
])
{
ret
=
-
1
;
}
else
{
inet6_protos
[
hash
]
=
prot
;
ret
=
0
;
}
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
ret
;
}
/*
* Remove a protocol from the hash tables.
*/
int
inet6_del_protocol
(
struct
inet6_protocol
*
prot
)
int
inet6_del_protocol
(
struct
inet6_protocol
*
prot
,
unsigned
char
protocol
)
{
struct
inet6_protocol
*
p
;
struct
inet6_protocol
*
lp
=
NULL
;
unsigned
char
hash
;
int
ret
,
hash
=
protocol
&
(
MAX_INET_PROTOS
-
1
);
hash
=
prot
->
protocol
&
(
MAX_INET_PROTOS
-
1
);
br_write_lock_bh
(
BR_NETPROTO_LOCK
);
if
(
prot
==
inet6_protos
[
hash
])
{
inet6_protos
[
hash
]
=
(
struct
inet6_protocol
*
)
inet6_protos
[
hash
]
->
next
;
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
(
0
);
}
p
=
(
struct
inet6_protocol
*
)
inet6_protos
[
hash
];
if
(
p
!=
NULL
&&
p
->
protocol
==
prot
->
protocol
)
lp
=
p
;
while
(
p
!=
NULL
)
{
/*
* We have to worry if the protocol being deleted is
* the last one on the list, then we may need to reset
* someone's copied bit.
*/
if
(
p
->
next
!=
NULL
&&
p
->
next
==
prot
)
{
/*
* if we are the last one with this protocol and
* there is a previous one, reset its copy bit.
*/
if
(
prot
->
copy
==
0
&&
lp
!=
NULL
)
lp
->
copy
=
0
;
p
->
next
=
prot
->
next
;
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
(
0
);
}
if
(
p
->
next
!=
NULL
&&
p
->
next
->
protocol
==
prot
->
protocol
)
lp
=
p
->
next
;
p
=
(
struct
inet6_protocol
*
)
p
->
next
;
if
(
inet6_protos
[
hash
]
!=
prot
)
{
ret
=
-
1
;
}
else
{
inet6_protos
[
hash
]
=
NULL
;
ret
=
0
;
}
br_write_unlock_bh
(
BR_NETPROTO_LOCK
);
return
(
-
1
);
return
ret
;
}
net/ipv6/raw.c
View file @
e442c99d
...
...
@@ -133,12 +133,14 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
* demultiplex raw sockets.
* (should consider queueing the skb in the sock receive_queue
* without calling rawv6.c)
*
* Caller owns SKB so we must make clones.
*/
struct
sock
*
ipv6_raw_deliver
(
struct
sk_buff
*
skb
,
int
nexthdr
)
void
ipv6_raw_deliver
(
struct
sk_buff
*
skb
,
int
nexthdr
)
{
struct
in6_addr
*
saddr
;
struct
in6_addr
*
daddr
;
struct
sock
*
sk
,
*
sk2
;
struct
sock
*
sk
;
__u8
hash
;
saddr
=
&
skb
->
nh
.
ipv6h
->
saddr
;
...
...
@@ -159,30 +161,18 @@ struct sock * ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
sk
=
__raw_v6_lookup
(
sk
,
nexthdr
,
daddr
,
saddr
);
if
(
sk
)
{
sk2
=
sk
;
while
((
sk2
=
__raw_v6_lookup
(
sk2
->
next
,
nexthdr
,
daddr
,
saddr
)))
{
struct
sk_buff
*
buff
;
if
(
nexthdr
==
IPPROTO_ICMPV6
&&
icmpv6_filter
(
sk2
,
skb
))
continue
;
while
(
sk
)
{
if
(
nexthdr
!=
IPPROTO_ICMPV6
||
!
icmpv6_filter
(
sk
,
skb
))
{
struct
sk_buff
*
clone
=
skb_clone
(
skb
,
GFP_ATOMIC
);
buff
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
buff
)
rawv6_rcv
(
sk
2
,
buff
);
/* Not releasing hash table! */
if
(
clone
)
rawv6_rcv
(
sk
,
clone
);
}
sk
=
__raw_v6_lookup
(
sk
->
next
,
nexthdr
,
daddr
,
saddr
);
}
if
(
sk
&&
nexthdr
==
IPPROTO_ICMPV6
&&
icmpv6_filter
(
sk
,
skb
))
sk
=
NULL
;
out:
if
(
sk
)
sock_hold
(
sk
);
read_unlock
(
&
raw_v6_lock
);
return
sk
;
}
/* This cleans up af_inet6 a bit. -DaveM */
...
...
net/ipv6/sit.c
View file @
e442c99d
...
...
@@ -835,19 +835,14 @@ int __init ipip6_fb_tunnel_init(struct net_device *dev)
}
static
struct
inet_protocol
sit_protocol
=
{
ipip6_rcv
,
ipip6_err
,
0
,
IPPROTO_IPV6
,
0
,
NULL
,
"IPv6"
.
handler
=
ipip6_rcv
,
.
err_handler
=
ipip6_err
,
};
#ifdef MODULE
void
sit_cleanup
(
void
)
{
inet_del_protocol
(
&
sit_protocol
);
inet_del_protocol
(
&
sit_protocol
,
IPPROTO_IPV6
);
unregister_netdev
(
&
ipip6_fb_tunnel_dev
);
}
#endif
...
...
@@ -856,9 +851,13 @@ int __init sit_init(void)
{
printk
(
KERN_INFO
"IPv6 over IPv4 tunneling driver
\n
"
);
if
(
inet_add_protocol
(
&
sit_protocol
,
IPPROTO_IPV6
)
<
0
)
{
printk
(
KERN_INFO
"sit init: Can't add protocol
\n
"
);
return
-
EAGAIN
;
}
ipip6_fb_tunnel_dev
.
priv
=
(
void
*
)
&
ipip6_fb_tunnel
;
strcpy
(
ipip6_fb_tunnel_dev
.
name
,
ipip6_fb_tunnel
.
parms
.
name
);
register_netdev
(
&
ipip6_fb_tunnel_dev
);
inet_add_protocol
(
&
sit_protocol
);
return
0
;
}
net/ipv6/tcp_ipv6.c
View file @
e442c99d
...
...
@@ -2156,12 +2156,9 @@ struct proto tcpv6_prot = {
.
get_port
=
tcp_v6_get_port
,
};
static
struct
inet6_protocol
tcpv6_protocol
=
{
.
handler
=
tcp_v6_rcv
,
.
err_handler
=
tcp_v6_err
,
.
protocol
=
IPPROTO_TCP
,
.
name
=
"TCPv6"
,
static
struct
inet6_protocol
tcpv6_protocol
=
{
.
handler
=
tcp_v6_rcv
,
.
err_handler
=
tcp_v6_err
,
};
extern
struct
proto_ops
inet6_stream_ops
;
...
...
@@ -2179,6 +2176,7 @@ static struct inet_protosw tcpv6_protosw = {
void
__init
tcpv6_init
(
void
)
{
/* register inet6 protocol */
inet6_add_protocol
(
&
tcpv6_protocol
);
if
(
inet6_add_protocol
(
&
tcpv6_protocol
,
IPPROTO_TCP
)
<
0
)
printk
(
KERN_ERR
"tcpv6_init: Could not register protocol
\n
"
);
inet6_register_protosw
(
&
tcpv6_protosw
);
}
net/ipv6/udp.c
View file @
e442c99d
...
...
@@ -907,10 +907,8 @@ static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen)
}
static
struct
inet6_protocol
udpv6_protocol
=
{
.
handler
=
udpv6_rcv
,
.
err_handler
=
udpv6_err
,
.
protocol
=
IPPROTO_UDP
,
.
name
=
"UDPv6"
,
.
handler
=
udpv6_rcv
,
.
err_handler
=
udpv6_err
,
};
#define LINE_LEN 190
...
...
@@ -1020,6 +1018,7 @@ static struct inet_protosw udpv6_protosw = {
void
__init
udpv6_init
(
void
)
{
inet6_add_protocol
(
&
udpv6_protocol
);
if
(
inet6_add_protocol
(
&
udpv6_protocol
,
IPPROTO_UDP
)
<
0
)
printk
(
KERN_ERR
"udpv6_init: Could not register protocol
\n
"
);
inet6_register_protosw
(
&
udpv6_protosw
);
}
net/sctp/ipv6.c
View file @
e442c99d
...
...
@@ -295,11 +295,6 @@ static struct inet_protosw sctpv6_protosw = {
static
struct
inet6_protocol
sctpv6_protocol
=
{
.
handler
=
sctp_rcv
,
.
err_handler
=
sctp_v6_err
,
.
next
=
NULL
,
.
protocol
=
IPPROTO_SCTP
,
.
copy
=
0
,
.
data
=
NULL
,
.
name
=
"SCTPv6"
};
static
sctp_func_t
sctp_ipv6_specific
=
{
...
...
@@ -320,10 +315,12 @@ static sctp_pf_t sctp_pf_inet6_specific = {
/* Initialize IPv6 support and register with inet6 stack. */
int
sctp_v6_init
(
void
)
{
/* Register inet6 protocol. */
if
(
inet6_add_protocol
(
&
sctpv6_protocol
,
IPPROTO_SCTP
)
<
0
)
return
-
EAGAIN
;
/* Add SCTPv6 to inetsw6 linked list. */
inet6_register_protosw
(
&
sctpv6_protosw
);
/* Register inet6 protocol. */
inet6_add_protocol
(
&
sctpv6_protocol
);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_set_pf_specific
(
PF_INET6
,
&
sctp_pf_inet6_specific
);
...
...
@@ -339,6 +336,6 @@ int sctp_v6_init(void)
void
sctp_v6_exit
(
void
)
{
list_del
(
&
sctp_ipv6_specific
.
list
);
inet6_del_protocol
(
&
sctpv6_protocol
);
inet6_del_protocol
(
&
sctpv6_protocol
,
IPPROTO_SCTP
);
inet6_unregister_protosw
(
&
sctpv6_protosw
);
}
net/sctp/protocol.c
View file @
e442c99d
...
...
@@ -434,10 +434,8 @@ struct inet_protosw sctp_protosw = {
/* Register with IP layer. */
static
struct
inet_protocol
sctp_protocol
=
{
.
handler
=
sctp_rcv
,
/* SCTP input handler. */
.
err_handler
=
sctp_v4_err
,
/* SCTP error control */
.
protocol
=
IPPROTO_SCTP
,
/* protocol ID */
.
name
=
"SCTP"
/* name */
.
handler
=
sctp_rcv
,
.
err_handler
=
sctp_v4_err
,
};
/* IPv4 address related functions. */
...
...
@@ -485,12 +483,13 @@ int sctp_init(void)
int
i
;
int
status
=
0
;
/* Add SCTP to inet_protos hash table. */
if
(
inet_add_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
)
<
0
)
return
-
EAGAIN
;
/* Add SCTP to inetsw linked list. */
inet_register_protosw
(
&
sctp_protosw
);
/* Add SCTP to inet_protos hash table. */
inet_add_protocol
(
&
sctp_protocol
);
/* Initialize proc fs directory. */
sctp_proc_init
();
...
...
@@ -626,7 +625,7 @@ int sctp_init(void)
err_ahash_alloc:
sctp_dbg_objcnt_exit
();
sctp_proc_exit
();
inet_del_protocol
(
&
sctp_protocol
);
inet_del_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
);
inet_unregister_protosw
(
&
sctp_protosw
);
return
status
;
}
...
...
@@ -656,7 +655,7 @@ void sctp_exit(void)
sctp_dbg_objcnt_exit
();
sctp_proc_exit
();
inet_del_protocol
(
&
sctp_protocol
);
inet_del_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
);
inet_unregister_protosw
(
&
sctp_protosw
);
}
...
...
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