All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Tunneling related patches
@ 2012-04-12 16:31 Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 1/4] tunnel: implement 64 bits statistics Stephen Hemminger
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 16:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Implement operational state and 64 bit stats on tunnels.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] tunnel: implement 64 bits statistics
  2012-04-12 16:31 [PATCH 0/4] Tunneling related patches Stephen Hemminger
@ 2012-04-12 16:31 ` Stephen Hemminger
  2012-04-14 18:51   ` David Miller
  2012-04-12 16:31 ` [PATCH 2/4] ipgre: follow state of lower device Stephen Hemminger
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 16:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

[-- Attachment #1: tunnel-64bit-stats.patch --]
[-- Type: text/plain, Size: 9277 bytes --]

Convert the per-cpu statistics kept for GRE, IPIP, and SIT tunnels
to use 64 bit statistics.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 include/net/ipip.h |    2 +
 net/ipv4/ip_gre.c  |   59 +++++++++++++++++++++++++++++++++++------------------
 net/ipv4/ipip.c    |   53 +++++++++++++++++++++++++++++++----------------
 net/ipv6/sit.c     |   52 ++++++++++++++++++++++++++++++----------------
 4 files changed, 111 insertions(+), 55 deletions(-)

--- a/include/net/ipip.h	2012-03-14 09:51:26.511060845 -0700
+++ b/include/net/ipip.h	2012-04-11 11:46:20.338815164 -0700
@@ -54,8 +54,10 @@ struct ip_tunnel_prl_entry {
 									\
 	err = ip_local_out(skb);					\
 	if (likely(net_xmit_eval(err) == 0)) {				\
+		u64_stats_update_begin(&(stats1)->syncp);		\
 		(stats1)->tx_bytes += pkt_len;				\
 		(stats1)->tx_packets++;					\
+		u64_stats_update_end(&(stats1)->syncp);			\
 	} else {							\
 		(stats2)->tx_errors++;					\
 		(stats2)->tx_aborted_errors++;				\
--- a/net/ipv4/ip_gre.c	2012-04-09 11:18:09.000000000 -0700
+++ b/net/ipv4/ip_gre.c	2012-04-11 11:46:20.338815164 -0700
@@ -169,30 +169,49 @@ struct ipgre_net {
 
 /* often modified stats are per cpu, other are shared (netdev->stats) */
 struct pcpu_tstats {
-	unsigned long	rx_packets;
-	unsigned long	rx_bytes;
-	unsigned long	tx_packets;
-	unsigned long	tx_bytes;
-} __attribute__((aligned(4*sizeof(unsigned long))));
+	u64	rx_packets;
+	u64	rx_bytes;
+	u64	tx_packets;
+	u64	tx_bytes;
+	struct u64_stats_sync	syncp;
+};
 
-static struct net_device_stats *ipgre_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev,
+						   struct rtnl_link_stats64 *tot)
 {
-	struct pcpu_tstats sum = { 0 };
 	int i;
 
 	for_each_possible_cpu(i) {
 		const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
+		unsigned int start;
+
+		do {
+			start = u64_stats_fetch_begin_bh(&tstats->syncp);
+			rx_packets = tstats->rx_packets;
+			tx_packets = tstats->tx_packets;
+			rx_bytes = tstats->rx_bytes;
+			tx_bytes = tstats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
+
+		tot->rx_packets += rx_packets;
+		tot->tx_packets += tx_packets;
+		tot->rx_bytes   += rx_bytes;
+		tot->tx_bytes   += tx_bytes;
+	}
+
+	tot->multicast = dev->stats.multicast;
+	tot->rx_crc_errors = dev->stats.rx_crc_errors;
+	tot->rx_fifo_errors = dev->stats.rx_fifo_errors;
+	tot->rx_length_errors = dev->stats.rx_length_errors;
+	tot->rx_errors = dev->stats.rx_errors;
+	tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
+	tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
+	tot->tx_dropped = dev->stats.tx_dropped;
+	tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
+	tot->tx_errors = dev->stats.tx_errors;
 
-		sum.rx_packets += tstats->rx_packets;
-		sum.rx_bytes   += tstats->rx_bytes;
-		sum.tx_packets += tstats->tx_packets;
-		sum.tx_bytes   += tstats->tx_bytes;
-	}
-	dev->stats.rx_packets = sum.rx_packets;
-	dev->stats.rx_bytes   = sum.rx_bytes;
-	dev->stats.tx_packets = sum.tx_packets;
-	dev->stats.tx_bytes   = sum.tx_bytes;
-	return &dev->stats;
+	return tot;
 }
 
 /* Given src, dst and key, find appropriate for input tunnel. */
@@ -672,8 +691,10 @@ static int ipgre_rcv(struct sk_buff *skb
 		}
 
 		tstats = this_cpu_ptr(tunnel->dev->tstats);
+		u64_stats_update_begin(&tstats->syncp);
 		tstats->rx_packets++;
 		tstats->rx_bytes += skb->len;
+		u64_stats_update_end(&tstats->syncp);
 
 		__skb_tunnel_rx(skb, tunnel->dev);
 
@@ -1253,7 +1274,7 @@ static const struct net_device_ops ipgre
 	.ndo_start_xmit		= ipgre_tunnel_xmit,
 	.ndo_do_ioctl		= ipgre_tunnel_ioctl,
 	.ndo_change_mtu		= ipgre_tunnel_change_mtu,
-	.ndo_get_stats		= ipgre_get_stats,
+	.ndo_get_stats64	= ipgre_get_stats64,
 };
 
 static void ipgre_dev_free(struct net_device *dev)
@@ -1507,7 +1528,7 @@ static const struct net_device_ops ipgre
 	.ndo_set_mac_address 	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= ipgre_tunnel_change_mtu,
-	.ndo_get_stats		= ipgre_get_stats,
+	.ndo_get_stats64	= ipgre_get_stats64,
 };
 
 static void ipgre_tap_setup(struct net_device *dev)
--- a/net/ipv4/ipip.c	2012-03-14 08:47:00.034845540 -0700
+++ b/net/ipv4/ipip.c	2012-04-11 11:46:20.338815164 -0700
@@ -144,30 +144,45 @@ static void ipip_dev_free(struct net_dev
 
 /* often modified stats are per cpu, other are shared (netdev->stats) */
 struct pcpu_tstats {
-	unsigned long	rx_packets;
-	unsigned long	rx_bytes;
-	unsigned long	tx_packets;
-	unsigned long	tx_bytes;
-} __attribute__((aligned(4*sizeof(unsigned long))));
+	u64	rx_packets;
+	u64	rx_bytes;
+	u64	tx_packets;
+	u64	tx_bytes;
+	struct u64_stats_sync	syncp;
+};
 
-static struct net_device_stats *ipip_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev,
+						  struct rtnl_link_stats64 *tot)
 {
-	struct pcpu_tstats sum = { 0 };
 	int i;
 
 	for_each_possible_cpu(i) {
 		const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
+		unsigned int start;
+
+		do {
+			start = u64_stats_fetch_begin_bh(&tstats->syncp);
+			rx_packets = tstats->rx_packets;
+			tx_packets = tstats->tx_packets;
+			rx_bytes = tstats->rx_bytes;
+			tx_bytes = tstats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
+
+		tot->rx_packets += rx_packets;
+		tot->tx_packets += tx_packets;
+		tot->rx_bytes   += rx_bytes;
+		tot->tx_bytes   += tx_bytes;
+	}
+
+	tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
+	tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
+	tot->tx_dropped = dev->stats.tx_dropped;
+	tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
+	tot->tx_errors = dev->stats.tx_errors;
+	tot->collisions = dev->stats.collisions;
 
-		sum.rx_packets += tstats->rx_packets;
-		sum.rx_bytes   += tstats->rx_bytes;
-		sum.tx_packets += tstats->tx_packets;
-		sum.tx_bytes   += tstats->tx_bytes;
-	}
-	dev->stats.rx_packets = sum.rx_packets;
-	dev->stats.rx_bytes   = sum.rx_bytes;
-	dev->stats.tx_packets = sum.tx_packets;
-	dev->stats.tx_bytes   = sum.tx_bytes;
-	return &dev->stats;
+	return tot;
 }
 
 static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
@@ -404,8 +419,10 @@ static int ipip_rcv(struct sk_buff *skb)
 		skb->pkt_type = PACKET_HOST;
 
 		tstats = this_cpu_ptr(tunnel->dev->tstats);
+		u64_stats_update_begin(&tstats->syncp);
 		tstats->rx_packets++;
 		tstats->rx_bytes += skb->len;
+		u64_stats_update_end(&tstats->syncp);
 
 		__skb_tunnel_rx(skb, tunnel->dev);
 
@@ -730,7 +747,7 @@ static const struct net_device_ops ipip_
 	.ndo_start_xmit	= ipip_tunnel_xmit,
 	.ndo_do_ioctl	= ipip_tunnel_ioctl,
 	.ndo_change_mtu	= ipip_tunnel_change_mtu,
-	.ndo_get_stats  = ipip_get_stats,
+	.ndo_get_stats64 = ipip_get_stats64,
 };
 
 static void ipip_dev_free(struct net_device *dev)
--- a/net/ipv6/sit.c	2012-04-09 11:18:09.685154426 -0700
+++ b/net/ipv6/sit.c	2012-04-11 11:46:20.338815164 -0700
@@ -87,31 +87,47 @@ struct sit_net {
 
 /* often modified stats are per cpu, other are shared (netdev->stats) */
 struct pcpu_tstats {
-	unsigned long	rx_packets;
-	unsigned long	rx_bytes;
-	unsigned long	tx_packets;
-	unsigned long	tx_bytes;
-} __attribute__((aligned(4*sizeof(unsigned long))));
+	u64	rx_packets;
+	u64	rx_bytes;
+	u64	tx_packets;
+	u64	tx_bytes;
+	struct u64_stats_sync	syncp;
+};
 
-static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev,
+						   struct rtnl_link_stats64 *tot)
 {
-	struct pcpu_tstats sum = { 0 };
 	int i;
 
 	for_each_possible_cpu(i) {
 		const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+		u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
+		unsigned int start;
+
+		do {
+			start = u64_stats_fetch_begin_bh(&tstats->syncp);
+			rx_packets = tstats->rx_packets;
+			tx_packets = tstats->tx_packets;
+			rx_bytes = tstats->rx_bytes;
+			tx_bytes = tstats->tx_bytes;
+		} while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
+
+		tot->rx_packets += rx_packets;
+		tot->tx_packets += tx_packets;
+		tot->rx_bytes   += rx_bytes;
+		tot->tx_bytes   += tx_bytes;
+	}
+
+	tot->rx_errors = dev->stats.rx_errors;
+	tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
+	tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
+	tot->tx_dropped = dev->stats.tx_dropped;
+	tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
+	tot->tx_errors = dev->stats.tx_errors;
 
-		sum.rx_packets += tstats->rx_packets;
-		sum.rx_bytes   += tstats->rx_bytes;
-		sum.tx_packets += tstats->tx_packets;
-		sum.tx_bytes   += tstats->tx_bytes;
-	}
-	dev->stats.rx_packets = sum.rx_packets;
-	dev->stats.rx_bytes   = sum.rx_bytes;
-	dev->stats.tx_packets = sum.tx_packets;
-	dev->stats.tx_bytes   = sum.tx_bytes;
-	return &dev->stats;
+	return tot;
 }
+
 /*
  * Must be invoked with rcu_read_lock
  */
@@ -1126,7 +1142,7 @@ static const struct net_device_ops ipip6
 	.ndo_start_xmit	= ipip6_tunnel_xmit,
 	.ndo_do_ioctl	= ipip6_tunnel_ioctl,
 	.ndo_change_mtu	= ipip6_tunnel_change_mtu,
-	.ndo_get_stats	= ipip6_get_stats,
+	.ndo_get_stats64= ipip6_get_stats64,
 };
 
 static void ipip6_dev_free(struct net_device *dev)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/4] ipgre: follow state of lower device
  2012-04-12 16:31 [PATCH 0/4] Tunneling related patches Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 1/4] tunnel: implement 64 bits statistics Stephen Hemminger
@ 2012-04-12 16:31 ` Stephen Hemminger
  2012-04-12 17:32   ` Ben Hutchings
  2012-04-14 18:53   ` David Miller
  2012-04-12 16:31 ` [PATCH 3/4] sit: " Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 4/4] ipip: " Stephen Hemminger
  3 siblings, 2 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 16:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

[-- Attachment #1: ipgre-lowerup.patch --]
[-- Type: text/plain, Size: 2275 bytes --]

GRE tunnels like other layered devices should propogate
carrier and RFC2863 state from lower device to tunnel.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/ipv4/ip_gre.c	2012-04-12 08:07:39.508107847 -0700
+++ b/net/ipv4/ip_gre.c	2012-04-12 08:10:14.177499183 -0700
@@ -991,6 +991,7 @@ static int ipgre_tunnel_bind_dev(struct
 	if (tdev) {
 		hlen = tdev->hard_header_len + tdev->needed_headroom;
 		mtu = tdev->mtu;
+		netif_stacked_transfer_operstate(tdev, dev);
 	}
 	dev->iflink = tunnel->parms.link;
 
@@ -1575,6 +1576,7 @@ static int ipgre_newlink(struct net *src
 
 	dev_hold(dev);
 	ipgre_tunnel_link(ign, nt);
+	linkwatch_fire_event(dev);
 
 out:
 	return err;
@@ -1732,6 +1734,36 @@ static struct rtnl_link_ops ipgre_tap_op
 	.fill_info	= ipgre_fill_info,
 };
 
+/* If lower device changes state, reflect that to the tunnel. */
+static int ipgre_notify(struct notifier_block *unused,
+			unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+	struct net *net = dev_net(dev);
+	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
+	unsigned int prio, h;
+	struct ip_tunnel *t;
+
+	if (event == NETDEV_CHANGE)
+		return NOTIFY_DONE;
+
+	for (prio = 0; prio < 4; prio++)
+		for (h = 0; h < HASH_SIZE; h++) {
+			for (t = rtnl_dereference(ign->tunnels[prio][h]);
+			     t; t = rtnl_dereference(t->next)) {
+				if (dev->ifindex != t->dev->iflink)
+					continue;
+				netif_stacked_transfer_operstate(dev, t->dev);
+			}
+		}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ipgre_notifier = {
+	.notifier_call = ipgre_notify,
+};
+
 /*
  *	And now the modules code and kernel interface.
  */
@@ -1760,9 +1792,15 @@ static int __init ipgre_init(void)
 	if (err < 0)
 		goto tap_ops_failed;
 
+	err = register_netdevice_notifier(&ipgre_notifier);
+	if (err < 0)
+		goto notify_failed;
+
 out:
 	return err;
 
+notify_failed:
+	rtnl_link_unregister(&ipgre_tap_ops);
 tap_ops_failed:
 	rtnl_link_unregister(&ipgre_link_ops);
 rtnl_link_failed:
@@ -1774,6 +1812,7 @@ add_proto_failed:
 
 static void __exit ipgre_fini(void)
 {
+	unregister_netdevice_notifier(&ipgre_notifier);
 	rtnl_link_unregister(&ipgre_tap_ops);
 	rtnl_link_unregister(&ipgre_link_ops);
 	if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/4] sit: follow state of lower device
  2012-04-12 16:31 [PATCH 0/4] Tunneling related patches Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 1/4] tunnel: implement 64 bits statistics Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 2/4] ipgre: follow state of lower device Stephen Hemminger
@ 2012-04-12 16:31 ` Stephen Hemminger
  2012-04-12 16:31 ` [PATCH 4/4] ipip: " Stephen Hemminger
  3 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 16:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

[-- Attachment #1: sit-lowerup.patch --]
[-- Type: text/plain, Size: 2515 bytes --]

SIT tunnels like other layered devices should propogate
carrier and RFC2863 state from lower device to tunnel.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/ipv6/sit.c	2012-04-12 08:31:05.249059443 -0700
+++ b/net/ipv6/sit.c	2012-04-12 08:34:44.093009537 -0700
@@ -284,6 +284,7 @@ static struct ip_tunnel *ipip6_tunnel_lo
 	dev_hold(dev);
 
 	ipip6_tunnel_link(sitn, nt);
+	linkwatch_fire_event(dev);
 	return nt;
 
 failed_free:
@@ -901,6 +902,7 @@ static void ipip6_tunnel_bind_dev(struct
 		dev->mtu = tdev->mtu - sizeof(struct iphdr);
 		if (dev->mtu < IPV6_MIN_MTU)
 			dev->mtu = IPV6_MIN_MTU;
+		netif_stacked_transfer_operstate(tdev, dev);
 	}
 	dev->iflink = tunnel->parms.link;
 }
@@ -1231,6 +1233,36 @@ static void __net_exit sit_destroy_tunne
 	}
 }
 
+/* If lower device changes state, reflect that to the tunnel. */
+static int sit_notify(struct notifier_block *unused,
+			unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+	struct net *net = dev_net(dev);
+	struct sit_net *sitn = net_generic(net, sit_net_id);
+	unsigned int prio, h;
+	struct ip_tunnel *t;
+
+	if (event == NETDEV_CHANGE)
+		return NOTIFY_DONE;
+
+	for (prio = 0; prio < 4; prio++)
+		for (h = 0; h < HASH_SIZE; h++) {
+			for (t = rtnl_dereference(sitn->tunnels[prio][h]);
+			     t; t = rtnl_dereference(t->next)) {
+				if (dev->ifindex != t->dev->iflink)
+					continue;
+				netif_stacked_transfer_operstate(dev, t->dev);
+			}
+		}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sit_notifier = {
+	.notifier_call = sit_notify,
+};
+
 static int __net_init sit_init_net(struct net *net)
 {
 	struct sit_net *sitn = net_generic(net, sit_net_id);
@@ -1293,6 +1325,7 @@ static struct pernet_operations sit_net_
 
 static void __exit sit_cleanup(void)
 {
+	unregister_netdevice_notifier(&sit_notifier);
 	xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
 
 	unregister_pernet_device(&sit_net_ops);
@@ -1309,11 +1342,21 @@ static int __init sit_init(void)
 	if (err < 0)
 		return err;
 	err = xfrm4_tunnel_register(&sit_handler, AF_INET6);
-	if (err < 0) {
-		unregister_pernet_device(&sit_net_ops);
-		printk(KERN_INFO "sit init: Can't add protocol\n");
-	}
+	if (err < 0)
+		goto xfrm4_failed;
+
+	err = register_netdevice_notifier(&sit_notifier);
+	if (err < 0)
+		goto notify_failed;
+
+out:
 	return err;
+
+notify_failed:
+	xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
+xfrm4_failed:
+	unregister_pernet_device(&sit_net_ops);
+	goto out;
 }
 
 module_init(sit_init);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/4] ipip: follow state of lower device
  2012-04-12 16:31 [PATCH 0/4] Tunneling related patches Stephen Hemminger
                   ` (2 preceding siblings ...)
  2012-04-12 16:31 ` [PATCH 3/4] sit: " Stephen Hemminger
@ 2012-04-12 16:31 ` Stephen Hemminger
  3 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 16:31 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

[-- Attachment #1: ipip-lowerup.patch --]
[-- Type: text/plain, Size: 2365 bytes --]

Same as other tunnels propogate
carrier and RFC2863 state from lower device to tunnel.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/net/ipv4/ipip.c	2012-04-12 08:07:39.000000000 -0700
+++ b/net/ipv4/ipip.c	2012-04-12 08:14:37.776589029 -0700
@@ -304,6 +304,8 @@ static struct ip_tunnel * ipip_tunnel_lo
 
 	dev_hold(dev);
 	ipip_tunnel_link(ipn, nt);
+	linkwatch_fire_event(dev);
+
 	return nt;
 
 failed_free:
@@ -614,6 +616,7 @@ static void ipip_tunnel_bind_dev(struct
 	if (tdev) {
 		dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
 		dev->mtu = tdev->mtu - sizeof(struct iphdr);
+		netif_stacked_transfer_operstate(tdev, dev);
 	}
 	dev->iflink = tunnel->parms.link;
 }
@@ -897,6 +900,36 @@ static struct pernet_operations ipip_net
 	.size = sizeof(struct ipip_net),
 };
 
+/* If lower device changes state, reflect that to the tunnel. */
+static int ipip_notify(struct notifier_block *unused,
+			unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+	struct net *net = dev_net(dev);
+	struct ipip_net *ipn = net_generic(net, ipip_net_id);
+	struct ip_tunnel *t;
+	unsigned int prio, h;
+
+	if (event == NETDEV_CHANGE)
+		return NOTIFY_DONE;
+
+	for (prio = 0; prio < 4; prio++)
+		for (h = 0; h < HASH_SIZE; h++) {
+			for (t = rtnl_dereference(ipn->tunnels[prio][h]); t;
+			     t = rtnl_dereference(t->next)) {
+				if (dev->ifindex != t->dev->iflink)
+					continue;
+				netif_stacked_transfer_operstate(dev, t->dev);
+			}
+		}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ipip_notifier = {
+	.notifier_call = ipip_notify,
+};
+
 static int __init ipip_init(void)
 {
 	int err;
@@ -906,12 +939,24 @@ static int __init ipip_init(void)
 	err = register_pernet_device(&ipip_net_ops);
 	if (err < 0)
 		return err;
+
+	err = register_netdevice_notifier(&ipip_notifier);
+	if (err < 0)
+		goto notify_failed;
+
 	err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
-	if (err < 0) {
-		unregister_pernet_device(&ipip_net_ops);
-		pr_info("%s: can't register tunnel\n", __func__);
-	}
+	if (err < 0)
+		goto xfrm4_tunnel_failed;
+out:
 	return err;
+
+xfrm4_tunnel_failed:
+	pr_info("%s: can't register tunnel\n", __func__);
+	unregister_netdevice_notifier(&ipip_notifier);
+
+notify_failed:
+	unregister_pernet_device(&ipip_net_ops);
+	goto out;
 }
 
 static void __exit ipip_fini(void)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] ipgre: follow state of lower device
  2012-04-12 16:31 ` [PATCH 2/4] ipgre: follow state of lower device Stephen Hemminger
@ 2012-04-12 17:32   ` Ben Hutchings
  2012-04-12 17:38     ` Stephen Hemminger
  2012-04-14 18:53   ` David Miller
  1 sibling, 1 reply; 12+ messages in thread
From: Ben Hutchings @ 2012-04-12 17:32 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev

On Thu, 2012-04-12 at 09:31 -0700, Stephen Hemminger wrote:

> GRE tunnels like other layered devices should propogate
> carrier and RFC2863 state from lower device to tunnel.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> --- a/net/ipv4/ip_gre.c	2012-04-12 08:07:39.508107847 -0700
> +++ b/net/ipv4/ip_gre.c	2012-04-12 08:10:14.177499183 -0700
[...]
> @@ -1732,6 +1734,36 @@ static struct rtnl_link_ops ipgre_tap_op
>  	.fill_info	= ipgre_fill_info,
>  };
>  
> +/* If lower device changes state, reflect that to the tunnel. */
> +static int ipgre_notify(struct notifier_block *unused,
> +			unsigned long event, void *ptr)
> +{
> +	struct net_device *dev = ptr;
> +	struct net *net = dev_net(dev);
> +	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
> +	unsigned int prio, h;
> +	struct ip_tunnel *t;
> +
> +	if (event == NETDEV_CHANGE)
> +		return NOTIFY_DONE;

Surely we should handle NETDEV_UP, NETDEV_CHANGE, NETDEV_DOWN here?  Not
everything other than NETDEV_CHANGE.

> +	for (prio = 0; prio < 4; prio++)
> +		for (h = 0; h < HASH_SIZE; h++) {
> +			for (t = rtnl_dereference(ign->tunnels[prio][h]);
> +			     t; t = rtnl_dereference(t->next)) {
> +				if (dev->ifindex != t->dev->iflink)
> +					continue;
> +				netif_stacked_transfer_operstate(dev, t->dev);
> +			}
> +		}
[...]

This seems potentially very inefficient.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] ipgre: follow state of lower device
  2012-04-12 17:32   ` Ben Hutchings
@ 2012-04-12 17:38     ` Stephen Hemminger
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-12 17:38 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev

On Thu, 12 Apr 2012 18:32:07 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:

> On Thu, 2012-04-12 at 09:31 -0700, Stephen Hemminger wrote:
> 
> > GRE tunnels like other layered devices should propogate
> > carrier and RFC2863 state from lower device to tunnel.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> > 
> > --- a/net/ipv4/ip_gre.c	2012-04-12 08:07:39.508107847 -0700
> > +++ b/net/ipv4/ip_gre.c	2012-04-12 08:10:14.177499183 -0700
> [...]
> > @@ -1732,6 +1734,36 @@ static struct rtnl_link_ops ipgre_tap_op
> >  	.fill_info	= ipgre_fill_info,
> >  };
> >  
> > +/* If lower device changes state, reflect that to the tunnel. */
> > +static int ipgre_notify(struct notifier_block *unused,
> > +			unsigned long event, void *ptr)
> > +{
> > +	struct net_device *dev = ptr;
> > +	struct net *net = dev_net(dev);
> > +	struct ipgre_net *ign = net_generic(net, ipgre_net_id);
> > +	unsigned int prio, h;
> > +	struct ip_tunnel *t;
> > +
> > +	if (event == NETDEV_CHANGE)
> > +		return NOTIFY_DONE;
> 
> Surely we should handle NETDEV_UP, NETDEV_CHANGE, NETDEV_DOWN here?  Not
> everything other than NETDEV_CHANGE.

yes, up and down needed as well.

> > +	for (prio = 0; prio < 4; prio++)
> > +		for (h = 0; h < HASH_SIZE; h++) {
> > +			for (t = rtnl_dereference(ign->tunnels[prio][h]);
> > +			     t; t = rtnl_dereference(t->next)) {
> > +				if (dev->ifindex != t->dev->iflink)
> > +					continue;
> > +				netif_stacked_transfer_operstate(dev, t->dev);
> > +			}
> > +		}
> [...]
> 
> This seems potentially very inefficient.

Yes, but there is no list of tunnels per device.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] tunnel: implement 64 bits statistics
  2012-04-12 16:31 ` [PATCH 1/4] tunnel: implement 64 bits statistics Stephen Hemminger
@ 2012-04-14 18:51   ` David Miller
  0 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2012-04-14 18:51 UTC (permalink / raw)
  To: shemminger; +Cc: netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 12 Apr 2012 09:31:16 -0700

> Convert the per-cpu statistics kept for GRE, IPIP, and SIT tunnels
> to use 64 bit statistics.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Looks good, applied.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] ipgre: follow state of lower device
  2012-04-12 16:31 ` [PATCH 2/4] ipgre: follow state of lower device Stephen Hemminger
  2012-04-12 17:32   ` Ben Hutchings
@ 2012-04-14 18:53   ` David Miller
  2012-04-15  2:56     ` Stephen Hemminger
  2012-05-03 22:40     ` Stephen Hemminger
  1 sibling, 2 replies; 12+ messages in thread
From: David Miller @ 2012-04-14 18:53 UTC (permalink / raw)
  To: shemminger; +Cc: netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 12 Apr 2012 09:31:17 -0700

> GRE tunnels like other layered devices should propogate
> carrier and RFC2863 state from lower device to tunnel.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Like others I don't like the ugly hash traversal.

A small hash on ifindex, iflink, or whatever ought to be easy and make
the code look much nicer.

Longer term project is that a lot of this tunneling code can be
commonized at some point.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] ipgre: follow state of lower device
  2012-04-14 18:53   ` David Miller
@ 2012-04-15  2:56     ` Stephen Hemminger
  2012-05-03 22:40     ` Stephen Hemminger
  1 sibling, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2012-04-15  2:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev



----- Original Message -----
> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Thu, 12 Apr 2012 09:31:17 -0700
> 
> > GRE tunnels like other layered devices should propogate
> > carrier and RFC2863 state from lower device to tunnel.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> Like others I don't like the ugly hash traversal.
> 
> A small hash on ifindex, iflink, or whatever ought to be easy and
> make
> the code look much nicer.
> 
> Longer term project is that a lot of this tunneling code can be
> commonized at some point.

yeah. also want to replace open coded rcu with rcu hlist.

other tunnels that are needed are gretap over ipv6, and vxvlan.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] ipgre: follow state of lower device
  2012-04-14 18:53   ` David Miller
  2012-04-15  2:56     ` Stephen Hemminger
@ 2012-05-03 22:40     ` Stephen Hemminger
  2012-05-04 23:34       ` Christian Benvenuti (benve)
  1 sibling, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2012-05-03 22:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Sat, 14 Apr 2012 14:53:02 -0400 (EDT)
David Miller <davem@davemloft.net> wrote:

> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Thu, 12 Apr 2012 09:31:17 -0700
> 
> > GRE tunnels like other layered devices should propogate
> > carrier and RFC2863 state from lower device to tunnel.
> > 
> > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> Like others I don't like the ugly hash traversal.
> 
> A small hash on ifindex, iflink, or whatever ought to be easy and make
> the code look much nicer.
> 
> Longer term project is that a lot of this tunneling code can be
> commonized at some point.

The whole set of tunnels needs to be cleaned up to be something modular, clean
and cached like the code in OpenVswitch.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH 2/4] ipgre: follow state of lower device
  2012-05-03 22:40     ` Stephen Hemminger
@ 2012-05-04 23:34       ` Christian Benvenuti (benve)
  0 siblings, 0 replies; 12+ messages in thread
From: Christian Benvenuti (benve) @ 2012-05-04 23:34 UTC (permalink / raw)
  To: Stephen Hemminger, David Miller; +Cc: netdev, kaber

Is this the same issue I described in the email below?

  Subject:Route flush on linkdown: physical vs virtual/stacked
interfaces
  http://marc.info/?l=linux-netdev&m=133468470719285&w=2

(ie, need to propagate carrier changes to upper layer device/s)

Thanks
/Chris

> -----Original Message-----
> From: netdev-owner@vger.kernel.org
[mailto:netdev-owner@vger.kernel.org] On Behalf Of Stephen
> Hemminger
> Sent: Thursday, May 03, 2012 3:40 PM
> To: David Miller
> Cc: netdev@vger.kernel.org
> Subject: Re: [PATCH 2/4] ipgre: follow state of lower device
> 
> On Sat, 14 Apr 2012 14:53:02 -0400 (EDT)
> David Miller <davem@davemloft.net> wrote:
> 
> > From: Stephen Hemminger <shemminger@vyatta.com>
> > Date: Thu, 12 Apr 2012 09:31:17 -0700
> >
> > > GRE tunnels like other layered devices should propogate
> > > carrier and RFC2863 state from lower device to tunnel.
> > >
> > > Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> >
> > Like others I don't like the ugly hash traversal.
> >
> > A small hash on ifindex, iflink, or whatever ought to be easy and
make
> > the code look much nicer.
> >
> > Longer term project is that a lot of this tunneling code can be
> > commonized at some point.
> 
> The whole set of tunnels needs to be cleaned up to be something
modular, clean
> and cached like the code in OpenVswitch.
> --
> 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

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-05-04 23:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-12 16:31 [PATCH 0/4] Tunneling related patches Stephen Hemminger
2012-04-12 16:31 ` [PATCH 1/4] tunnel: implement 64 bits statistics Stephen Hemminger
2012-04-14 18:51   ` David Miller
2012-04-12 16:31 ` [PATCH 2/4] ipgre: follow state of lower device Stephen Hemminger
2012-04-12 17:32   ` Ben Hutchings
2012-04-12 17:38     ` Stephen Hemminger
2012-04-14 18:53   ` David Miller
2012-04-15  2:56     ` Stephen Hemminger
2012-05-03 22:40     ` Stephen Hemminger
2012-05-04 23:34       ` Christian Benvenuti (benve)
2012-04-12 16:31 ` [PATCH 3/4] sit: " Stephen Hemminger
2012-04-12 16:31 ` [PATCH 4/4] ipip: " Stephen Hemminger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.