diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2012-11-09 01:10:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-09 19:36:20 -0500 |
commit | ba3e3f50a0e5de76fc0684d856394931f2bc39fa (patch) | |
tree | fd55e376775b87c74b2ad2b085828fe78302df7c /net/ipv6/sit.c | |
parent | 0974658da47cb399b76794057823bf3cd22acf37 (diff) |
sit: 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>
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3ed54ffd8d50..b543c56cad28 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -68,6 +68,7 @@ | |||
68 | static int ipip6_tunnel_init(struct net_device *dev); | 68 | static int ipip6_tunnel_init(struct net_device *dev); |
69 | static void ipip6_tunnel_setup(struct net_device *dev); | 69 | static void ipip6_tunnel_setup(struct net_device *dev); |
70 | static void ipip6_dev_free(struct net_device *dev); | 70 | static void ipip6_dev_free(struct net_device *dev); |
71 | static struct rtnl_link_ops sit_link_ops __read_mostly; | ||
71 | 72 | ||
72 | static int sit_net_id __read_mostly; | 73 | static int sit_net_id __read_mostly; |
73 | struct sit_net { | 74 | struct sit_net { |
@@ -282,6 +283,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, | |||
282 | goto failed_free; | 283 | goto failed_free; |
283 | 284 | ||
284 | strcpy(nt->parms.name, dev->name); | 285 | strcpy(nt->parms.name, dev->name); |
286 | dev->rtnl_link_ops = &sit_link_ops; | ||
285 | 287 | ||
286 | dev_hold(dev); | 288 | dev_hold(dev); |
287 | 289 | ||
@@ -1216,6 +1218,47 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1216 | return 0; | 1218 | return 0; |
1217 | } | 1219 | } |
1218 | 1220 | ||
1221 | static size_t sit_get_size(const struct net_device *dev) | ||
1222 | { | ||
1223 | return | ||
1224 | /* IFLA_IPTUN_LINK */ | ||
1225 | nla_total_size(4) + | ||
1226 | /* IFLA_IPTUN_LOCAL */ | ||
1227 | nla_total_size(4) + | ||
1228 | /* IFLA_IPTUN_REMOTE */ | ||
1229 | nla_total_size(4) + | ||
1230 | /* IFLA_IPTUN_TTL */ | ||
1231 | nla_total_size(1) + | ||
1232 | /* IFLA_IPTUN_TOS */ | ||
1233 | nla_total_size(1) + | ||
1234 | 0; | ||
1235 | } | ||
1236 | |||
1237 | static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1238 | { | ||
1239 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
1240 | struct ip_tunnel_parm *parm = &tunnel->parms; | ||
1241 | |||
1242 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1243 | nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || | ||
1244 | nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || | ||
1245 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || | ||
1246 | nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) | ||
1247 | goto nla_put_failure; | ||
1248 | return 0; | ||
1249 | |||
1250 | nla_put_failure: | ||
1251 | return -EMSGSIZE; | ||
1252 | } | ||
1253 | |||
1254 | static struct rtnl_link_ops sit_link_ops __read_mostly = { | ||
1255 | .kind = "sit", | ||
1256 | .maxtype = IFLA_IPTUN_MAX, | ||
1257 | .priv_size = sizeof(struct ip_tunnel), | ||
1258 | .get_size = sit_get_size, | ||
1259 | .fill_info = sit_fill_info, | ||
1260 | }; | ||
1261 | |||
1219 | static struct xfrm_tunnel sit_handler __read_mostly = { | 1262 | static struct xfrm_tunnel sit_handler __read_mostly = { |
1220 | .handler = ipip6_rcv, | 1263 | .handler = ipip6_rcv, |
1221 | .err_handler = ipip6_err, | 1264 | .err_handler = ipip6_err, |
@@ -1302,6 +1345,7 @@ static struct pernet_operations sit_net_ops = { | |||
1302 | 1345 | ||
1303 | static void __exit sit_cleanup(void) | 1346 | static void __exit sit_cleanup(void) |
1304 | { | 1347 | { |
1348 | rtnl_link_unregister(&sit_link_ops); | ||
1305 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1349 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
1306 | 1350 | ||
1307 | unregister_pernet_device(&sit_net_ops); | 1351 | unregister_pernet_device(&sit_net_ops); |
@@ -1319,10 +1363,21 @@ static int __init sit_init(void) | |||
1319 | return err; | 1363 | return err; |
1320 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); | 1364 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); |
1321 | if (err < 0) { | 1365 | if (err < 0) { |
1322 | unregister_pernet_device(&sit_net_ops); | ||
1323 | pr_info("%s: can't add protocol\n", __func__); | 1366 | pr_info("%s: can't add protocol\n", __func__); |
1367 | goto xfrm_tunnel_failed; | ||
1324 | } | 1368 | } |
1369 | err = rtnl_link_register(&sit_link_ops); | ||
1370 | if (err < 0) | ||
1371 | goto rtnl_link_failed; | ||
1372 | |||
1373 | out: | ||
1325 | return err; | 1374 | return err; |
1375 | |||
1376 | rtnl_link_failed: | ||
1377 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | ||
1378 | xfrm_tunnel_failed: | ||
1379 | unregister_pernet_device(&sit_net_ops); | ||
1380 | goto out; | ||
1326 | } | 1381 | } |
1327 | 1382 | ||
1328 | module_init(sit_init); | 1383 | module_init(sit_init); |