Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Dichtel and committed by
David S. Miller
0974658d 465b1678

+67 -1
+11
include/uapi/linux/if_tunnel.h
··· 37 37 struct iphdr iph; 38 38 }; 39 39 40 + enum { 41 + IFLA_IPTUN_UNSPEC, 42 + IFLA_IPTUN_LINK, 43 + IFLA_IPTUN_LOCAL, 44 + IFLA_IPTUN_REMOTE, 45 + IFLA_IPTUN_TTL, 46 + IFLA_IPTUN_TOS, 47 + __IFLA_IPTUN_MAX, 48 + }; 49 + #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) 50 + 40 51 /* SIT-mode i_flags */ 41 52 #define SIT_ISATAP 0x0001 42 53
+56 -1
net/ipv4/ipip.c
··· 138 138 static int ipip_tunnel_init(struct net_device *dev); 139 139 static void ipip_tunnel_setup(struct net_device *dev); 140 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 144 * Locking : hash tables are protected by RCU and RTNL ··· 306 305 goto failed_free; 307 306 308 307 strcpy(nt->parms.name, dev->name); 308 + dev->rtnl_link_ops = &ipip_link_ops; 309 309 310 310 dev_hold(dev); 311 311 ipip_tunnel_link(ipn, nt); ··· 843 841 return 0; 844 842 } 845 843 844 + static size_t ipip_get_size(const struct net_device *dev) 845 + { 846 + return 847 + /* IFLA_IPTUN_LINK */ 848 + nla_total_size(4) + 849 + /* IFLA_IPTUN_LOCAL */ 850 + nla_total_size(4) + 851 + /* IFLA_IPTUN_REMOTE */ 852 + nla_total_size(4) + 853 + /* IFLA_IPTUN_TTL */ 854 + nla_total_size(1) + 855 + /* IFLA_IPTUN_TOS */ 856 + nla_total_size(1) + 857 + 0; 858 + } 859 + 860 + static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev) 861 + { 862 + struct ip_tunnel *tunnel = netdev_priv(dev); 863 + struct ip_tunnel_parm *parm = &tunnel->parms; 864 + 865 + if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || 866 + nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || 867 + nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || 868 + nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || 869 + nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) 870 + goto nla_put_failure; 871 + return 0; 872 + 873 + nla_put_failure: 874 + return -EMSGSIZE; 875 + } 876 + 877 + static struct rtnl_link_ops ipip_link_ops __read_mostly = { 878 + .kind = "ipip", 879 + .maxtype = IFLA_IPTUN_MAX, 880 + .priv_size = sizeof(struct ip_tunnel), 881 + .get_size = ipip_get_size, 882 + .fill_info = ipip_fill_info, 883 + }; 884 + 846 885 static struct xfrm_tunnel ipip_handler __read_mostly = { 847 886 .handler = ipip_rcv, 848 887 .err_handler = ipip_err, ··· 980 937 return err; 981 938 err = xfrm4_tunnel_register(&ipip_handler, AF_INET); 982 939 if (err < 0) { 983 - unregister_pernet_device(&ipip_net_ops); 984 940 pr_info("%s: can't register tunnel\n", __func__); 941 + goto xfrm_tunnel_failed; 985 942 } 943 + err = rtnl_link_register(&ipip_link_ops); 944 + if (err < 0) 945 + goto rtnl_link_failed; 946 + 947 + out: 986 948 return err; 949 + 950 + rtnl_link_failed: 951 + xfrm4_tunnel_deregister(&ipip_handler, AF_INET); 952 + xfrm_tunnel_failed: 953 + unregister_pernet_device(&ipip_net_ops); 954 + goto out; 987 955 } 988 956 989 957 static void __exit ipip_fini(void) 990 958 { 959 + rtnl_link_unregister(&ipip_link_ops); 991 960 if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) 992 961 pr_info("%s: can't deregister tunnel\n", __func__); 993 962