The replicator is different from the other classifiers we have described earlier, in that it does not use the classify function. Rather, it simply uses the classifier as a table of n slots; it overloads the []recv method to produce n copies of a packet, that are delivered to all n objects referenced in the table.
To support multicast packet forwarding, a classifier receiving a multicast packet from source S destined for group G computes a hash function h(S,G) giving a ``slot number'' in the classifier's object table. In multicast delivery, the packet must be copied once for each link leading to nodes subscribed to G minus one. Production of additional copies of the packet is performed by a Replicator class, defined in replicator.cc:
/*
* A replicator is not really a packet classifier but
* we simply find convenience in leveraging its slot table.
* (this object used to implement fan-out on a multicast
* router as well as broadcast LANs)
*/
class Replicator : public Classifier {
public:
Replicator();
void recv(Packet*, Handler* h = 0);
virtual int classify(Packet* const) {};
protected:
int ignore_;
};
void Replicator::recv(Packet* p, Handler*)
{
IPHeader *iph = IPHeader::access(p-\>bits());
if (maxslot_ \< 0) {
if (!ignore_)
Tcl::instance().evalf("%s drop %u %u", name(),
iph-\>src(), iph-\>dst());
Packet::free(p);
return;
}
for (int i = 0; i \< maxslot_; ++i) {
NsObject* o = slot_[i];
if (o != 0)
o-\>recv(p-\>copy());
}
/* we know that maxslot is non-null */
slot_[maxslot_]-\>recv(p);
}
As we can see from the code,
this class does not really classify packets.
Rather, it replicates a packet, one for each entry in its table,
and delivers the copies to each of the nodes listed in the table.
The last entry in the table gets the ``original'' packet.
Since the []classify method is pure virtual in the base class,
the replicator defines an empty []classify method.