diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2012-11-09 01:09:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-09 19:36:20 -0500 |
commit | 0974658da47cb399b76794057823bf3cd22acf37 (patch) | |
tree | 9db7dbe10459d9c7de24d3afd7ba6a82fe9fef33 /net/ipv4 | |
parent | 465b1678ebdf5dbd9bc0502358ae472343351c2c (diff) |
ipip: advertise tunnel param via rtnl
It is usefull for daemons that monitor link event to have the full parameters of
these interfaces when a rtnl message is sent.
It allows also to dump them via rtnetlink.
It is based on what is done for GRE tunnels.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ipip.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index cc49cc1ff3b9..720855e41100 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -138,6 +138,7 @@ struct ipip_net { | |||
138 | static int ipip_tunnel_init(struct net_device *dev); | 138 | static int ipip_tunnel_init(struct net_device *dev); |
139 | static void ipip_tunnel_setup(struct net_device *dev); | 139 | static void ipip_tunnel_setup(struct net_device *dev); |
140 | static void ipip_dev_free(struct net_device *dev); | 140 | static void ipip_dev_free(struct net_device *dev); |
141 | static struct rtnl_link_ops ipip_link_ops __read_mostly; | ||
141 | 142 | ||
142 | /* | 143 | /* |
143 | * Locking : hash tables are protected by RCU and RTNL | 144 | * Locking : hash tables are protected by RCU and RTNL |
@@ -305,6 +306,7 @@ static struct ip_tunnel *ipip_tunnel_locate(struct net *net, | |||
305 | goto failed_free; | 306 | goto failed_free; |
306 | 307 | ||
307 | strcpy(nt->parms.name, dev->name); | 308 | strcpy(nt->parms.name, dev->name); |
309 | dev->rtnl_link_ops = &ipip_link_ops; | ||
308 | 310 | ||
309 | dev_hold(dev); | 311 | dev_hold(dev); |
310 | ipip_tunnel_link(ipn, nt); | 312 | ipip_tunnel_link(ipn, nt); |
@@ -841,6 +843,47 @@ static int __net_init ipip_fb_tunnel_init(struct net_device *dev) | |||
841 | return 0; | 843 | return 0; |
842 | } | 844 | } |
843 | 845 | ||
846 | static size_t ipip_get_size(const struct net_device *dev) | ||
847 | { | ||
848 | return | ||
849 | /* IFLA_IPTUN_LINK */ | ||
850 | nla_total_size(4) + | ||
851 | /* IFLA_IPTUN_LOCAL */ | ||
852 | nla_total_size(4) + | ||
853 | /* IFLA_IPTUN_REMOTE */ | ||
854 | nla_total_size(4) + | ||
855 | /* IFLA_IPTUN_TTL */ | ||
856 | nla_total_size(1) + | ||
857 | /* IFLA_IPTUN_TOS */ | ||
858 | nla_total_size(1) + | ||
859 | 0; | ||
860 | } | ||
861 | |||
862 | static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
863 | { | ||
864 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
865 | struct ip_tunnel_parm *parm = &tunnel->parms; | ||
866 | |||
867 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
868 | nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || | ||
869 | nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || | ||
870 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || | ||
871 | nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) | ||
872 | goto nla_put_failure; | ||
873 | return 0; | ||
874 | |||
875 | nla_put_failure: | ||
876 | return -EMSGSIZE; | ||
877 | } | ||
878 | |||
879 | static struct rtnl_link_ops ipip_link_ops __read_mostly = { | ||
880 | .kind = "ipip", | ||
881 | .maxtype = IFLA_IPTUN_MAX, | ||
882 | .priv_size = sizeof(struct ip_tunnel), | ||
883 | .get_size = ipip_get_size, | ||
884 | .fill_info = ipip_fill_info, | ||
885 | }; | ||
886 | |||
844 | static struct xfrm_tunnel ipip_handler __read_mostly = { | 887 | static struct xfrm_tunnel ipip_handler __read_mostly = { |
845 | .handler = ipip_rcv, | 888 | .handler = ipip_rcv, |
846 | .err_handler = ipip_err, | 889 | .err_handler = ipip_err, |
@@ -937,14 +980,26 @@ static int __init ipip_init(void) | |||
937 | return err; | 980 | return err; |
938 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); | 981 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); |
939 | if (err < 0) { | 982 | if (err < 0) { |
940 | unregister_pernet_device(&ipip_net_ops); | ||
941 | pr_info("%s: can't register tunnel\n", __func__); | 983 | pr_info("%s: can't register tunnel\n", __func__); |
984 | goto xfrm_tunnel_failed; | ||
942 | } | 985 | } |
986 | err = rtnl_link_register(&ipip_link_ops); | ||
987 | if (err < 0) | ||
988 | goto rtnl_link_failed; | ||
989 | |||
990 | out: | ||
943 | return err; | 991 | return err; |
992 | |||
993 | rtnl_link_failed: | ||
994 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | ||
995 | xfrm_tunnel_failed: | ||
996 | unregister_pernet_device(&ipip_net_ops); | ||
997 | goto out; | ||
944 | } | 998 | } |
945 | 999 | ||
946 | static void __exit ipip_fini(void) | 1000 | static void __exit ipip_fini(void) |
947 | { | 1001 | { |
1002 | rtnl_link_unregister(&ipip_link_ops); | ||
948 | if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) | 1003 | if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) |
949 | pr_info("%s: can't deregister tunnel\n", __func__); | 1004 | pr_info("%s: can't deregister tunnel\n", __func__); |
950 | 1005 | ||