diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2012-11-09 01:10:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-09 19:36:20 -0500 |
commit | c075b13098b399dc565b4d53f42047a8d40ed3ba (patch) | |
tree | e7d443ab220da2f1e9f5d48373bc50754a70ce5d | |
parent | ba3e3f50a0e5de76fc0684d856394931f2bc39fa (diff) |
ip6tnl: 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>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/uapi/linux/if_tunnel.h | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 57 |
2 files changed, 60 insertions, 0 deletions
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index ccb21d585bf4..c1bf0b5a8da1 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h | |||
@@ -44,6 +44,9 @@ enum { | |||
44 | IFLA_IPTUN_REMOTE, | 44 | IFLA_IPTUN_REMOTE, |
45 | IFLA_IPTUN_TTL, | 45 | IFLA_IPTUN_TTL, |
46 | IFLA_IPTUN_TOS, | 46 | IFLA_IPTUN_TOS, |
47 | IFLA_IPTUN_ENCAP_LIMIT, | ||
48 | IFLA_IPTUN_FLOWINFO, | ||
49 | IFLA_IPTUN_FLAGS, | ||
47 | __IFLA_IPTUN_MAX, | 50 | __IFLA_IPTUN_MAX, |
48 | }; | 51 | }; |
49 | #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) | 52 | #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 09482f723064..424ed45ef122 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -83,6 +83,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) | |||
83 | 83 | ||
84 | static int ip6_tnl_dev_init(struct net_device *dev); | 84 | static int ip6_tnl_dev_init(struct net_device *dev); |
85 | static void ip6_tnl_dev_setup(struct net_device *dev); | 85 | static void ip6_tnl_dev_setup(struct net_device *dev); |
86 | static struct rtnl_link_ops ip6_link_ops __read_mostly; | ||
86 | 87 | ||
87 | static int ip6_tnl_net_id __read_mostly; | 88 | static int ip6_tnl_net_id __read_mostly; |
88 | struct ip6_tnl_net { | 89 | struct ip6_tnl_net { |
@@ -299,6 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | |||
299 | goto failed_free; | 300 | goto failed_free; |
300 | 301 | ||
301 | strcpy(t->parms.name, dev->name); | 302 | strcpy(t->parms.name, dev->name); |
303 | dev->rtnl_link_ops = &ip6_link_ops; | ||
302 | 304 | ||
303 | dev_hold(dev); | 305 | dev_hold(dev); |
304 | ip6_tnl_link(ip6n, t); | 306 | ip6_tnl_link(ip6n, t); |
@@ -1504,6 +1506,55 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1504 | return 0; | 1506 | return 0; |
1505 | } | 1507 | } |
1506 | 1508 | ||
1509 | static size_t ip6_get_size(const struct net_device *dev) | ||
1510 | { | ||
1511 | return | ||
1512 | /* IFLA_IPTUN_LINK */ | ||
1513 | nla_total_size(4) + | ||
1514 | /* IFLA_IPTUN_LOCAL */ | ||
1515 | nla_total_size(sizeof(struct in6_addr)) + | ||
1516 | /* IFLA_IPTUN_REMOTE */ | ||
1517 | nla_total_size(sizeof(struct in6_addr)) + | ||
1518 | /* IFLA_IPTUN_TTL */ | ||
1519 | nla_total_size(1) + | ||
1520 | /* IFLA_IPTUN_ENCAP_LIMIT */ | ||
1521 | nla_total_size(1) + | ||
1522 | /* IFLA_IPTUN_FLOWINFO */ | ||
1523 | nla_total_size(4) + | ||
1524 | /* IFLA_IPTUN_FLAGS */ | ||
1525 | nla_total_size(4) + | ||
1526 | 0; | ||
1527 | } | ||
1528 | |||
1529 | static int ip6_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1530 | { | ||
1531 | struct ip6_tnl *tunnel = netdev_priv(dev); | ||
1532 | struct __ip6_tnl_parm *parm = &tunnel->parms; | ||
1533 | |||
1534 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1535 | nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), | ||
1536 | &parm->raddr) || | ||
1537 | nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), | ||
1538 | &parm->laddr) || | ||
1539 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) || | ||
1540 | nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || | ||
1541 | nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || | ||
1542 | nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags)) | ||
1543 | goto nla_put_failure; | ||
1544 | return 0; | ||
1545 | |||
1546 | nla_put_failure: | ||
1547 | return -EMSGSIZE; | ||
1548 | } | ||
1549 | |||
1550 | static struct rtnl_link_ops ip6_link_ops __read_mostly = { | ||
1551 | .kind = "ip6tnl", | ||
1552 | .maxtype = IFLA_IPTUN_MAX, | ||
1553 | .priv_size = sizeof(struct ip6_tnl), | ||
1554 | .get_size = ip6_get_size, | ||
1555 | .fill_info = ip6_fill_info, | ||
1556 | }; | ||
1557 | |||
1507 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { | 1558 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { |
1508 | .handler = ip4ip6_rcv, | 1559 | .handler = ip4ip6_rcv, |
1509 | .err_handler = ip4ip6_err, | 1560 | .err_handler = ip4ip6_err, |
@@ -1612,9 +1663,14 @@ static int __init ip6_tunnel_init(void) | |||
1612 | pr_err("%s: can't register ip6ip6\n", __func__); | 1663 | pr_err("%s: can't register ip6ip6\n", __func__); |
1613 | goto out_ip6ip6; | 1664 | goto out_ip6ip6; |
1614 | } | 1665 | } |
1666 | err = rtnl_link_register(&ip6_link_ops); | ||
1667 | if (err < 0) | ||
1668 | goto rtnl_link_failed; | ||
1615 | 1669 | ||
1616 | return 0; | 1670 | return 0; |
1617 | 1671 | ||
1672 | rtnl_link_failed: | ||
1673 | xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); | ||
1618 | out_ip6ip6: | 1674 | out_ip6ip6: |
1619 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); | 1675 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); |
1620 | out_ip4ip6: | 1676 | out_ip4ip6: |
@@ -1629,6 +1685,7 @@ out_pernet: | |||
1629 | 1685 | ||
1630 | static void __exit ip6_tunnel_cleanup(void) | 1686 | static void __exit ip6_tunnel_cleanup(void) |
1631 | { | 1687 | { |
1688 | rtnl_link_unregister(&ip6_link_ops); | ||
1632 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) | 1689 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) |
1633 | pr_info("%s: can't deregister ip4ip6\n", __func__); | 1690 | pr_info("%s: can't deregister ip4ip6\n", __func__); |
1634 | 1691 | ||