aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/sit.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r--net/ipv6/sit.c57
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 @@
68static int ipip6_tunnel_init(struct net_device *dev); 68static int ipip6_tunnel_init(struct net_device *dev);
69static void ipip6_tunnel_setup(struct net_device *dev); 69static void ipip6_tunnel_setup(struct net_device *dev);
70static void ipip6_dev_free(struct net_device *dev); 70static void ipip6_dev_free(struct net_device *dev);
71static struct rtnl_link_ops sit_link_ops __read_mostly;
71 72
72static int sit_net_id __read_mostly; 73static int sit_net_id __read_mostly;
73struct sit_net { 74struct 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
1221static 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
1237static 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
1250nla_put_failure:
1251 return -EMSGSIZE;
1252}
1253
1254static 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
1219static struct xfrm_tunnel sit_handler __read_mostly = { 1262static 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
1303static void __exit sit_cleanup(void) 1346static 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
1373out:
1325 return err; 1374 return err;
1375
1376rtnl_link_failed:
1377 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1378xfrm_tunnel_failed:
1379 unregister_pernet_device(&sit_net_ops);
1380 goto out;
1326} 1381}
1327 1382
1328module_init(sit_init); 1383module_init(sit_init);