On Oct 27, 4:11 pm, Tom Henderson <
t...@tomh.org> wrote:
> I would probably suggest to overload RouteOutput() to have versions
> with/without oif. A question I have is whether we should support a
> class that is equivalent to Linux struct flowi (which includes other
> items that might constrain the route selection like tos and scope).
>
> So one possibility is, if we introduce some kind of struct/class flowi:
>
> RouteOutput (Ptr<Packet>, header, errno_);
> RouteOutput (Ptr<Packet>, header, flowi, errno_);
> RouteOutput (Ptr<Packet>, header, oif_, errno_); // calls the "flowi"
> version for when oif_ is the only relevant parameter
>
> I am not too concerned about this API change since this is internally
> used and presently unimplemented by everyone anyway.
Flowi (taken from include/net/flow.h) in Linux sources is basically:
struct flowi {
int oif;
int iif;
__u32 mark;
union {
struct {
__be32 daddr;
__be32 saddr;
__u8 tos;
__u8 scope;
} ip4_u;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
__be32 flowlabel;
} ip6_u;
struct {
__le16 daddr;
__le16 saddr;
__u8 scope;
} dn_u;
} nl_u;
which, if taken directly, might be a bit over the top (also, I can't
find any good documentation on it - is the __u32 mark meant to signify
what's the datatype currently in the nl_u union?).
Anyway, right now oif is an integer, not even Ptr<Ipv4Interface> which
is probably more appropriate. Nevertheless, right now I'm thinking
along the lines of
RouteOutput (Ptr<Packet>, header, oif, errno_, uint32 constraints =
0);
where default would be zero and that would mean that stuff should
happen as before.
I'm using "uint32 constraints" instead of "bool
limit_to_specificed_interface" so that flowi can perhaps be added
later. Now you just need a bunch of macros or some sort of type
definitions, perhaps as bit-fields, say
CONSTRAINT_INTERFACE=0x00000001
CONSTRAINT_TOS=0x00000002
CONSTRAINT_SCOPE=0x00000004
...and so on. Granted, there isn't exactly a socket option that would
make the routing process depend on other aspects of flowi, so I'm not
sure if there is use for going for a more "generic" approach here.
The other alternative I'm thinking might actually be a bit better and
more in sync with the demuxer (see below) would be do the change of
oif from integer to Ptr. So
RouteOutput (Ptr<Packet>, header, Ptr<Ipv4Interface> oif, errno_);
With this, you don't need to include additional "constraint"
parameter. If the oif pointer is zero, there aren't any. If the oif
actually points at something, lookup the route that goes via specified
interface.
> > Also, this only covers the sending of stuff. Anyway, on the receiving
> > side, a packet ends up at Ipv4-endpoint-demuxer. There is a
> I haven't checked how this is done in Linux/BSD (where access to the
> socket data structure is probably available at the demultiplexing point)
> but I would recommend that we align the demux accordingly, even if this
> is an internal API change.
With this in mind, I think I'd do the following changes in ipv4-end-
point.h
Add public member functions:
void SetBoundIf (Ptr<Ipv4Interface>);
Ptr<Ipv4Interface> GetBoundIf ();
bool CompareBoundIf(Ptr<Ipv4Interface>); // Returns true if
m_interface == 0 or matches the parameter
and new private members:
Ptr<Ipv4Interface> m_interface; // Initialized to zero at
constructor
and
change ipv4-end-point-demuxer so that
EndPoints Lookup (Ipv4Address daddr,
uint16_t dport,
Ipv4Address saddr,
uint16_t sport,
Ptr<Ipv4Interface> incomingInterface);
will also check with CompareBoundIf(incomingInterface) if it matches
to the endpoint.
So, I don't think coding this is too hard, however, I'd like to figure
out whether it's better to use uint32 to point to the interface or a
Ptr. I specifically would like the idea of using Names facility to
name node's interfaces (so you could call them e.g. "eth0", or "lan",
"wlan") and then do binding to the name. You can attach such name to
Ptr<Ipv4Interface> object, but you can't do that with a number.
The weird part is that current API doesn't have functions from getting
the Ptr to Ipv4Interface based on index number, or vice versa. You
have stuff like GetNInterfaces(), and
int32_t GetInterfaceForAddress (Ipv4Address addr) const;
int32_t GetInterfaceForPrefix (Ipv4Address addr, Ipv4Mask mask)
const;
int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const;
but all these just return an integer. I'm a bit baffled why in this
particular case you'd wish to run with integers. There is also no
simple Ptr <Ipv4Interface> GetInterface(int32_t index).
So, full list of changes:
Implement functions to get from ifindex to Ptr<Ipv4Interface> and
vice versa. For ifindex to ptr it's a simple matter of grabbing the
pointer. For vice versa, is there really no simpler path than
{ Ptr<NetDevice> netdev = GetDevice(); return netdev->GetNode()-
>GetObject<Ipv4>()->GetInterfaceForDevice(netdev); } ?
Implement attributes to sockets. For name-based one, there's
MakeStringAccessor. Can I make accessors to objects (in this case,
Ptr<Ipv4Interface>)? Is there some way to make an "union" of attribute
accessors, so that the interface can only be specified once with
whatever method the user chooses, so that you can't e.g. specify a
conflicting name and Ptr at the same time?
Or should this perhaps be done just as member functions and
completely forget about attributes? You already have the Ptr<Socket>
anyway, so just use ->BindToIf() with various formats...Anyway, in the
end this will just pass on the interface pointer to the endpoint class
and store it there.
Change the socket's send functionality so that it grabs the bound if
from Endpoint class and sends it to the routing protocol as a compared
attribute.
Problem with the sockets that I have right now is that, as said, all
the socket types implement their own route lookup calls and their own
sending functions, and lot of the code is replicated across all of
them. However, there's not a "Socket-impl" base class which would have
common stuff to perhaps include this. Then again, right now we have
what, 4 socket types (UDP, TCP, Raw, packet), so maybe it's
acceptable. But could also set up the "socket-impl" which perhaps
should inherit Socket class and be a friend class to all the sub-
types.
Implement the RouteLookup change. If I cook up the above
functionality from going to and from Ptr<Ipv4Interface> and ifindex
integer, I can use the "constraint ="-option and not having to change
stuff on routing protocols that don't necessarily need to be touched
right now (like OLSR).
Implement the Demuxer change. This is reasonably simple - the changes
are shown above.
....time to start coding...