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
06da9228
Commit
06da9228
authored
Apr 15, 2003
by
David Stevens
Committed by
David S. Miller
Apr 15, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV6]: Add MLDv2 support.
parent
98fab1e4
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1708 additions
and
99 deletions
+1708
-99
include/linux/icmpv6.h
include/linux/icmpv6.h
+13
-0
include/linux/in.h
include/linux/in.h
+33
-0
include/linux/ip.h
include/linux/ip.h
+1
-0
include/linux/tcp.h
include/linux/tcp.h
+1
-0
include/linux/udp.h
include/linux/udp.h
+1
-0
include/net/addrconf.h
include/net/addrconf.h
+28
-39
include/net/icmp.h
include/net/icmp.h
+1
-0
include/net/if_inet6.h
include/net/if_inet6.h
+42
-0
net/ipv6/ip6_input.c
net/ipv6/ip6_input.c
+1
-1
net/ipv6/ip6_output.c
net/ipv6/ip6_output.c
+2
-1
net/ipv6/ipv6_sockglue.c
net/ipv6/ipv6_sockglue.c
+102
-0
net/ipv6/mcast.c
net/ipv6/mcast.c
+1481
-56
net/ipv6/raw.c
net/ipv6/raw.c
+1
-1
net/ipv6/udp.c
net/ipv6/udp.c
+1
-1
No files found.
include/linux/icmpv6.h
View file @
06da9228
...
...
@@ -86,6 +86,19 @@ struct icmp6hdr {
#define ICMPV6_MGM_REPORT 131
#define ICMPV6_MGM_REDUCTION 132
/* definitions for MLDv2 */
#define MLD2_MODE_IS_INCLUDE 1
#define MLD2_MODE_IS_EXCLUDE 2
#define MLD2_CHANGE_TO_INCLUDE 3
#define MLD2_CHANGE_TO_EXCLUDE 4
#define MLD2_ALLOW_NEW_SOURCES 5
#define MLD2_BLOCK_OLD_SOURCES 6
/* this must be an IANA-assigned value; 206 for testing only */
#define ICMPV6_MLD2_REPORT 206
#define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } }
/*
* Codes for Destination Unreachable
*/
...
...
include/linux/in.h
View file @
06da9228
...
...
@@ -90,6 +90,13 @@ struct in_addr {
#define IP_ADD_SOURCE_MEMBERSHIP 39
#define IP_DROP_SOURCE_MEMBERSHIP 40
#define IP_MSFILTER 41
#define MCAST_JOIN_GROUP 42
#define MCAST_BLOCK_SOURCE 43
#define MCAST_UNBLOCK_SOURCE 44
#define MCAST_LEAVE_GROUP 45
#define MCAST_JOIN_SOURCE_GROUP 46
#define MCAST_LEAVE_SOURCE_GROUP 47
#define MCAST_MSFILTER 48
#define MCAST_EXCLUDE 0
#define MCAST_INCLUDE 1
...
...
@@ -131,6 +138,32 @@ struct ip_msfilter {
(sizeof(struct ip_msfilter) - sizeof(__u32) \
+ (numsrc) * sizeof(__u32))
struct
group_req
{
__u32
gr_interface
;
/* interface index */
struct
sockaddr_storage
gr_group
;
/* group address */
};
struct
group_source_req
{
__u32
gsr_interface
;
/* interface index */
struct
sockaddr_storage
gsr_group
;
/* group address */
struct
sockaddr_storage
gsr_source
;
/* source address */
};
struct
group_filter
{
__u32
gf_interface
;
/* interface index */
struct
sockaddr_storage
gf_group
;
/* multicast address */
__u32
gf_fmode
;
/* filter mode */
__u32
gf_numsrc
;
/* number of sources */
struct
sockaddr_storage
gf_slist
[
1
];
/* interface index */
};
#define GROUP_FILTER_SIZE(numsrc) \
(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
+ (numsrc) * sizeof(struct sockaddr_storage))
struct
in_pktinfo
{
int
ipi_ifindex
;
...
...
include/linux/ip.h
View file @
06da9228
...
...
@@ -79,6 +79,7 @@
#define IPOPT_TS_PRESPEC 3
/* specified modules only */
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/types.h>
#include <net/sock.h>
#include <linux/igmp.h>
...
...
include/linux/tcp.h
View file @
06da9228
...
...
@@ -17,6 +17,7 @@
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
#include <linux/config.h>
#include <linux/skbuff.h>
#include <asm/byteorder.h>
#include <net/sock.h>
...
...
include/linux/udp.h
View file @
06da9228
...
...
@@ -17,6 +17,7 @@
#ifndef _LINUX_UDP_H
#define _LINUX_UDP_H
#include <linux/config.h>
#include <asm/byteorder.h>
#include <net/sock.h>
#include <linux/ip.h>
...
...
include/net/addrconf.h
View file @
06da9228
...
...
@@ -76,49 +76,38 @@ extern void addrconf_leave_solict(struct net_device *dev,
/*
* multicast prototypes (mcast.c)
*/
extern
int
ipv6_sock_mc_join
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
int
ipv6_sock_mc_drop
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
void
ipv6_sock_mc_close
(
struct
sock
*
sk
);
extern
int
inet6_mc_check
(
struct
sock
*
sk
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_mc_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_mc_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
void
ipv6_mc_up
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_down
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_init_dev
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_destroy_dev
(
struct
inet6_dev
*
idev
);
extern
void
addrconf_dad_failure
(
struct
inet6_ifaddr
*
ifp
);
extern
int
ipv6_chk_mcast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
void
addrconf_prefix_rcv
(
struct
net_device
*
dev
,
u8
*
opt
,
int
len
);
extern
int
ipv6_sock_mc_join
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
int
ipv6_sock_mc_drop
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
void
ipv6_sock_mc_close
(
struct
sock
*
sk
);
extern
int
inet6_mc_check
(
struct
sock
*
sk
,
struct
in6_addr
*
mc_addr
,
struct
in6_addr
*
src_addr
);
extern
int
ipv6_dev_mc_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_mc_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
void
ipv6_mc_up
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_down
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_init_dev
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_destroy_dev
(
struct
inet6_dev
*
idev
);
extern
void
addrconf_dad_failure
(
struct
inet6_ifaddr
*
ifp
);
extern
int
ipv6_chk_mcast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
group
,
struct
in6_addr
*
src_addr
);
extern
void
addrconf_prefix_rcv
(
struct
net_device
*
dev
,
u8
*
opt
,
int
len
);
/*
* anycast prototypes (anycast.c)
*/
extern
int
ipv6_sock_ac_join
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
int
ipv6_sock_ac_drop
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
void
ipv6_sock_ac_close
(
struct
sock
*
sk
);
extern
int
inet6_ac_check
(
struct
sock
*
sk
,
struct
in6_addr
*
addr
,
int
ifindex
);
extern
int
ipv6_dev_ac_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_ac_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_chk_acast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_sock_ac_join
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
int
ipv6_sock_ac_drop
(
struct
sock
*
sk
,
int
ifindex
,
struct
in6_addr
*
addr
);
extern
void
ipv6_sock_ac_close
(
struct
sock
*
sk
);
extern
int
inet6_ac_check
(
struct
sock
*
sk
,
struct
in6_addr
*
addr
,
int
ifindex
);
extern
int
ipv6_dev_ac_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_ac_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_chk_acast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
/* Device notifier */
...
...
include/net/icmp.h
View file @
06da9228
...
...
@@ -18,6 +18,7 @@
#ifndef _ICMP_H
#define _ICMP_H
#include <linux/config.h>
#include <linux/icmp.h>
#include <linux/skbuff.h>
...
...
include/net/if_inet6.h
View file @
06da9228
...
...
@@ -52,27 +52,58 @@ struct inet6_ifaddr
int
dead
;
};
struct
ip6_sf_socklist
{
unsigned
int
sl_max
;
unsigned
int
sl_count
;
struct
in6_addr
sl_addr
[
0
];
};
#define IP6_SFLSIZE(count) (sizeof(struct ip6_sf_socklist) + \
(count) * sizeof(struct in6_addr))
#define IP6_SFBLOCK 10
/* allocate this many at once */
struct
ipv6_mc_socklist
{
struct
in6_addr
addr
;
int
ifindex
;
struct
ipv6_mc_socklist
*
next
;
unsigned
int
sfmode
;
/* MCAST_{INCLUDE,EXCLUDE} */
struct
ip6_sf_socklist
*
sflist
;
};
struct
ip6_sf_list
{
struct
ip6_sf_list
*
sf_next
;
struct
in6_addr
sf_addr
;
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 */
};
#define MAF_TIMER_RUNNING 0x01
#define MAF_LAST_REPORTER 0x02
#define MAF_LOADED 0x04
#define MAF_NOREPORT 0x08
#define MAF_GSQUERY 0x10
struct
ifmcaddr6
{
struct
in6_addr
mca_addr
;
struct
inet6_dev
*
idev
;
struct
ifmcaddr6
*
next
;
struct
ip6_sf_list
*
mca_sources
;
struct
ip6_sf_list
*
mca_tomb
;
unsigned
int
mca_sfmode
;
unsigned
long
mca_sfcount
[
2
];
struct
timer_list
mca_timer
;
unsigned
mca_flags
;
int
mca_users
;
atomic_t
mca_refcnt
;
spinlock_t
mca_lock
;
unsigned
char
mca_crcount
;
};
/* Anycast stuff */
...
...
@@ -126,7 +157,18 @@ struct inet6_dev
struct
net_device
*
dev
;
struct
inet6_ifaddr
*
addr_list
;
struct
ifmcaddr6
*
mc_list
;
struct
ifmcaddr6
*
mc_tomb
;
rwlock_t
mc_lock
;
unsigned
long
mc_v1_seen
;
unsigned
long
mc_maxdelay
;
unsigned
char
mc_qrv
;
unsigned
char
mc_gq_running
;
unsigned
char
mc_ifc_count
;
struct
timer_list
mc_gq_timer
;
/* general query timer */
struct
timer_list
mc_ifc_timer
;
/* interface change timer */
struct
ifacaddr6
*
ac_list
;
rwlock_t
lock
;
atomic_t
refcnt
;
...
...
net/ipv6/ip6_input.c
View file @
06da9228
...
...
@@ -217,7 +217,7 @@ int ip6_mc_input(struct sk_buff *skb)
IP6_INC_STATS_BH
(
Ip6InMcastPkts
);
hdr
=
skb
->
nh
.
ipv6h
;
if
(
ipv6_chk_mcast_addr
(
skb
->
dev
,
&
hdr
->
daddr
))
if
(
ipv6_chk_mcast_addr
(
skb
->
dev
,
&
hdr
->
daddr
,
&
hdr
->
saddr
))
deliver
=
1
;
/*
...
...
net/ipv6/ip6_output.c
View file @
06da9228
...
...
@@ -110,7 +110,8 @@ int ip6_output(struct sk_buff *skb)
struct
ipv6_pinfo
*
np
=
skb
->
sk
?
inet6_sk
(
skb
->
sk
)
:
NULL
;
if
(
!
(
dev
->
flags
&
IFF_LOOPBACK
)
&&
(
!
np
||
np
->
mc_loop
)
&&
ipv6_chk_mcast_addr
(
dev
,
&
skb
->
nh
.
ipv6h
->
daddr
))
{
ipv6_chk_mcast_addr
(
dev
,
&
skb
->
nh
.
ipv6h
->
daddr
,
&
skb
->
nh
.
ipv6h
->
saddr
))
{
struct
sk_buff
*
newskb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
/* Do not check for IFF_ALLMULTI; multicast routing
...
...
net/ipv6/ipv6_sockglue.c
View file @
06da9228
...
...
@@ -19,6 +19,10 @@
* o Return -EINVAL for setsockopt of short lengths
* o Truncate getsockopt returns
* o Return an optlen of the truncated length if need be
*
* Changes:
* David L Stevens <dlstevens@us.ibm.com>:
* - added multicast source filtering API for MLDv2
*/
#include <linux/module.h>
...
...
@@ -375,6 +379,89 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
retv
=
ipv6_sock_ac_drop
(
sk
,
mreq
.
ipv6mr_ifindex
,
&
mreq
.
ipv6mr_acaddr
);
break
;
}
case
MCAST_JOIN_GROUP
:
case
MCAST_LEAVE_GROUP
:
{
struct
group_req
greq
;
struct
sockaddr_in6
*
psin6
;
retv
=
-
EFAULT
;
if
(
copy_from_user
(
&
greq
,
optval
,
sizeof
(
struct
group_req
)))
break
;
if
(
greq
.
gr_group
.
ss_family
!=
AF_INET6
)
{
retv
=
-
EADDRNOTAVAIL
;
break
;
}
psin6
=
(
struct
sockaddr_in6
*
)
&
greq
.
gr_group
;
if
(
optname
==
IPV6_ADD_MEMBERSHIP
)
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
);
}
case
MCAST_JOIN_SOURCE_GROUP
:
case
MCAST_LEAVE_SOURCE_GROUP
:
case
MCAST_BLOCK_SOURCE
:
case
MCAST_UNBLOCK_SOURCE
:
{
struct
group_source_req
greqs
;
int
omode
,
add
;
if
(
optlen
!=
sizeof
(
struct
group_source_req
))
goto
e_inval
;
if
(
copy_from_user
(
&
greqs
,
optval
,
sizeof
(
greqs
)))
{
retv
=
-
EFAULT
;
break
;
}
if
(
greqs
.
gsr_group
.
ss_family
!=
AF_INET6
)
{
retv
=
-
EADDRNOTAVAIL
;
break
;
}
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
sockaddr_in6
*
psin6
;
psin6
=
(
struct
sockaddr_in6
*
)
&
greqs
.
gsr_group
;
retv
=
ipv6_sock_mc_join
(
sk
,
greqs
.
gsr_interface
,
&
psin6
->
sin6_addr
);
if
(
retv
)
break
;
omode
=
MCAST_INCLUDE
;
add
=
1
;
}
else
/*IP_DROP_SOURCE_MEMBERSHIP */
{
omode
=
MCAST_INCLUDE
;
add
=
0
;
}
retv
=
ip6_mc_source
(
add
,
omode
,
sk
,
&
greqs
);
break
;
}
case
MCAST_MSFILTER
:
{
struct
group_filter
*
gsf
;
if
(
optlen
<
GROUP_FILTER_SIZE
(
0
))
goto
e_inval
;
gsf
=
(
struct
group_filter
*
)
kmalloc
(
optlen
,
GFP_KERNEL
);
if
(
gsf
==
0
)
{
retv
=
-
ENOBUFS
;
break
;
}
retv
=
-
EFAULT
;
if
(
copy_from_user
(
gsf
,
optval
,
optlen
))
{
kfree
(
gsf
);
break
;
}
retv
=
ip6_mc_msfilter
(
sk
,
gsf
);
kfree
(
gsf
);
break
;
}
case
IPV6_ROUTER_ALERT
:
retv
=
ip6_ra_control
(
sk
,
val
,
NULL
);
break
;
...
...
@@ -448,6 +535,21 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, char *optval,
return
-
ENOTCONN
;
val
=
sk
->
family
;
break
;
case
MCAST_MSFILTER
:
{
struct
group_filter
gsf
;
int
err
;
if
(
len
<
GROUP_FILTER_SIZE
(
0
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
gsf
,
optval
,
GROUP_FILTER_SIZE
(
0
)))
return
-
EFAULT
;
lock_sock
(
sk
);
err
=
ip6_mc_msfget
(
sk
,
&
gsf
,
(
struct
group_filter
*
)
optval
,
optlen
);
release_sock
(
sk
);
return
err
;
}
case
IPV6_PKTOPTIONS
:
{
...
...
net/ipv6/mcast.c
View file @
06da9228
This diff is collapsed.
Click to expand it.
net/ipv6/raw.c
View file @
06da9228
...
...
@@ -99,7 +99,7 @@ struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
if
(
!
ipv6_addr_cmp
(
&
np
->
rcv_saddr
,
loc_addr
))
break
;
if
((
addr_type
&
IPV6_ADDR_MULTICAST
)
&&
inet6_mc_check
(
s
,
loc_addr
))
inet6_mc_check
(
s
,
loc_addr
,
rmt_addr
))
break
;
continue
;
}
...
...
net/ipv6/udp.c
View file @
06da9228
...
...
@@ -592,7 +592,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
if
(
!
ipv6_addr_cmp
(
&
np
->
rcv_saddr
,
loc_addr
))
return
s
;
}
if
(
!
inet6_mc_check
(
s
,
loc_addr
))
if
(
!
inet6_mc_check
(
s
,
loc_addr
,
rmt_addr
))
continue
;
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