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
3a3a07de
Commit
3a3a07de
authored
Apr 22, 2003
by
David Stevens
Committed by
Arnaldo Carvalho de Melo
Apr 22, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IGMPv3/MPDv2]: Bug fixes and ipv4 multiprotocol API.
parent
c1f25dc7
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
306 additions
and
102 deletions
+306
-102
include/linux/igmp.h
include/linux/igmp.h
+5
-3
net/ipv4/igmp.c
net/ipv4/igmp.c
+126
-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/ipv6/ipv6_sockglue.c
net/ipv6/ipv6_sockglue.c
+10
-2
net/ipv6/mcast.c
net/ipv6/mcast.c
+3
-33
No files found.
include/linux/igmp.h
View file @
3a3a07de
...
@@ -191,7 +191,7 @@ struct ip_mc_list
...
@@ -191,7 +191,7 @@ struct ip_mc_list
(IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
(IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
#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
ip_check_mc
(
struct
in_device
*
dev
,
u32
mc_addr
,
u32
src_addr
,
u16
proto
);
extern
int
igmp_rcv
(
struct
sk_buff
*
);
extern
int
igmp_rcv
(
struct
sk_buff
*
);
...
@@ -199,10 +199,12 @@ extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
...
@@ -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
int
ip_mc_leave_group
(
struct
sock
*
sk
,
struct
ip_mreqn
*
imr
);
extern
void
ip_mc_drop_socket
(
struct
sock
*
sk
);
extern
void
ip_mc_drop_socket
(
struct
sock
*
sk
);
extern
int
ip_mc_source
(
int
add
,
int
omode
,
struct
sock
*
sk
,
extern
int
ip_mc_source
(
int
add
,
int
omode
,
struct
sock
*
sk
,
struct
ip_mreq_source
*
mreqs
);
struct
ip_mreq_source
*
mreqs
,
int
ifindex
);
extern
int
ip_mc_msfilter
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
);
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
,
extern
int
ip_mc_msfget
(
struct
sock
*
sk
,
struct
ip_msfilter
*
msf
,
struct
ip_msfilter
*
optval
,
int
*
optlen
);
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
int
ip_mc_sf_allow
(
struct
sock
*
sk
,
u32
local
,
u32
rmt
,
int
dif
);
extern
void
ip_mr_init
(
void
);
extern
void
ip_mr_init
(
void
);
extern
void
ip_mc_init_dev
(
struct
in_device
*
);
extern
void
ip_mc_init_dev
(
struct
in_device
*
);
...
...
net/ipv4/igmp.c
View file @
3a3a07de
This diff is collapsed.
Click to expand it.
net/ipv4/ip_output.c
View file @
3a3a07de
...
@@ -1312,6 +1312,6 @@ void __init ip_init(void)
...
@@ -1312,6 +1312,6 @@ void __init ip_init(void)
#ifdef CONFIG_IP_MULTICAST
#ifdef CONFIG_IP_MULTICAST
proc_net_create
(
"igmp"
,
0
,
ip_mc_procinfo
);
proc_net_create
(
"igmp"
,
0
,
ip_mc_procinfo
);
proc_net_create
(
"mcfilter"
,
0
,
ip_mcf_procinfo
);
#endif
#endif
proc_net_create
(
"mcfilter"
,
0
,
ip_mcf_procinfo
);
}
}
net/ipv4/ip_sockglue.c
View file @
3a3a07de
...
@@ -631,7 +631,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
...
@@ -631,7 +631,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
kfree
(
msf
);
kfree
(
msf
);
break
;
break
;
}
}
err
=
ip_mc_msfilter
(
sk
,
msf
);
err
=
ip_mc_msfilter
(
sk
,
msf
,
0
);
kfree
(
msf
);
kfree
(
msf
);
break
;
break
;
}
}
...
@@ -670,7 +670,142 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
...
@@ -670,7 +670,142 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
omode
=
MCAST_INCLUDE
;
omode
=
MCAST_INCLUDE
;
add
=
0
;
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
;
break
;
}
}
case
IP_ROUTER_ALERT
:
case
IP_ROUTER_ALERT
:
...
@@ -826,15 +961,37 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
...
@@ -826,15 +961,37 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
struct
ip_msfilter
msf
;
struct
ip_msfilter
msf
;
int
err
;
int
err
;
if
(
len
<
IP_MSFILTER_SIZE
(
0
))
if
(
len
<
IP_MSFILTER_SIZE
(
0
))
{
release_sock
(
sk
);
return
-
EINVAL
;
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
;
return
-
EFAULT
;
}
err
=
ip_mc_msfget
(
sk
,
&
msf
,
err
=
ip_mc_msfget
(
sk
,
&
msf
,
(
struct
ip_msfilter
*
)
optval
,
optlen
);
(
struct
ip_msfilter
*
)
optval
,
optlen
);
release_sock
(
sk
);
release_sock
(
sk
);
return
err
;
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
:
case
IP_PKTOPTIONS
:
{
{
struct
msghdr
msg
;
struct
msghdr
msg
;
...
...
net/ipv6/ipv6_sockglue.c
View file @
3a3a07de
...
@@ -120,6 +120,12 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
...
@@ -120,6 +120,12 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
return
0
;
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
ipv6_setsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
int
optlen
)
...
@@ -393,12 +399,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
...
@@ -393,12 +399,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
break
;
break
;
}
}
psin6
=
(
struct
sockaddr_in6
*
)
&
greq
.
gr_group
;
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
,
retv
=
ipv6_sock_mc_join
(
sk
,
greq
.
gr_interface
,
&
psin6
->
sin6_addr
);
&
psin6
->
sin6_addr
);
else
else
retv
=
ipv6_sock_mc_drop
(
sk
,
greq
.
gr_interface
,
retv
=
ipv6_sock_mc_drop
(
sk
,
greq
.
gr_interface
,
&
psin6
->
sin6_addr
);
&
psin6
->
sin6_addr
);
break
;
}
}
case
MCAST_JOIN_SOURCE_GROUP
:
case
MCAST_JOIN_SOURCE_GROUP
:
case
MCAST_LEAVE_SOURCE_GROUP
:
case
MCAST_LEAVE_SOURCE_GROUP
:
...
@@ -414,7 +421,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
...
@@ -414,7 +421,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
retv
=
-
EFAULT
;
retv
=
-
EFAULT
;
break
;
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
;
retv
=
-
EADDRNOTAVAIL
;
break
;
break
;
}
}
...
...
net/ipv6/mcast.c
View file @
3a3a07de
...
@@ -768,7 +768,7 @@ static void mld_clear_delrec(struct inet6_dev *idev)
...
@@ -768,7 +768,7 @@ static void mld_clear_delrec(struct inet6_dev *idev)
psf
=
pmc
->
mca_tomb
;
psf
=
pmc
->
mca_tomb
;
pmc
->
mca_tomb
=
0
;
pmc
->
mca_tomb
=
0
;
spin_unlock_bh
(
&
pmc
->
mca_lock
);
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
;
psf_next
=
psf
->
sf_next
;
kfree
(
psf
);
kfree
(
psf
);
}
}
...
@@ -1042,6 +1042,8 @@ int igmp6_event_query(struct sk_buff *skb)
...
@@ -1042,6 +1042,8 @@ int igmp6_event_query(struct sk_buff *skb)
mld_clear_delrec
(
idev
);
mld_clear_delrec
(
idev
);
}
else
if
(
len
>=
28
)
{
}
else
if
(
len
>=
28
)
{
max_delay
=
MLDV2_MRC
(
ntohs
(
mlh2
->
mrc
))
*
(
HZ
/
10
);
max_delay
=
MLDV2_MRC
(
ntohs
(
mlh2
->
mrc
))
*
(
HZ
/
10
);
if
(
!
max_delay
)
max_delay
=
1
;
idev
->
mc_maxdelay
=
max_delay
;
idev
->
mc_maxdelay
=
max_delay
;
if
(
mlh2
->
qrv
)
if
(
mlh2
->
qrv
)
idev
->
mc_qrv
=
mlh2
->
qrv
;
idev
->
mc_qrv
=
mlh2
->
qrv
;
...
@@ -2096,8 +2098,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
...
@@ -2096,8 +2098,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
unsigned
long
icount
,
xcount
,
i
;
unsigned
long
icount
,
xcount
,
i
;
spin_lock_bh
(
&
imc
->
mca_lock
);
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
)
{
for
(
psf
=
imc
->
mca_sources
;
psf
;
psf
=
psf
->
sf_next
)
{
if
(
first
)
{
if
(
first
)
{
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
len
+=
sprintf
(
buffer
+
len
,
"%3s %6s "
...
@@ -2130,36 +2130,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
...
@@ -2130,36 +2130,6 @@ static int ip6_mcf_read_proc(char *buffer, char **start, off_t offset,
in6_dev_put
(
idev
);
in6_dev_put
(
idev
);
goto
done
;
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
);
spin_unlock_bh
(
&
imc
->
mca_lock
);
}
}
...
...
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