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
c96fa28d
Commit
c96fa28d
authored
Apr 10, 2003
by
David Stevens
Committed by
David S. Miller
Apr 10, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV4]: IGMPv3 support, with help from Vinay Kulkarni
parent
af4f80fe
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1542 additions
and
40 deletions
+1542
-40
include/linux/igmp.h
include/linux/igmp.h
+96
-2
include/linux/in.h
include/linux/in.h
+26
-0
include/linux/inetdevice.h
include/linux/inetdevice.h
+10
-0
include/net/ip.h
include/net/ip.h
+1
-0
net/ipv4/igmp.c
net/ipv4/igmp.c
+1329
-34
net/ipv4/ip_output.c
net/ipv4/ip_output.c
+1
-0
net/ipv4/ip_sockglue.c
net/ipv4/ip_sockglue.c
+74
-2
net/ipv4/route.c
net/ipv4/route.c
+3
-2
net/ipv4/udp.c
net/ipv4/udp.c
+2
-0
No files found.
include/linux/igmp.h
View file @
c96fa28d
...
@@ -32,13 +32,60 @@ struct igmphdr
...
@@ -32,13 +32,60 @@ struct igmphdr
__u32
group
;
__u32
group
;
};
};
/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE 1
#define IGMPV3_MODE_IS_EXCLUDE 2
#define IGMPV3_CHANGE_TO_INCLUDE 3
#define IGMPV3_CHANGE_TO_EXCLUDE 4
#define IGMPV3_ALLOW_NEW_SOURCES 5
#define IGMPV3_BLOCK_OLD_SOURCES 6
struct
igmpv3_grec
{
__u8
grec_type
;
__u8
grec_auxwords
;
__u16
grec_nsrcs
;
__u32
grec_mca
;
__u32
grec_src
[
0
];
};
struct
igmpv3_report
{
__u8
type
;
__u8
resv1
;
__u16
csum
;
__u16
resv2
;
__u16
ngrec
;
struct
igmpv3_grec
grec
[
0
];
};
struct
igmpv3_query
{
__u8
type
;
__u8
code
;
__u16
csum
;
__u32
group
;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8
qrv
:
3
,
suppress:
1
,
resv:
4
;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8
resv
:
4
,
suppress:
1
,
qrv:
3
;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8
qqic
;
__u16
nsrcs
;
__u32
srcs
[
0
];
};
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11
/* From RFC1112 */
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11
/* From RFC1112 */
#define IGMP_HOST_MEMBERSHIP_REPORT 0x12
/* Ditto */
#define IGMP_HOST_MEMBERSHIP_REPORT 0x12
/* Ditto */
#define IGMP_DVMRP 0x13
/* DVMRP routing */
#define IGMP_DVMRP 0x13
/* DVMRP routing */
#define IGMP_PIM 0x14
/* PIM routing */
#define IGMP_PIM 0x14
/* PIM routing */
#define IGMP_TRACE 0x15
#define IGMP_TRACE 0x15
#define IGMP
_HOST_NEW_MEMBERSHIP_REPORT 0x16
/* New
version of 0x11 */
#define IGMP
V2_HOST_MEMBERSHIP_REPORT 0x16
/* V2
version of 0x11 */
#define IGMP_HOST_LEAVE_MESSAGE 0x17
#define IGMP_HOST_LEAVE_MESSAGE 0x17
#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22
/* V3 version of 0x11 */
#define IGMP_MTRACE_RESP 0x1e
#define IGMP_MTRACE_RESP 0x1e
#define IGMP_MTRACE 0x1f
#define IGMP_MTRACE 0x1f
...
@@ -68,6 +115,7 @@ struct igmphdr
...
@@ -68,6 +115,7 @@ struct igmphdr
#define IGMP_ALL_HOSTS htonl(0xE0000001L)
#define IGMP_ALL_HOSTS htonl(0xE0000001L)
#define IGMP_ALL_ROUTER htonl(0xE0000002L)
#define IGMP_ALL_ROUTER htonl(0xE0000002L)
#define IGMPV3_ALL_MCR htonl(0xE0000016L)
#define IGMP_LOCAL_GROUP htonl(0xE0000000L)
#define IGMP_LOCAL_GROUP htonl(0xE0000000L)
#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L)
#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L)
...
@@ -79,6 +127,18 @@ struct igmphdr
...
@@ -79,6 +127,18 @@ struct igmphdr
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/in.h>
struct
ip_sf_socklist
{
unsigned
int
sl_max
;
unsigned
int
sl_count
;
__u32
sl_addr
[
0
];
};
#define IP_SFLSIZE(count) (sizeof(struct ip_sf_socklist) + \
(count) * sizeof(__u32))
#define IP_SFBLOCK 10
/* allocate this many at once */
/* ip_mc_socklist is real list now. Speed is not argument;
/* ip_mc_socklist is real list now. Speed is not argument;
this list never used in fast path code
this list never used in fast path code
*/
*/
...
@@ -88,12 +148,28 @@ struct ip_mc_socklist
...
@@ -88,12 +148,28 @@ struct ip_mc_socklist
struct
ip_mc_socklist
*
next
;
struct
ip_mc_socklist
*
next
;
int
count
;
int
count
;
struct
ip_mreqn
multi
;
struct
ip_mreqn
multi
;
unsigned
int
sfmode
;
/* MCAST_{INCLUDE,EXCLUDE} */
struct
ip_sf_socklist
*
sflist
;
};
struct
ip_sf_list
{
struct
ip_sf_list
*
sf_next
;
__u32
sf_inaddr
;
unsigned
long
sf_count
[
2
];
/* include/exclude counts */
unsigned
char
sf_gsresp
;
/* include in g & s response? */
unsigned
char
sf_oldin
;
/* change state */
unsigned
char
sf_crcount
;
/* retrans. left to send */
};
};
struct
ip_mc_list
struct
ip_mc_list
{
{
struct
in_device
*
interface
;
struct
in_device
*
interface
;
unsigned
long
multiaddr
;
unsigned
long
multiaddr
;
struct
ip_sf_list
*
sources
;
struct
ip_sf_list
*
tomb
;
unsigned
int
sfmode
;
unsigned
long
sfcount
[
2
];
struct
ip_mc_list
*
next
;
struct
ip_mc_list
*
next
;
struct
timer_list
timer
;
struct
timer_list
timer
;
int
users
;
int
users
;
...
@@ -103,13 +179,31 @@ struct ip_mc_list
...
@@ -103,13 +179,31 @@ struct ip_mc_list
char
reporter
;
char
reporter
;
char
unsolicit_count
;
char
unsolicit_count
;
char
loaded
;
char
loaded
;
unsigned
char
gsquery
;
/* check source marks? */
unsigned
char
crcount
;
};
};
extern
int
ip_check_mc
(
struct
in_device
*
dev
,
u32
mc_addr
);
/* V3 exponential field decoding */
#define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
#define IGMPV3_EXP(thresh, nbmant, nbexp, value) \
((value) < (thresh) ? (value) : \
((IGMPV3_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \
(IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
#define IGMPV3_MRC(value) IGMPV3_EXP(0x8000, 12, 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
*
);
extern
int
igmp_rcv
(
struct
sk_buff
*
);
extern
int
ip_mc_join_group
(
struct
sock
*
sk
,
struct
ip_mreqn
*
imr
);
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
,
struct
ip_mreq_source
*
mreqs
);
extern
int
ip_mc_msfilter
(
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
);
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
*
);
extern
void
ip_mc_destroy_dev
(
struct
in_device
*
);
extern
void
ip_mc_destroy_dev
(
struct
in_device
*
);
...
...
include/linux/in.h
View file @
c96fa28d
...
@@ -85,6 +85,14 @@ struct in_addr {
...
@@ -85,6 +85,14 @@ struct in_addr {
#define IP_MULTICAST_LOOP 34
#define IP_MULTICAST_LOOP 34
#define IP_ADD_MEMBERSHIP 35
#define IP_ADD_MEMBERSHIP 35
#define IP_DROP_MEMBERSHIP 36
#define IP_DROP_MEMBERSHIP 36
#define IP_UNBLOCK_SOURCE 37
#define IP_BLOCK_SOURCE 38
#define IP_ADD_SOURCE_MEMBERSHIP 39
#define IP_DROP_SOURCE_MEMBERSHIP 40
#define IP_MSFILTER 41
#define MCAST_EXCLUDE 0
#define MCAST_INCLUDE 1
/* These need to appear somewhere around here */
/* These need to appear somewhere around here */
#define IP_DEFAULT_MULTICAST_TTL 1
#define IP_DEFAULT_MULTICAST_TTL 1
...
@@ -105,6 +113,24 @@ struct ip_mreqn
...
@@ -105,6 +113,24 @@ struct ip_mreqn
int
imr_ifindex
;
/* Interface index */
int
imr_ifindex
;
/* Interface index */
};
};
struct
ip_mreq_source
{
__u32
imr_multiaddr
;
__u32
imr_interface
;
__u32
imr_sourceaddr
;
};
struct
ip_msfilter
{
__u32
imsf_multiaddr
;
__u32
imsf_interface
;
__u32
imsf_fmode
;
__u32
imsf_numsrc
;
__u32
imsf_slist
[
1
];
};
#define IP_MSFILTER_SIZE(numsrc) \
(sizeof(struct ip_msfilter) - sizeof(__u32) \
+ (numsrc) * sizeof(__u32))
struct
in_pktinfo
struct
in_pktinfo
{
{
int
ipi_ifindex
;
int
ipi_ifindex
;
...
...
include/linux/inetdevice.h
View file @
c96fa28d
...
@@ -34,7 +34,17 @@ struct in_device
...
@@ -34,7 +34,17 @@ struct in_device
int
dead
;
int
dead
;
struct
in_ifaddr
*
ifa_list
;
/* IP ifaddr chain */
struct
in_ifaddr
*
ifa_list
;
/* IP ifaddr chain */
struct
ip_mc_list
*
mc_list
;
/* IP multicast filter chain */
struct
ip_mc_list
*
mc_list
;
/* IP multicast filter chain */
rwlock_t
mc_lock
;
/* for mc_tomb */
struct
ip_mc_list
*
mc_tomb
;
unsigned
long
mr_v1_seen
;
unsigned
long
mr_v1_seen
;
unsigned
long
mr_v2_seen
;
unsigned
long
mr_maxdelay
;
unsigned
char
mr_qrv
;
unsigned
char
mr_gq_running
;
unsigned
char
mr_ifc_count
;
struct
timer_list
mr_gq_timer
;
/* general query timer */
struct
timer_list
mr_ifc_timer
;
/* interface change timer */
struct
neigh_parms
*
arp_parms
;
struct
neigh_parms
*
arp_parms
;
struct
ipv4_devconf
cnf
;
struct
ipv4_devconf
cnf
;
};
};
...
...
include/net/ip.h
View file @
c96fa28d
...
@@ -79,6 +79,7 @@ extern rwlock_t ip_ra_lock;
...
@@ -79,6 +79,7 @@ extern rwlock_t ip_ra_lock;
extern
void
ip_mc_dropsocket
(
struct
sock
*
);
extern
void
ip_mc_dropsocket
(
struct
sock
*
);
extern
void
ip_mc_dropdevice
(
struct
net_device
*
dev
);
extern
void
ip_mc_dropdevice
(
struct
net_device
*
dev
);
extern
int
ip_mc_procinfo
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
ip_mc_procinfo
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
ip_mcf_procinfo
(
char
*
,
char
**
,
off_t
,
int
);
/*
/*
* Functions provided by ip.c
* Functions provided by ip.c
...
...
net/ipv4/igmp.c
View file @
c96fa28d
This diff is collapsed.
Click to expand it.
net/ipv4/ip_output.c
View file @
c96fa28d
...
@@ -1312,5 +1312,6 @@ void __init ip_init(void)
...
@@ -1312,5 +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
}
}
net/ipv4/ip_sockglue.c
View file @
c96fa28d
...
@@ -610,9 +610,67 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
...
@@ -610,9 +610,67 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
}
}
if
(
optname
==
IP_ADD_MEMBERSHIP
)
if
(
optname
==
IP_ADD_MEMBERSHIP
)
err
=
ip_mc_join_group
(
sk
,
&
mreq
);
err
=
ip_mc_join_group
(
sk
,
&
mreq
);
else
else
err
=
ip_mc_leave_group
(
sk
,
&
mreq
);
err
=
ip_mc_leave_group
(
sk
,
&
mreq
);
break
;
}
case
IP_MSFILTER
:
{
struct
ip_msfilter
*
msf
;
if
(
optlen
<
IP_MSFILTER_SIZE
(
0
))
goto
e_inval
;
msf
=
(
struct
ip_msfilter
*
)
kmalloc
(
optlen
,
GFP_KERNEL
);
if
(
msf
==
0
)
{
err
=
-
ENOBUFS
;
break
;
}
err
=
-
EFAULT
;
if
(
copy_from_user
(
msf
,
optval
,
optlen
))
{
kfree
(
msf
);
break
;
}
err
=
ip_mc_msfilter
(
sk
,
msf
);
kfree
(
msf
);
break
;
}
case
IP_BLOCK_SOURCE
:
case
IP_UNBLOCK_SOURCE
:
case
IP_ADD_SOURCE_MEMBERSHIP
:
case
IP_DROP_SOURCE_MEMBERSHIP
:
{
struct
ip_mreq_source
mreqs
;
int
omode
,
add
;
if
(
optlen
!=
sizeof
(
struct
ip_mreq_source
))
goto
e_inval
;
if
(
copy_from_user
(
&
mreqs
,
optval
,
sizeof
(
mreqs
)))
{
err
=
-
EFAULT
;
break
;
}
if
(
optname
==
IP_BLOCK_SOURCE
)
{
omode
=
MCAST_EXCLUDE
;
add
=
1
;
}
else
if
(
optname
==
IP_UNBLOCK_SOURCE
)
{
omode
=
MCAST_EXCLUDE
;
add
=
0
;
}
else
if
(
optname
==
IP_ADD_SOURCE_MEMBERSHIP
)
{
struct
ip_mreqn
mreq
;
mreq
.
imr_multiaddr
.
s_addr
=
mreqs
.
imr_multiaddr
;
mreq
.
imr_address
.
s_addr
=
mreqs
.
imr_interface
;
mreq
.
imr_ifindex
=
0
;
err
=
ip_mc_join_group
(
sk
,
&
mreq
);
if
(
err
)
break
;
omode
=
MCAST_INCLUDE
;
add
=
1
;
}
else
/*IP_DROP_SOURCE_MEMBERSHIP */
{
omode
=
MCAST_INCLUDE
;
add
=
0
;
}
err
=
ip_mc_source
(
add
,
omode
,
sk
,
&
mreqs
);
break
;
break
;
}
}
case
IP_ROUTER_ALERT
:
case
IP_ROUTER_ALERT
:
...
@@ -763,6 +821,20 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
...
@@ -763,6 +821,20 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
return
-
EFAULT
;
return
-
EFAULT
;
return
0
;
return
0
;
}
}
case
IP_MSFILTER
:
{
struct
ip_msfilter
msf
;
int
err
;
if
(
len
<
IP_MSFILTER_SIZE
(
0
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
msf
,
optval
,
IP_MSFILTER_SIZE
(
0
)))
return
-
EFAULT
;
err
=
ip_mc_msfget
(
sk
,
&
msf
,
(
struct
ip_msfilter
*
)
optval
,
optlen
);
release_sock
(
sk
);
return
err
;
}
case
IP_PKTOPTIONS
:
case
IP_PKTOPTIONS
:
{
{
struct
msghdr
msg
;
struct
msghdr
msg
;
...
...
net/ipv4/route.c
View file @
c96fa28d
...
@@ -1790,7 +1790,8 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
...
@@ -1790,7 +1790,8 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
read_lock
(
&
inetdev_lock
);
read_lock
(
&
inetdev_lock
);
if
((
in_dev
=
__in_dev_get
(
dev
))
!=
NULL
)
{
if
((
in_dev
=
__in_dev_get
(
dev
))
!=
NULL
)
{
int
our
=
ip_check_mc
(
in_dev
,
daddr
);
int
our
=
ip_check_mc
(
in_dev
,
daddr
,
saddr
,
skb
->
nh
.
iph
->
protocol
);
if
(
our
if
(
our
#ifdef CONFIG_IP_MROUTE
#ifdef CONFIG_IP_MROUTE
||
(
!
LOCAL_MCAST
(
daddr
)
&&
IN_DEV_MFORWARD
(
in_dev
))
||
(
!
LOCAL_MCAST
(
daddr
)
&&
IN_DEV_MFORWARD
(
in_dev
))
...
@@ -2020,7 +2021,7 @@ int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
...
@@ -2020,7 +2021,7 @@ int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
}
}
}
else
if
(
res
.
type
==
RTN_MULTICAST
)
{
}
else
if
(
res
.
type
==
RTN_MULTICAST
)
{
flags
|=
RTCF_MULTICAST
|
RTCF_LOCAL
;
flags
|=
RTCF_MULTICAST
|
RTCF_LOCAL
;
if
(
!
ip_check_mc
(
in_dev
,
oldflp
->
fl4_dst
))
if
(
!
ip_check_mc
(
in_dev
,
oldflp
->
fl4_dst
,
oldflp
->
fl4_src
,
oldflp
->
proto
))
flags
&=
~
RTCF_LOCAL
;
flags
&=
~
RTCF_LOCAL
;
/* If multicast route do not exist use
/* If multicast route do not exist use
default one, but do not gateway in this case.
default one, but do not gateway in this case.
...
...
net/ipv4/udp.c
View file @
c96fa28d
...
@@ -298,6 +298,8 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
...
@@ -298,6 +298,8 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
ipv6_only_sock
(
s
)
||
ipv6_only_sock
(
s
)
||
(
s
->
bound_dev_if
&&
s
->
bound_dev_if
!=
dif
))
(
s
->
bound_dev_if
&&
s
->
bound_dev_if
!=
dif
))
continue
;
continue
;
if
(
!
ip_mc_sf_allow
(
sk
,
loc_addr
,
rmt_addr
,
dif
))
continue
;
break
;
break
;
}
}
return
s
;
return
s
;
...
...
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