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
70ced8bf
Commit
70ced8bf
authored
Apr 22, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
b3d4c027
6febb776
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
385 additions
and
135 deletions
+385
-135
include/linux/igmp.h
include/linux/igmp.h
+5
-3
include/linux/net.h
include/linux/net.h
+3
-0
include/net/ip6_route.h
include/net/ip6_route.h
+1
-1
net/core/dev.c
net/core/dev.c
+10
-0
net/core/sock.c
net/core/sock.c
+9
-4
net/ipv4/igmp.c
net/ipv4/igmp.c
+129
-59
net/ipv4/ip_output.c
net/ipv4/ip_output.c
+1
-1
net/ipv4/ip_sockglue.c
net/ipv4/ip_sockglue.c
+161
-4
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Kconfig
+1
-1
net/ipv6/ipv6_sockglue.c
net/ipv6/ipv6_sockglue.c
+10
-2
net/ipv6/mcast.c
net/ipv6/mcast.c
+3
-33
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+3
-3
net/ipv6/route.c
net/ipv6/route.c
+10
-8
net/netlink/af_netlink.c
net/netlink/af_netlink.c
+7
-1
net/socket.c
net/socket.c
+32
-15
No files found.
include/linux/igmp.h
View file @
70ced8bf
...
...
@@ -191,7 +191,7 @@ struct ip_mc_list
(IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
#define IGMPV3_MRC(value) IGMPV3_EXP(0x80
00, 12
, 3, value)
#define IGMPV3_MRC(value) IGMPV3_EXP(0x80
, 4
, 3, value)
extern
int
ip_check_mc
(
struct
in_device
*
dev
,
u32
mc_addr
,
u32
src_addr
,
u16
proto
);
extern
int
igmp_rcv
(
struct
sk_buff
*
);
...
...
@@ -199,10 +199,12 @@ extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern
int
ip_mc_leave_group
(
struct
sock
*
sk
,
struct
ip_mreqn
*
imr
);
extern
void
ip_mc_drop_socket
(
struct
sock
*
sk
);
extern
int
ip_mc_source
(
int
add
,
int
omode
,
struct
sock
*
sk
,
struct
ip_mreq_source
*
mreqs
);
extern
int
ip_mc_msfilter
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
);
struct
ip_mreq_source
*
mreqs
,
int
ifindex
);
extern
int
ip_mc_msfilter
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
,
int
ifindex
);
extern
int
ip_mc_msfget
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
,
struct
ip_msfilter
*
optval
,
int
*
optlen
);
extern
int
ip_mc_gsfget
(
struct
sock
*
sk
,
struct
group_filter
*
gsf
,
struct
group_filter
*
optval
,
int
*
optlen
);
extern
int
ip_mc_sf_allow
(
struct
sock
*
sk
,
u32
local
,
u32
rmt
,
int
dif
);
extern
void
ip_mr_init
(
void
);
extern
void
ip_mc_init_dev
(
struct
in_device
*
);
...
...
include/linux/net.h
View file @
70ced8bf
...
...
@@ -140,6 +140,9 @@ struct net_proto_family {
struct
module
*
owner
;
};
extern
int
net_family_get
(
int
family
);
extern
void
net_family_put
(
int
family
);
struct
iovec
;
extern
int
sock_wake_async
(
struct
socket
*
sk
,
int
how
,
int
band
);
...
...
include/net/ip6_route.h
View file @
70ced8bf
...
...
@@ -59,7 +59,7 @@ extern struct rt6_info *rt6_lookup(struct in6_addr *daddr,
struct
in6_addr
*
saddr
,
int
oif
,
int
flags
);
extern
struct
rt6_info
*
ndisc_get_dummy_rt
(
void
);
extern
struct
rt6_info
*
ip6_dst_alloc
(
void
);
/*
* support functions for ND
...
...
net/core/dev.c
View file @
70ced8bf
...
...
@@ -2582,6 +2582,16 @@ int register_netdevice(struct net_device *dev)
if
((
ret
=
kobject_register
(
&
dev
->
kobj
)))
goto
out_err
;
/* Fix illegal SG+CSUM combinations. */
if
((
dev
->
features
&
NETIF_F_SG
)
&&
!
(
dev
->
features
&
(
NETIF_F_IP_CSUM
|
NETIF_F_NO_CSUM
|
NETIF_F_HW_CSUM
)))
{
printk
(
"%s: Dropping NETIF_F_SG since no checksum feature.
\n
"
,
dev
->
name
);
dev
->
features
&=
~
NETIF_F_SG
;
}
/*
* nil rebuild_header routine,
* that should be never called and used as just bug trap.
...
...
net/core/sock.c
View file @
70ced8bf
...
...
@@ -589,8 +589,10 @@ static kmem_cache_t *sk_cachep;
*/
struct
sock
*
sk_alloc
(
int
family
,
int
priority
,
int
zero_it
,
kmem_cache_t
*
slab
)
{
struct
sock
*
sk
;
struct
sock
*
sk
=
NULL
;
if
(
!
net_family_get
(
family
))
goto
out
;
if
(
!
slab
)
slab
=
sk_cachep
;
sk
=
kmem_cache_alloc
(
slab
,
priority
);
...
...
@@ -602,14 +604,16 @@ struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
sock_lock_init
(
sk
);
}
sk
->
slab
=
slab
;
}
}
else
net_family_put
(
family
);
out:
return
sk
;
}
void
sk_free
(
struct
sock
*
sk
)
{
struct
sk_filter
*
filter
;
const
int
family
=
sk
->
family
;
if
(
sk
->
destruct
)
sk
->
destruct
(
sk
);
...
...
@@ -624,6 +628,7 @@ void sk_free(struct sock *sk)
printk
(
KERN_DEBUG
"sk_free: optmem leakage (%d bytes) detected.
\n
"
,
atomic_read
(
&
sk
->
omem_alloc
));
kmem_cache_free
(
sk
->
slab
,
sk
);
net_family_put
(
family
);
}
void
__init
sk_init
(
void
)
...
...
net/ipv4/igmp.c
View file @
70ced8bf
...
...
@@ -103,6 +103,7 @@
#define IP_MAX_MEMBERSHIPS 20
#ifdef CONFIG_IP_MULTICAST
/* Parameter names and values are taken from igmp-v2-06 draft */
#define IGMP_V1_Router_Present_Timeout (400*HZ)
...
...
@@ -126,13 +127,12 @@
#define IGMP_V2_SEEN(in_dev) ((in_dev)->mr_v2_seen && \
time_before(jiffies, (in_dev)->mr_v2_seen))
#ifdef CONFIG_MULTICAST
static
void
igmpv3_add_delrec
(
struct
in_device
*
in_dev
,
struct
ip_mc_list
*
im
);
#endif
static
void
igmpv3_del_delrec
(
struct
in_device
*
in_dev
,
__u32
multiaddr
);
static
void
igmpv3_clear_delrec
(
struct
in_device
*
in_dev
);
static
int
sf_setstate
(
struct
ip_mc_list
*
pmc
);
static
void
sf_markstate
(
struct
ip_mc_list
*
pmc
);
#endif
static
void
ip_mc_clear_src
(
struct
ip_mc_list
*
pmc
);
int
ip_mc_add_src
(
struct
in_device
*
in_dev
,
__u32
*
pmca
,
int
sfmode
,
int
sfcount
,
__u32
*
psfsrc
,
int
delta
);
...
...
@@ -770,11 +770,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
in_dev
->
mr_v2_seen
=
jiffies
+
IGMP_V2_Router_Present_Timeout
;
}
/* cancel the interface change timer */
in_dev
->
mr_ifc_count
=
0
;
if
(
del_timer
(
&
in_dev
->
mr_ifc_timer
))
atomic_dec
(
&
in_dev
->
refcnt
);
/* clear deleted report items */
igmpv3_clear_delrec
(
in_dev
);
}
else
if
(
len
<
12
)
{
return
;
/* ignore bogus packet; freed by caller */
}
else
{
/* v3 */
max_delay
=
IGMPV3_MRC
(
ih3
->
code
)
*
(
HZ
/
IGMP_TIMER_SCALE
);
if
(
!
max_delay
)
max_delay
=
1
;
/* can't mod w/ 0 */
in_dev
->
mr_maxdelay
=
max_delay
;
if
(
ih3
->
qrv
)
in_dev
->
mr_qrv
=
ih3
->
qrv
;
...
...
@@ -951,7 +958,6 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
in_dev
->
mc_tomb
=
pmc
;
write_unlock_bh
(
&
in_dev
->
mc_lock
);
}
#endif
static
void
igmpv3_del_delrec
(
struct
in_device
*
in_dev
,
__u32
multiaddr
)
{
...
...
@@ -997,7 +1003,23 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
in_dev_put
(
pmc
->
interface
);
kfree
(
pmc
);
}
/* clear dead sources, too */
read_lock
(
&
in_dev
->
lock
);
for
(
pmc
=
in_dev
->
mc_list
;
pmc
;
pmc
=
pmc
->
next
)
{
struct
ip_sf_list
*
psf
,
*
psf_next
;
spin_lock_bh
(
&
pmc
->
lock
);
psf
=
pmc
->
tomb
;
pmc
->
tomb
=
0
;
spin_unlock_bh
(
&
pmc
->
lock
);
for
(;
psf
;
psf
=
psf_next
)
{
psf_next
=
psf
->
sf_next
;
kfree
(
psf
);
}
}
read_unlock
(
&
in_dev
->
lock
);
}
#endif
static
void
igmp_group_dropped
(
struct
ip_mc_list
*
im
)
{
...
...
@@ -1030,8 +1052,8 @@ static void igmp_group_dropped(struct ip_mc_list *im)
igmp_ifc_event
(
in_dev
);
done:
ip_mc_clear_src
(
im
);
#endif
ip_mc_clear_src
(
im
);
}
static
void
igmp_group_added
(
struct
ip_mc_list
*
im
)
...
...
@@ -1102,7 +1124,7 @@ void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
im
->
crcount
=
0
;
atomic_set
(
&
im
->
refcnt
,
1
);
spin_lock_init
(
&
im
->
lock
);
#ifdef
CONFIG_IP_MULTICAST
#ifdef CONFIG_IP_MULTICAST
im
->
tm_running
=
0
;
init_timer
(
&
im
->
timer
);
im
->
timer
.
data
=
(
unsigned
long
)
im
;
...
...
@@ -1116,7 +1138,9 @@ void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
im
->
next
=
in_dev
->
mc_list
;
in_dev
->
mc_list
=
im
;
write_unlock_bh
(
&
in_dev
->
lock
);
#ifdef CONFIG_IP_MULTICAST
igmpv3_del_delrec
(
in_dev
,
im
->
multiaddr
);
#endif
igmp_group_added
(
im
);
if
(
in_dev
->
dev
->
flags
&
IFF_UP
)
ip_rt_multicast_event
(
in_dev
);
...
...
@@ -1173,7 +1197,9 @@ void ip_mc_down(struct in_device *in_dev)
for
(
i
=
in_dev
->
mc_list
;
i
;
i
=
i
->
next
)
igmp_group_dropped
(
i
);
#ifdef CONFIG_IP_MULTICAST
igmpv3_clear_delrec
(
in_dev
);
#endif
ip_mc_dec_group
(
in_dev
,
IGMP_ALL_HOSTS
);
}
...
...
@@ -1186,12 +1212,12 @@ void ip_mc_up(struct in_device *in_dev)
ASSERT_RTNL
();
in_dev
->
mc_tomb
=
0
;
#ifdef CONFIG_IP_MULTICAST
in_dev
->
mr_gq_running
=
0
;
init_timer
(
&
in_dev
->
mr_gq_timer
);
in_dev
->
mr_gq_timer
.
data
=
(
unsigned
long
)
in_dev
;
in_dev
->
mr_gq_timer
.
function
=&
igmp_gq_timer_expire
;
in_dev
->
mc_tomb
=
0
;
in_dev
->
mr_ifc_count
=
0
;
init_timer
(
&
in_dev
->
mr_ifc_timer
);
in_dev
->
mr_ifc_timer
.
data
=
(
unsigned
long
)
in_dev
;
...
...
@@ -1237,6 +1263,12 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
struct
net_device
*
dev
=
NULL
;
struct
in_device
*
idev
=
NULL
;
if
(
imr
->
imr_ifindex
)
{
idev
=
inetdev_by_index
(
imr
->
imr_ifindex
);
if
(
idev
)
__in_dev_put
(
idev
);
return
idev
;
}
if
(
imr
->
imr_address
.
s_addr
)
{
dev
=
ip_dev_find
(
imr
->
imr_address
.
s_addr
);
if
(
!
dev
)
...
...
@@ -1282,13 +1314,16 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
ip_rt_multicast_event
(
pmc
->
interface
);
}
if
(
!
psf
->
sf_count
[
MCAST_INCLUDE
]
&&
!
psf
->
sf_count
[
MCAST_EXCLUDE
])
{
#ifdef CONFIG_IP_MULTICAST
struct
in_device
*
in_dev
=
pmc
->
interface
;
#endif
/* no more filters for this source */
if
(
psf_prev
)
psf_prev
->
sf_next
=
psf
->
sf_next
;
else
pmc
->
sources
=
psf
->
sf_next
;
#ifdef CONFIG_IP_MULTICAST
if
(
psf
->
sf_oldin
&&
!
IGMP_V1_SEEN
(
in_dev
)
&&
!
IGMP_V2_SEEN
(
in_dev
))
{
psf
->
sf_crcount
=
in_dev
->
mr_qrv
?
in_dev
->
mr_qrv
:
...
...
@@ -1297,6 +1332,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
pmc
->
tomb
=
psf
;
rv
=
1
;
}
else
#endif
kfree
(
psf
);
}
return
rv
;
...
...
@@ -1327,7 +1363,9 @@ int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
}
spin_lock_bh
(
&
pmc
->
lock
);
read_unlock
(
&
in_dev
->
lock
);
#ifdef CONFIG_IP_MULTICAST
sf_markstate
(
pmc
);
#endif
if
(
!
delta
)
{
if
(
!
pmc
->
sfcount
[
sfmode
])
return
-
EINVAL
;
...
...
@@ -1344,10 +1382,13 @@ int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
if
(
pmc
->
sfmode
==
MCAST_EXCLUDE
&&
pmc
->
sfcount
[
MCAST_EXCLUDE
]
==
0
&&
pmc
->
sfcount
[
MCAST_INCLUDE
])
{
#ifdef CONFIG_IP_MULTICAST
struct
ip_sf_list
*
psf
;
#endif
/* filter mode change */
pmc
->
sfmode
=
MCAST_INCLUDE
;
#ifdef CONFIG_IP_MULTICAST
pmc
->
crcount
=
in_dev
->
mr_qrv
?
in_dev
->
mr_qrv
:
IGMP_Unsolicited_Report_Count
;
in_dev
->
mr_ifc_count
=
pmc
->
crcount
;
...
...
@@ -1356,6 +1397,7 @@ int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
igmp_ifc_event
(
pmc
->
interface
);
}
else
if
(
sf_setstate
(
pmc
)
||
changerec
)
{
igmp_ifc_event
(
pmc
->
interface
);
#endif
}
spin_unlock_bh
(
&
pmc
->
lock
);
return
err
;
...
...
@@ -1393,6 +1435,7 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
return
0
;
}
#ifdef CONFIG_IP_MULTICAST
static
void
sf_markstate
(
struct
ip_mc_list
*
pmc
)
{
struct
ip_sf_list
*
psf
;
...
...
@@ -1428,6 +1471,7 @@ static int sf_setstate(struct ip_mc_list *pmc)
}
return
rv
;
}
#endif
/*
* Add multicast source filter list to the interface list
...
...
@@ -1454,7 +1498,9 @@ int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
spin_lock_bh
(
&
pmc
->
lock
);
read_unlock
(
&
in_dev
->
lock
);
#ifdef CONFIG_IP_MULTICAST
sf_markstate
(
pmc
);
#endif
isexclude
=
pmc
->
sfmode
==
MCAST_EXCLUDE
;
if
(
!
delta
)
pmc
->
sfcount
[
sfmode
]
++
;
...
...
@@ -1471,14 +1517,17 @@ int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
for
(
j
=
0
;
j
<
i
;
j
++
)
(
void
)
ip_mc_del1_src
(
pmc
,
sfmode
,
&
psfsrc
[
i
]);
}
else
if
(
isexclude
!=
(
pmc
->
sfcount
[
MCAST_EXCLUDE
]
!=
0
))
{
#ifdef CONFIG_IP_MULTICAST
struct
in_device
*
in_dev
=
pmc
->
interface
;
struct
ip_sf_list
*
psf
;
#endif
/* filter mode change */
if
(
pmc
->
sfcount
[
MCAST_EXCLUDE
])
pmc
->
sfmode
=
MCAST_EXCLUDE
;
else
if
(
pmc
->
sfcount
[
MCAST_INCLUDE
])
pmc
->
sfmode
=
MCAST_INCLUDE
;
#ifdef CONFIG_IP_MULTICAST
/* else no filters; keep old mode for reports */
pmc
->
crcount
=
in_dev
->
mr_qrv
?
in_dev
->
mr_qrv
:
...
...
@@ -1487,8 +1536,10 @@ int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode,
for
(
psf
=
pmc
->
sources
;
psf
;
psf
=
psf
->
sf_next
)
psf
->
sf_crcount
=
0
;
igmp_ifc_event
(
in_dev
);
}
else
if
(
sf_setstate
(
pmc
))
}
else
if
(
sf_setstate
(
pmc
))
{
igmp_ifc_event
(
in_dev
);
#endif
}
spin_unlock_bh
(
&
pmc
->
lock
);
return
err
;
}
...
...
@@ -1530,13 +1581,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
rtnl_shlock
();
if
(
!
imr
->
imr_ifindex
)
in_dev
=
ip_mc_find_dev
(
imr
);
else
{
in_dev
=
inetdev_by_index
(
imr
->
imr_ifindex
);
if
(
in_dev
)
__in_dev_put
(
in_dev
);
}
in_dev
=
ip_mc_find_dev
(
imr
);
if
(
!
in_dev
)
{
iml
=
NULL
;
...
...
@@ -1638,13 +1683,13 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
}
int
ip_mc_source
(
int
add
,
int
omode
,
struct
sock
*
sk
,
struct
ip_mreq_source
*
mreqs
)
ip_mreq_source
*
mreqs
,
int
ifindex
)
{
int
err
;
struct
ip_mreqn
imr
;
struct
ip_mreqn
imr
;
u32
addr
=
mreqs
->
imr_multiaddr
;
struct
ip_mc_socklist
*
pmc
;
struct
in_device
*
in_dev
;
struct
in_device
*
in_dev
=
0
;
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ip_sf_socklist
*
psl
;
int
i
,
j
,
rv
;
...
...
@@ -1656,7 +1701,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
imr
.
imr_multiaddr
.
s_addr
=
mreqs
->
imr_multiaddr
;
imr
.
imr_address
.
s_addr
=
mreqs
->
imr_interface
;
imr
.
imr_ifindex
=
0
;
imr
.
imr_ifindex
=
ifindex
;
in_dev
=
ip_mc_find_dev
(
&
imr
);
if
(
!
in_dev
)
{
...
...
@@ -1753,7 +1798,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
return
err
;
}
int
ip_mc_msfilter
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
)
int
ip_mc_msfilter
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
,
int
ifindex
)
{
int
err
;
struct
ip_mreqn
imr
;
...
...
@@ -1773,7 +1818,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf)
imr
.
imr_multiaddr
.
s_addr
=
msf
->
imsf_multiaddr
;
imr
.
imr_address
.
s_addr
=
msf
->
imsf_interface
;
imr
.
imr_ifindex
=
0
;
imr
.
imr_ifindex
=
ifindex
;
in_dev
=
ip_mc_find_dev
(
&
imr
);
if
(
!
in_dev
)
{
...
...
@@ -1783,7 +1828,8 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf)
err
=
-
EADDRNOTAVAIL
;
for
(
pmc
=
inet
->
mc_list
;
pmc
;
pmc
=
pmc
->
next
)
{
if
(
memcmp
(
&
pmc
->
multi
,
&
imr
,
sizeof
(
imr
))
==
0
)
if
(
pmc
->
multi
.
imr_multiaddr
.
s_addr
==
msf
->
imsf_multiaddr
&&
pmc
->
multi
.
imr_ifindex
==
imr
.
imr_ifindex
)
break
;
}
if
(
!
pmc
)
/* must have a prior join */
...
...
@@ -1834,9 +1880,6 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
if
(
!
MULTICAST
(
addr
))
return
-
EINVAL
;
if
(
msf
->
imsf_fmode
!=
MCAST_INCLUDE
&&
msf
->
imsf_fmode
!=
MCAST_EXCLUDE
)
return
-
EINVAL
;
rtnl_shlock
();
...
...
@@ -1852,7 +1895,8 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
err
=
-
EADDRNOTAVAIL
;
for
(
pmc
=
inet
->
mc_list
;
pmc
;
pmc
=
pmc
->
next
)
{
if
(
memcmp
(
&
pmc
->
multi
,
&
imr
,
sizeof
(
imr
))
==
0
)
if
(
pmc
->
multi
.
imr_multiaddr
.
s_addr
==
msf
->
imsf_multiaddr
&&
pmc
->
multi
.
imr_ifindex
==
imr
.
imr_ifindex
)
break
;
}
if
(
!
pmc
)
/* must have a prior join */
...
...
@@ -1882,6 +1926,61 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
return
err
;
}
int
ip_mc_gsfget
(
struct
sock
*
sk
,
struct
group_filter
*
gsf
,
struct
group_filter
*
optval
,
int
*
optlen
)
{
int
err
,
i
,
count
,
copycount
;
struct
sockaddr_in
*
psin
;
u32
addr
;
struct
ip_mc_socklist
*
pmc
;
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ip_sf_socklist
*
psl
;
psin
=
(
struct
sockaddr_in
*
)
&
gsf
->
gf_group
;
if
(
psin
->
sin_family
!=
AF_INET
)
return
-
EINVAL
;
addr
=
psin
->
sin_addr
.
s_addr
;
if
(
!
MULTICAST
(
addr
))
return
-
EINVAL
;
rtnl_shlock
();
err
=
-
EADDRNOTAVAIL
;
for
(
pmc
=
inet
->
mc_list
;
pmc
;
pmc
=
pmc
->
next
)
{
if
(
pmc
->
multi
.
imr_multiaddr
.
s_addr
==
addr
&&
pmc
->
multi
.
imr_ifindex
==
gsf
->
gf_interface
)
break
;
}
if
(
!
pmc
)
/* must have a prior join */
goto
done
;
gsf
->
gf_fmode
=
pmc
->
sfmode
;
psl
=
pmc
->
sflist
;
rtnl_shunlock
();
count
=
psl
?
psl
->
sl_count
:
0
;
copycount
=
count
<
gsf
->
gf_numsrc
?
count
:
gsf
->
gf_numsrc
;
gsf
->
gf_numsrc
=
count
;
if
(
put_user
(
GROUP_FILTER_SIZE
(
copycount
),
optlen
)
||
copy_to_user
((
void
*
)
optval
,
gsf
,
GROUP_FILTER_SIZE
(
0
)))
{
return
-
EFAULT
;
}
for
(
i
=
0
;
i
<
copycount
;
i
++
)
{
struct
sockaddr_in
*
psin
;
struct
sockaddr_storage
ss
;
psin
=
(
struct
sockaddr_in
*
)
&
ss
;
memset
(
&
ss
,
0
,
sizeof
(
ss
));
psin
->
sin_family
=
AF_INET
;
psin
->
sin_addr
.
s_addr
=
psl
->
sl_addr
[
i
];
if
(
copy_to_user
((
void
*
)
&
optval
->
gf_slist
[
i
],
&
ss
,
sizeof
(
ss
)))
return
-
EFAULT
;
}
return
0
;
done:
rtnl_shunlock
();
return
err
;
}
/*
* check if a multicast source filter allows delivery for a given <src,dst,intf>
*/
...
...
@@ -1892,6 +1991,9 @@ int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif)
struct
ip_sf_socklist
*
psl
;
int
i
;
if
(
!
MULTICAST
(
loc_addr
))
return
1
;
for
(
pmc
=
inet
->
mc_list
;
pmc
;
pmc
=
pmc
->
next
)
{
if
(
pmc
->
multi
.
imr_multiaddr
.
s_addr
==
loc_addr
&&
pmc
->
multi
.
imr_ifindex
==
dif
)
...
...
@@ -1972,8 +2074,6 @@ int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr, u16 proto)
}
#ifdef CONFIG_IP_MULTICAST
int
ip_mc_procinfo
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
off_t
pos
=
0
,
begin
=
0
;
...
...
@@ -1991,7 +2091,9 @@ int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length)
if
(
in_dev
==
NULL
)
continue
;
#ifdef CONFIG_IP_MULTICAST
querier
=
IGMP_V1_SEEN
(
in_dev
)
?
"V1"
:
"V2"
;
#endif
len
+=
sprintf
(
buffer
+
len
,
"%d
\t
%-10s: %5d %7s
\n
"
,
dev
->
ifindex
,
dev
->
name
,
dev
->
mc_count
,
querier
);
...
...
@@ -2049,11 +2151,8 @@ int ip_mcf_procinfo(char *buffer, char **start, off_t offset, int length)
for
(
imc
=
in_dev
->
mc_list
;
imc
;
imc
=
imc
->
next
)
{
struct
ip_sf_list
*
psf
;
unsigned
long
icount
,
xcount
;
spin_lock_bh
(
&
imc
->
lock
);
icount
=
imc
->
sfcount
[
MCAST_INCLUDE
];
xcount
=
imc
->
sfcount
[
MCAST_EXCLUDE
];
for
(
psf
=
imc
->
sources
;
psf
;
psf
=
psf
->
sf_next
)
{
if
(
first
)
{
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
...
...
@@ -2080,33 +2179,6 @@ int ip_mcf_procinfo(char *buffer, char **start, off_t offset, int length)
in_dev_put
(
in_dev
);
goto
done
;
}
icount
-=
psf
->
sf_count
[
MCAST_INCLUDE
];
xcount
-=
psf
->
sf_count
[
MCAST_EXCLUDE
];
}
if
(
icount
>
0
||
xcount
>
0
)
{
if
(
first
)
{
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
"%10s %10s %6s %6s
\n
"
,
"Idx"
,
"Device"
,
"MCA"
,
"SRC"
,
"INC"
,
"EXC"
);
first
=
0
;
}
len
+=
sprintf
(
buffer
+
len
,
"%3d %6.6s 0x%08x "
"%10s %6lu %6lu
\n
"
,
dev
->
ifindex
,
dev
->
name
,
ntohl
(
imc
->
multiaddr
),
"NONE"
,
icount
,
xcount
);
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
{
spin_unlock_bh
(
&
imc
->
lock
);
read_unlock
(
&
in_dev
->
lock
);
in_dev_put
(
in_dev
);
goto
done
;
}
}
spin_unlock_bh
(
&
imc
->
lock
);
}
...
...
@@ -2125,5 +2197,3 @@ int ip_mcf_procinfo(char *buffer, char **start, off_t offset, int length)
return
len
;
}
#endif
net/ipv4/ip_output.c
View file @
70ced8bf
...
...
@@ -1312,6 +1312,6 @@ void __init ip_init(void)
#ifdef CONFIG_IP_MULTICAST
proc_net_create
(
"igmp"
,
0
,
ip_mc_procinfo
);
proc_net_create
(
"mcfilter"
,
0
,
ip_mcf_procinfo
);
#endif
proc_net_create
(
"mcfilter"
,
0
,
ip_mcf_procinfo
);
}
net/ipv4/ip_sockglue.c
View file @
70ced8bf
...
...
@@ -631,7 +631,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
kfree
(
msf
);
break
;
}
err
=
ip_mc_msfilter
(
sk
,
msf
);
err
=
ip_mc_msfilter
(
sk
,
msf
,
0
);
kfree
(
msf
);
break
;
}
...
...
@@ -670,7 +670,142 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
omode
=
MCAST_INCLUDE
;
add
=
0
;
}
err
=
ip_mc_source
(
add
,
omode
,
sk
,
&
mreqs
);
err
=
ip_mc_source
(
add
,
omode
,
sk
,
&
mreqs
,
0
);
break
;
}
case
MCAST_JOIN_GROUP
:
case
MCAST_LEAVE_GROUP
:
{
struct
group_req
greq
;
struct
sockaddr_in
*
psin
;
struct
ip_mreqn
mreq
;
if
(
optlen
<
sizeof
(
struct
group_req
))
goto
e_inval
;
err
=
-
EFAULT
;
if
(
copy_from_user
(
&
greq
,
optval
,
sizeof
(
greq
)))
break
;
psin
=
(
struct
sockaddr_in
*
)
&
greq
.
gr_group
;
if
(
psin
->
sin_family
!=
AF_INET
)
goto
e_inval
;
memset
(
&
mreq
,
0
,
sizeof
(
mreq
));
mreq
.
imr_multiaddr
=
psin
->
sin_addr
;
mreq
.
imr_ifindex
=
greq
.
gr_interface
;
if
(
optname
==
MCAST_JOIN_GROUP
)
err
=
ip_mc_join_group
(
sk
,
&
mreq
);
else
err
=
ip_mc_leave_group
(
sk
,
&
mreq
);
break
;
}
case
MCAST_JOIN_SOURCE_GROUP
:
case
MCAST_LEAVE_SOURCE_GROUP
:
case
MCAST_BLOCK_SOURCE
:
case
MCAST_UNBLOCK_SOURCE
:
{
struct
group_source_req
greqs
;
struct
ip_mreq_source
mreqs
;
struct
sockaddr_in
*
psin
;
int
omode
,
add
;
if
(
optlen
!=
sizeof
(
struct
group_source_req
))
goto
e_inval
;
if
(
copy_from_user
(
&
greqs
,
optval
,
sizeof
(
greqs
)))
{
err
=
-
EFAULT
;
break
;
}
if
(
greqs
.
gsr_group
.
ss_family
!=
AF_INET
||
greqs
.
gsr_source
.
ss_family
!=
AF_INET
)
{
err
=
-
EADDRNOTAVAIL
;
break
;
}
psin
=
(
struct
sockaddr_in
*
)
&
greqs
.
gsr_group
;
mreqs
.
imr_multiaddr
=
psin
->
sin_addr
.
s_addr
;
psin
=
(
struct
sockaddr_in
*
)
&
greqs
.
gsr_source
;
mreqs
.
imr_sourceaddr
=
psin
->
sin_addr
.
s_addr
;
mreqs
.
imr_interface
=
0
;
/* use index for mc_source */
if
(
optname
==
MCAST_BLOCK_SOURCE
)
{
omode
=
MCAST_EXCLUDE
;
add
=
1
;
}
else
if
(
optname
==
MCAST_UNBLOCK_SOURCE
)
{
omode
=
MCAST_EXCLUDE
;
add
=
0
;
}
else
if
(
optname
==
MCAST_JOIN_SOURCE_GROUP
)
{
struct
ip_mreqn
mreq
;
psin
=
(
struct
sockaddr_in
*
)
&
greqs
.
gsr_group
;
mreq
.
imr_multiaddr
=
psin
->
sin_addr
;
mreq
.
imr_address
.
s_addr
=
0
;
mreq
.
imr_ifindex
=
greqs
.
gsr_interface
;
err
=
ip_mc_join_group
(
sk
,
&
mreq
);
if
(
err
)
break
;
omode
=
MCAST_INCLUDE
;
add
=
1
;
}
else
/* MCAST_LEAVE_SOURCE_GROUP */
{
omode
=
MCAST_INCLUDE
;
add
=
0
;
}
err
=
ip_mc_source
(
add
,
omode
,
sk
,
&
mreqs
,
greqs
.
gsr_interface
);
break
;
}
case
MCAST_MSFILTER
:
{
struct
sockaddr_in
*
psin
;
struct
ip_msfilter
*
msf
=
0
;
struct
group_filter
*
gsf
=
0
;
int
msize
,
i
,
ifindex
;
if
(
optlen
<
GROUP_FILTER_SIZE
(
0
))
goto
e_inval
;
gsf
=
(
struct
group_filter
*
)
kmalloc
(
optlen
,
GFP_KERNEL
);
if
(
gsf
==
0
)
{
err
=
-
ENOBUFS
;
break
;
}
err
=
-
EFAULT
;
if
(
copy_from_user
(
gsf
,
optval
,
optlen
))
{
goto
mc_msf_out
;
}
if
(
GROUP_FILTER_SIZE
(
gsf
->
gf_numsrc
)
<
optlen
)
{
err
=
EINVAL
;
goto
mc_msf_out
;
}
msize
=
IP_MSFILTER_SIZE
(
gsf
->
gf_numsrc
);
msf
=
(
struct
ip_msfilter
*
)
kmalloc
(
msize
,
GFP_KERNEL
);
if
(
msf
==
0
)
{
err
=
-
ENOBUFS
;
goto
mc_msf_out
;
}
ifindex
=
gsf
->
gf_interface
;
psin
=
(
struct
sockaddr_in
*
)
&
gsf
->
gf_group
;
if
(
psin
->
sin_family
!=
AF_INET
)
{
err
=
-
EADDRNOTAVAIL
;
goto
mc_msf_out
;
}
msf
->
imsf_multiaddr
=
psin
->
sin_addr
.
s_addr
;
msf
->
imsf_interface
=
0
;
msf
->
imsf_fmode
=
gsf
->
gf_fmode
;
msf
->
imsf_numsrc
=
gsf
->
gf_numsrc
;
err
=
-
EADDRNOTAVAIL
;
for
(
i
=
0
;
i
<
gsf
->
gf_numsrc
;
++
i
)
{
psin
=
(
struct
sockaddr_in
*
)
&
gsf
->
gf_slist
[
i
];
if
(
psin
->
sin_family
!=
AF_INET
)
goto
mc_msf_out
;
msf
->
imsf_slist
[
i
]
=
psin
->
sin_addr
.
s_addr
;
}
kfree
(
gsf
);
gsf
=
0
;
err
=
ip_mc_msfilter
(
sk
,
msf
,
ifindex
);
mc_msf_out:
if
(
msf
)
kfree
(
msf
);
if
(
gsf
)
kfree
(
gsf
);
break
;
}
case
IP_ROUTER_ALERT
:
...
...
@@ -826,15 +961,37 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
struct
ip_msfilter
msf
;
int
err
;
if
(
len
<
IP_MSFILTER_SIZE
(
0
))
if
(
len
<
IP_MSFILTER_SIZE
(
0
))
{
release_sock
(
sk
);
return
-
EINVAL
;
if
(
copy_from_user
(
&
msf
,
optval
,
IP_MSFILTER_SIZE
(
0
)))
}
if
(
copy_from_user
(
&
msf
,
optval
,
IP_MSFILTER_SIZE
(
0
)))
{
release_sock
(
sk
);
return
-
EFAULT
;
}
err
=
ip_mc_msfget
(
sk
,
&
msf
,
(
struct
ip_msfilter
*
)
optval
,
optlen
);
release_sock
(
sk
);
return
err
;
}
case
MCAST_MSFILTER
:
{
struct
group_filter
gsf
;
int
err
;
if
(
len
<
GROUP_FILTER_SIZE
(
0
))
{
release_sock
(
sk
);
return
-
EINVAL
;
}
if
(
copy_from_user
(
&
gsf
,
optval
,
GROUP_FILTER_SIZE
(
0
)))
{
release_sock
(
sk
);
return
-
EFAULT
;
}
err
=
ip_mc_gsfget
(
sk
,
&
gsf
,
(
struct
group_filter
*
)
optval
,
optlen
);
release_sock
(
sk
);
return
err
;
}
case
IP_PKTOPTIONS
:
{
struct
msghdr
msg
;
...
...
net/ipv4/netfilter/Kconfig
View file @
70ced8bf
...
...
@@ -48,7 +48,7 @@ config IP_NF_IRC
<file:Documentation/modules.txt>. If unsure, say `Y'.
config IP_NF_TFTP
tristate "TFTP prtocol support"
tristate "TFTP pr
o
tocol support"
depends on IP_NF_CONNTRACK
help
TFTP connection tracking helper, this is required depending
...
...
net/ipv6/ipv6_sockglue.c
View file @
70ced8bf
...
...
@@ -120,6 +120,12 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
return
0
;
}
extern
int
ip6_mc_source
(
int
add
,
int
omode
,
struct
sock
*
sk
,
struct
group_source_req
*
pgsr
);
extern
int
ip6_mc_msfilter
(
struct
sock
*
sk
,
struct
group_filter
*
gsf
);
extern
int
ip6_mc_msfget
(
struct
sock
*
sk
,
struct
group_filter
*
gsf
,
struct
group_filter
*
optval
,
int
*
optlen
);
int
ipv6_setsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
...
...
@@ -393,12 +399,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
break
;
}
psin6
=
(
struct
sockaddr_in6
*
)
&
greq
.
gr_group
;
if
(
optname
==
IPV6_ADD_MEMBERSHI
P
)
if
(
optname
==
MCAST_JOIN_GROU
P
)
retv
=
ipv6_sock_mc_join
(
sk
,
greq
.
gr_interface
,
&
psin6
->
sin6_addr
);
else
retv
=
ipv6_sock_mc_drop
(
sk
,
greq
.
gr_interface
,
&
psin6
->
sin6_addr
);
break
;
}
case
MCAST_JOIN_SOURCE_GROUP
:
case
MCAST_LEAVE_SOURCE_GROUP
:
...
...
@@ -414,7 +421,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
retv
=
-
EFAULT
;
break
;
}
if
(
greqs
.
gsr_group
.
ss_family
!=
AF_INET6
)
{
if
(
greqs
.
gsr_group
.
ss_family
!=
AF_INET6
||
greqs
.
gsr_source
.
ss_family
!=
AF_INET6
)
{
retv
=
-
EADDRNOTAVAIL
;
break
;
}
...
...
net/ipv6/mcast.c
View file @
70ced8bf
...
...
@@ -768,7 +768,7 @@ static void mld_clear_delrec(struct inet6_dev *idev)
psf
=
pmc
->
mca_tomb
;
pmc
->
mca_tomb
=
0
;
spin_unlock_bh
(
&
pmc
->
mca_lock
);
for
(
psf
=
pmc
->
mca_tomb
;
psf
;
psf
=
psf_next
)
{
for
(;
psf
;
psf
=
psf_next
)
{
psf_next
=
psf
->
sf_next
;
kfree
(
psf
);
}
...
...
@@ -1042,6 +1042,8 @@ int igmp6_event_query(struct sk_buff *skb)
mld_clear_delrec
(
idev
);
}
else
if
(
len
>=
28
)
{
max_delay
=
MLDV2_MRC
(
ntohs
(
mlh2
->
mrc
))
*
(
HZ
/
10
);
if
(
!
max_delay
)
max_delay
=
1
;
idev
->
mc_maxdelay
=
max_delay
;
if
(
mlh2
->
qrv
)
idev
->
mc_qrv
=
mlh2
->
qrv
;
...
...
@@ -2096,8 +2098,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
unsigned
long
icount
,
xcount
,
i
;
spin_lock_bh
(
&
imc
->
mca_lock
);
icount
=
imc
->
mca_sfcount
[
MCAST_INCLUDE
];
xcount
=
imc
->
mca_sfcount
[
MCAST_EXCLUDE
];
for
(
psf
=
imc
->
mca_sources
;
psf
;
psf
=
psf
->
sf_next
)
{
if
(
first
)
{
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
...
...
@@ -2130,36 +2130,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
in6_dev_put
(
idev
);
goto
done
;
}
icount
-=
psf
->
sf_count
[
MCAST_INCLUDE
];
xcount
-=
psf
->
sf_count
[
MCAST_EXCLUDE
];
}
if
(
icount
>
0
||
xcount
>
0
)
{
if
(
first
)
{
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
"%32s %32s %6s %6s
\n
"
,
"Idx"
,
"Device"
,
"Multicast Address"
,
"Source Address"
,
"INC"
,
"EXC"
);
first
=
0
;
}
len
+=
sprintf
(
buffer
+
len
,
"%3d %6.6s "
,
dev
->
ifindex
,
dev
->
name
);
for
(
i
=
0
;
i
<
16
;
i
++
)
len
+=
sprintf
(
buffer
+
len
,
"%02x"
,
imc
->
mca_addr
.
s6_addr
[
i
]);
len
+=
sprintf
(
buffer
+
len
,
" %32s %6lu %6lu
\n
"
,
"NONE"
,
icount
,
xcount
);
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
{
spin_unlock_bh
(
&
imc
->
mca_lock
);
read_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
goto
done
;
}
}
spin_unlock_bh
(
&
imc
->
mca_lock
);
}
...
...
net/ipv6/ndisc.c
View file @
70ced8bf
...
...
@@ -427,7 +427,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
len
=
sizeof
(
struct
icmp6hdr
)
+
sizeof
(
struct
in6_addr
);
rt
=
ndisc_get_dummy_rt
();
rt
=
ip6_dst_alloc
();
if
(
!
rt
)
return
;
...
...
@@ -524,7 +524,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
saddr
=
&
addr_buf
;
}
rt
=
ndisc_get_dummy_rt
();
rt
=
ip6_dst_alloc
();
if
(
!
rt
)
return
;
...
...
@@ -595,7 +595,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
int
len
;
int
err
;
rt
=
ndisc_get_dummy_rt
();
rt
=
ip6_dst_alloc
();
if
(
!
rt
)
return
;
...
...
net/ipv6/route.c
View file @
70ced8bf
...
...
@@ -130,12 +130,17 @@ struct fib6_node ip6_routing_table = {
rwlock_t
rt6_lock
=
RW_LOCK_UNLOCKED
;
/*
Dummy rt for ndisc
*/
st
ruct
rt6_info
*
ndisc_get_dummy_rt
(
)
/*
allocate dst with ip6_dst_ops
*/
st
atic
__inline__
struct
rt6_info
*
__ip6_dst_alloc
(
void
)
{
return
dst_alloc
(
&
ip6_dst_ops
);
}
struct
rt6_info
*
ip6_dst_alloc
(
void
)
{
return
__ip6_dst_alloc
();
}
/*
* Route lookup. Any rt6_lock is implied.
*/
...
...
@@ -640,7 +645,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh)
if
(
rtmsg
->
rtmsg_metric
==
0
)
rtmsg
->
rtmsg_metric
=
IP6_RT_PRIO_USER
;
rt
=
dst_alloc
(
&
ip6_dst_ops
);
rt
=
__ip6_dst_alloc
(
);
if
(
rt
==
NULL
)
return
-
ENOMEM
;
...
...
@@ -1035,9 +1040,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
static
struct
rt6_info
*
ip6_rt_copy
(
struct
rt6_info
*
ort
)
{
struct
rt6_info
*
rt
;
rt
=
dst_alloc
(
&
ip6_dst_ops
);
struct
rt6_info
*
rt
=
__ip6_dst_alloc
();
if
(
rt
)
{
rt
->
u
.
dst
.
input
=
ort
->
u
.
dst
.
input
;
...
...
@@ -1181,9 +1184,8 @@ int ip6_pkt_discard(struct sk_buff *skb)
int
ip6_rt_addr_add
(
struct
in6_addr
*
addr
,
struct
net_device
*
dev
)
{
struct
rt6_info
*
rt
;
struct
rt6_info
*
rt
=
__ip6_dst_alloc
()
;
rt
=
dst_alloc
(
&
ip6_dst_ops
);
if
(
rt
==
NULL
)
return
-
ENOMEM
;
...
...
net/netlink/af_netlink.c
View file @
70ced8bf
...
...
@@ -1052,6 +1052,7 @@ struct proto_ops netlink_ops = {
struct
net_proto_family
netlink_family_ops
=
{
.
family
=
PF_NETLINK
,
.
create
=
netlink_create
,
.
owner
=
THIS_MODULE
,
/* for consistency 8) */
};
static
int
__init
netlink_proto_init
(
void
)
...
...
@@ -1065,6 +1066,11 @@ static int __init netlink_proto_init(void)
sock_register
(
&
netlink_family_ops
);
#ifdef CONFIG_PROC_FS
create_proc_read_entry
(
"net/netlink"
,
0
,
0
,
netlink_read_proc
,
NULL
);
#endif
/* The netlink device handler may be needed early. */
rtnetlink_init
();
#ifdef CONFIG_NETLINK_DEV
init_netlink
();
#endif
return
0
;
}
...
...
@@ -1075,7 +1081,7 @@ static void __exit netlink_proto_exit(void)
remove_proc_entry
(
"net/netlink"
,
NULL
);
}
module_init
(
netlink_proto_init
);
subsys_initcall
(
netlink_proto_init
);
module_exit
(
netlink_proto_exit
);
MODULE_LICENSE
(
"GPL"
);
net/socket.c
View file @
70ced8bf
...
...
@@ -69,8 +69,6 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/wanrouter.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_bridge.h>
#include <linux/init.h>
#include <linux/poll.h>
...
...
@@ -143,6 +141,36 @@ static struct file_operations socket_file_ops = {
static
struct
net_proto_family
*
net_families
[
NPROTO
];
static
__inline__
void
net_family_bug
(
int
family
)
{
printk
(
KERN_ERR
"%d is not yet sock_registered!
\n
"
,
family
);
BUG
();
}
int
net_family_get
(
int
family
)
{
struct
net_proto_family
*
prot
=
net_families
[
family
];
int
rc
=
1
;
barrier
();
if
(
likely
(
prot
!=
NULL
))
rc
=
try_module_get
(
prot
->
owner
);
else
net_family_bug
(
family
);
return
rc
;
}
void
net_family_put
(
int
family
)
{
struct
net_proto_family
*
prot
=
net_families
[
family
];
barrier
();
if
(
likely
(
prot
!=
NULL
))
module_put
(
prot
->
owner
);
else
net_family_bug
(
family
);
}
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
static
atomic_t
net_family_lockct
=
ATOMIC_INIT
(
0
);
static
spinlock_t
net_family_lock
=
SPIN_LOCK_UNLOCKED
;
...
...
@@ -511,7 +539,7 @@ void sock_release(struct socket *sock)
sock
->
ops
->
release
(
sock
);
sock
->
ops
=
NULL
;
module_put
(
net_families
[
family
]
->
owner
);
net_family_put
(
family
);
}
if
(
sock
->
fasync_list
)
...
...
@@ -1064,7 +1092,7 @@ int sock_create(int family, int type, int protocol, struct socket **res)
sock
->
type
=
type
;
i
=
-
EBUSY
;
if
(
!
try_module_get
(
net_families
[
family
]
->
owner
))
if
(
!
net_family_get
(
family
))
goto
out_release
;
if
((
i
=
net_families
[
family
]
->
create
(
sock
,
protocol
))
<
0
)
...
...
@@ -1953,17 +1981,6 @@ void __init sock_init(void)
* do_initcalls is run.
*/
/*
* The netlink device handler may be needed early.
*/
#ifdef CONFIG_NET
rtnetlink_init
();
#endif
#ifdef CONFIG_NETLINK_DEV
init_netlink
();
#endif
#ifdef CONFIG_NETFILTER
netfilter_init
();
#endif
...
...
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