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.
Unified · Split
| @@ -68,6 +68,7 @@ · 67 unmodified lines | |||
| 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, · 208 unmodified lines | |||
| 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) · 928 unmodified lines | |||
| 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 = { · 80 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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); |