diff mbox

support force_igmp_version=3 and force_mld_version=2 ?

Message ID alpine.LRH.2.00.0809250908590.21286@netcore.fi
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Pekka Savola Sept. 25, 2008, 6:40 a.m. UTC
On Wed, 24 Sep 2008, Pekka Savola wrote:
> I've spotted some irritating IGMPv3/v2 compat problems on RHEL4, and 
> I'm working on trying to see if these are due to bugs already fixed 
> in latest kernels.

OK, I've done some tests.

1) in a RHEL4 2.6.8 kernel, the logic of timeouting seeing a V2
    querier earlier seems to be broken -- even if there are no IGMPv2
    reports or queries on the LAN for a long time, the system (as seen
    by /proc/net/igmp) doesn't go back to V3.  I tested that this works
    in 2.6.26.5 so this is OK.

2) only force_igmp_version=[12] is supported.  It might be useful to
    support "force_igmp_version=3" as well, where the system will not
    fall back to IGMPv1 or IGMPv2 compat mode even if it thinks it sees
    or has seen an IGMPv1/v2 query.

    This behaviour would be useful for example in scenarios where you
    know that the router is IGMPv3/MLDv2 capable, and you want to
    ignore queries sent by other routers, snooping switches or rogue
    hosts, or membership reports by other hosts (but Linux currently
    doesn't seem to support group-specific IGMP downgrade so this is
    not a problem right now) [see e.g. RFC4604 for more on various
    other things, e.g. warning errors, that could be added].

    What I refer to something like the follows (not tested, whitespace
    probably broken due to cut'n'pasting), or some similar changes in
    the logic where IGMP_Vx_SEEN is used (similar with MLD_V1_SEEN):

Comments

David Stevens Sept. 25, 2008, 7:10 a.m. UTC | #1
> 2) only force_igmp_version=[12] is supported.  It might be useful to
>     support "force_igmp_version=3" as well, where the system will not
>     fall back to IGMPv1 or IGMPv2 compat mode even if it thinks it sees
>     or has seen an IGMPv1/v2 query.
> 

        IGMPv3 defines the interaction with IGMPv2-- there isn't any
choice about it, which is why v3 isn't in the force set. Forcing
earlier versions may be a requirement for switches, which is why
the knob is there, but forcing later versions, which all require
full knowledge of prior versions, doesn't make sense to me.
        Answering a v2 query with a v3 response wouldn't work, since
obviously v2 queriers don't know v3 packets, and ignoring them is
a technical violation of RFC 3376. Even 4604 doesn't suggest
these queries be ignored.
        Logging an error, as suggested in RFC 4604, is ok, but it
really is only a performance issue. Without the filter information,
the group memberships may be bigger than they need to be, but
the filters will still be applied on the receiver. Ignoring queries
or answering them with v3 are both broken, at least for the v2
querier.

        So, I don't think forcing IGMPv3 makes much sense. If you
really cared about it, you could always add an iptables entry to
drop them, right?

                                                        +-DLS

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Savola Sept. 25, 2008, 9:18 a.m. UTC | #2
On Thu, 25 Sep 2008, David Stevens wrote:
>> 2) only force_igmp_version=[12] is supported.  It might be useful to
>>     support "force_igmp_version=3" as well, where the system will not
>>     fall back to IGMPv1 or IGMPv2 compat mode even if it thinks it sees
>>     or has seen an IGMPv1/v2 query.
...
>        Logging an error, as suggested in RFC 4604, is ok, but it
> really is only a performance issue. Without the filter information,
> the group memberships may be bigger than they need to be, but
> the filters will still be applied on the receiver. Ignoring queries
> or answering them with v3 are both broken, at least for the v2
> querier.

Note that it's not just a performance issue if the host would want to 
report an (S,G) for an SSM group.  This requires IGMPv3/MLDv2.  Then 
if it falls back to IGMPv2, it can only report (*,G), and it can no 
longer get the SSM transmission.  If a malicious host would send an 
IGMPv2 query on an otherwise IGMPv3-capable network segment, that 
packet would be a trivial DoS.

What I'm saying is that the compatibility mode is required in a 
scenario where you don't know which IGMP versions the legitimate nodes 
in the LAN support, but it also a DoS vector.  But in a managed 
network where you know the IGMP versions supported, forcing it may 
make sense.  This is why when you use sysctl toggles to change default 
behaviour, you're supposed to know what you're doing.

>        So, I don't think forcing IGMPv3 makes much sense. If you
> really cared about it, you could always add an iptables entry to
> drop them, right?

It's a bit tricky to figure out the correct rules to use if you want 
to drop all IGMPv1 and IGMPv2 traffic.
diff mbox

Patch

--- igmp.c.orig 2008-09-25 09:33:00.000000000 +0300
+++ igmp.c      2008-09-25 09:35:20.000000000 +0300
@@ -2,9 +2,13 @@ 
           (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \
            IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
            ((in_dev)->mr_v1_seen && \
+           IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) != 3 && \
+           IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) != 3 && \
             time_before(jiffies, (in_dev)->mr_v1_seen)))
  #define IGMP_V2_SEEN(in_dev) \
           (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \
            IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
            ((in_dev)->mr_v2_seen && \
+           IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) != 3 && \
+           IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) != 3 && \
             time_before(jiffies, (in_dev)->mr_v2_seen)))