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