Phil and Seb,
I ran into an interesting issue with IPMP ipnet support which I wanted
your input on. As you may recall, the original proposal (from the design
doc) for IPMP support is:
Packets sent to and received from underlying interfaces will be visible
by monitoring the corresponding /dev/ipnet node; monitoring the IPMP
group interface will allow one to see all IP packets sent to and
received from all underlying interfaces in the IPMP group. If
promiscuous-mode is not enabled, only packets associated with the
addresses hosted on a particular interface will be visible. Since only
test addresses will be hosted on underlying interfaces, IP promiscuous
mode must be enabled to see the non-test traffic flowing over those
interfaces.
My original thought was that this could be accomplished by just adding the
following to the end of ipnet_hook():
/*
* If this interface is under IPMP, re-run the hook on the IPMP
* meta-interface so the packet will be visible there too.
*/
if (IS_UNDER_IPMP(ill) && (ill = ipmp_ill_hold_ipmp_ill(ill)) != NULL) {
ipnet_hook(mp, htype, zsrc, zdst, ill, ipver, hlen, ipst);
ill_refrele(ill);
}
However, because ipnet_accept() does not generally consider ifindex when
deciding whether to receive a unicast IP packet, this means snoop ends up
getting most packets twice. I see three possible solutions to this:
1. Invoke ipnet_hook() twice as above, and revise ipnet_accept() to
consider ifindex for unicast IP traffic. This seems undesirable
since I believe it's at-odds with our defined semantics -- e.g.,
packets arriving on the wrong IP interface but with the right IP
destination address should generally be accepted.
2. Invoke ipnet_hook() only once, but always use the IPMP group
interface index. This seems like it will mostly work, except that
broadcast and multicast traffic will not be visible when snooping
underlying interfaces in the group (since the ifindex won't match
in ipnet_accept()), which runs counter to our proposed behavior
in the design document.
3. Invoke ipnet_hook() only once, but have it record both the passed-in
interface's index *and* the IPMP group interface's index in the
ipnet_hook_data_t (by adding a new ihd_grifindex field). Last, update
ipnet_accept() to check both indices for a match. This seems like it
would match the proposed behavior, at the expense of having an
additional IPMP-specific field in the ipnet_hook_data_t.
Thoughts?
--
meem