1 /* 2 * SR-IPv6 implementation 3 * 4 * Authors: 5 * David Lebrun <david.lebrun@uclouvain.be> 6 * eBPF support: Mathieu Xhonneux <m.xhonneux@gmail.com> 7 * 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 12 * 2 of the License, or (at your option) any later version. 13 */ 14 15 #include <linux/types.h> 16 #include <linux/skbuff.h> 17 #include <linux/net.h> 18 #include <linux/module.h> 19 #include <net/ip.h> 20 #include <net/lwtunnel.h> 21 #include <net/netevent.h> 22 #include <net/netns/generic.h> 23 #include <net/ip6_fib.h> 24 #include <net/route.h> 25 #include <net/seg6.h> 26 #include <linux/seg6.h> 27 #include <linux/seg6_local.h> 28 #include <net/addrconf.h> 29 #include <net/ip6_route.h> 30 #include <net/dst_cache.h> 31 #ifdef CONFIG_IPV6_SEG6_HMAC 32 #include <net/seg6_hmac.h> 33 #endif 34 #include <net/seg6_local.h> 35 #include <linux/etherdevice.h> 36 #include <linux/bpf.h> 37 38 struct seg6_local_lwt; 39 40 struct seg6_action_desc { 41 int action; 42 unsigned long attrs; 43 int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt); 44 int static_headroom; 45 }; 46 47 struct bpf_lwt_prog { 48 struct bpf_prog *prog; 49 char *name; 50 }; 51 52 struct seg6_local_lwt { 53 int action; 54 struct ipv6_sr_hdr *srh; 55 int table; 56 struct in_addr nh4; 57 struct in6_addr nh6; 58 int iif; 59 int oif; 60 struct bpf_lwt_prog bpf; 61 62 int headroom; 63 struct seg6_action_desc *desc; 64 }; 65 66 static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt) 67 { 68 return (struct seg6_local_lwt *)lwt->data; 69 } 70 71 static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb) 72 { 73 struct ipv6_sr_hdr *srh; 74 int len, srhoff = 0; 75 76 if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) 77 return NULL; 78 79 if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) 80 return NULL; 81 82 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); 83 84 len = (srh->hdrlen + 1) << 3; 85 86 if (!pskb_may_pull(skb, srhoff + len)) 87 return NULL; 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 seg6_lookup_nexthop(skb, nhaddr, 0); 345 346 return dst_input(skb); 347 drop: 348 kfree_skb(skb); 349 return -EINVAL; 350 } 351 352 static int input_action_end_dx4(struct sk_buff *skb, 353 struct seg6_local_lwt *slwt) 354 { 355 struct iphdr *iph; 356 __be32 nhaddr; 357 int err; 358 359 if (!decap_and_validate(skb, IPPROTO_IPIP)) 360 goto drop; 361 362 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 363 goto drop; 364 365 skb->protocol = htons(ETH_P_IP); 366 367 iph = ip_hdr(skb); 368 369 nhaddr = slwt->nh4.s_addr ?: iph->daddr; 370 371 skb_dst_drop(skb); 372 373 err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev); 374 if (err) 375 goto drop; 376 377 return dst_input(skb); 378 379 drop: 380 kfree_skb(skb); 381 return -EINVAL; 382 } 383 384 static int input_action_end_dt6(struct sk_buff *skb, 385 struct seg6_local_lwt *slwt) 386 { 387 if (!decap_and_validate(skb, IPPROTO_IPV6)) 388 goto drop; 389 390 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 391 goto drop; 392 393 seg6_lookup_nexthop(skb, NULL, slwt->table); 394 395 return dst_input(skb); 396 397 drop: 398 kfree_skb(skb); 399 return -EINVAL; 400 } 401 402 /* push an SRH on top of the current one */ 403 static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt) 404 { 405 struct ipv6_sr_hdr *srh; 406 int err = -EINVAL; 407 408 srh = get_and_validate_srh(skb); 409 if (!srh) 410 goto drop; 411 412 err = seg6_do_srh_inline(skb, slwt->srh); 413 if (err) 414 goto drop; 415 416 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 417 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 418 419 seg6_lookup_nexthop(skb, NULL, 0); 420 421 return dst_input(skb); 422 423 drop: 424 kfree_skb(skb); 425 return err; 426 } 427 428 /* encapsulate within an outer IPv6 header and a specified SRH */ 429 static int input_action_end_b6_encap(struct sk_buff *skb, 430 struct seg6_local_lwt *slwt) 431 { 432 struct ipv6_sr_hdr *srh; 433 int err = -EINVAL; 434 435 srh = get_and_validate_srh(skb); 436 if (!srh) 437 goto drop; 438 439 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 440 441 skb_reset_inner_headers(skb); 442 skb->encapsulation = 1; 443 444 err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6); 445 if (err) 446 goto drop; 447 448 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 449 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 450 451 seg6_lookup_nexthop(skb, NULL, 0); 452 453 return dst_input(skb); 454 455 drop: 456 kfree_skb(skb); 457 return err; 458 } 459 460 DEFINE_PER_CPU(struct seg6_bpf_srh_state, seg6_bpf_srh_states); 461 462 static int input_action_end_bpf(struct sk_buff *skb, 463 struct seg6_local_lwt *slwt) 464 { 465 struct seg6_bpf_srh_state *srh_state = 466 this_cpu_ptr(&seg6_bpf_srh_states); 467 struct seg6_bpf_srh_state local_srh_state; 468 struct ipv6_sr_hdr *srh; 469 int srhoff = 0; 470 int ret; 471 472 srh = get_and_validate_srh(skb); 473 if (!srh) 474 goto drop; 475 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 476 477 /* preempt_disable is needed to protect the per-CPU buffer srh_state, 478 * which is also accessed by the bpf_lwt_seg6_* helpers 479 */ 480 preempt_disable(); 481 srh_state->hdrlen = srh->hdrlen << 3; 482 srh_state->valid = 1; 483 484 rcu_read_lock(); 485 bpf_compute_data_pointers(skb); 486 ret = bpf_prog_run_save_cb(slwt->bpf.prog, skb); 487 rcu_read_unlock(); 488 489 local_srh_state = *srh_state; 490 preempt_enable(); 491 492 switch (ret) { 493 case BPF_OK: 494 case BPF_REDIRECT: 495 break; 496 case BPF_DROP: 497 goto drop; 498 default: 499 pr_warn_once("bpf-seg6local: Illegal return value %u\n", ret); 500 goto drop; 501 } 502 503 if (unlikely((local_srh_state.hdrlen & 7) != 0)) 504 goto drop; 505 506 if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) 507 goto drop; 508 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); 509 srh->hdrlen = (u8)(local_srh_state.hdrlen >> 3); 510 511 if (!local_srh_state.valid && 512 unlikely(!seg6_validate_srh(srh, (srh->hdrlen + 1) << 3))) 513 goto drop; 514 515 if (ret != BPF_REDIRECT) 516 seg6_lookup_nexthop(skb, NULL, 0); 517 518 return dst_input(skb); 519 520 drop: 521 kfree_skb(skb); 522 return -EINVAL; 523 } 524 525 static struct seg6_action_desc seg6_action_table[] = { 526 { 527 .action = SEG6_LOCAL_ACTION_END, 528 .attrs = 0, 529 .input = input_action_end, 530 }, 531 { 532 .action = SEG6_LOCAL_ACTION_END_X, 533 .attrs = (1 << SEG6_LOCAL_NH6), 534 .input = input_action_end_x, 535 }, 536 { 537 .action = SEG6_LOCAL_ACTION_END_T, 538 .attrs = (1 << SEG6_LOCAL_TABLE), 539 .input = input_action_end_t, 540 }, 541 { 542 .action = SEG6_LOCAL_ACTION_END_DX2, 543 .attrs = (1 << SEG6_LOCAL_OIF), 544 .input = input_action_end_dx2, 545 }, 546 { 547 .action = SEG6_LOCAL_ACTION_END_DX6, 548 .attrs = (1 << SEG6_LOCAL_NH6), 549 .input = input_action_end_dx6, 550 }, 551 { 552 .action = SEG6_LOCAL_ACTION_END_DX4, 553 .attrs = (1 << SEG6_LOCAL_NH4), 554 .input = input_action_end_dx4, 555 }, 556 { 557 .action = SEG6_LOCAL_ACTION_END_DT6, 558 .attrs = (1 << SEG6_LOCAL_TABLE), 559 .input = input_action_end_dt6, 560 }, 561 { 562 .action = SEG6_LOCAL_ACTION_END_B6, 563 .attrs = (1 << SEG6_LOCAL_SRH), 564 .input = input_action_end_b6, 565 }, 566 { 567 .action = SEG6_LOCAL_ACTION_END_B6_ENCAP, 568 .attrs = (1 << SEG6_LOCAL_SRH), 569 .input = input_action_end_b6_encap, 570 .static_headroom = sizeof(struct ipv6hdr), 571 }, 572 { 573 .action = SEG6_LOCAL_ACTION_END_BPF, 574 .attrs = (1 << SEG6_LOCAL_BPF), 575 .input = input_action_end_bpf, 576 }, 577 578 }; 579 580 static struct seg6_action_desc *__get_action_desc(int action) 581 { 582 struct seg6_action_desc *desc; 583 int i, count; 584 585 count = ARRAY_SIZE(seg6_action_table); 586 for (i = 0; i < count; i++) { 587 desc = &seg6_action_table[i]; 588 if (desc->action == action) 589 return desc; 590 } 591 592 return NULL; 593 } 594 595 static int seg6_local_input(struct sk_buff *skb) 596 { 597 struct dst_entry *orig_dst = skb_dst(skb); 598 struct seg6_action_desc *desc; 599 struct seg6_local_lwt *slwt; 600 601 if (skb->protocol != htons(ETH_P_IPV6)) { 602 kfree_skb(skb); 603 return -EINVAL; 604 } 605 606 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); 607 desc = slwt->desc; 608 609 return desc->input(skb, slwt); 610 } 611 612 static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = { 613 [SEG6_LOCAL_ACTION] = { .type = NLA_U32 }, 614 [SEG6_LOCAL_SRH] = { .type = NLA_BINARY }, 615 [SEG6_LOCAL_TABLE] = { .type = NLA_U32 }, 616 [SEG6_LOCAL_NH4] = { .type = NLA_BINARY, 617 .len = sizeof(struct in_addr) }, 618 [SEG6_LOCAL_NH6] = { .type = NLA_BINARY, 619 .len = sizeof(struct in6_addr) }, 620 [SEG6_LOCAL_IIF] = { .type = NLA_U32 }, 621 [SEG6_LOCAL_OIF] = { .type = NLA_U32 }, 622 [SEG6_LOCAL_BPF] = { .type = NLA_NESTED }, 623 }; 624 625 static int parse_nla_srh(struct nlattr **attrs, struct seg6_local_lwt *slwt) 626 { 627 struct ipv6_sr_hdr *srh; 628 int len; 629 630 srh = nla_data(attrs[SEG6_LOCAL_SRH]); 631 len = nla_len(attrs[SEG6_LOCAL_SRH]); 632 633 /* SRH must contain at least one segment */ 634 if (len < sizeof(*srh) + sizeof(struct in6_addr)) 635 return -EINVAL; 636 637 if (!seg6_validate_srh(srh, len)) 638 return -EINVAL; 639 640 slwt->srh = kmalloc(len, GFP_KERNEL); 641 if (!slwt->srh) 642 return -ENOMEM; 643 644 memcpy(slwt->srh, srh, len); 645 646 slwt->headroom += len; 647 648 return 0; 649 } 650 651 static int put_nla_srh(struct sk_buff *skb, struct seg6_local_lwt *slwt) 652 { 653 struct ipv6_sr_hdr *srh; 654 struct nlattr *nla; 655 int len; 656 657 srh = slwt->srh; 658 len = (srh->hdrlen + 1) << 3; 659 660 nla = nla_reserve(skb, SEG6_LOCAL_SRH, len); 661 if (!nla) 662 return -EMSGSIZE; 663 664 memcpy(nla_data(nla), srh, len); 665 666 return 0; 667 } 668 669 static int cmp_nla_srh(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 670 { 671 int len = (a->srh->hdrlen + 1) << 3; 672 673 if (len != ((b->srh->hdrlen + 1) << 3)) 674 return 1; 675 676 return memcmp(a->srh, b->srh, len); 677 } 678 679 static int parse_nla_table(struct nlattr **attrs, struct seg6_local_lwt *slwt) 680 { 681 slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]); 682 683 return 0; 684 } 685 686 static int put_nla_table(struct sk_buff *skb, struct seg6_local_lwt *slwt) 687 { 688 if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table)) 689 return -EMSGSIZE; 690 691 return 0; 692 } 693 694 static int cmp_nla_table(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 695 { 696 if (a->table != b->table) 697 return 1; 698 699 return 0; 700 } 701 702 static int parse_nla_nh4(struct nlattr **attrs, struct seg6_local_lwt *slwt) 703 { 704 memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]), 705 sizeof(struct in_addr)); 706 707 return 0; 708 } 709 710 static int put_nla_nh4(struct sk_buff *skb, struct seg6_local_lwt *slwt) 711 { 712 struct nlattr *nla; 713 714 nla = nla_reserve(skb, SEG6_LOCAL_NH4, sizeof(struct in_addr)); 715 if (!nla) 716 return -EMSGSIZE; 717 718 memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr)); 719 720 return 0; 721 } 722 723 static int cmp_nla_nh4(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 724 { 725 return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr)); 726 } 727 728 static int parse_nla_nh6(struct nlattr **attrs, struct seg6_local_lwt *slwt) 729 { 730 memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]), 731 sizeof(struct in6_addr)); 732 733 return 0; 734 } 735 736 static int put_nla_nh6(struct sk_buff *skb, struct seg6_local_lwt *slwt) 737 { 738 struct nlattr *nla; 739 740 nla = nla_reserve(skb, SEG6_LOCAL_NH6, sizeof(struct in6_addr)); 741 if (!nla) 742 return -EMSGSIZE; 743 744 memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr)); 745 746 return 0; 747 } 748 749 static int cmp_nla_nh6(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 750 { 751 return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr)); 752 } 753 754 static int parse_nla_iif(struct nlattr **attrs, struct seg6_local_lwt *slwt) 755 { 756 slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]); 757 758 return 0; 759 } 760 761 static int put_nla_iif(struct sk_buff *skb, struct seg6_local_lwt *slwt) 762 { 763 if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif)) 764 return -EMSGSIZE; 765 766 return 0; 767 } 768 769 static int cmp_nla_iif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 770 { 771 if (a->iif != b->iif) 772 return 1; 773 774 return 0; 775 } 776 777 static int parse_nla_oif(struct nlattr **attrs, struct seg6_local_lwt *slwt) 778 { 779 slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]); 780 781 return 0; 782 } 783 784 static int put_nla_oif(struct sk_buff *skb, struct seg6_local_lwt *slwt) 785 { 786 if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif)) 787 return -EMSGSIZE; 788 789 return 0; 790 } 791 792 static int cmp_nla_oif(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 793 { 794 if (a->oif != b->oif) 795 return 1; 796 797 return 0; 798 } 799 800 #define MAX_PROG_NAME 256 801 static const struct nla_policy bpf_prog_policy[SEG6_LOCAL_BPF_PROG_MAX + 1] = { 802 [SEG6_LOCAL_BPF_PROG] = { .type = NLA_U32, }, 803 [SEG6_LOCAL_BPF_PROG_NAME] = { .type = NLA_NUL_STRING, 804 .len = MAX_PROG_NAME }, 805 }; 806 807 static int parse_nla_bpf(struct nlattr **attrs, struct seg6_local_lwt *slwt) 808 { 809 struct nlattr *tb[SEG6_LOCAL_BPF_PROG_MAX + 1]; 810 struct bpf_prog *p; 811 int ret; 812 u32 fd; 813 814 ret = nla_parse_nested(tb, SEG6_LOCAL_BPF_PROG_MAX, 815 attrs[SEG6_LOCAL_BPF], bpf_prog_policy, NULL); 816 if (ret < 0) 817 return ret; 818 819 if (!tb[SEG6_LOCAL_BPF_PROG] || !tb[SEG6_LOCAL_BPF_PROG_NAME]) 820 return -EINVAL; 821 822 slwt->bpf.name = nla_memdup(tb[SEG6_LOCAL_BPF_PROG_NAME], GFP_KERNEL); 823 if (!slwt->bpf.name) 824 return -ENOMEM; 825 826 fd = nla_get_u32(tb[SEG6_LOCAL_BPF_PROG]); 827 p = bpf_prog_get_type(fd, BPF_PROG_TYPE_LWT_SEG6LOCAL); 828 if (IS_ERR(p)) { 829 kfree(slwt->bpf.name); 830 return PTR_ERR(p); 831 } 832 833 slwt->bpf.prog = p; 834 return 0; 835 } 836 837 static int put_nla_bpf(struct sk_buff *skb, struct seg6_local_lwt *slwt) 838 { 839 struct nlattr *nest; 840 841 if (!slwt->bpf.prog) 842 return 0; 843 844 nest = nla_nest_start(skb, SEG6_LOCAL_BPF); 845 if (!nest) 846 return -EMSGSIZE; 847 848 if (nla_put_u32(skb, SEG6_LOCAL_BPF_PROG, slwt->bpf.prog->aux->id)) 849 return -EMSGSIZE; 850 851 if (slwt->bpf.name && 852 nla_put_string(skb, SEG6_LOCAL_BPF_PROG_NAME, slwt->bpf.name)) 853 return -EMSGSIZE; 854 855 return nla_nest_end(skb, nest); 856 } 857 858 static int cmp_nla_bpf(struct seg6_local_lwt *a, struct seg6_local_lwt *b) 859 { 860 if (!a->bpf.name && !b->bpf.name) 861 return 0; 862 863 if (!a->bpf.name || !b->bpf.name) 864 return 1; 865 866 return strcmp(a->bpf.name, b->bpf.name); 867 } 868 869 struct seg6_action_param { 870 int (*parse)(struct nlattr **attrs, struct seg6_local_lwt *slwt); 871 int (*put)(struct sk_buff *skb, struct seg6_local_lwt *slwt); 872 int (*cmp)(struct seg6_local_lwt *a, struct seg6_local_lwt *b); 873 }; 874 875 static struct seg6_action_param seg6_action_params[SEG6_LOCAL_MAX + 1] = { 876 [SEG6_LOCAL_SRH] = { .parse = parse_nla_srh, 877 .put = put_nla_srh, 878 .cmp = cmp_nla_srh }, 879 880 [SEG6_LOCAL_TABLE] = { .parse = parse_nla_table, 881 .put = put_nla_table, 882 .cmp = cmp_nla_table }, 883 884 [SEG6_LOCAL_NH4] = { .parse = parse_nla_nh4, 885 .put = put_nla_nh4, 886 .cmp = cmp_nla_nh4 }, 887 888 [SEG6_LOCAL_NH6] = { .parse = parse_nla_nh6, 889 .put = put_nla_nh6, 890 .cmp = cmp_nla_nh6 }, 891 892 [SEG6_LOCAL_IIF] = { .parse = parse_nla_iif, 893 .put = put_nla_iif, 894 .cmp = cmp_nla_iif }, 895 896 [SEG6_LOCAL_OIF] = { .parse = parse_nla_oif, 897 .put = put_nla_oif, 898 .cmp = cmp_nla_oif }, 899 900 [SEG6_LOCAL_BPF] = { .parse = parse_nla_bpf, 901 .put = put_nla_bpf, 902 .cmp = cmp_nla_bpf }, 903 904 }; 905 906 static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt) 907 { 908 struct seg6_action_param *param; 909 struct seg6_action_desc *desc; 910 int i, err; 911 912 desc = __get_action_desc(slwt->action); 913 if (!desc) 914 return -EINVAL; 915 916 if (!desc->input) 917 return -EOPNOTSUPP; 918 919 slwt->desc = desc; 920 slwt->headroom += desc->static_headroom; 921 922 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 923 if (desc->attrs & (1 << i)) { 924 if (!attrs[i]) 925 return -EINVAL; 926 927 param = &seg6_action_params[i]; 928 929 err = param->parse(attrs, slwt); 930 if (err < 0) 931 return err; 932 } 933 } 934 935 return 0; 936 } 937 938 static int seg6_local_build_state(struct nlattr *nla, unsigned int family, 939 const void *cfg, struct lwtunnel_state **ts, 940 struct netlink_ext_ack *extack) 941 { 942 struct nlattr *tb[SEG6_LOCAL_MAX + 1]; 943 struct lwtunnel_state *newts; 944 struct seg6_local_lwt *slwt; 945 int err; 946 947 if (family != AF_INET6) 948 return -EINVAL; 949 950 err = nla_parse_nested(tb, SEG6_LOCAL_MAX, nla, seg6_local_policy, 951 extack); 952 953 if (err < 0) 954 return err; 955 956 if (!tb[SEG6_LOCAL_ACTION]) 957 return -EINVAL; 958 959 newts = lwtunnel_state_alloc(sizeof(*slwt)); 960 if (!newts) 961 return -ENOMEM; 962 963 slwt = seg6_local_lwtunnel(newts); 964 slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]); 965 966 err = parse_nla_action(tb, slwt); 967 if (err < 0) 968 goto out_free; 969 970 newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; 971 newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; 972 newts->headroom = slwt->headroom; 973 974 *ts = newts; 975 976 return 0; 977 978 out_free: 979 kfree(slwt->srh); 980 kfree(newts); 981 return err; 982 } 983 984 static void seg6_local_destroy_state(struct lwtunnel_state *lwt) 985 { 986 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 987 988 kfree(slwt->srh); 989 990 if (slwt->desc->attrs & (1 << SEG6_LOCAL_BPF)) { 991 kfree(slwt->bpf.name); 992 bpf_prog_put(slwt->bpf.prog); 993 } 994 995 return; 996 } 997 998 static int seg6_local_fill_encap(struct sk_buff *skb, 999 struct lwtunnel_state *lwt) 1000 { 1001 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 1002 struct seg6_action_param *param; 1003 int i, err; 1004 1005 if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action)) 1006 return -EMSGSIZE; 1007 1008 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 1009 if (slwt->desc->attrs & (1 << i)) { 1010 param = &seg6_action_params[i]; 1011 err = param->put(skb, slwt); 1012 if (err < 0) 1013 return err; 1014 } 1015 } 1016 1017 return 0; 1018 } 1019 1020 static int seg6_local_get_encap_size(struct lwtunnel_state *lwt) 1021 { 1022 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt); 1023 unsigned long attrs; 1024 int nlsize; 1025 1026 nlsize = nla_total_size(4); /* action */ 1027 1028 attrs = slwt->desc->attrs; 1029 1030 if (attrs & (1 << SEG6_LOCAL_SRH)) 1031 nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3); 1032 1033 if (attrs & (1 << SEG6_LOCAL_TABLE)) 1034 nlsize += nla_total_size(4); 1035 1036 if (attrs & (1 << SEG6_LOCAL_NH4)) 1037 nlsize += nla_total_size(4); 1038 1039 if (attrs & (1 << SEG6_LOCAL_NH6)) 1040 nlsize += nla_total_size(16); 1041 1042 if (attrs & (1 << SEG6_LOCAL_IIF)) 1043 nlsize += nla_total_size(4); 1044 1045 if (attrs & (1 << SEG6_LOCAL_OIF)) 1046 nlsize += nla_total_size(4); 1047 1048 if (attrs & (1 << SEG6_LOCAL_BPF)) 1049 nlsize += nla_total_size(sizeof(struct nlattr)) + 1050 nla_total_size(MAX_PROG_NAME) + 1051 nla_total_size(4); 1052 1053 return nlsize; 1054 } 1055 1056 static int seg6_local_cmp_encap(struct lwtunnel_state *a, 1057 struct lwtunnel_state *b) 1058 { 1059 struct seg6_local_lwt *slwt_a, *slwt_b; 1060 struct seg6_action_param *param; 1061 int i; 1062 1063 slwt_a = seg6_local_lwtunnel(a); 1064 slwt_b = seg6_local_lwtunnel(b); 1065 1066 if (slwt_a->action != slwt_b->action) 1067 return 1; 1068 1069 if (slwt_a->desc->attrs != slwt_b->desc->attrs) 1070 return 1; 1071 1072 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) { 1073 if (slwt_a->desc->attrs & (1 << i)) { 1074 param = &seg6_action_params[i]; 1075 if (param->cmp(slwt_a, slwt_b)) 1076 return 1; 1077 } 1078 } 1079 1080 return 0; 1081 } 1082 1083 static const struct lwtunnel_encap_ops seg6_local_ops = { 1084 .build_state = seg6_local_build_state, 1085 .destroy_state = seg6_local_destroy_state, 1086 .input = seg6_local_input, 1087 .fill_encap = seg6_local_fill_encap, 1088 .get_encap_size = seg6_local_get_encap_size, 1089 .cmp_encap = seg6_local_cmp_encap, 1090 .owner = THIS_MODULE, 1091 }; 1092 1093 int __init seg6_local_init(void) 1094 { 1095 return lwtunnel_encap_add_ops(&seg6_local_ops, 1096 LWTUNNEL_ENCAP_SEG6_LOCAL); 1097 } 1098 1099 void seg6_local_exit(void) 1100 { 1101 lwtunnel_encap_del_ops(&seg6_local_ops, LWTUNNEL_ENCAP_SEG6_LOCAL); 1102 } 1103