The IPv6 multicast routing daemons manipulate the forwarding information maintained in the kernel via socket options and through ioctl commands. Figure 2-21 shows call graphs of the related functions.
Table 2-7 summarizes socket options used by the multicast routing daemon. These are effectively only available on an ICMPv6 socket as we will see in Section 2.8.2.
Table 2-8 summarizes ioctl commands used by the multicast routing daemon.
1 ip6_mrouter_set() Function
The ip6_mrouter_set() function handles the set operation of socket options related to multicast routing sent from the routing daemon.
FIGURE 2-21
TABLE 2-7
optname |
optval type |
Function |
Description |
|
MRT6_INIT |
ip6_mrouter_init |
Start multicast routing |
||
MRT6_DONE |
ip6_mrouter_done |
Shut down multicast routing |
||
MRT6_ADD_MIF |
struct |
mif6ctl |
add_m6if |
Add multicast interface |
MRT6_DEL_MIF |
mifi_t |
del_m6if |
Delete multicast interface |
|
MRT6_ADD_MFC |
struct |
mf6cctl |
add_m6fc |
Add forwarding cache entry |
MRT6_DEL_MFC |
struct |
mf6cctl |
del_m6fc |
Delete forwarding cache entry |
MRT6_PIM |
int |
set_pim6 |
Toggle PIM routing |
TABLE 2-8
Command |
Argument type |
|
Function |
Description |
SIOCGETSGCNT_IN6 |
struct sioc_ |
_sg_req6 |
get_sg_cnt |
Get multicast forwarding statistics |
SIOCGETMIFCNT_IN6 |
struct sioc_ |
_mif_req6 |
get_mif6_cnt |
Get statistics for a multicast interface |
Listing 2-17
321—322 The first command issued by the routing daemon must be MRT6_INIT. As will be seen shortly, the socket pointer on which this option is set is stored in ip6_mrouter. Any other socket options must be specified on this socket.
324—327 Function soopt_getm() allocates an mbuf for the socket command and command options. Function soopt_mcopyin() transfers the command and its options to the newly created mbuf. These utility functions are used here to provide better portability to other BSD variants than FreeBSD.
329—361 An appropriate function is called for each specific option. These functions are described in the succeeding subsections. The temporary mbuf is freed and the error code is returned to the caller.
Note: This code has a bug. It can pass the mbuf to the subroutine function even if the data is too short for the specific option; the length must be checked beforehand. This bug is fixed in a later version of the KAME kernel.
ip6_mrouter_init() Function
The ip6_mrouter_init() function enables multicast routing in the kernel.
Listing 2-18
548—553 The multicast routing socket options must be issued on an ICMPv6 socket. The socket option must be present and the option value must be an integer. An appropriate error is returned if one of the conditions is not met.
The ENOPROTOOPT code is not an appropriate error for an invalid argument. EINVAL would have been a better choice.
555—557 The integer value specifies the kernel version supporting IPv6 multicast routing. The only currently available kernel version is 1. Any other version number is an error and the ENOPROTOOPT error code is returned.
Listing 2-19
559 The check on ip6_mrouter variable is for avoiding repeated initialization.
561—567 The global variable ip6_mrouter points to the socket corresponding to the routing daemon that is performing the kernel multicast routing initialization. ip6_mrouter_ver remembers the socket option command to provide backward compatibility (see Listing 2-54). Variable pim6 is reset to 0 to disable multicast packet forwarding until the routing daemon explicitly starts PIM routing.
570-571 Function callout_reset() starts a new timer identified by a file-scope global variable expire_upcalls_ch. The timer expires every 250 ms and invokes function expire_upcalls() (Section 2.9.3) to process stale events.
ip6_mrouter_get() Function
The ip6_mrouter_get() function is called from rip6_ctloutput() to perform the get operation of multicast routing socket options.
Listing 2-20
399 Only the active routing daemon is allowed to issue the get operation; otherwise, an error of EACCES is returned.
401-405 The only available option for the get operation is MRT6_PIM that corresponds to the pim6 variable. This variable has a binary value indicating whether PIM routing is enabled. Function sooptcopyout() copies the value of pim6 into the socket option structure to be returned to the application.
This function should actually return an error code for get options other than MRT6_PIM. Later versions of the kernel return an error of EOPNOTSUPP in such cases.
set_pim6() Function
The set_pim6() function, shown in Listing 2-21, is called by function ip6_mrouter_set() when the routing daemon starts or stops PIM routing. pim6 is set to the given binary value, which can only be either 0 or 1.
Listing 2-21