From patchwork Mon Mar 19 23:58:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stephen hemminger X-Patchwork-Id: 147688 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 64F40B7028 for ; Tue, 20 Mar 2012 10:59:17 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755610Ab2CSX6t (ORCPT ); Mon, 19 Mar 2012 19:58:49 -0400 Received: from mail.vyatta.com ([76.74.103.46]:57413 "EHLO mail.vyatta.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755177Ab2CSX6s (ORCPT ); Mon, 19 Mar 2012 19:58:48 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.vyatta.com (Postfix) with ESMTP id 61A87141000E; Mon, 19 Mar 2012 16:58:47 -0700 (PDT) X-Virus-Scanned: amavisd-new at tahiti.vyatta.com Received: from mail.vyatta.com ([127.0.0.1]) by localhost (mail.vyatta.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nu4QnR6mVEI8; Mon, 19 Mar 2012 16:58:45 -0700 (PDT) Received: from nehalam.linuxnetplumber.net (static-50-53-80-93.bvtn.or.frontiernet.net [50.53.80.93]) by mail.vyatta.com (Postfix) with ESMTPSA id 2A7BF1410007; Mon, 19 Mar 2012 16:58:45 -0700 (PDT) Date: Mon, 19 Mar 2012 16:58:43 -0700 From: Stephen Hemminger To: Herbert Xu , David Miller Cc: netdev@vger.kernel.org Subject: [PATCH] gre: propagate state of link back go to tunnel Message-ID: <20120319165843.7b18412a@nehalam.linuxnetplumber.net> Organization: Vyatta X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.10; x86_64-pc-linux-gnu) Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org GRE tunnels like other layered devices should propagate carrier and RFC2863 state from lower device to tunnel. Based on similar code in vlan device driver. By using operstate it is possible for user mode to create tunnel and use stepped outlined in Documentation/networking/operstate.txt to control carrier. Signed-off-by: Stephen Hemminger --- Not urgent, can wait if the release window is already over the queue limit -- 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 --- a/net/ipv4/ip_gre.c 2012-03-19 16:09:46.662376422 -0700 +++ b/net/ipv4/ip_gre.c 2012-03-19 16:13:49.845108466 -0700 @@ -961,6 +961,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; @@ -1545,6 +1546,7 @@ static int ipgre_newlink(struct net *src dev_hold(dev); ipgre_tunnel_link(ign, nt); + linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ out: return err; @@ -1701,6 +1703,34 @@ 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 i, h; + struct ip_tunnel *t; + + if (event == NETDEV_CHANGE) + return NOTIFY_DONE; + + for (i = 0; i < 4; i++) + for (h = 0; h < HASH_SIZE; h++) + for(t = ign->tunnels[i][h]; t; t = 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. */ @@ -1729,9 +1759,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: @@ -1743,6 +1779,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)