* Stefan Rompf <[EMAIL PROTECTED]> 2005-11-07 17:41
> > Can't we put the driver, stacked interface, etc. in charge for dropping
> > packets which shouldn't be let through yet? I would favour this and have
> > the dormant state limited to link layer responsibilities.
> 
> Imagine this situation:
> 
>  +---+
>  | 1 |
>  +---+
>    |    +---+   +---+
>    +----| 2 |---| 3 |
>     A   +---+ B +---+
>           |       |     +---+
>       ----+-------+-----| 4 |
>               C         +---+
> 
> 1,2,3,4 are acting as routers with the quagga daemon running. A,B,C are 
> networks.
> 
> Now (1) wants to reach (4). Normally, the packet would travel to (2) via (A), 
> from there to (4) via (C).
> 
> But what happens when the link from (2) to (C) fails? The routing protocol 
> would realize it (actually it was me how has added IFF_RUNNING support to 
> quagga) and add a route to (C) via (3) on (B). However, the "connected" route 
> would still have precedence and the linux IP stack on (2) would happily try 
> to continue using the broken link to (C), even if we add juju magic to the 
> link layer to recognize and drop L3 packets.
> 
> That's why I think L3 protocols should be responsible for not using a broken 
> link and why we need OPER_DORMANTL3DOWN.

I'm sorry, I don't get the point. I assume the above is not a carrier
failure but something else to be detected by a keepalive protocol. That
keepalive protocol could put the interface into dormant state and thus
control the IFF_RUNNING flag with the queues enabled so it can continue
sending. Isn't it the routing daemon's fault when preferring a route
which has the IFF_RUNNING flag cleared? I'm sorry fot not getting it. ;-)

> OPER_DORMANTL3UP is another beast. Dial on demand interfaces may be dormant, 
> but of course layer L3 must consider routes pointing to them, or they would 
> never dial.

This is clear, the packet must get to the interface in order to actually
trigger the dial.

> OTOH, we don't need to be completely atomic as the netif_carrier_*-functions 
> already require driver controlled synchronisation. We just need to make sure 
> that the caches are coherent before linkwatch kernel thread runs.

The reason we now have netif_carrier_* instead of |= IFF_RUNNING as it
used to be is exactly atomicty. Since you write to oper_state from
various locations the operation must be atomic to avoid corruption.

> > +#define IFF_LINK_UP        0x2000          /* lower link up                
> > */
> > +#define IFF_DORMANT        0x4000          /* waiting for external event   
> > */
> > +#define IFF_WAIT   0x8000          /* auto. enter dormant state    */
> 
> > +int dev_oper_state(struct net_device *dev)
> > +{
> > +   if (!netif_device_present(dev))
> > +           return IF_OPER_NOTPRESENT;
> > +
> > +   if (!netif_running(dev))
> > +           return IF_OPER_DOWN;
> 
> No, !netif_running() is ADMIN down, mostly representing the IFF_UP flag.

Right but the RFC specifies that admin. down implies operational down:

                 If ifAdminStatus is down(2) then ifOperStatus
        should be down(2). If ifAdminStatus is changed to up(1)
        then ifOperStatus should change to up(1) if the interface is
        ready to transmit and receive network traffic; it should
        change to dormant(5) if the interface is waiting for
        external actions (such as a serial line waiting for an
        incoming connection); it should remain in the down(2) state
        if and only if there is a fault that prevents it from going
        to the up(1) state; it should remain in the notPresent(6)
        state if the interface has missing (typically, hardware)
        components."

This also describes why your scheme cannot work, we have to memorize
the status of for example carrier state.

> > +   if (!netif_carrier_ok(dev))
> > +           return IF_OPER_LOWERLAYERDOWN;
> 
> No, this is OPER_DOWN. LOWERLAYERDOWN is IMHO f.e. for VLANs stacked on a 
> physical interface that is OPER_DOWN.

Correct, I agree although I don't understand this. The physical lower
link is just like a the lower interface(s) of a stackable interface. I
can't seem to understand how the RFC proposes to retreive the carrier
state while the interface is administratively down.

> >  void netif_carrier_on(struct net_device *dev)
> >  {
> > +   if ((dev->flags & IFF_WAIT) &&
> > +       test_bit(__LINK_STATE_NOCARRIER, &dev->state))
> > +           netif_dormant_on(dev);
> 
> That would be for avoiding the userspace supplicant race I assume. Bad 
> problem 
> here: To allow software/userspace controlled probe and association packets, 
> wireless devices must not go to netif_carrier_off() anymore when the 
> association is lost or must have a way to transmit packets without using the 
> kernel scheduler ;-( May be wireless developers could live with this 
> limitation.

The wireless driver can just issue netif_dormant_on(). the automatic
dormant state when the carrier is on again is just for userspace to
guarneteed actions after the link has been down.

> What to do now? I have the impression that most arguments are said. Maybe 
> someone like acme or davem should chime in and decide which direction to 
> take?

We're not far apart, the difference is for the additional L3 disabled
dormant state which I don't understand yet and secondaly that I continue
to keep the current link states with the addition of a new dormant state
and then translate it into the RFC2863 operational status.
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to