1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([["2432"],{90280:function(e,n,t){t.r(n),t.d(n,{frontMatter:()=>c,toc:()=>h,default:()=>p,metadata:()=>i,assets:()=>d,contentTitle:()=>o});var i=JSON.parse('{"id":"getting-started/kubernetes/vpp/getting-started","title":"Get started with VPP networking","description":"Install Calico with the VPP data plane on a Kubernetes cluster.","source":"@site/calico_versioned_docs/version-3.28/getting-started/kubernetes/vpp/getting-started.mdx","sourceDirName":"getting-started/kubernetes/vpp","slug":"/getting-started/kubernetes/vpp/getting-started","permalink":"/calico/3.28/getting-started/kubernetes/vpp/getting-started","draft":false,"unlisted":false,"editUrl":"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.28/getting-started/kubernetes/vpp/getting-started.mdx","tags":[],"version":"3.28","frontMatter":{"description":"Install Calico with the VPP data plane on a Kubernetes cluster."},"sidebar":"calicoSidebar","previous":{"title":"VPP data plane","permalink":"/calico/3.28/getting-started/kubernetes/vpp/"},"next":{"title":"IPsec configuration with VPP","permalink":"/calico/3.28/getting-started/kubernetes/vpp/ipsec"}}'),r=t(37937),s=t(17869),a=t(71018),l=t(38958);let c={description:"Install Calico with the VPP data plane on a Kubernetes cluster."},o="Get started with VPP networking",d={},h=[{value:"Big picture",id:"big-picture",level:2},{value:"Value",id:"value",level:2},{value:"Concepts",id:"concepts",level:2},{value:"VPP",id:"vpp",level:3},{value:"Operator based installation",id:"operator-based-installation",level:3},{value:"How to",id:"how-to",level:2},{value:"Install Calico with the VPP data plane on an EKS cluster",id:"install-calico-with-the-vpp-data-plane-on-an-eks-cluster",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Provision the cluster",id:"provision-the-cluster",level:3},{value:"Install and configure Calico with the VPP data plane",id:"install-and-configure-calico-with-the-vpp-data-plane",level:3},{value:"Install Calico with the VPP data plane on an EKS cluster with the DPDK driver",id:"install-calico-with-the-vpp-data-plane-on-an-eks-cluster-with-the-dpdk-driver",level:2},{value:"Requirements",id:"requirements-1",level:3},{value:"Provision the cluster",id:"provision-the-cluster-1",level:3},{value:"Install and configure Calico with the VPP data plane",id:"install-and-configure-calico-with-the-vpp-data-plane-1",level:3},{value:"Install Calico with the VPP data plane on any Kubernetes cluster",id:"install-calico-with-the-vpp-data-plane-on-any-kubernetes-cluster",level:2},{value:"Requirements",id:"requirements-2",level:3},{value:"Required",id:"required",level:4},{value:"Optional",id:"optional",level:4},{value:"Install Calico and configure it for VPP",id:"install-calico-and-configure-it-for-vpp",level:3},{value:"Install the VPP data plane components",id:"install-the-vpp-data-plane-components",level:3},{value:"Required Configuration",id:"required-configuration",level:4},{value:"CALICOVPP_INTERFACES spec",id:"calicovpp_interfaces-spec",level:5},{value:"InterfaceSpec",id:"interfacespec",level:5},{value:"UplinkInterfaceSpec",id:"uplinkinterfacespec",level:5},{value:"Optional Configuration",id:"optional-configuration",level:4},{value:"Legacy options",id:"legacy-options",level:4},{value:"Apply the configuration",id:"apply-the-configuration",level:3},{value:"Next steps",id:"next-steps",level:2}];function u(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components},{GeekDetails:t}=n;return t||function(e,n){throw Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("GeekDetails",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"get-started-with-vpp-networking",children:"Get started with VPP networking"})}),"\n","\n",(0,r.jsx)(n.h2,{id:"big-picture",children:"Big picture"}),"\n",(0,r.jsx)(n.p,{children:"Install Calico and enable the VPP data plane."}),"\n",(0,r.jsx)(n.h2,{id:"value",children:"Value"}),"\n",(0,r.jsx)(n.p,{children:"The VPP data plane mode has several advantages over standard Linux networking pipeline mode:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Scales to higher throughput, especially with WireGuard encryption enabled"}),"\n",(0,r.jsx)(n.li,{children:"Further improves encryption performance with IPsec"}),"\n",(0,r.jsxs)(n.li,{children:["Native support for Kubernetes services without needing kube-proxy, which:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Reduces first-packet latency for packets to
1services"}),"\n",(0,r.jsx)(n.li,{children:"Preserves external client source IP addresses all the way to the pod"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The VPP data plane is entirely compatible with the other Calico data planes, meaning you can have a cluster with VPP-enabled nodes along with regular nodes. This makes it possible to migrate a cluster from Linux or eBPF networking to VPP networking."}),"\n",(0,r.jsxs)(n.p,{children:["In addition, the VPP data plane offers some specific features for network-intensive applications, such as providing ",(0,r.jsx)(n.code,{children:"memif"})," userspace packet interfaces to the pods (instead of regular Linux network devices), or exposing the VPP Host Stack to run optimized L4+ applications in the pods."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The VPP data plane has some minor behavioural differences wrt the other Calico data planes and some of the features are not supported. For details please refer to ",(0,r.jsx)(n.a,{href:"/calico/3.28/getting-started/kubernetes/vpp/specifics",children:"Known issues & unsupported features"}),".\nPlease report bugs on the ",(0,r.jsx)(n.a,{href:"https://calicousers.slack.com/archives/C017220EXU1",children:"Calico Users slack"})," or ",(0,r.jsx)(n.a,{href:"https://github.com/projectcalico/vpp-dataplane/issues",children:"GitHub"}),")."]})}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.h3,{id:"vpp",children:"VPP"}),"\n",(0,r.jsxs)(n.p,{children:["The Vector Packet Processor (VPP) is a high-performance, open-source userspace network data plane written in C, developed under the ",(0,r.jsx)(n.a,{href:"https://fd.io",children:"fd.io"})," umbrella. It supports many standard networking features (L2 switching, L3 routing, NAT, encapsulations), and is easily extensible using plugins. The VPP data plane uses plugins to efficiently implement Kubernetes services load balancing and Calico policies."]}),"\n",(0,r.jsx)(n.h3,{id:"operator-based-installation",children:"Operator based installation"}),"\n",(0,r.jsx)(n.p,{children:"This guide uses the Tigera Operator to install Calico. The operator provides lifecycle management for Calico\nexposed via the Kubernetes API defined as a custom resource definition. While it is also technically possible to install Calico\nand configure it for VPP using manifests directly, only operator based installations are supported at this stage."}),"\n",(0,r.jsx)(n.h2,{id:"how-to",children:"How to"}),"\n",(0,r.jsx)(n.p,{children:"This guide details ways to install Calico with the VPP data plane:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"On a managed EKS cluster. This is the option that requires the least configuration."}),"\n",(0,r.jsx)(n.li,{children:"On a managed EKS cluster with the DPDK interface driver. This options is more complex to set up but provides better performance."}),"\n",(0,r.jsx)(n.li,{children:"On any Kubernetes cluster."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"In all cases, here are the details of what you will get:"}),"\n",(0,r.jsx)(t,{prodname:"Calico",details:"Policy:Calico,IPAM:Calico,CNI:Calico,Overlay:IPIP,Routing:BGP,Datastore:Kubernetes"}),"\n",(0,r.jsxs)(a.A,{children:[(0,r.jsxs)(l.A,{label:"Install on EKS",value:"Install on EKS-0",children:[(0,r.jsx)(n.h2,{id:"install-calico-with-the-vpp-data-plane-on-an-eks-cluster",children:"Install Calico with the VPP data plane on an EKS cluster"}),(0,r.jsx)(n.h3,{id:"requirements",children:"Requirements"}),(0,r.jsxs)(n.p,{children:["For these instructions, we will use ",(0,r.jsx)(n.code,{children:"eksctl"})," to provision the cluster. However, you can use any of the methods in ",(0,r.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html",children:"Getting Started with Amazon EKS"})]}),(0,r.jsxs)(n.p,{children:["Before you get started, make sure you have downloaded and configured the ",(0,r.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html#eksctl-prereqs",children:"necessary prerequisites"})]}),(0,r.jsx)(n.h3,{id:"provision-the-cluster",children:"Provision the cluster"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"First, create an Amazon EKS cluster without any nodes."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"eksctl create cluster --name my-calico-cluster --without-nodegroup\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Since this cluster will use Calico for networking, you must delete the ",(0,r.jsx)(n.code,{children:"aws-node"})," DaemonSet to disable the default AWS VPC networking for the pods."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl delete daemonset -n kube-system aws-node\n"})}),"\n"]}),"\n"]}),(0,r.jsx)(n.h3,{id:"install-and-configure-calico-with-the-vpp-data-plane",children:"Install and configure Calico with the VPP data plane"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Now that you have an empty cluster configured, you can install the Tigera Operator."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.5/manifests/tigera-operator.yaml\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Due to the large size of the CRD bundle, ",(0,r.jsx)(n.code,{children:"kubectl apply"})," might exceed request limits. Instead, use ",(0,r.jsx)(n.code,{children:"kubectl create"})," or ",(0,r.jsx)(n.code,{children:"kubectl replace"}),"."]})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Then, you need to configure the Calico installation for the VPP data plane. The yaml in the link below contains a minimal viable configuration for EKS. For more information on configuration options available in this manifest, see ",(0,r.jsx)(n.a,{href:"/calico/3.28/reference/installation/api",children:"the installation reference"}),"."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Before applying this manifest, read its contents and make sure its settings are correct for your environment. For example,\nyou may need to specify the default IP pool CIDR to match your desired pod network CIDR."})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/calico/installation-eks.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Now is time to install the VPP data plane components."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/generated/calico-vpp-eks.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Finally, add nodes to the cluster."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"eksctl create nodegroup --cluster my-calico-cluster --node-type t3.medium --node-ami auto --max-pods-per-node 50\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["The --max-pods-per-node option above, ensures that EKS does not limit the ",(0,r.jsx)(n.a,{href:"https://github.com/awslabs/amazon-eks-ami/blob/main/nodeadm/internal/kubelet/eni-max-pods.txt",children:"number of pods based on node-type"}),". For the full set of node group options, see ",(0,r.jsx)(n.code,{children:"eksctl create nodegroup --help"}),"."]})}),"\n"]}),"\n"]})]}),(0,r.jsxs)(l.A,{label:"Install on EKS with DPDK",value:"Install on EKS with DPDK-1",children:[(0,r.jsx)(n.h2,{id:"install-calico-with-the-vpp-data-plane-on-an-eks-cluster-with-the-dpdk-driver",children:"Install Calico with the VPP data plane on an EKS cluster with the DPDK driver"}),(0,r.jsx)(n.h3,{id:"requirements-1",children:"Requirements"}),(0,r.jsxs)(n.p,{children:["DPDK provides better performance compared to the standard install but it requires some additional customisations (hugepages, for instance) in the EKS worker instances. We have a bash script, ",(0,r.jsx)(n.a,{href:"https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/scripts/init_eks.sh",children:"init_eks.sh"}),", which takes care of applying the required customizations and we make use of the ",(0,r.jsx)(n.code,{children:"preBootstrapCommands"})," property of ",(0,r.jsx)(n.code,{children:"eksctl"})," ",(0,r.jsx)(n.a,{href:"https://eksctl.io/usage/schema",children:"configuration file"})," to execute the script during the worker node creation. These instructions require the latest version of ",(0,r.jsx)(n.code,{children:"eksctl"}),"."]}),(0,r.jsx)(n.h3,{id:"provision-the-cluster-1",children:"Provision the cluster"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"First, create an Amazon EKS cluster without any nodes."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"eksctl create cluster --name my-calico-cluster --without-nodegroup\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Since this cluster will use Calico for networking, you must delete the ",(0,r.jsx)(n.code,{children:"aws-node"})," DaemonSet to disable the default AWS VPC networking for the pods."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl delete daemonset -n kube-system aws-node\n"})}),"\n"]}),"\n"]}),(0,r.jsx)(n.h3,{id:"install-and-configure-calico-with-the-vpp-data-plane-1",children:"Install and configure Calico with the VPP data plane"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Now that you have an empty cluster configured, you can install the Tigera Operator."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.5/manifests/tigera-operator.yaml\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Due to the large size of the CRD bundle, ",(0,r.jsx)(n.code,{children:"kubectl apply"})," might exceed request limits. Instead, use ",(0,r.jsx)(n.code,{children:"kubectl create"})," or ",(0,r.jsx)(n.code,{children:"kubectl replace"}),"."]})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Then, you need to configure the Calico installation for the VPP data plane. The yaml in the link below contains a minimal viable configuration for EKS. For more information on configuration options available in this manifest, see ",(0,r.jsx)(n.a,{href:"/calico/3.28/reference/installation/api",children:"the installation reference"}),"."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Before applying this manifest, read its contents and make sure its settings are correct for your environment. For example,\nyou may need to specify the default IP pool CIDR to match your desired pod network CIDR."})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/calico/installation-eks.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Now is time to install the VPP data plane components."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/generated/calico-vpp-eks-dpdk.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Finally, time to add nodes to the cluster. Since we need to customize the nodes for DPDK, we will use an ",(0,r.jsx)(n.code,{children:"eksctl"})," config file with the ",(0,r.jsx)(n.code,{children:"preBootstrapCommands"})," property to create the worker nodes. The following command will create a managed nodegroup with 2 t3.large worker nodes in the cluster:"]}
1),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'cat <<EOF | eksctl create nodegroup -f -\napiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\nmetadata:\n name: my-calico-cluster\n region: us-east-2\nmanagedNodeGroups:\n- name: my-calico-cluster-ng\n desiredCapacity: 2\n instanceType: t3.large\n labels: {role: worker}\n preBootstrapCommands:\n - sudo curl -o /tmp/init_eks.sh "https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/scripts/init_eks.sh"\n - sudo chmod +x /tmp/init_eks.sh\n - sudo /tmp/init_eks.sh\nEOF\n'})}),"\n",(0,r.jsx)(n.p,{children:"Please edit the cluster name, region and other fields as appropriate for your cluster. In case you want to enable ssh access to the EKS worker instances, add the following to the above config file:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"ssh:\n publicKeyPath: <path to public key>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["For details on ssh access refer to ",(0,r.jsx)(n.a,{href:"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html",children:"Amazon EC2 key pairs and Linux instances"}),"."]}),"\n"]}),"\n"]})]}),(0,r.jsxs)(l.A,{label:"Install on any cluster",value:"Install on any cluster-2",children:[(0,r.jsx)(n.h2,{id:"install-calico-with-the-vpp-data-plane-on-any-kubernetes-cluster",children:"Install Calico with the VPP data plane on any Kubernetes cluster"}),(0,r.jsx)(n.h3,{id:"requirements-2",children:"Requirements"}),(0,r.jsx)(n.p,{children:"The VPP data plane has the following requirements:"}),(0,r.jsx)(n.h4,{id:"required",children:"Required"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"A blank Kubernetes cluster, where no CNI was ever configured."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["These ",(0,r.jsx)(n.a,{href:"/calico/3.28/getting-started/kubernetes/requirements",children:"base requirements"}),", except those related to the management of ",(0,r.jsx)(n.code,{children:"cali*"}),", ",(0,r.jsx)(n.code,{children:"tunl*"})," and ",(0,r.jsx)(n.code,{children:"vxlan.calico"})," interfaces."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["If you are using ",(0,r.jsx)(n.code,{children:"kubeadm"})," to create the cluster please make sure to specify the pod network CIDR using the ",(0,r.jsx)(n.code,{children:"--pod-network-cidr"})," command-line argument, i.e., ",(0,r.jsx)(n.code,{children:"sudo kubeadm init --pod-network-cidr=192.168.0.0/16"}),". If 192.168.0.0/16 is already in use within your network you must select a different pod network CIDR."]})}),"\n"]}),"\n"]}),(0,r.jsx)(n.h4,{id:"optional",children:"Optional"}),(0,r.jsx)(n.p,{children:"For some hardware, the following hugepages configuration may enable VPP to use more efficient drivers:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["At least 512 x 2MB-hugepages are available (",(0,r.jsx)(n.code,{children:"grep HugePages_Free /proc/meminfo"}),")"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"vfio-pci"})," (",(0,r.jsx)(n.code,{children:"vfio_pci"})," on centos) or ",(0,r.jsx)(n.code,{children:"uio_pci_generic"})," kernel module is loaded. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'echo "vfio-pci" > /etc/modules-load.d/95-vpp.conf\nmodprobe vfio-pci\necho "vm.nr_hugepages = 512" >> /etc/sysctl.conf\nsysctl -p\n # restart kubelet to take the changes into account\n # you may need to use a different command depending on how kubelet was installed\nsystemctl restart kubelet\n'})}),"\n"]}),"\n"]}),(0,r.jsx)(n.h3,{id:"install-calico-and-configure-it-for-vpp",children:"Install Calico and configure it for VPP"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Start by installing the Tigera Operator on your cluster."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.5/manifests/tigera-operator.yaml\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Due to the large size of the CRD bundle, ",(0,r.jsx)(n.code,{children:"kubectl apply"})," might exceed request limits. Instead, use ",(0,r.jsx)(n.code,{children:"kubectl create"})," or ",(0,r.jsx)(n.code,{children:"kubectl replace"}),"."]})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Then, you need to configure the Calico installation for the VPP data plane. The yaml in the link below contains a minimal viable configuration for VPP. For more information on configuration options available in this manifest, see ",(0,r.jsx)(n.a,{href:"/calico/3.28/reference/installation/api",children:"the installation reference"}),"."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Before applying this manifest, read its contents and make sure its settings are correct for your environment. For example,\nyou may need to specify the default IP pool CIDR to match your desired pod network CIDR."})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/calico/installation-default.yaml\n"})}),"\n"]}),"\n"]}),(0,r.jsx)(n.h3,{id:"install-the-vpp-data-plane-components",children:"Install the VPP data plane components"}),(0,r.jsx)(n.p,{children:"Start by getting the appropriate yaml manifest file for the VPP data plane resources:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# If you have configured hugepages on your machines\ncurl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/generated/calico-vpp.yaml\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# If not, or if you're unsure\ncurl -o calico-vpp.yaml https://raw.githubusercontent.com/projectcalico/vpp-dataplane/v3.28.0/yaml/generated/calico-vpp-nohuge.yaml\n"})}),(0,r.jsxs)(n.p,{children:["Then locate the ",(0,r.jsx)(n.code,{children:"calico-vpp-config"})," ConfigMap in this yaml manifest file and configure it as follows."]}),(0,r.jsx)(n.h4,{id:"required-configuration",children:"Required Configuration"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"SERVICE_PREFIX"})," is the Kubernetes service CIDR. You can retrieve it by running:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl cluster-info dump | grep -m 1 service-cluster-ip-range\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If this command doesn't return anything, you can leave the default value of ",(0,r.jsx)(n.code,{children:"10.96.0.0/12"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACES"})," contains a dictionary with parameters specific to interfaces in VPP. The field ",(0,r.jsx)(n.code,{children:"uplinkInterfaces"})," contains a list of uplink interfaces and their configuration, with the first element of the list being the primary/main uplink interface, and the rest (if any) being the secondary host interfaces. You ",(0,r.jsx)(n.strong,{children:"must"})," specify at the least the primary/main uplink interface name, for example,"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'CALICOVPP_INTERFACES: |-\n{\n "uplinkInterfaces": [ { "interfaceName": "eth0" } ]\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Please make sure that the interface name is that of a valid Linux interface and that it is up and configured with an address. Also, the address configured on this interface ",(0,r.jsx)(n.strong,{children:"must"})," be the node address in Kubernetes (",(0,r.jsx)(n.code,{children:"kubectl get nodes -o wide"}),")."]}),"\n",(0,r.jsx)(n.h5,{id:"calicovpp_interfaces-spec",children:"CALICOVPP_INTERFACES spec"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Field"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Type"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"maxPodIfSpec"}),(0,r.jsx)(n.td,{children:"spec containing max values for pod interfaces config"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"#interfacespec",children:"InterfaceSpec"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"defaultPodIfSpec"}),(0,r.jsx)(n.td,{children:"spec containing default values for pod interfaces config"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"#interfacespec",children:"InterfaceSpec"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"vppHostTapSpec"}),(0,r.jsx)(n.td,{children:"spec containing config for host tap interface in vpp"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"#interfacespec",children:"InterfaceSpec"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"uplinkInterfaces"}),(0,r.jsx)(n.td,{children:"list of host interfaces in vpp"}),(0,r.jsxs)(n.td,{children:["List of ",(0,r.jsx)(n.a,{href:"#uplinkinterfacespec",children:"UplinkInterfaceSpec"})]})]})]})]}),"\n",(0,r.jsx)(n.h5,{id:"interfacespec",children:"InterfaceSpec"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Field"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Default"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rx"}),(0,r.jsx)(n.td,{children:"Number of RX queues"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"tx"}),(0,r.jsx)(n.td,{children:"Number of TX queues"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rxqsz"}),(0,r.jsx)(n.td,{children:"RX queue size"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1024"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"txqsz"}),(0,r.jsx)(n.td,{children:"TX queue size"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1024"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"isl3"}),(0,r.jsx)(n.td,{children:"Defines the interface mode (L2/L3)"}),(0,r.jsx)(n.td,{children:"boolean"}),(0,r.jsx)(n.td,{children:"true for tuntap ; false for memif"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rxMode"}),(0,r.jsx)(n.td,{children:"RX mode"}),(0,r.jsx)(n.td,{children:'string among "interrupt", "adaptive", or "polling"'}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"adaptive"})})]})]})]}),"\n",(0,r.jsx)(n.h5,{id:"uplinkinterfacespec",children:"UplinkInterfaceSpec"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Field"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Default"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rx"}),(0,r.jsx)(n.td,{children:"Number of RX queues"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"tx"}),(0,r.jsx)(n.td,{children:"Number of TX queues"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rxqsz"}),(0,r.jsx)(n.td,{children:"RX queue size"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1024"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"txqsz"}),(0,r.jsx)(n.td,{children:"TX queue size"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"1024"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"isl3"}),(0,r.jsx)(n.td,{children:"Defines the interface mode (L2/L3) for drivers that support it"}),(0,r.jsx)(n.td,{children:"boolean"}),(0,r.jsx)(n.td,{children:"true"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"rxMode"}),(0,r.jsx)(n.td,{children:"RX mode"}),(0,r.jsx)(n.td,{children:'string among "interrupt", "adaptive", or "polling"'}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"adaptive"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"InterfaceName"}),(0,r.jsx)(n.td,{children:"interface name"}),(0,r.jsx)(n.td,{children:"string"}),(0,r.jsx)(n.td,{children:"unset"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"vppDriver"}),(0,r.jsx)(n.td,{children:"driver to use in vpp"}),(0,r.jsx)(n.td,{children:"string"}),(0,r.jsx)(n.td,{children:"unset"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"newDriver"}),(0,r.jsx)(n.td,{children:"linux driver to use before passing the interface to VPP"}),(0,r.jsx)(n.td,{children:"string"}),(0,r.jsx)(n.td,{children:"unset"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"mtu"}),(0,r.jsx)(n.td,{children:"the interface's mtu"}),(0,r.jsx)(n.td,{children:"int"}),(0,r.jsx)(n.td,{children:"use the existing MTU in linux"})]})]})]}),"\n"]}),"\n"]}),(0,r.jsx)(n.h4,{id:"optional-configuration",children:"Optional Configuration"}),(0,r.jsxs)(n.p,{children:["To configure how VPP drives the uplink interface, use the ",(0,r.jsx)(n.code,{children:"vppDriver"})," field in ",(0,r.jsx)(n.code,{children:"uplinkInterfaces"})," in ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACES"}),"."]}),(0,r.jsx)(n.p,{children:"The supported values will depend on the interface type. Available values are:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:'""'})," : will automatically select and try drivers based on interface type and available resources, starting with the fastest"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"af_xdp"})," : use an AF_XDP socket to drive the interface (requires kernel 5.4 or newer)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"af_packet"})," : use an AF_PACKET socket to drive the interface (not optimized but works everywhere)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"avf"})," : use the VPP native driver for Intel 700-Series and 800-Series interfaces (requires hugepages)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"vmxnet3"})," : use the VPP native driver for VMware virtual interfaces (requires hugepages)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"virtio"})," : use the VPP native driver for Virtio virtual interfaces (requires hugepages)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"rdma"})," : use the VPP native driver for Mellanox CX-4 and CX-5 interfaces (requires hugepages)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"dpdk"})," : use the DPDK interface drivers with VPP (requires hugepages, works with most interfaces)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"none"})," : do not configure connectivity automatically. This can be used when ",(0,r.jsx)(n.a,{href:"/calico/3.28/reference/vpp/uplink-configuration",children:"configuring the interface manually"})]}),"\n"]}),(0,r.jsx)(n.p,{children:"For example,"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:' CALICOVPP_INTERFACES: |-\n {\n ...\n "uplinkInterfaces": [\n {\n "interfaceName": "eth0",\n "vppDriver": "af_packet"\n }\n ]\n ...\n }\n'})}),(0,r.jsx)(n.h4,{id:"legacy-options",children:"Legacy options"}),(0,r.jsxs)(n.p,{children:["We still maintain legacy support for the ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACE"})," and ",(0,r.jsx)(n.code,{children:"CALICOVPP_NATIVE_DRIVER"})," environment variables. If ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACES"})," is unspecified, ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACE"})," is the primary interface to be used and ",(0,r.jsx)(n.code,{children:"CALICOVPP_NATIVE_DRIVER"})," the uplink driver to be used by VPP."]}),(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACE"})," --\x3e ",(0,r.jsx)(n.code,{children:"uplinkInterfaces[0].interfaceName"})]}),(0,r.jsxs)(n.p,{
1children:[(0,r.jsx)(n.code,{children:"CALICOVPP_NATIVE_DRIVER"})," --\x3e ",(0,r.jsx)(n.code,{children:"uplinkInterfaces[0].vppDriver"})]}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Example"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:"noValidation",children:'kind: ConfigMap\napiVersion: v1\nmetadata:\n name: calico-vpp-config\n namespace: calico-vpp-dataplane\ndata:\n ...\n CALICOVPP_INTERFACE: eth1\n CALICOVPP_NATIVE_DRIVER: "af_packet"\n ...\n'})}),(0,r.jsx)(n.admonition,{type:"caution",children:(0,r.jsxs)(n.p,{children:["Please note that ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACE"})," and ",(0,r.jsx)(n.code,{children:"CALICOVPP_NATIVE_DRIVER"})," are marked ",(0,r.jsx)(n.strong,{children:"deprecated"})," and will no longer be supported in the future releases. Please use ",(0,r.jsx)(n.code,{children:"CALICOVPP_INTERFACES"})," instead."]})}),(0,r.jsx)(n.h3,{id:"apply-the-configuration",children:"Apply the configuration"}),(0,r.jsx)(n.p,{children:"To apply the configuration, run:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create -f calico-vpp.yaml\n"})}),(0,r.jsx)(n.p,{children:"This will install all the resources required by the VPP data plane in your cluster."})]})]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(n.p,{children:["After installing Calico with the VPP data plane, you can benefit from the features of the VPP data plane, such as fast ",(0,r.jsx)(n.a,{href:"/calico/3.28/getting-started/kubernetes/vpp/ipsec",children:"IPsec"})," or ",(0,r.jsx)(n.a,{href:"/calico/3.28/network-policy/encrypt-cluster-pod-traffic",children:"Wireguard"})," encryption."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Tools"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/calico/3.28/operations/calicoctl/install",children:"Install and configure calicoctl"})," to configure and monitor your cluster."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Security"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/calico/3.28/network-policy/get-started/calico-policy/calico-network-policy",children:"Secure pods with Calico network policy"})}),"\n"]})]})}function p(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},38958:function(e,n,t){t.d(n,{A:()=>s});var i=t(37937);t(82645);var r=t(71918);function s({children:e,hidden:n,className:t}){return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.A)("tabItem_lI36",t),hidden:n,children:e})}},71018:function(e,n,t){t.d(n,{A:()=>v});var i=t(37937),r=t(82645),s=t(71918),a=t(22669),l=t(52678),c=t(13526),o=t(64855),d=t(66235),h=t(77848),u=t(24947);function p(e){return r.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function x({value:e,tabValues:n}){return n.some(n=>n.value===e)}var j=t(21);function f({className:e,block:n,selectedValue:t,selectValue:r,tabValues:a}){let c=[],{blockElementScrollPositionUntilNextRender:o}=(0,l.a_)(),d=e=>{let n=e.currentTarget,i=a[c.indexOf(n)].value;i!==t&&(o(n),r(i))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{let t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{let t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1]}}n?.focus()};return(0,i.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":n},e),children:a.map(({value:e,label:n,attributes:r})=>(0,i.jsx)("li",{role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>{c.push(e)},onKeyDown:h,onClick:d,...r,className:(0,s.A)("tabs__item","tabItem_tQpp",r?.className,{"tabs__item--active":t===e}),children:n??e},e))})}function m({lazy:e,children:n,selectedValue:t}
1){let a=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){let e=a.find(e=>e.props.value===t);return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,i.jsx)("div",{className:"margin-top--md",children:a.map((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==t}))})}function g(e){let n=function(e){let n,{defaultValue:t,queryString:i=!1,groupId:s}=e,a=function(e){let{values:n,children:t}=e;return(0,r.useMemo)(()=>{let e=n??p(t).map(({props:{value:e,label:n,attributes:t,default:i}})=>({value:e,label:n,attributes:t,default:i})),i=(0,h.XI)(e,(e,n)=>e.value===n.value);if(i.length>0)throw Error(`Docusaurus error: Duplicate values "${i.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,t])}(e),[l,j]=(0,r.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!x({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let t=n.find(e=>e.default)??n[0];if(!t)throw Error("Unexpected error: 0 tabValues");return t.value})({defaultValue:t,tabValues:a})),[f,m]=function({queryString:e=!1,groupId:n}){let t=(0,c.W6)(),i=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,d.aZ)(i),(0,r.useCallback)(e=>{if(!i)return;let n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})},[i,t])]}({queryString:i,groupId:s}),[g,v]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[t,i]=(0,u.Dv)(n);return[t,(0,r.useCallback)(e=>{n&&i.set(e)},[n,i])]}({groupId:s}),b=x({value:n=f??g,tabValues:a})?n:null;return(0,o.A)(()=>{b&&j(b)},[b]),{selectedValue:l,selectValue:(0,r.useCallback)(e=>{if(!x({value:e,tabValues:a}))throw Error(`Can't select invalid tab value=${e}`);j(e),m(e),v(e)},[m,v,a]),tabValues:a}}(e);return(0,i.jsxs)("div",{className:(0,s.A)(a.G.tabs.container,"tabs-container","tabList_HImo"),children:[(0,i.jsx)(f,{...n,...e}),(0,i.jsx)(m,{...n,...e})]})}function v(e){let n=(0,j.A)();return(0,i.jsx)(g,{...e,children:p(e.children)},String(n))}},17869:function(e,n,t){t.d(n,{R:()=>a,x:()=>l});var i=t(82645);let r={},s=i.createContext(r);function a(e){let n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.