> 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