clarify use of wildcards in multicast routes versus default mulicast routes.
--- a/examples/csma-multicast.cc Tue Sep 04 15:10:47 2007 -0700
+++ b/examples/csma-multicast.cc Tue Sep 04 18:06:06 2007 -0700
@@ -221,8 +221,8 @@
Ptr<Ipv4> ipv4;
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
- uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr(n2Lan0Addr);
- uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr(n2Lan1Addr);
+ uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr (n2Lan0Addr);
+ uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr (n2Lan1Addr);
//
// Now, we need to do is to call the AddMulticastRoute () method on node
// two's Ipv4 interface and tell it that whenever it receives a packet on
@@ -238,6 +238,41 @@
ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0,
outputInterfaces);
//
+// We need to specify how the source node handles multicasting. There are a
+// number of ways we can deal with this, we just need to pick one. The first
+// method is to add an explicit route out of the source node, just as we did
+// for the forwarding node. Use this method when you want to send packets out
+// multiple interfaces or send packets out different interfaces based on the
+// differing multicast groups. Since the source is local, there will be no
+// input interface over which packets are received, so use
+// Ipv4RoutingProtocol::IF_INDEX_ANY as a wildcard.
+//
+// A second way is to specify a multicast route using wildcards. If you
+// want to send multicasts out differing sets of interfaces based on the
+// multicast group, you can use AddMulticastRoute () but specify the origin
+// as a wildcard. If you want all multicasts to go out a single set of
+// interfaces, you can make both the origin and group a wildcard.
+//
+// If you have a simple system, where the source has a single interface, this
+// can be done via the SetDefaultMulticastRoute () method on the Ipv4
+// interface. This tells the system to send all multicasts out a single
+// specified network interface index.
+//
+// A last way is to specify a (or use an existing) default unicast route. The
+// multicast routing code uses the unicast default route as a multicast "route
+// of last resort." this method for is also on Ipv4 and is called
+// SetDefaultRoute ().
+//
+// Since this is a simple multicast example, we use the
+// SetDefaultMulticastRoute () approach. We are going to first need the
+// Ipv4 interface for node 0 which is the multicast source. We use this
+// interface to find the output interface index, and tell node zero to send
+// its multicast traffic out that interface.
+//
+ ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
+ uint32_t ifIndexSrc = ipv4->FindInterfaceForAddr (multicastSource);
+ ipv4->SetDefaultMulticastRoute (ifIndexSrc);
+//
// As described above, node four will be the only node listening for the
// multicast data. To enable forwarding bits up the protocol stack, we need
// to tell the stack to join the multicast group.
--- a/src/internet-node/ipv4-static-routing.cc Tue Sep 04 15:10:47 2007 -0700
+++ b/src/internet-node/ipv4-static-routing.cc Tue Sep 04 18:06:06 2007 -0700
@@ -289,14 +289,27 @@
Ipv4Address group,
uint32_t ifIndex)
{
+//
+// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching
+// scheme.
+//
+ Ipv4Address wildcard = Ipv4Address::GetAny ();
+
for (MulticastRoutesI i = m_multicastRoutes.begin ();
i != m_multicastRoutes.end ();
i++)
{
Ipv4MulticastRoute *route = *i;
- if ( (origin == route->GetOrigin () ||
- origin == Ipv4Address::GetAny ()) &&
- group == route->GetGroup ())
+//
+// We've been passed an origin address, a multicast group address and an
+// interface index. We have to decide if the current route in the list is
+// a match.
+//
+// The first case is the restrictive case where the origin, group and index
+// matches. This picks up exact routes during forwarded and exact routes from
+// the local node (in which case the ifIndex is a wildcard).
+//
+ if (origin == route->GetOrigin () && group == route->GetGroup ())
{
if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY ||
ifIndex == route->GetInputInterface ())
@@ -305,7 +318,67 @@
}
}
}
+//
+// If the input interface index is not a wildcard (that means that the packet
+// did not originally come from this node), we're done. We don't
+// just happily forward packets we don't really know what to do with.
+// Multicast storms are not generally considered a good thing.
+//
+ if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY)
+ {
+ return 0;
+ }
+//
+// Now, we're going to get a litle less restricive. This only applies in the
+// case where the packet in question is coming from the local node. In order
+// to avoid dependencies on the order in which routes were added, we will
+// actually walk the list two more times, the first time looking for routes
+// with a single wildcard, and the last time looking for the first route
+// with two wildcards.
+//
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ Ipv4MulticastRoute *route = *i;
+//
+// Here we will ignore the origin. We know that a single source address must
+// be picked for a packet, but we may want to send multicast packets out
+// multiple interfaces. To support this case, a user would need to add
+// a Multicast route with the route's origin set to wildcard. N.B As a
+// result, packets sourced from a node with multiple interface may have a
+// source IP address different from that of the interface actually used to
+// send the packet.
+//
+ if (route->GetOrigin () == wildcard && group == route->GetGroup ())
+ {
+ return *i;
+ }
+ }
+//
+// Finally we want to allow users to specify a default route that specifies
+// sending all multicast packets out multiple interfaces. The standard
+// default multicast route is patterned after other systems and limits the
+// number of outputs to one. If, however a client manually adds a multicast
+// route with the origin, the multicast group and the input interface index
+// all set to wildcard, she has created a default route with multiple output
+// interfaces.
+//
+ for (MulticastRoutesI i = m_multicastRoutes.begin ();
+ i != m_multicastRoutes.end ();
+ i++)
+ {
+ Ipv4MulticastRoute *route = *i;
+ if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard)
+ {
+ return *i;
+ }
+ }
+//
+// We also allow users to specify a typical default multicast route. This
+// default route is limited to specifying a single output interface.
+//
if (m_defaultMulticastRoute != 0)
{
return m_defaultMulticastRoute;
@@ -445,33 +518,7 @@
if (ipHeader.GetDestination ().IsMulticast ())
{
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination");
-//
-// We have a multicast packet we're going to send. There are two distinct
-// cases we need to support. The first is if the current node is the source
-// of the packet. In that case, we don't want to have to consult multicast
-// routing tables (nor build them) in order to send multicasts. The interface
-// index (ifIndex) is Ipv4RoutingProtocol::IF_INDEX_ANY if we're the source.
-//
-// The second case is if the current packet has gotten to us by being
-// received over one of our interfaces. In this case, ifIndex is set to the
-// index over which we received the packet. For these packets, we need to
-// consult the multicast routing table for a disposition.
-//
-// So, first let's see if we're the source. In this case, we don't consult
-// the routing tables, but just return false and let the caller (up in
-// ipv4-l3-protocol) flood the multicast packet out of all of its interfaces.
-// We can't really do it here even if we wanted to since we have no easy way
-// to get to the Ipv4 interface which we would need.
-//
- if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
- {
- return false;
- }
-//
-// If we fall through to this point, we have a multicast packet that has
-// not originated at this node. We need to deal with forwarding. Let's
-// see if we have a route, and if so go ahead and forward this puppy.
-//
+
Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
ipHeader.GetDestination (), ifIndex);
@@ -479,6 +526,7 @@
{
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
"Multicast route found");
+
for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
{
Packet p = packet;
@@ -495,7 +543,7 @@
return false; // Let other routing protocols try to handle this
}
//
-// See if this is a unicast packet we have a route for.
+// This is a unicast packet. Check to see if we have a route for it.
//
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination");
Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
--- a/src/internet-node/ipv4-static-routing.h Tue Sep 04 15:10:47 2007 -0700
+++ b/src/internet-node/ipv4-static-routing.h Tue Sep 04 18:06:06 2007 -0700
@@ -317,21 +317,34 @@
/**
* @brief Add a multicast route to the static routing table.
*
- * A multicast route must specify an origin IP address -- the address of the
- * node that originates packets destined for a given multicast group. This
- * address may be Ipv4Address::GetAny (typically 0.0.0.0) if the multicast
- * group is open, or it may specify a single IP address if the multicast
- * group is closed. The route must also specify the multicast group address.
+ * A multicast route must specify an origin IP address, a multicast group and
+ * an input network interface index as conditions and provide a vector of
+ * output network interface indices over which packets matching the conditions
+ * are sent.
+ *
+ * Typically there are two main types of multicast routes: routes of the
+ * first kind are used during forwarding. All of the conditions must be
+ * exlicitly provided. The second kind of routes are used to get packets off
+ * of a local node. The difference is in the input interface. Routes for
+ * forwarding will always have an explicit input interface specified. Routes
+ * off of a node will always set the input interface to a wildcard specified
+ * by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
*
- * For each route, the input nework interface must be specified. For
- * forwarding operations, this is the interface index that you expect multicast
- * packets to arrive over. If you want to specify routes off of a local node
- * for given multicast groups, this index may be set to
- * Ipv4RoutingProtocol::IF_INDEX_ANY.
+ * For routes off of a local node wildcards may be used in the origin and
+ * multicast group addresses. The wildcard used for Ipv4Adresses is that
+ * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
+ * of a wildcard allows one to specify default behavior to varying degrees.
*
- * For each route, a vector of output network interfaces must also be
- * specified. When the RequestRoute operation is performed, copies of a
- * packet are sent out all of the specified interfaces.
+ * For example, making the origin address a wildcard, but leaving the
+ * multicast group specific allows one (in the case of a node with multiple
+ * interfaces) to create different routes using different output interfaces
+ * for each multicast group.
+ *
+ * If the origin and multicast addresses are made wildcards, you have created
+ * essentially a default multicast address that can forward to multiple
+ * interfaces. Compare this to the actual default multicast address that is
+ * limited to specifying a single output interface for compatibility with
+ * existing functionality in other systems.
*
* @param origin The Ipv4Address of the origin of packets for this route. May
* be Ipv4Address:GetAny for open groups.
@@ -425,6 +438,12 @@
* This method causes the multicast routing table to be searched for the first
* route that matches the parameters and removes it.
*
+ * Wildcards may be provided to this function, but the wildcards are used to
+ * exacly match wildcards in the routes (see AddMulticastRoute). That is,
+ * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
+ * remove routes with any address in the origin, but will only remove routes
+ * with "0.0.0.0" set as the the origin.
+ *
* @param origin The IP address specified as the origin of packets for the
* route.
* @param origin The IP address specified as the multicast group addres of
@@ -433,9 +452,8 @@
* input interface for the route.
* @returns True if a route was found and removed, false otherwise.
*
- * @see Ipv4Route
- * @see Ipv4StaticRouting::GetRoute
- * @see Ipv4StaticRouting::AddRoute
+ * @see Ipv4MulticastRoute
+ * @see Ipv4StaticRouting::AddMulticastRoute
*/
bool RemoveMulticastRoute (Ipv4Address origin,
Ipv4Address group,