1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * SR-IPv6 implementation 4 * 5 * Authors: 6 * David Lebrun <david.lebrun@uclouvain.be> 7 * eBPF support: Mathieu Xhonneux <m.xhonneux@gmail.com> 8 */ 9 10 #include <linux/types.h> 11 #include <linux/skbuff.h> 12 #include <linux/net.h> 13 #include <linux/module.h> 14 #include <net/ip.h> 15 #include <net/lwtunnel.h> 16 #include <net/netevent.h> 17 #include <net/netns/generic.h> 18 #include <net/ip6_fib.h> 19 #include <net/route.h> 20 #include <net/seg6.h> 21 #include <linux/seg6.h> 22 #include <linux/seg6_local.h> 23 #include <net/addrconf.h> 24 #include <net/ip6_route.h> 25 #include <net/dst_cache.h> 26 #ifdef CONFIG_IPV6_SEG6_HMAC 27 #include <net/seg6_hmac.h> 28 #endif 29 #include <net/seg6_local.h> 30 #include <linux/etherdevice.h> 31 #include <linux/bpf.h> 32 33 struct seg6_local_lwt; 34 35 struct seg6_action_desc { 36 int action; 37 unsigned long attrs; 38 int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt); 39 int static_headroom; 40 }; 41 42 struct bpf_lwt_prog { 43 struct bpf_prog *prog; 44 char *name; 45 }; 46 47 struct seg6_local_lwt { 48 int action; 49 struct ipv6_sr_hdr *srh; 50 int table; 51 struct in_addr nh4; 52 struct in6_addr nh6; 53 int iif; 54 int oif; 55 struct bpf_lwt_prog bpf; 56 57 int headroom; 58 struct seg6_action_desc *desc; 59 }; 60 61 static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt) 62 { 63 return (struct seg6_local_lwt *)lwt->data; 64 } 65 66 static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb) 67 { 68 struct ipv6_sr_hdr *srh; 69 int len, srhoff = 0; 70 71 if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) 72 return NULL; 73 74 if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) 75 return NULL; 76 77 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); 78 79 len = (srh->hdrlen + 1) << 3; 80 81 if (!pskb_may_pull(skb, srhoff + len)) 82 return NULL; 83 84 /* note that pskb_may_pull may change pointers in header; 85 * for this reason it is necessary to reload them when needed. 86 */ 87 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); 88 89 if (!seg6_validate_srh(srh, len)) 90 return NULL; 91 92 return srh; 93 } 94 95 static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb) 96 { 97 struct ipv6_sr_hdr *srh; 98 99 srh = get_srh(skb); 100 if (!srh) 101 return NULL; 102 103 if (srh->segments_left == 0) 104 return NULL; 105 106 #ifdef CONFIG_IPV6_SEG6_HMAC 107 if (!seg6_hmac_validate_skb(skb)) 108 return NULL; 109 #endif 110 111 return srh; 112 } 113 114 static bool decap_and_validate(struct sk_buff *skb, int proto) 115 { 116 struct ipv6_sr_hdr *srh; 117 unsigned int off = 0; 118 119 srh = get_srh(skb); 120 if (srh && srh->segments_left > 0) 121 return false; 122 123 #ifdef CONFIG_IPV6_SEG6_HMAC 124 if (srh && !seg6_hmac_validate_skb(skb)) 125 return false; 126 #endif 127 128 if (ipv6_find_hdr(skb, &off, proto, NULL, NULL) < 0) 129 return false; 130 131 if (!pskb_pull(skb, off)) 132 return false; 133 134 skb_postpull_rcsum(skb, skb_network_header(skb), off); 135 136 skb_reset_network_header(skb); 137 skb_reset_transport_header(skb); 138 skb->encapsulation = 0; 139 140 return true; 141 } 142 143 static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr) 144 { 145 struct in6_addr *addr; 146 147 srh->segments_left--; 148 addr = srh->segments + srh->segments_left; 149 *daddr = *addr; 150 } 151 152 int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, 153 u32 tbl_id) 154 { 155 struct net *net = dev_net(skb->dev); 156 struct ipv6hdr *hdr = ipv6_hdr(skb); 157 int flags = RT6_LOOKUP_F_HAS_SADDR; 158 struct dst_entry *dst = NULL; 159 struct rt6_info *rt; 160 struct flowi6 fl6; 161 162 fl6.flowi6_iif = skb->dev->ifindex; 163 fl6.daddr = nhaddr ? *nhaddr : hdr->daddr; 164 fl6.saddr = hdr->saddr; 165 fl6.flowlabel = ip6_flowinfo(hdr); 166 fl6.flowi6_mark = skb->mark; 167 fl6.flowi6_proto = hdr->nexthdr; 168 169 if (nhaddr) 170 fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH; 171 172 if (!tbl_id) { 173 dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags); 174 } else { 175 struct fib6_table *table; 176 177 table = fib6_get_table(net, tbl_id); 178 if (!table) 179 goto out; 180 181 rt = ip6_pol_route(net, table, 0, &fl6, skb, flags); 182 dst = &rt->dst; 183 } 184 185 if (dst && dst->dev->flags & IFF_LOOPBACK && !dst->error) { 186 dst_release(dst); 187 dst = NULL; 188 } 189 190 out: 191 if (!dst) { 192 rt = net->ipv6.ip6_blk_hole_entry; 193 dst = &rt->dst; 194 dst_hold(dst); 195 } 196 197 skb_dst_drop(skb); 198 skb_dst_set(skb, dst); 199 return dst->error; 200 } 201 202 /* regular endpoint function */ 203 static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt) 204 { 205 struct ipv6_sr_hdr *srh; 206 207 srh = get_and_validate_srh(skb); 208 if (!srh) 209 goto drop; 210 211 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 212 213 seg6_lookup_nexthop(skb, NULL, 0); 214 215 return dst_input(skb); 216 217 drop: 218 kfree_skb(skb); 219 return -EINVAL; 220 } 221 222 /* regular endpoint, and forward to specified nexthop */ 223 static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt) 224 { 225 struct ipv6_sr_hdr *srh; 226 227 srh = get_and_validate_srh(skb); 228 if (!srh) 229 goto drop; 230 231 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 232 233 seg6_lookup_nexthop(skb, &slwt->nh6, 0); 234 235 return dst_input(skb); 236 237 drop: 238 kfree_skb(skb); 239 return -EINVAL; 240 } 241 242 static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt) 243 { 244 struct ipv6_sr_hdr *srh; 245 246 srh = get_and_validate_srh(skb); 247 if (!srh) 248 goto drop; 249 250 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 251 252 seg6_lookup_nexthop(skb, NULL, slwt->table); 253 254 return dst_input(skb); 255 256 drop: 257 kfree_skb(skb); 258 return -EINVAL; 259 } 260 261 /* decapsulate and forward inner L2 frame on specified interface */ 262 static int input_action_end_dx2(struct sk_buff *skb, 263 struct seg6_local_lwt *slwt) 264 { 265 struct net *net = dev_net(skb->dev); 266 struct net_device *odev; 267 struct ethhdr *eth; 268 269 if (!decap_and_validate(skb, NEXTHDR_NONE)) 270 goto drop; 271 272 if (!pskb_may_pull(skb, ETH_HLEN)) 273 goto drop; 274 275 skb_reset_mac_header(skb); 276 eth = (struct ethhdr *)skb->data; 277 278 /* To determine the frame's protocol, we assume it is 802.3. This avoids 279 * a call to eth_type_trans(), which is not really relevant for our 280 * use case. 281 */ 282 if (!eth_proto_is_802_3(eth->h_proto)) 283 goto drop; 284 285 odev = dev_get_by_index_rcu(net, slwt->oif); 286 if (!odev) 287 goto drop; 288 289 /* As we accept Ethernet frames, make sure the egress device is of 290 * the correct type. 291 */ 292 if (odev->type != ARPHRD_ETHER) 293 goto drop; 294 295 if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev)) 296 goto drop; 297 298 skb_orphan(skb); 299 300 if (skb_warn_if_lro(skb)) 301 goto drop; 302 303 skb_forward_csum(skb); 304 305 if (skb->len - ETH_HLEN > odev->mtu) 306 goto drop; 307 308 skb->dev = odev; 309 skb->protocol = eth->h_proto; 310 311 return dev_queue_xmit(skb); 312 313 drop: 314 kfree_skb(skb); 315 return -EINVAL; 316 } 317 318 /* decapsulate and forward to specified nexthop */ 319 static int input_action_end_dx6(struct sk_buff *skb, 320 struct seg6_local_lwt *slwt) 321 { 322 struct in6_addr *nhaddr = NULL; 323 324 /* this function accepts IPv6 encapsulated packets, with either 325 * an SRH with SL=0, or no SRH. 326 */ 327 328 if (!decap_and_validate(skb, IPPROTO_IPV6)) 329 goto drop; 330 331 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 332 goto drop; 333 334 /* The inner packet is not associated to any local interface, 335 * so we do not call netif_rx(). 336 * 337 * If slwt->nh6 is set to ::, then lookup the nexthop for the 338 * inner packet's DA. Otherwise, use the specified nexthop. 339 */ 340 341 if (!ipv6_addr_any(&slwt->nh6)) 342 nhaddr = &slwt->nh6; 343 344 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 345 346 seg6_lookup_nexthop(skb, nhaddr, 0); 347 348 return dst_input(skb); 349 drop: 350 kfree_skb(skb); 351 return -EINVAL; 352 } 353 354 static int input_action_end_dx4(struct sk_buff *skb, 355 struct seg6_local_lwt *slwt) 356 { 357 struct iphdr *iph; 358 __be32 nhaddr; 359 int err; 360 361 if (!decap_and_validate(skb, IPPROTO_IPIP)) 362 goto drop; 363 364 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 365 goto drop; 366 367 skb->protocol = htons(ETH_P_IP); 368 369 iph = ip_hdr(skb); 370 371 nhaddr = slwt->nh4.s_addr ?: iph->daddr; 372 373 skb_dst_drop(skb); 374 375 skb_set_transport_header(skb, sizeof(struct iphdr)); 376 377 err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev); 378 if (err) 379 goto drop; 380 381 return dst_input(skb); 382 383 drop: 384 kfree_skb(skb); 385 return -EINVAL; 386 } 387 388 static int input_action_end_dt6(struct sk_buff *skb, 389 struct seg6_local_lwt *slwt) 390 { 391 if (!decap_and_validate(skb, IPPROTO_IPV6)) 392 goto drop; 393 394 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 395 goto drop; 396 397 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 398 399 seg6_lookup_nexthop(skb, NULL, slwt->table); 400 401 return dst_input(skb); 402 403 drop: 404 kfree_skb(skb); 405 return -EINVAL; 406 } 407 408 /* push an SRH on top of the current one */ 409 static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt) 410 { 411 struct ipv6_sr_hdr *srh; 412 int err = -EINVAL; 413 414 srh = get_and_validate_srh(skb); 415 if (!srh) 416 goto drop; 417 418 err = seg6_do_srh_inline(skb, slwt->srh); 419 if (err) 420 goto drop; 421 422 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 423 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 424 425 seg6_lookup_nexthop(skb, NULL, 0); 426 427 return dst_input(skb); 428 429 drop: 430 kfree_skb(skb); 431 return err; 432 } 433 434 /* encapsulate within an outer IPv6 header and a specified SRH */ 435 static int input_action_end_b6_encap(struct sk_buff *skb, 436 struct seg6_local_lwt *slwt) 437 { 438 struct ipv6_sr_hdr *srh; 439 int err = -EINVAL; 440 441 srh = get_and_validate_srh(skb); 442 if (!srh) 443 goto drop; 444 445 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 446 447 skb_reset_inner_headers(skb); 448 skb->encapsulation = 1; 449 450 err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6); 451 if (err) 452 goto drop; 453 454 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 455 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 456 457 seg6_lookup_nexthop(skb, NULL, 0); 458 459 return dst_input(skb); 460 461 drop: 462 kfree_skb(skb); 463 return err; 464 } 465 466 DEFINE_PER_CPU(struct seg6_bpf_srh_state, seg6_bpf_srh_states); 467 468 bool seg6_bpf_has_valid_srh(struct sk_buff *skb) 469 { 470 struct seg6_bpf_srh_state *srh_state = 471 this_cpu_ptr(&seg6_bpf_srh_states); 472 struct ipv6_sr_hdr *srh = srh_state->srh; 473 474 if (unlikely(srh == NULL)) 475 return false; 476 477 if (unlikely(!srh_state->valid)) { 478 if ((srh_state->hdrlen & 7) != 0) 479 return false; 480 481 srh->hdrlen = (u8)(srh_state->hdrlen >> 3); 482 if (!seg6_validate_srh(srh, (srh->hdrlen + 1) << 3)) 483 return false; 484 485 srh_state->valid = true; 486 } 487 488 return true; 489 } 490 491 static int input_action_end_bpf(struct sk_buff *skb, 492 struct seg6_local_lwt *slwt) 493 { 494 struct seg6_bpf_srh_state *srh_state = 495 this_cpu_ptr(&seg6_bpf_srh_states); 496 struct ipv6_sr_hdr *srh; 497 int ret; 498 499 srh = get_and_validate_srh(skb); 500 if (!srh) { 501 kfree_skb(skb); 502 return -EINVAL; 503 } 504 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 505 506 /* preempt_disable is needed to protect the per-CPU buffer srh_state, 507 * which is also accessed by the bpf_lwt_seg6_* helpers 508 */ 509 preempt_disable(); 510 srh_state->srh = srh; 511 srh_state->hdrlen = srh->hdrlen << 3; 512 srh_state->valid = true; 513 514 rcu_read_lock(); 515 bpf_compute_data_pointers(skb); 516 ret = bpf_prog_run_save_cb(slwt->bpf.prog, skb); 517 rcu_read_unlock(); 518 519 switch (ret) { 520 case BPF_OK: 521 case BPF_REDIRECT: 522 break; 523 case BPF_DROP: 524 goto drop; 525 default: 526 pr_warn_once("bpf-seg6local: Illegal return value %u\n", ret); 527 goto drop; 528 } 529 530 if (srh_state->srh && !seg6_bpf_has_valid_srh(skb)) 531 goto drop; 532 533 preempt_enable(); 534 if (ret != BPF_REDIRECT) 535 seg6_lookup_nexthop(skb, NULL, 0); 536 537 return dst_input(skb); 538 539 drop: 540 preempt_enable(); 541 kfree_skb(skb); 542 return -EINVAL; 543 } 544 545 static struct seg6_action_desc seg6_action_table[] = { 546 { 547 .action = SEG6_LOCAL_ACTION_END, 548 .attrs = 0, 549 .input = input_action_end, 550 }, 551 { 552 .action = SEG6_LOCAL_ACTION_END_X, 553 .attrs = (1 << SEG6_LOCAL_NH6), 554 .input = input_action_end_x, 555 }, 556 { 557 .action = SEG6_LOCAL_ACTION_END_T, 558 .attrs = (1 << SEG6_LOCAL_TABLE), 559 .input = input_action_end_t, 560 }, 561 { 562 .action = SEG6_LOCAL_ACTION_END_DX2, 563 .attrs = (1 << SEG6_LOCAL_OIF), 564 .input = input_action_end_dx2, 565 }, 566 { 567 .action = SEG6_LOCAL_ACTION_END_DX6, 568 .attrs = (1 << SEG6_LOCAL_NH6), 569 .input = input_action_end_dx6, 570 }, 571 { 572 .action = SEG6_LOCAL_ACTION_END_DX4, 573 .attrs = (1 << SEG6_LOCAL_NH4), 574 .input = input_action_end_dx4, 575 }, 576 { 577 .action = SEG6_LOCAL_ACTION_END_DT6, 578 .attrs = (1 << SEG6_LOCAL_TABLE), 579 .input = input_action_end_dt6, 580 }, 581 { 582 .action = SEG6_LOCAL_ACTION_END_B6, 583 .attrs = (1 << SEG6_LOCAL_SRH), 584 .input = input_action_end_b6, 585 }, 586 { 587 .action = SEG6_LOCAL_ACTION_END_B6_ENCAP, 588 .attrs = (1 << SEG6_LOCAL_SRH), 589 .input = input_action_end_b6_encap, 590 .static_headroom = sizeof(struct ipv6hdr), 591 }, 592 { 593 .action = SEG6_LOCAL_ACTION_END_BPF, 594 .attrs = (1 << SEG6_LOCAL_BPF), 595 .input = input_action_end_bpf, 596 }, 597 598 }; 599 600 static struct seg6_action_desc *__get_action_desc(int action) 601 { 602 struct seg6_action_desc *desc; 603 int i, count; 604 605 count = ARRAY_SIZE(seg6_action_table); 606 for (i = 0; i < count; i++) { 607 desc = &seg6_action_table[i]; 608 if (desc->action == action) 609 return desc; 610 } 611 612 return NULL; 613 } 614 615 static int seg6_local_input(struct sk_buff *skb) 616 { 617 struct dst_entry *orig_dst = skb_dst(skb); 618 struct seg6_action_desc *desc; 619 struct seg6_local_lwt *slwt; 620 621 if (skb->protocol != htons(ETH_P_IPV6)) { 622 kfree_skb(skb); 623 return -EINVAL; 624 } 625 626 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); 627 desc = slwt->desc; 628 629 return desc->input(skb, slwt); 630 } 631 632 static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = { 633 [SEG6_LOCAL_ACTION] = { .type = NLA_U32 }, 634 [SEG6_LOCAL_SRH] = { .type = NLA_BINARY }, 635 [SEG6_LOCAL_TABLE] = { .type = NLA_U32 }, 636 [SEG6_LOCAL_NH4] = { .type = NLA_BINARY, 637 .len = sizeof(struct in_addr) }, 638 [SEG6_LOCAL_NH6] = { .type = NLA_BINARY, 639 .len = sizeof(struct in6_addr) }, 640 [SEG6_LOCAL_IIF] = { .type = NLA_U32 }, 641 [SEG6_LOCAL_OIF] = { .type = NLA_U32 }, 642 [SEG6_LOCAL_BPF] = { .type = NLA_NESTED }, 643 }; 644 645 static int parse_nla_srh(struct nlattr **attrs, struct seg6_local_lwt *slwt) 646 { 647 struct ipv6_sr_hdr *srh; 648 int len; 649 650 srh = nla_data(attrs[SEG6_LOCAL_SRH]); 651 len = nla_len(attrs[SEG6_LOCAL_SRH]); 652 653 /* SRH must contain at least one segment */ 654 if (len < sizeof(*srh) + sizeof(struct in6_addr)) 655 return -EINVAL; 656 657 if (!seg6_validate_srh(srh, len)) 658 return -EINVAL; 659 660 slwt->srh = kmemdup(srh, len, GFP_KERNEL); 661 if (!slwt->srh) 662 return -ENOMEM; 663 664 slwt->headroom += len; 665 666 return 0; 667 } 668 669 static int put_nla_srh(struct sk_buff *skb, struct seg6_local_lwt *slwt) 670 { 671 struct ipv6_sr_hdr *srh; 672 struct nlattr *nla; 673 int len; 674 675 srh = slwt->srh; 676 len = (srh->hdrlen + 1) << 3; 677 678 nla = nla_reserve(skb, SEG6_LOCAL_SRH, len); 679 if (!nla) 680 return -EMSGSIZE; 681 682 memcpy(nla_data(nla), srh, len); 683 684 return 0; 685 } 686 687 static int cmp_nla_srh(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 688 { 689 int len = (a->srh->hdrlen + 1) << 3; 690 691 if (len != ((b->srh->hdrlen + 1) << 3)) 692 return 1; 693 694 return memcmp(a->srh, b->srh, len); 695 } 696 697 static int parse_nla_table(struct nlattr **attrs, struct seg6_local_lwt *slwt) 698 { 699 slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]); 700 701 return 0; 702 } 703 704 static int put_nla_table(struct sk_buff *skb, struct seg6_local_lwt *slwt) 705 { 706 if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table)) 707 return -EMSGSIZE; 708 709 return 0; 710 } 711 712 static int cmp_nla_table(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 713 { 714 if (a->table != b->table) 715 return 1; 716 717 return 0; 718 } 719 720 static int parse_nla_nh4(struct nlattr **attrs, struct seg6_local_lwt *slwt) 721 { 722 memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]), 723 sizeof(struct in_addr)); 724 725 return 0; 726 } 727 728 static int put_nla_nh4(struct sk_buff *skb, struct seg6_local_lwt *slwt) 729 { 730 struct nlattr *nla; 731 732 nla = nla_reserve(skb, SEG6_LOCAL_NH4, sizeof(struct in_addr)); 733 if (!nla) 734 return -EMSGSIZE; 735 736 memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr)); 737 738 return 0; 739 } 740 741 static int cmp_nla_nh4(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 742 { 743 return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr)); 744 } 745 746 static int parse_nla_nh6(struct nlattr **attrs, struct seg6_local_lwt *slwt) 747 { 748 memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]), 749 sizeof(struct in6_addr)); 750 751 return 0; 752 } 753 754 static int put_nla_nh6(struct sk_buff *skb, struct seg6_local_lwt *slwt) 755 { 756 struct nlattr *nla; 757 758 nla = nla_reserve(skb, SEG6_LOCAL_NH6, sizeof(struct in6_addr)); 759 if (!nla) 760 return -EMSGSIZE; 761 762 memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr)); 763 764 return 0; 765 } 766 767 static int cmp_nla_nh6(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 768 { 769 return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr)); 770 } 771 772 static int parse_nla_iif(struct nlattr **attrs, struct seg6_local_lwt *slwt) 773 { 774 slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]); 775 776 return 0; 777 } 778 779 static int put_nla_iif(struct sk_buff *skb, struct seg6_local_lwt *slwt) 780 { 781 if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif)) 782 return -EMSGSIZE; 783 784 return 0; 785 } 786 787 static int cmp_nla_iif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 788 { 789 if (a->iif != b->iif) 790 return 1; 791 792 return 0; 793 } 794 795 static int parse_nla_oif(struct nlattr **attrs, struct seg6_local_lwt *slwt) 796 { 797 slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]); 798 799 return 0; 800 } 801 802 static int put_nla_oif(struct sk_buff *skb, struct seg6_local_lwt *slwt) 803 { 804 if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif)) 805 return -EMSGSIZE; 806 807 return 0; 808 } 809 810 static int cmp_nla_oif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 811 { 812 if (a->oif != b->oif) 813 return 1; 814 815 return 0; 816 } 817 818 #define MAX_PROG_NAME 256 819 static const struct nla_policy bpf_prog_policy[SEG6_LOCAL_BPF_PROG_MAX + 1] = { 820 [SEG6_LOCAL_BPF_PROG] = { .type = NLA_U32, }, 821 [SEG6_LOCAL_BPF_PROG_NAME] = { .type = NLA_NUL_STRING, 822 .len = MAX_PROG_NAME }, 823 }; 824 825 static int parse_nla_bpf(struct nlattr **attrs, struct seg6_local_lwt *slwt) 826 { 827 struct nlattr *tb[SEG6_LOCAL_BPF_PROG_MAX + 1]; 828 struct bpf_prog *p; 829 int ret; 830 u32 fd; 831 832 ret = nla_parse_nested_deprecated(tb, SEG6_LOCAL_BPF_PROG_MAX, 833 attrs[SEG6_LOCAL_BPF], 834 bpf_prog_policy, NULL); 835 if (ret < 0) 836 return ret; 837 838 if (!tb[SEG6_LOCAL_BPF_PROG] || !tb[SEG6_LOCAL_BPF_PROG_NAME]) 839 return -EINVAL; 840 841 slwt->bpf.name = nla_memdup(tb[SEG6_LOCAL_BPF_PROG_NAME], GFP_KERNEL); 842 if (!slwt->bpf.name) 843 return -ENOMEM; 844 845 fd = nla_get_u32(tb[SEG6_LOCAL_BPF_PROG]); 846 p = bpf_prog_get_type(fd, BPF_PROG_TYPE_LWT_SEG6LOCAL); 847 if (IS_ERR(p)) { 848 kfree(slwt->bpf.name); 849 return PTR_ERR(p); 850 } 851 852 slwt->bpf.prog = p; 853 return 0; 854 } 855 856 static int put_nla_bpf(struct sk_buff *skb, struct seg6_local_lwt *slwt) 857 { 858 struct nlattr *nest; 859 860 if (!slwt->bpf.prog) 861 return 0; 862 863 nest = nla_nest_start_noflag(skb, SEG6_LOCAL_BPF); 864 if (!nest) 865 return -EMSGSIZE; 866 867 if (nla_put_u32(skb, SEG6_LOCAL_BPF_PROG, slwt->bpf.prog->aux->id)) 868 return -EMSGSIZE; 869 870 if (slwt->bpf.name && 871 nla_put_string(skb, SEG6_LOCAL_BPF_PROG_NAME, slwt->bpf.name)) 872 return -EMSGSIZE; 873 874 return nla_nest_end(skb, nest); 875 } 876 877 static int cmp_nla_bpf(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 878 { 879 if (!a->bpf.name && !b->bpf.name) 880 return 0; 881 882 if (!a->bpf.name || !b->bpf.name) 883 return 1; 884 885 return strcmp(a->bpf.name, b->bpf.name); 886 } 887 888 struct seg6_action_param { 889 int (*parse)(struct nlattr **attrs, struct seg6_local_lwt *slwt); 890 int (*put)(struct sk_buff *skb, struct seg6_local_lwt *slwt); 891 int (*cmp)(struct seg6_local_lwt *a, struct seg6_local_lwt *b); 892 }; 893 894 static struct seg6_action_param seg6_action_params[SEG6_LOCAL_MAX + 1] = { 895 [SEG6_LOCAL_SRH] = { .parse = parse_nla_srh, 896 .put = put_nla_srh, 897 .cmp = cmp_nla_srh }, 898 899 [SEG6_LOCAL_TABLE] = { .parse = parse_nla_table, 900 .put = put_nla_table, 901 .cmp = cmp_nla_table }, 902 903 [SEG6_LOCAL_NH4] = { .parse = parse_nla_nh4, 904 .put = put_nla_nh4, 905 .cmp = cmp_nla_nh4 }, 906 907 [SEG6_LOCAL_NH6] = { .parse = parse_nla_nh6, 908 .put = put_nla_nh6, 909 .cmp = cmp_nla_nh6 }, 910 911 [SEG6_LOCAL_IIF] = { .parse = parse_nla_iif, 912 .put = put_nla_iif, 913 .cmp = cmp_nla_iif }, 914 915 [SEG6_LOCAL_OIF] = { .parse = parse_nla_oif, 916 .put = put_nla_oif, 917 .cmp = cmp_nla_oif }, 918 919 [SEG6_LOCAL_BPF] = { .parse = parse_nla_bpf, 920 .put = put_nla_bpf, 921 .cmp = cmp_nla_bpf }, 922 923 }; 924 925 static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt) 926 { 927 struct seg6_action_param *param; 928 struct seg6_action_desc *desc; 929 int i, err; 930 931 desc = __get_action_desc(slwt->action); 932 if (!desc) 933 return -EINVAL; 934 935 if (!desc->input) 936 return -EOPNOTSUPP; 937 938 slwt->desc = desc; 939 slwt->headroom += desc->static_headroom; 940 941 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 942 if (desc->attrs & (1 << i)) { 943 if (!attrs[i]) 944 return -EINVAL; 945 946 param = &seg6_action_params[i]; 947 948 err = param->parse(attrs, slwt); 949 if (err < 0) 950 return err; 951 } 952 } 953 954 return 0; 955 } 956 957 static int seg6_local_build_state(struct nlattr *nla, unsigned int family, 958 const void *cfg, struct lwtunnel_state **ts, 959 struct netlink_ext_ack *extack) 960 { 961 struct nlattr *tb[SEG6_LOCAL_MAX + 1]; 962 struct lwtunnel_state *newts; 963 struct seg6_local_lwt *slwt; 964 int err; 965 966 if (family != AF_INET6) 967 return -EINVAL; 968 969 err = nla_parse_nested_deprecated(tb, SEG6_LOCAL_MAX, nla, 970 seg6_local_policy, extack); 971 972 if (err < 0) 973 return err; 974 975 if (!tb[SEG6_LOCAL_ACTION]) 976 return -EINVAL; 977 978 newts = lwtunnel_state_alloc(sizeof(*slwt)); 979 if (!newts) 980 return -ENOMEM; 981 982 slwt = seg6_local_lwtunnel(newts); 983 slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]); 984 985 err = parse_nla_action(tb, slwt); 986 if (err < 0) 987 goto out_free; 988 989 newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; 990 newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; 991 newts->headroom = slwt->headroom; 992 993 *ts = newts; 994 995 return 0; 996 997 out_free: 998 kfree(slwt->srh); 999 kfree(newts); 1000 return err; 1001 } 1002 1003 static void seg6_local_destroy_state(struct lwtunnel_state *lwt) 1004 { 1005 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 1006 1007 kfree(slwt->srh); 1008 1009 if (slwt->desc->attrs & (1 << SEG6_LOCAL_BPF)) { 1010 kfree(slwt->bpf.name); 1011 bpf_prog_put(slwt->bpf.prog); 1012 } 1013 1014 return; 1015 } 1016 1017 static int seg6_local_fill_encap(struct sk_buff *skb, 1018 struct lwtunnel_state *lwt) 1019 { 1020 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 1021 struct seg6_action_param *param; 1022 int i, err; 1023 1024 if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action)) 1025 return -EMSGSIZE; 1026 1027 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 1028 if (slwt->desc->attrs & (1 << i)) { 1029 param = &seg6_action_params[i]; 1030 err = param->put(skb, slwt); 1031 if (err < 0) 1032 return err; 1033 } 1034 } 1035 1036 return 0; 1037 } 1038 1039 static int seg6_local_get_encap_size(struct lwtunnel_state *lwt) 1040 { 1041 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 1042 unsigned long attrs; 1043 int nlsize; 1044 1045 nlsize = nla_total_size(4); /* action */ 1046 1047 attrs = slwt->desc->attrs; 1048 1049 if (attrs & (1 << SEG6_LOCAL_SRH)) 1050 nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3); 1051 1052 if (attrs & (1 << SEG6_LOCAL_TABLE)) 1053 nlsize += nla_total_size(4); 1054 1055 if (attrs & (1 << SEG6_LOCAL_NH4)) 1056 nlsize += nla_total_size(4); 1057 1058 if (attrs & (1 << SEG6_LOCAL_NH6)) 1059 nlsize += nla_total_size(16); 1060 1061 if (attrs & (1 << SEG6_LOCAL_IIF)) 1062 nlsize += nla_total_size(4); 1063 1064 if (attrs & (1 << SEG6_LOCAL_OIF)) 1065 nlsize += nla_total_size(4); 1066 1067 if (attrs & (1 << SEG6_LOCAL_BPF)) 1068 nlsize += nla_total_size(sizeof(struct nlattr)) + 1069 nla_total_size(MAX_PROG_NAME) + 1070 nla_total_size(4); 1071 1072 return nlsize; 1073 } 1074 1075 static int seg6_local_cmp_encap(struct lwtunnel_state *a, 1076 struct lwtunnel_state *b) 1077 { 1078 struct seg6_local_lwt *slwt_a, *slwt_b; 1079 struct seg6_action_param *param; 1080 int i; 1081 1082 slwt_a = seg6_local_lwtunnel(a); 1083 slwt_b = seg6_local_lwtunnel(b); 1084 1085 if (slwt_a->action != slwt_b->action) 1086 return 1; 1087 1088 if (slwt_a->desc->attrs != slwt_b->desc->attrs) 1089 return 1; 1090 1091 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 1092 if (slwt_a->desc->attrs & (1 << i)) { 1093 param = &seg6_action_params[i]; 1094 if (param->cmp(slwt_a, slwt_b)) 1095 return 1; 1096 } 1097 } 1098 1099 return 0; 1100 } 1101 1102 static const struct lwtunnel_encap_ops seg6_local_ops = { 1103 .build_state = seg6_local_build_state, 1104 .destroy_state = seg6_local_destroy_state, 1105 .input = seg6_local_input, 1106 .fill_encap = seg6_local_fill_encap, 1107 .get_encap_size = seg6_local_get_encap_size, 1108 .cmp_encap = seg6_local_cmp_encap, 1109 .owner = THIS_MODULE, 1110 }; 1111 1112 int __init seg6_local_init(void) 1113 { 1114 return lwtunnel_encap_add_ops(&seg6_local_ops, 1115 LWTUNNEL_ENCAP_SEG6_LOCAL); 1116 } 1117 1118 void seg6_local_exit(void) 1119 { 1120 lwtunnel_encap_del_ops(&seg6_local_ops, LWTUNNEL_ENCAP_SEG6_LOCAL); 1121 } 1122