> My suggestion is at this point to ignore any L3 issues and have people 
> post their patches. RFC 2863 states MUST be taken into consideration.
> Proper naming must be taken into account.

Split up in 3 patches, not implementing the bits allowing userspace to
trigger leaving dormant state.

[NET]: Support dormant interface state

Adds a new link state "dormant" which may be used to have
a link wait for an external event before it reaches opertional
up state.

The notification to userspace is extended:
 - IFF_LOWER_UP is set for all links with a working underlying
   layer, this can be a carrier or a set of child interfaces. 
 - IFF_DORMANT is set for links in dormant state.

Based on a patch by Krzysztof Halasa <[EMAIL PROTECTED]>

Index: net-2.6/include/linux/netdevice.h
===================================================================
--- net-2.6.orig/include/linux/netdevice.h
+++ net-2.6/include/linux/netdevice.h
@@ -230,7 +230,8 @@ enum netdev_state_t
        __LINK_STATE_SCHED,
        __LINK_STATE_NOCARRIER,
        __LINK_STATE_RX_SCHED,
-       __LINK_STATE_LINKWATCH_PENDING
+       __LINK_STATE_LINKWATCH_PENDING,
+       __LINK_STATE_DORMANT,
 };
 
 
@@ -713,6 +714,10 @@ static inline void dev_put(struct net_de
 /* Carrier loss detection, dial on demand. The functions netif_carrier_on
  * and _off may be called from IRQ context, but it is caller
  * who is responsible for serialization of these calls.
+ *
+ * The name carrier is inappropriate, these functions should really be
+ * called netif_lowerlayer_*() because they represent the state of any
+ * kind of lower layer not just hardware media.
  */
 
 extern void linkwatch_fire_event(struct net_device *dev);
@@ -751,6 +756,23 @@ static inline void netif_device_attach(s
        }
 }
 
+static inline void netif_dormant_on(struct net_device *dev)
+{
+       if (!test_and_set_bit(__LINK_STATE_DORMANT, &dev->state))
+               linkwatch_fire_event(dev);
+}
+
+static inline void netif_dormant_off(struct net_device *dev)
+{
+       if (test_and_clear_bit(__LINK_STATE_DORMANT, &dev->state))
+               linkwatch_fire_event(dev);
+}
+
+static inline int netif_dormant(const struct net_device *dev)
+{
+       return test_bit(__LINK_STATE_DORMANT, &dev->state);
+}
+
 /*
  * Network interface message level settings
  */
Index: net-2.6/net/core/dev.c
===================================================================
--- net-2.6.orig/net/core/dev.c
+++ net-2.6/net/core/dev.c
@@ -2157,8 +2157,13 @@ unsigned dev_get_flags(const struct net_
                (dev->gflags & (IFF_PROMISC |
                                IFF_ALLMULTI));
 
-       if (netif_running(dev) && netif_carrier_ok(dev))
-               flags |= IFF_RUNNING;
+       if (netif_running(dev) && netif_carrier_ok(dev)) {
+               flags |= IFF_LOWER_UP;
+               if (netif_dormant(dev))
+                       flags |= IFF_DORMANT;
+               else
+                       flags |= IFF_RUNNING;
+       }
 
        return flags;
 }
Index: net-2.6/include/linux/if.h
===================================================================
--- net-2.6.orig/include/linux/if.h
+++ net-2.6/include/linux/if.h
@@ -42,8 +42,12 @@
 #define IFF_SLAVE      0x800           /* slave of a load balancer     */
 
 #define IFF_MULTICAST  0x1000          /* Supports multicast           */
+#define IFF_LOWER_UP   0x2000          /* lower layer is up & running  */
+#define IFF_DORMANT    0x4000          /* waiting for external event   */
 
-#define IFF_VOLATILE   
(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING)
+#define IFF_VOLATILE   (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST | \
+                        IFF_MASTER | IFF_SLAVE | IFF_RUNNING | IFF_LOWER_UP | \
+                        IFF_DORMANT)
 
 #define IFF_PORTSEL    0x2000          /* can set media type           */
 #define IFF_AUTOMEDIA  0x4000          /* auto media select active     */


[NET]: Provide operational state as per rfc2863 

Provides the operational state as defined in rfc2863 via the
function dev_oper_state() derived from the actual link states.
Complex devices may implement the state via the new device
callback dev->oper_state().

Index: net-2.6/include/linux/if.h
===================================================================
--- net-2.6.orig/include/linux/if.h
+++ net-2.6/include/linux/if.h
@@ -84,6 +84,16 @@
 #define IF_PROTO_FR_ETH_PVC 0x200B
 #define IF_PROTO_RAW    0x200C          /* RAW Socket                   */
 
+/* RFC 2863 operational status */
+enum {
+       IF_OPER_UNKNOWN,
+       IF_OPER_NOTPRESENT,
+       IF_OPER_DOWN,
+       IF_OPER_LOWERLAYERDOWN,
+       IF_OPER_TESTING,
+       IF_OPER_DORMANT,
+       IF_OPER_UP,
+};
 
 /*
  *     Device mapping structure. I'd just gone off and designed a 
Index: net-2.6/include/linux/netdevice.h
===================================================================
--- net-2.6.orig/include/linux/netdevice.h
+++ net-2.6/include/linux/netdevice.h
@@ -493,6 +493,8 @@ struct net_device
        void                    (*poll_controller)(struct net_device *dev);
 #endif
 
+       int                     (*oper_state)(struct net_device *dev);
+
        /* bridge stuff */
        struct net_bridge_port  *br_port;
 
@@ -948,6 +950,7 @@ extern void         dev_mcast_init(void);
 extern int             netdev_max_backlog;
 extern int             weight_p;
 extern int             netdev_set_master(struct net_device *dev, struct 
net_device *master);
+extern int             dev_oper_state(struct net_device *dev);
 extern int skb_checksum_help(struct sk_buff *skb, int inward);
 #ifdef CONFIG_BUG
 extern void netdev_rx_csum_fault(struct net_device *dev);
Index: net-2.6/net/core/dev.c
===================================================================
--- net-2.6.orig/net/core/dev.c
+++ net-2.6/net/core/dev.c
@@ -994,6 +994,31 @@ int call_netdevice_notifiers(unsigned lo
        return notifier_call_chain(&netdev_chain, val, v);
 }
 
+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;
+
+       if (dev->oper_state)
+               return dev->oper_state(dev);
+
+       /* RFC2863 specifices LOWERLAYERDOWN to describe the state of
+        * underlying interfaces not including the carrier state. Since
+        * it really is a refinement of the down state we can use it to
+        * describe the carrier state as well.
+        */
+       if (!netif_carrier_ok(dev))
+               return IF_OPER_LOWERLAYERDOWN;
+
+       if (netif_dormant(dev))
+               return IF_OPER_DORMANT;
+
+       return IF_OPER_UP;
+}
+
 /* When > 0 there are consumers of rx skb time stamps */
 static atomic_t netstamp_needed = ATOMIC_INIT(0);
 
@@ -3289,6 +3314,7 @@ EXPORT_SYMBOL(dev_set_promiscuity);
 EXPORT_SYMBOL(dev_change_flags);
 EXPORT_SYMBOL(dev_set_mtu);
 EXPORT_SYMBOL(dev_set_mac_address);
+EXPORT_SYMBOL(dev_oper_state);
 EXPORT_SYMBOL(free_netdev);
 EXPORT_SYMBOL(netdev_boot_setup_check);
 EXPORT_SYMBOL(netdev_set_master);

[NET]: Implement auto wait interfaces

Adds a new flag IFF_WAIT which if set causes an interface going
down to automatically enter dormant state before it is mared
opertional again.

Index: net-2.6/net/core/dev.c
===================================================================
--- net-2.6.orig/net/core/dev.c
+++ net-2.6/net/core/dev.c
@@ -2204,7 +2204,7 @@ int dev_change_flags(struct net_device *
 
        dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP |
                               IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |
-                              IFF_AUTOMEDIA)) |
+                              IFF_AUTOMEDIA | IFF_WAIT)) |
                     (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |
                                    IFF_ALLMULTI));
 
Index: net-2.6/include/linux/if.h
===================================================================
--- net-2.6.orig/include/linux/if.h
+++ net-2.6/include/linux/if.h
@@ -44,6 +44,7 @@
 #define IFF_MULTICAST  0x1000          /* Supports multicast           */
 #define IFF_LOWER_UP   0x2000          /* lower layer is up & running  */
 #define IFF_DORMANT    0x4000          /* waiting for external event   */
+#define IFF_WAIT       0x8000          /* auto. enter dormant state    */
 
 #define IFF_VOLATILE   (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST | \
                         IFF_MASTER | IFF_SLAVE | IFF_RUNNING | IFF_LOWER_UP | \
Index: net-2.6/net/sched/sch_generic.c
===================================================================
--- net-2.6.orig/net/sched/sch_generic.c
+++ net-2.6/net/sched/sch_generic.c
@@ -240,6 +240,10 @@ static void dev_watchdog_down(struct net
 
 void netif_carrier_on(struct net_device *dev)
 {
+       if ((dev->flags & IFF_WAIT) &&
+           test_bit(__LINK_STATE_NOCARRIER, &dev->state))
+               netif_dormant_on(dev);
+
        if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
                linkwatch_fire_event(dev);
        if (netif_running(dev))
-
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