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

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>

authored by

Nicolas Dichtel and committed by
David S. Miller
ba3e3f50 0974658d

+56 -1
+56 -1
net/ipv6/sit.c
··· 68 68 static int ipip6_tunnel_init(struct net_device *dev); 69 69 static void ipip6_tunnel_setup(struct net_device *dev); 70 70 static void ipip6_dev_free(struct net_device *dev); 71 + static struct rtnl_link_ops sit_link_ops __read_mostly; 71 72 72 73 static int sit_net_id __read_mostly; 73 74 struct sit_net { ··· 283 282 goto failed_free; 284 283 285 284 strcpy(nt->parms.name, dev->name); 285 + dev->rtnl_link_ops = &sit_link_ops; 286 286 287 287 dev_hold(dev); 288 288 ··· 1218 1216 return 0; 1219 1217 } 1220 1218 1219 + static size_t sit_get_size(const struct net_device *dev) 1220 + { 1221 + return 1222 + /* IFLA_IPTUN_LINK */ 1223 + nla_total_size(4) + 1224 + /* IFLA_IPTUN_LOCAL */ 1225 + nla_total_size(4) + 1226 + /* IFLA_IPTUN_REMOTE */ 1227 + nla_total_size(4) + 1228 + /* IFLA_IPTUN_TTL */ 1229 + nla_total_size(1) + 1230 + /* IFLA_IPTUN_TOS */ 1231 + nla_total_size(1) + 1232 + 0; 1233 + } 1234 + 1235 + static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev) 1236 + { 1237 + struct ip_tunnel *tunnel = netdev_priv(dev); 1238 + struct ip_tunnel_parm *parm = &tunnel->parms; 1239 + 1240 + if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || 1241 + nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || 1242 + nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || 1243 + nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || 1244 + nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) 1245 + goto nla_put_failure; 1246 + return 0; 1247 + 1248 + nla_put_failure: 1249 + return -EMSGSIZE; 1250 + } 1251 + 1252 + static struct rtnl_link_ops sit_link_ops __read_mostly = { 1253 + .kind = "sit", 1254 + .maxtype = IFLA_IPTUN_MAX, 1255 + .priv_size = sizeof(struct ip_tunnel), 1256 + .get_size = sit_get_size, 1257 + .fill_info = sit_fill_info, 1258 + }; 1259 + 1221 1260 static struct xfrm_tunnel sit_handler __read_mostly = { 1222 1261 .handler = ipip6_rcv, 1223 1262 .err_handler = ipip6_err, ··· 1345 1302 1346 1303 static void __exit sit_cleanup(void) 1347 1304 { 1305 + rtnl_link_unregister(&sit_link_ops); 1348 1306 xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1349 1307 1350 1308 unregister_pernet_device(&sit_net_ops); ··· 1363 1319 return err; 1364 1320 err = xfrm4_tunnel_register(&sit_handler, AF_INET6); 1365 1321 if (err < 0) { 1366 - unregister_pernet_device(&sit_net_ops); 1367 1322 pr_info("%s: can't add protocol\n", __func__); 1323 + goto xfrm_tunnel_failed; 1368 1324 } 1325 + err = rtnl_link_register(&sit_link_ops); 1326 + if (err < 0) 1327 + goto rtnl_link_failed; 1328 + 1329 + out: 1369 1330 return err; 1331 + 1332 + rtnl_link_failed: 1333 + xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1334 + xfrm_tunnel_failed: 1335 + unregister_pernet_device(&sit_net_ops); 1336 + goto out; 1370 1337 } 1371 1338 1372 1339 module_init(sit_init);