1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * IPv6 Address Label subsystem 4 * for the IPv6 "Default" Source Address Selection 5 * 6 * Copyright (C)2007 USAGI/WIDE Project 7 */ 8 /* 9 * Author: 10 * YOSHIFUJI Hideaki @ USAGI/WIDE Project <yoshfuji@linux-ipv6.org> 11 */ 12 13 #include <linux/kernel.h> 14 #include <linux/list.h> 15 #include <linux/rcupdate.h> 16 #include <linux/in6.h> 17 #include <linux/slab.h> 18 #include <net/addrconf.h> 19 #include <linux/if_addrlabel.h> 20 #include <linux/netlink.h> 21 #include <linux/rtnetlink.h> 22 23 #if 0 24 #define ADDRLABEL(x...) printk(x) 25 #else 26 #define ADDRLABEL(x...) do { ; } while (0) 27 #endif 28 29 /* 30 * Policy Table 31 */ 32 struct ip6addrlbl_entry { 33 struct in6_addr prefix; 34 int prefixlen; 35 int ifindex; 36 int addrtype; 37 u32 label; 38 struct hlist_node list; 39 struct rcu_head rcu; 40 }; 41 42 /* 43 * Default policy table (RFC6724 + extensions) 44 * 45 * prefix addr_type label 46 * ------------------------------------------------------------------------- 47 * ::1/128 LOOPBACK 0 48 * ::/0 N/A 1 49 * 2002::/16 N/A 2 50 * ::/96 COMPATv4 3 51 * ::ffff:0:0/96 V4MAPPED 4 52 * fc00::/7 N/A 5 ULA (RFC 4193) 53 * 2001::/32 N/A 6 Teredo (RFC 4380) 54 * 2001:10::/28 N/A 7 ORCHID (RFC 4843) 55 * fec0::/10 N/A 11 Site-local 56 * (deprecated by RFC3879) 57 * 3ffe::/16 N/A 12 6bone 58 * 59 * Note: 0xffffffff is used if we do not have any policies. 60 * Note: Labels for ULA and 6to4 are different from labels listed in RFC6724. 61 */ 62 63 #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 64 65 static const __net_initconst struct ip6addrlbl_init_table 66 { 67 const struct in6_addr *prefix; 68 int prefixlen; 69 u32 label; 70 } ip6addrlbl_init_table[] = { 71 { /* ::/0 */ 72 .prefix = &in6addr_any, 73 .label = 1, 74 }, { /* fc00::/7 */ 75 .prefix = &(struct in6_addr){ { { 0xfc } } } , 76 .prefixlen = 7, 77 .label = 5, 78 }, { /* fec0::/10 */ 79 .prefix = &(struct in6_addr){ { { 0xfe, 0xc0 } } }, 80 .prefixlen = 10, 81 .label = 11, 82 }, { /* 2002::/16 */ 83 .prefix = &(struct in6_addr){ { { 0x20, 0x02 } } }, 84 .prefixlen = 16, 85 .label = 2, 86 }, { /* 3ffe::/16 */ 87 .prefix = &(struct in6_addr){ { { 0x3f, 0xfe } } }, 88 .prefixlen = 16, 89 .label = 12, 90 }, { /* 2001::/32 */ 91 .prefix = &(struct in6_addr){ { { 0x20, 0x01 } } }, 92 .prefixlen = 32, 93 .label = 6, 94 }, { /* 2001:10::/28 */ 95 .prefix = &(struct in6_addr){ { { 0x20, 0x01, 0x00, 0x10 } } }, 96 .prefixlen = 28, 97 .label = 7, 98 }, { /* ::ffff:0:0 */ 99 .prefix = &(struct in6_addr){ { { [10] = 0xff, [11] = 0xff } } }, 100 .prefixlen = 96, 101 .label = 4, 102 }, { /* ::/96 */ 103 .prefix = &in6addr_any, 104 .prefixlen = 96, 105 .label = 3, 106 }, { /* ::1/128 */ 107 .prefix = &in6addr_loopback, 108 .prefixlen = 128, 109 .label = 0, 110 } 111 }; 112 113 /* Find label */ 114 static bool __ip6addrlbl_match(const struct ip6addrlbl_entry *p, 115 const struct in6_addr *addr, 116 int addrtype, int ifindex) 117 { 118 if (p->ifindex && p->ifindex != ifindex) 119 return false; 120 if (p->addrtype && p->addrtype != addrtype) 121 return false; 122 if (!ipv6_prefix_equal(addr, &p->prefix, p->prefixlen)) 123 return false; 124 return true; 125 } 126 127 static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net, 128 const struct in6_addr *addr, 129 int type, int ifindex) 130 { 131 struct ip6addrlbl_entry *p; 132 133 hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) { 134 if (__ip6addrlbl_match(p, addr, type, ifindex)) 135 return p; 136 } 137 return NULL; 138 } 139 140 u32 ipv6_addr_label(struct net *net, 141 const struct in6_addr *addr, int type, int ifindex) 142 { 143 u32 label; 144 struct ip6addrlbl_entry *p; 145 146 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 147 148 rcu_read_lock(); 149 p = __ipv6_addr_label(net, addr, type, ifindex); 150 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 151 rcu_read_unlock(); 152 153 ADDRLABEL(KERN_DEBUG "%s(addr=%pI6, type=%d, ifindex=%d) => %08x\n", 154 __func__, addr, type, ifindex, label); 155 156 return label; 157 } 158 159 /* allocate one entry */ 160 static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 161 int prefixlen, int ifindex, 162 u32 label) 163 { 164 struct ip6addrlbl_entry *newp; 165 int addrtype; 166 167 ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u)\n", 168 __func__, prefix, prefixlen, ifindex, (unsigned int)label); 169 170 addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK); 171 172 switch (addrtype) { 173 case IPV6_ADDR_MAPPED: 174 if (prefixlen > 96) 175 return ERR_PTR(-EINVAL); 176 if (prefixlen < 96) 177 addrtype = 0; 178 break; 179 case IPV6_ADDR_COMPATv4: 180 if (prefixlen != 96) 181 addrtype = 0; 182 break; 183 case IPV6_ADDR_LOOPBACK: 184 if (prefixlen != 128) 185 addrtype = 0; 186 break; 187 } 188 189 newp = kmalloc(sizeof(*newp), GFP_KERNEL); 190 if (!newp) 191 return ERR_PTR(-ENOMEM); 192 193 ipv6_addr_prefix(&newp->prefix, prefix, prefixlen); 194 newp->prefixlen = prefixlen; 195 newp->ifindex = ifindex; 196 newp->addrtype = addrtype; 197 newp->label = label; 198 INIT_HLIST_NODE(&newp->list); 199 return newp; 200 } 201 202 /* add a label */ 203 static int __ip6addrlbl_add(struct net *net, struct ip6addrlbl_entry *newp, 204 int replace) 205 { 206 struct ip6addrlbl_entry *last = NULL, *p = NULL; 207 struct hlist_node *n; 208 int ret = 0; 209 210 ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n", __func__, newp, 211 replace); 212 213 hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) { 214 if (p->prefixlen == newp->prefixlen && 215 p->ifindex == newp->ifindex && 216 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 217 if (!replace) { 218 ret = -EEXIST; 219 goto out; 220 } 221 hlist_replace_rcu(&p->list, &newp->list); 222 kfree_rcu(p, rcu); 223 goto out; 224 } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) || 225 (p->prefixlen < newp->prefixlen)) { 226 hlist_add_before_rcu(&newp->list, &p->list); 227 goto out; 228 } 229 last = p; 230 } 231 if (last) 232 hlist_add_behind_rcu(&newp->list, &last->list); 233 else 234 hlist_add_head_rcu(&newp->list, &net->ipv6.ip6addrlbl_table.head); 235 out: 236 if (!ret) 237 net->ipv6.ip6addrlbl_table.seq++; 238 return ret; 239 } 240 241 /* add a label */ 242 static int ip6addrlbl_add(struct net *net, 243 const struct in6_addr *prefix, int prefixlen, 244 int ifindex, u32 label, int replace) 245 { 246 struct ip6addrlbl_entry *newp; 247 int ret = 0; 248 249 ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n", 250 __func__, prefix, prefixlen, ifindex, (unsigned int)label, 251 replace); 252 253 newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 254 if (IS_ERR(newp)) 255 return PTR_ERR(newp); 256 spin_lock(&net->ipv6.ip6addrlbl_table.lock); 257 ret = __ip6addrlbl_add(net, newp, replace); 258 spin_unlock(&net->ipv6.ip6addrlbl_table.lock); 259 if (ret) 260 kfree(newp); 261 return ret; 262 } 263 264 /* remove a label */ 265 static int __ip6addrlbl_del(struct net *net, 266 const struct in6_addr *prefix, int prefixlen, 267 int ifindex) 268 { 269 struct ip6addrlbl_entry *p = NULL; 270 struct hlist_node *n; 271 int ret = -ESRCH; 272 273 ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n", 274 __func__, prefix, prefixlen, ifindex); 275 276 hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) { 277 if (p->prefixlen == prefixlen && 278 p->ifindex == ifindex && 279 ipv6_addr_equal(&p->prefix, prefix)) { 280 hlist_del_rcu(&p->list); 281 kfree_rcu(p, rcu); 282 ret = 0; 283 break; 284 } 285 } 286 return ret; 287 } 288 289 static int ip6addrlbl_del(struct net *net, 290 const struct in6_addr *prefix, int prefixlen, 291 int ifindex) 292 { 293 struct in6_addr prefix_buf; 294 int ret; 295 296 ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n", 297 __func__, prefix, prefixlen, ifindex); 298 299 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 300 spin_lock(&net->ipv6.ip6addrlbl_table.lock); 301 ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex); 302 spin_unlock(&net->ipv6.ip6addrlbl_table.lock); 303 return ret; 304 } 305 306 /* add default label */ 307 static int __net_init ip6addrlbl_net_init(struct net *net) 308 { 309 struct ip6addrlbl_entry *p = NULL; 310 struct hlist_node *n; 311 int err; 312 int i; 313 314 ADDRLABEL(KERN_DEBUG "%s\n", __func__); 315 316 spin_lock_init(&net->ipv6.ip6addrlbl_table.lock); 317 INIT_HLIST_HEAD(&net->ipv6.ip6addrlbl_table.head); 318 319 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 320 err = ip6addrlbl_add(net, 321 ip6addrlbl_init_table[i].prefix, 322 ip6addrlbl_init_table[i].prefixlen, 323 0, 324 ip6addrlbl_init_table[i].label, 0); 325 if (err) 326 goto err_ip6addrlbl_add; 327 } 328 return 0; 329 330 err_ip6addrlbl_add: 331 hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) { 332 hlist_del_rcu(&p->list); 333 kfree_rcu(p, rcu); 334 } 335 return err; 336 } 337 338 static void __net_exit ip6addrlbl_net_exit(struct net *net) 339 { 340 struct ip6addrlbl_entry *p = NULL; 341 struct hlist_node *n; 342 343 /* Remove all labels belonging to the exiting net */ 344 spin_lock(&net->ipv6.ip6addrlbl_table.lock); 345 hlist_for_each_entry_safe(p, n, &net->ipv6.ip6addrlbl_table.head, list) { 346 hlist_del_rcu(&p->list); 347 kfree_rcu(p, rcu); 348 } 349 spin_unlock(&net->ipv6.ip6addrlbl_table.lock); 350 } 351 352 static struct pernet_operations ipv6_addr_label_ops = { 353 .init = ip6addrlbl_net_init, 354 .exit = ip6addrlbl_net_exit, 355 }; 356 357 int __init ipv6_addr_label_init(void) 358 { 359 return register_pernet_subsys(&ipv6_addr_label_ops); 360 } 361 362 void ipv6_addr_label_cleanup(void) 363 { 364 unregister_pernet_subsys(&ipv6_addr_label_ops); 365 } 366 367 static const struct nla_policy ifal_policy[IFAL_MAX+1] = { 368 [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, 369 [IFAL_LABEL] = { .len = sizeof(u32), }, 370 }; 371 372 static bool addrlbl_ifindex_exists(struct net *net, int ifindex) 373 { 374 375 struct net_device *dev; 376 377 rcu_read_lock(); 378 dev = dev_get_by_index_rcu(net, ifindex); 379 rcu_read_unlock(); 380 381 return dev != NULL; 382 } 383 384 static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, 385 struct netlink_ext_ack *extack) 386 { 387 struct net *net = sock_net(skb->sk); 388 struct ifaddrlblmsg *ifal; 389 struct nlattr *tb[IFAL_MAX+1]; 390 struct in6_addr *pfx; 391 u32 label; 392 int err = 0; 393 394 err = nlmsg_parse_deprecated(nlh, sizeof(*ifal), tb, IFAL_MAX, 395 ifal_policy, extack); 396 if (err < 0) 397 return err; 398 399 ifal = nlmsg_data(nlh); 400 401 if (ifal->ifal_family != AF_INET6 || 402 ifal->ifal_prefixlen > 128) 403 return -EINVAL; 404 405 if (!tb[IFAL_ADDRESS]) 406 return -EINVAL; 407 pfx = nla_data(tb[IFAL_ADDRESS]); 408 409 if (!tb[IFAL_LABEL]) 410 return -EINVAL; 411 label = nla_get_u32(tb[IFAL_LABEL]); 412 if (label == IPV6_ADDR_LABEL_DEFAULT) 413 return -EINVAL; 414 415 switch (nlh->nlmsg_type) { 416 case RTM_NEWADDRLABEL: 417 if (ifal->ifal_index && 418 !addrlbl_ifindex_exists(net, ifal->ifal_index)) 419 return -EINVAL; 420 421 err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen, 422 ifal->ifal_index, label, 423 nlh->nlmsg_flags & NLM_F_REPLACE); 424 break; 425 case RTM_DELADDRLABEL: 426 err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen, 427 ifal->ifal_index); 428 break; 429 default: 430 err = -EOPNOTSUPP; 431 } 432 return err; 433 } 434 435 static void ip6addrlbl_putmsg(struct nlmsghdr *nlh, 436 int prefixlen, int ifindex, u32 lseq) 437 { 438 struct ifaddrlblmsg *ifal = nlmsg_data(nlh); 439 ifal->ifal_family = AF_INET6; 440 ifal->__ifal_reserved = 0; 441 ifal->ifal_prefixlen = prefixlen; 442 ifal->ifal_flags = 0; 443 ifal->ifal_index = ifindex; 444 ifal->ifal_seq = lseq; 445 }; 446 447 static int ip6addrlbl_fill(struct sk_buff *skb, 448 struct ip6addrlbl_entry *p, 449 u32 lseq, 450 u32 portid, u32 seq, int event, 451 unsigned int flags) 452 { 453 struct nlmsghdr *nlh = nlmsg_put(skb, portid, seq, event, 454 sizeof(struct ifaddrlblmsg), flags); 455 if (!nlh) 456 return -EMSGSIZE; 457 458 ip6addrlbl_putmsg(nlh, p->prefixlen, p->ifindex, lseq); 459 460 if (nla_put_in6_addr(skb, IFAL_ADDRESS, &p->prefix) < 0 || 461 nla_put_u32(skb, IFAL_LABEL, p->label) < 0) { 462 nlmsg_cancel(skb, nlh); 463 return -EMSGSIZE; 464 } 465 466 nlmsg_end(skb, nlh); 467 return 0; 468 } 469 470 static int ip6addrlbl_valid_dump_req(const struct nlmsghdr *nlh, 471 struct netlink_ext_ack *extack) 472 { 473 struct ifaddrlblmsg *ifal; 474 475 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifal))) { 476 NL_SET_ERR_MSG_MOD(extack, "Invalid header for address label dump request"); 477 return -EINVAL; 478 } 479 480 ifal = nlmsg_data(nlh); 481 if (ifal->__ifal_reserved || ifal->ifal_prefixlen || 482 ifal->ifal_flags || ifal->ifal_index || ifal->ifal_seq) { 483 NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address label dump request"); 484 return -EINVAL; 485 } 486 487 if (nlmsg_attrlen(nlh, sizeof(*ifal))) { 488 NL_SET_ERR_MSG_MOD(extack, "Invalid data after header for address label dump request"); 489 return -EINVAL; 490 } 491 492 return 0; 493 } 494 495 static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) 496 { 497 const struct nlmsghdr *nlh = cb->nlh; 498 struct net *net = sock_net(skb->sk); 499 struct ip6addrlbl_entry *p; 500 int idx = 0, s_idx = cb->args[0]; 501 int err; 502 503 if (cb->strict_check) { 504 err = ip6addrlbl_valid_dump_req(nlh, cb->extack); 505 if (err < 0) 506 return err; 507 } 508 509 rcu_read_lock(); 510 hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) { 511 if (idx >= s_idx) { 512 err = ip6addrlbl_fill(skb, p, 513 net->ipv6.ip6addrlbl_table.seq, 514 NETLINK_CB(cb->skb).portid, 515 nlh->nlmsg_seq, 516 RTM_NEWADDRLABEL, 517 NLM_F_MULTI); 518 if (err < 0) 519 break; 520 } 521 idx++; 522 } 523 rcu_read_unlock(); 524 cb->args[0] = idx; 525 return skb->len; 526 } 527 528 static inline int ip6addrlbl_msgsize(void) 529 { 530 return NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) 531 + nla_total_size(16) /* IFAL_ADDRESS */ 532 + nla_total_size(4); /* IFAL_LABEL */ 533 } 534 535 static int ip6addrlbl_valid_get_req(struct sk_buff *skb, 536 const struct nlmsghdr *nlh, 537 struct nlattr **tb, 538 struct netlink_ext_ack *extack) 539 { 540 struct ifaddrlblmsg *ifal; 541 int i, err; 542 543 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifal))) { 544 NL_SET_ERR_MSG_MOD(extack, "Invalid header for addrlabel get request"); 545 return -EINVAL; 546 } 547 548 if (!netlink_strict_get_check(skb)) 549 return nlmsg_parse_deprecated(nlh, sizeof(*ifal), tb, 550 IFAL_MAX, ifal_policy, extack); 551 552 ifal = nlmsg_data(nlh); 553 if (ifal->__ifal_reserved || ifal->ifal_flags || ifal->ifal_seq) { 554 NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for addrlabel get request"); 555 return -EINVAL; 556 } 557 558 err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifal), tb, IFAL_MAX, 559 ifal_policy, extack); 560 if (err) 561 return err; 562 563 for (i = 0; i <= IFAL_MAX; i++) { 564 if (!tb[i]) 565 continue; 566 567 switch (i) { 568 case IFAL_ADDRESS: 569 break; 570 default: 571 NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in addrlabel get request"); 572 return -EINVAL; 573 } 574 } 575 576 return 0; 577 } 578 579 static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh, 580 struct netlink_ext_ack *extack) 581 { 582 struct net *net = sock_net(in_skb->sk); 583 struct ifaddrlblmsg *ifal; 584 struct nlattr *tb[IFAL_MAX+1]; 585 struct in6_addr *addr; 586 u32 lseq; 587 int err = 0; 588 struct ip6addrlbl_entry *p; 589 struct sk_buff *skb; 590 591 err = ip6addrlbl_valid_get_req(in_skb, nlh, tb, extack); 592 if (err < 0) 593 return err; 594 595 ifal = nlmsg_data(nlh); 596 597 if (ifal->ifal_family != AF_INET6 || 598 ifal->ifal_prefixlen != 128) 599 return -EINVAL; 600 601 if (ifal->ifal_index && 602 !addrlbl_ifindex_exists(net, ifal->ifal_index)) 603 return -EINVAL; 604 605 if (!tb[IFAL_ADDRESS]) 606 return -EINVAL; 607 addr = nla_data(tb[IFAL_ADDRESS]); 608 609 skb = nlmsg_new(ip6addrlbl_msgsize(), GFP_KERNEL); 610 if (!skb) 611 return -ENOBUFS; 612 613 err = -ESRCH; 614 615 rcu_read_lock(); 616 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index); 617 lseq = net->ipv6.ip6addrlbl_table.seq; 618 if (p) 619 err = ip6addrlbl_fill(skb, p, lseq, 620 NETLINK_CB(in_skb).portid, 621 nlh->nlmsg_seq, 622 RTM_NEWADDRLABEL, 0); 623 rcu_read_unlock(); 624 625 if (err < 0) { 626 WARN_ON(err == -EMSGSIZE); 627 kfree_skb(skb); 628 } else { 629 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); 630 } 631 return err; 632 } 633 634 int __init ipv6_addr_label_rtnl_register(void) 635 { 636 int ret; 637 638 ret = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_NEWADDRLABEL, 639 ip6addrlbl_newdel, 640 NULL, RTNL_FLAG_DOIT_UNLOCKED); 641 if (ret < 0) 642 return ret; 643 ret = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_DELADDRLABEL, 644 ip6addrlbl_newdel, 645 NULL, RTNL_FLAG_DOIT_UNLOCKED); 646 if (ret < 0) 647 return ret; 648 ret = rtnl_register_module(THIS_MODULE, PF_INET6, RTM_GETADDRLABEL, 649 ip6addrlbl_get, 650 ip6addrlbl_dump, RTNL_FLAG_DOIT_UNLOCKED); 651 return ret; 652 } 653