RIPng Protocol Operation (IPv6 Unicast Routing Protocols) Part 1

This section provides detailed descriptions of RIPng protocol processing of the route6d implementation. Figure 1-50 shows function call graphs involved in the processing. After initialization, route6d first sends out a RIPng request message on every available interface to ask neighbor routers for their routing table contents. This is done by the sendrequest() function. The route6d daemon then waits for incoming RIPng messages in an infinite loop. The riprecv() function is called on the receipt of a message and processes the messages depending on the command, that is, request or response.

A request message is handled in riprequest(). If the request asks for the whole routing table, riprequest() calls the ripsend() function with the RRTF_SENDANYWAY flag to indicate the response should be sent to any interface; normally routed does not send a response to a loopback interface not to confuse itself. On the other hand, if the request asks for the route for specific destinations, riprequest() generates the corresponding response by itself and passes it to the sendpacket() function to transmit the final packet to the network.

A response message is mainly handled in the riprecv() function. It updates the routing table based on the contents of the response message, and calls ripsend() with the RRTF_CHANGED flag if a triggered update is necessary.

A separate function named ripalarm() is called from the infinite loop about every 30 seconds to send response message for regular updates.


FIGURE 1-50

FIGURE 1-50

The ripsend() function handles various cases of generating a response message. It examines the routing table entries and builds the appropriate response message considering configured route filtering and applying the split horizon algorithm. The ripflush() function is a simple subroutine of ripsend(), which just passes a single response message to the sendpacket() function.

The sendpacket() function sets up an ancillary data object for the given response message that specifies the outgoing interface and sends out the message to the network via the RIPng (AF_INET6 UDP) socket.

The following subsections explain the details of the functions shown in Figure 1-50 except main(), ripflush() and sendpacket(), which are pretty trivial and not actually relevant to the RIPng protocol operation.

sendrequest() Function

The sendrequest() function, shown in Listing 1-27, is called to send out a RIPng request message asking for the whole routing table of the receiver over a given interface.

Listing 1-27

Listing 1-27

1369—1370 Since the request is expected to be sent to other neighbor routers, it is suppressed on a loopback interface.

1371—1374 A request message asking for a full table dump (the destination prefix is ::/0 and an infinite metric) is built in the global buffer ripbuf. The other fields of the message were set in the initialization phase of route6d (not described in this topic).

1377—1384 The sendpacket() function is called to send the response packet to the all-rip-routers multicast address (ff02::9) from the interface identified by ifcp. If sending the packet fails with an error of EAFNOSUPPORT, it means that interface does not allow IPv6 communication (some interfaces only allow IPv4 communication). The route6d daemon detects the failure at an early stage and disables the interface for the RIPng operation.

1385 The route6d daemon never sends a request message after this initial set of requests. The command field of the global buffer is thus reset to RIP6_RESPONSE.

In fact, this function is called in a loop examining all interfaces, and rewriting the command field should be deferred after the loop.

riprecv() Function

The riprecv() function is called to process received RIPng packets. The kernel routing table may be modified as a result of the RIPng response packet processing. riprecv() may call function ripsend() to send triggered updates if necessary.

Receive Packet Listing 1-28

Receive Packet Listing 1-28

1079—1101 The local variable need_trigger serves as an indicator of whether to generate a triggered update. When response packet processing completes, if need_trigger is set to 1 then a triggered update will be sent, provided that delay requirement is satisfied.

Listing 1-29

Listing 1-29

1103—1115 The recvmsg() system call requires the caller to supply a msghdr{} structure that describes storage for receiving both data and control information. The function recvmsg() is called once the msghdr{} is built. On return from the recvmsg() call, fsock will contain the source address of the packet, which is the address of the originator of the RIPng packet. len holds the number of bytes read from the socket.

1117—1126 The route6d daemon is interested in receiving the packet information that includes the packet destination address and the interface on which the packet arrived. idx will store the interface index if the IPV6_PKTINF0 ancillary data object is present.

Listing 1-30

Listing 1-30

1127—1128 If the receiving interface index is known, and the request packet came from a link-local address, then the interface index is embedded into the address. This is necessary because this address can be passed to the kernel as the gateway address of a route entry and the kernel expects the embedded form (see Section 1.8.1), although this necessary evil should be deferred until it is really necessary, that is, until installing a route with this address into the kernel.

Listing 1-31

Listing 1-31

1130—1134 nh holds the next hop address, which is the source address of the received packet. The number of RTEs that are present in the message is calculated according to the formula given in Equation 1.1.rp points to the beginning of the RIPng packet header. np points to the beginning of the RTE list.

Figure 1-51 shows how these variables are set for a RIPng response message containing a route entry for prefix 2001:db8:1111::/48 with the metric of 3.

Handle Request Listing 1-32

Handle Request Listing 1-32

1136—1139 Currently the only defined version is RIPng version 1 as explained in Section 1.4.1. riprecv() returns here if version validation fails.

1140—1148 This if block processes an incoming RIPng request message. The index of the arrival interface is usually provided in the interface table of the route6d daemon, but there are some exceptional cases: the kernel may fail to allocate the ancillary data object, in which case the message is received by the daemon without an interface index, although the daemon should then discard the message rather than try to deal with the missing information; or, the packet may be received on an interface on which no IPv6 address is configured, although this is a very unlikely scenario. In either case, riprequest() is called to generate and transmit a RIPng response.

FIGURE 1-51

FIGURE 1-51

Next post:

Previous post: