Merge "Update sdfabric helm chart"
diff --git a/bess-upf/.gitignore b/bess-upf/.gitignore
new file mode 100644
index 0000000..616ae1a
--- /dev/null
+++ b/bess-upf/.gitignore
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
+#
+# SPDX-License-Identifier: Apache-2.0
+
+charts/
diff --git a/bess-upf/.helmignore b/bess-upf/.helmignore
new file mode 100644
index 0000000..931186d
--- /dev/null
+++ b/bess-upf/.helmignore
@@ -0,0 +1,25 @@
+# SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/bess-upf/Chart.yaml b/bess-upf/Chart.yaml
new file mode 100644
index 0000000..0ae02d7
--- /dev/null
+++ b/bess-upf/Chart.yaml
@@ -0,0 +1,10 @@
+# Copyright 2020-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+apiVersion: v1
+description: OMEC user plane based on BESS
+name: bess-upf
+icon: https://guide.opencord.org/logos/cord.svg
+
+version: 0.0.1
diff --git a/bess-upf/templates/_helpers.tpl b/bess-upf/templates/_helpers.tpl
new file mode 100644
index 0000000..b879a09
--- /dev/null
+++ b/bess-upf/templates/_helpers.tpl
@@ -0,0 +1,48 @@
+{{- /*
+
+# Copyright 2020-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+*/ -}}
+
+{{/*
+Renders a set of standardised labels.
+*/}}
+{{- define "omec-user-plane.metadata_labels" -}}
+{{- $application := index . 0 -}}
+{{- $context := index . 1 -}}
+release: {{ $context.Release.Name }}
+app: {{ $application }}
+{{- end -}}
+
+{{/*
+Render the given template.
+*/}}
+{{- define "omec-user-plane.template" -}}
+{{- $name := index . 0 -}}
+{{- $context := index . 1 -}}
+{{- $last := base $context.Template.Name }}
+{{- $wtf := $context.Template.Name | replace $last $name -}}
+{{ include $wtf $context }}
+{{- end -}}
+
+{{/*
+Render init container for coredump.
+*/}}
+{{- define "omec-user-plane.coredump_init" -}}
+{{- $pod := index . 0 -}}
+{{- $context := index . 1 -}}
+- name: {{ $pod }}-coredump-init
+  image: {{ $context.Values.images.tags.tools | quote }}
+  imagePullPolicy: {{ $context.Values.images.pullPolicy }}
+  securityContext:
+    privileged: true
+    runAsUser: 0
+  command: ["sh", "-xc"]
+  args:
+    - echo '/tmp/coredump/core.%h.%e.%t' > /mnt/host-rootfs/proc/sys/kernel/core_pattern
+  volumeMounts:
+    - name: host-rootfs
+      mountPath: /mnt/host-rootfs
+{{- end -}}
diff --git a/bess-upf/templates/bin/_bessd-poststart.sh.tpl b/bess-upf/templates/bin/_bessd-poststart.sh.tpl
new file mode 100644
index 0000000..642306c
--- /dev/null
+++ b/bess-upf/templates/bin/_bessd-poststart.sh.tpl
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Copyright 2020-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+set -ex
+
+until bessctl run /opt/bess/bessctl/conf/up4; do
+    sleep 2;
+done;
diff --git a/bess-upf/templates/configmap-upf.yaml b/bess-upf/templates/configmap-upf.yaml
new file mode 100644
index 0000000..ff97c1c
--- /dev/null
+++ b/bess-upf/templates/configmap-upf.yaml
@@ -0,0 +1,19 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: upf
+  labels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+data:
+{{- range $key, $value := .Values.config.upf.cfgFiles }}
+  {{ $key }}: {{ toJson $value | quote }}
+{{- end }}
+  bessd-poststart.sh: |
+{{ tuple "bin/_bessd-poststart.sh.tpl" . | include "omec-user-plane.template" | indent 4 }}
diff --git a/bess-upf/templates/networks.yaml b/bess-upf/templates/networks.yaml
new file mode 100644
index 0000000..7f731e9
--- /dev/null
+++ b/bess-upf/templates/networks.yaml
@@ -0,0 +1,60 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+---
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: access-net
+{{- if $.Values.config.upf.sriov.enabled }}
+  annotations:
+    k8s.v1.cni.cncf.io/resourceName: {{ .Values.config.upf.access.resourceName }}
+{{- end }}
+spec:
+  config: '{
+    "cniVersion": "0.3.1",
+  {{- if hasKey .Values.config.upf.access "vlan" }}
+    "vlan": {{ .Values.config.upf.access.vlan }},
+  {{- end }}
+    "type": {{ .Values.config.upf.cniPlugin | quote }},
+  {{- if eq .Values.config.upf.cniPlugin "macvlan" }}
+    "master": {{ .Values.config.upf.access.iface | quote }},
+  {{- end }}
+  {{- if eq .Values.config.upf.cniPlugin "host-device" }}
+    "device": {{ .Values.config.upf.access.iface | quote }},
+  {{- end }}
+    "ipam": {
+        "type": {{ .Values.config.upf.ipam | quote }}
+    },
+    "capabilities": { "mac": true}
+  }'
+---
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: core-net
+{{- if $.Values.config.upf.sriov.enabled }}
+  annotations:
+    k8s.v1.cni.cncf.io/resourceName: {{ .Values.config.upf.core.resourceName }}
+{{- end }}
+spec:
+  config: '{
+    "cniVersion": "0.3.1",
+  {{- if hasKey .Values.config.upf.core "vlan" }}
+    "vlan": {{ .Values.config.upf.core.vlan }},
+  {{- end }}
+    "type": {{ .Values.config.upf.cniPlugin | quote }},
+  {{- if eq .Values.config.upf.cniPlugin "macvlan" }}
+    "master": {{ .Values.config.upf.core.iface | quote }},
+  {{- end }}
+  {{- if eq .Values.config.upf.cniPlugin "host-device" }}
+    "device": {{ .Values.config.upf.core.iface | quote }},
+  {{- end }}
+    "ipam": {
+        "type": {{ .Values.config.upf.ipam | quote }}
+    },
+    "capabilities": { "mac": true}
+  }'
diff --git a/bess-upf/templates/podsecuritypolicy-upf.yaml b/bess-upf/templates/podsecuritypolicy-upf.yaml
new file mode 100644
index 0000000..2578f6c
--- /dev/null
+++ b/bess-upf/templates/podsecuritypolicy-upf.yaml
@@ -0,0 +1,48 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+{{- if .Values.podsecuritypolicy.enabled }}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+    name: 1-upf
+spec:
+    {{ if or .Values.config.coreDump.enabled  .Values.config.upf.privileged }}
+    privileged: true
+    allowPrivilegeEscalation: true
+    {{ else }}
+    privileged: false
+    allowPrivilegeEscalation: false
+    {{ end }}
+    allowedCapabilities:
+    - IPC_LOCK
+    - NET_ADMIN
+    volumes:
+    - 'configMap'
+    - 'emptyDir'
+    - 'secret'
+    {{- if .Values.config.coreDump.enabled }}
+    - 'hostPath'
+    allowedHostPaths:
+    - pathPrefix: "/"
+    - pathPrefix: "/tmp/coredump"
+    {{- end }}
+    seLinux:
+        rule: RunAsAny
+    supplementalGroups:
+      rule: 'MustRunAs'
+      ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+    runAsUser:
+        rule: RunAsAny
+    fsGroup:
+      rule: 'MustRunAs'
+      ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+{{- end }}
diff --git a/bess-upf/templates/pspclusterrole-upf.yaml b/bess-upf/templates/pspclusterrole-upf.yaml
new file mode 100644
index 0000000..22bc94b
--- /dev/null
+++ b/bess-upf/templates/pspclusterrole-upf.yaml
@@ -0,0 +1,17 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+{{- if .Values.podsecuritypolicy.enabled }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: psp:upf
+rules:
+- apiGroups: ['policy']
+  resources: ['podsecuritypolicies']
+  verbs:     ['use']
+  resourceNames:
+  - 1-upf
+{{- end }}
diff --git a/bess-upf/templates/psprolebinding-upf.yaml b/bess-upf/templates/psprolebinding-upf.yaml
new file mode 100644
index 0000000..275f1a0
--- /dev/null
+++ b/bess-upf/templates/psprolebinding-upf.yaml
@@ -0,0 +1,20 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+{{- if .Values.podsecuritypolicy.enabled }}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: role:psp:upf
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: psp:upf
+subjects:
+- kind: Group
+  name: system:serviceaccounts:{{ .Release.Namespace }}
+  namespace: {{ .Release.Namespace }}
+{{- end }}
diff --git a/bess-upf/templates/service-upf.yaml b/bess-upf/templates/service-upf.yaml
new file mode 100644
index 0000000..e7a2cbc
--- /dev/null
+++ b/bess-upf/templates/service-upf.yaml
@@ -0,0 +1,55 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: upf
+  labels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+{{- with .Values.service.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+{{- end }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if .Values.service.externalIp }}
+  externalIPs:
+    - {{ .Values.service.externalIp }}
+{{- end }}
+  selector:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+  ports:
+  - name: pfcp
+    protocol: UDP
+    port: 8805
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: upf-http
+  labels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+{{- with .Values.service.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+{{- end }}
+spec:
+  type: {{ .Values.service.type }}
+{{- if .Values.service.externalIp }}
+  externalIPs:
+    - {{ .Values.service.externalIp }}
+{{- end }}
+  selector:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+  ports:
+  - name: bess-web
+    protocol: TCP
+    port: 8000
+  - name: prometheus-exporter
+    protocol: TCP
+    port: 8080
diff --git a/bess-upf/templates/servicemonitor-upf.yaml b/bess-upf/templates/servicemonitor-upf.yaml
new file mode 100644
index 0000000..14c2a3b
--- /dev/null
+++ b/bess-upf/templates/servicemonitor-upf.yaml
@@ -0,0 +1,19 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+{{- if .Values.servicemonitor.enabled }}
+---
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: upf
+spec:
+  endpoints:
+  - path: /metrics
+    port: prometheus-exporter
+  selector:
+    matchLabels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 6 }}
+{{- end }}
diff --git a/bess-upf/templates/statefulset-upf.yaml b/bess-upf/templates/statefulset-upf.yaml
new file mode 100644
index 0000000..8816359
--- /dev/null
+++ b/bess-upf/templates/statefulset-upf.yaml
@@ -0,0 +1,236 @@
+{{/*
+# Copyright 2020-present Open Networking Foundation
+
+# SPDX-License-Identifier: Apache-2.0
+*/}}
+
+{{- $upfConfig := index .Values.config.upf.cfgFiles "upf.json" }}
+{{- $accessConfig := index $upfConfig "access" }}
+{{- $coreConfig := index $upfConfig "core" }}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: upf
+  labels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 4 }}
+spec:
+  replicas: 1
+  serviceName: upf-headless
+  selector:
+    matchLabels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 6 }}
+  template:
+    metadata:
+      labels:
+{{ tuple "upf" . | include "omec-user-plane.metadata_labels" | indent 8 }}
+      annotations:
+        k8s.v1.cni.cncf.io/networks: '[
+          {
+            "name": "access-net",
+            "interface": {{ index $accessConfig "ifname" | quote }},
+          {{- if hasKey .Values.config.upf.access "mac" }}
+            "mac": {{ .Values.config.upf.access.mac | quote }},
+          {{- end }}
+            "ips": [{{ .Values.config.upf.access.ip | quote }}]
+          },
+          {
+            "name": "core-net",
+            "interface": {{ index $coreConfig "ifname" | quote }},
+          {{- if hasKey .Values.config.upf.core "mac" }}
+            "mac": {{ .Values.config.upf.core.mac | quote }},
+          {{- end }}
+            "ips": [{{ .Values.config.upf.core.ip | quote }}]
+          }
+        ]'
+    spec:
+      shareProcessNamespace: true
+    {{- if .Values.nodeSelectors.enabled }}
+      nodeSelector:
+        {{ .Values.nodeSelectors.upf.label }}: {{ .Values.nodeSelectors.upf.value }}
+    {{- end }}
+    {{- if hasKey .Values.images "pullSecrets" }}
+      imagePullSecrets:
+{{ toYaml .Values.images.pullSecrets | indent 8 }}
+    {{- end }}
+      initContainers:
+      - name: bess-init
+        image: {{ .Values.images.tags.bess | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        command: ["sh", "-xec"]
+        args:
+        - ip route replace {{ .Values.config.upf.enb.subnet }} via {{ .Values.config.upf.access.gateway }};
+          ip route replace default via {{ .Values.config.upf.core.gateway }} metric 110;
+          iptables -I OUTPUT -p icmp --icmp-type port-unreachable -j DROP;
+        securityContext:
+          capabilities:
+            add:
+            - NET_ADMIN
+        resources:
+          limits:
+            cpu: 128m
+            memory: 64Mi
+          requests:
+            cpu: 128m
+            memory: 64Mi
+    {{- if .Values.config.coreDump.enabled }}
+{{ tuple "upf" . | include "omec-user-plane.coredump_init" | indent 6 }}
+    {{- end }}
+      containers:
+      - name: bessd
+        image: {{ .Values.images.tags.bess | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        securityContext:
+        {{- if .Values.config.upf.privileged }}
+          privileged: true
+        {{- end }}
+          capabilities:
+            add:
+            - IPC_LOCK
+        stdin: true
+        tty: true
+        command: ["/bin/bash", "-xc"]
+        args:
+        {{- if .Values.config.upf.hugepage.enabled }}
+          - bessd -f -grpc-url=0.0.0.0:10514
+        {{- else }}
+          - bessd -m 0 -f -grpc-url=0.0.0.0:10514
+        {{- end }}
+        lifecycle:
+          postStart:
+            exec:
+              command: ["/etc/bess/conf/bessd-poststart.sh"]
+        livenessProbe:
+          tcpSocket:
+            port: 10514
+          initialDelaySeconds: 15
+          periodSeconds: 20
+        resources:
+          requests:
+          {{- if .Values.resources.enabled }}
+{{ toYaml .Values.resources.bess.requests | indent 12 }}
+          {{- end }}
+          {{- if .Values.config.upf.hugepage.enabled }}
+            hugepages-1Gi: 2Gi
+          {{- end }}
+          {{- if .Values.config.upf.sriov.enabled }}
+          {{- if eq .Values.config.upf.access.resourceName .Values.config.upf.core.resourceName }}
+            {{ .Values.config.upf.access.resourceName }}: 2
+          {{- else }}
+            {{ .Values.config.upf.access.resourceName }}: 1
+            {{ .Values.config.upf.core.resourceName }}: 1
+          {{- end }}
+          {{- end }}
+          limits:
+          {{- if .Values.resources.enabled }}
+{{ toYaml .Values.resources.bess.limits | indent 12 }}
+          {{- end }}
+          {{- if .Values.config.upf.hugepage.enabled }}
+            hugepages-1Gi: 2Gi
+          {{- end }}
+          {{- if .Values.config.upf.sriov.enabled }}
+          {{- if eq .Values.config.upf.access.resourceName .Values.config.upf.core.resourceName }}
+            {{ .Values.config.upf.access.resourceName }}: 2
+          {{- else }}
+            {{ .Values.config.upf.access.resourceName }}: 1
+            {{ .Values.config.upf.core.resourceName }}: 1
+          {{- end }}
+          {{- end }}
+        env:
+          - name: CONF_FILE
+            value: /etc/bess/conf/upf.json
+        volumeMounts:
+          - name: shared-app
+            mountPath: /pod-share
+        {{- if .Values.config.upf.hugepage.enabled }}
+          - name: hugepages
+            mountPath: /dev/hugepages
+        {{- end }}
+          - name: configs
+            mountPath: /etc/bess/conf
+        {{- if .Values.config.coreDump.enabled }}
+          - name: coredump
+            mountPath: /tmp/coredump
+        {{- end }}
+      - name: routectl
+        image: {{ .Values.images.tags.bess | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        env:
+          - name: PYTHONUNBUFFERED
+            value: "1"
+        command: ["/opt/bess/bessctl/conf/route_control.py"]
+        args:
+          - -i
+          - {{ index $accessConfig "ifname" }}
+          - {{ index $coreConfig "ifname" }}
+      {{- if .Values.resources.enabled }}
+        resources:
+{{ toYaml .Values.resources.routectl | indent 10 }}
+      {{- end }}
+      - name: web
+        image: {{ .Values.images.tags.bess | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        command: ["/bin/bash", "-xc", "bessctl http 0.0.0.0 8000"]
+      {{- if .Values.resources.enabled }}
+        resources:
+{{ toYaml .Values.resources.web | indent 10 }}
+      {{- end }}
+      - name: pfcp-agent
+        image: {{ .Values.images.tags.pfcpiface | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        command: ["pfcpiface"]
+        args:
+          - -config
+          - /tmp/conf/upf.json
+      {{- if .Values.resources.enabled }}
+        resources:
+{{ toYaml .Values.resources.cpiface | indent 10 }}
+      {{- end }}
+        volumeMounts:
+          - name: shared-app
+            mountPath: /pod-share
+          - name: configs
+            mountPath: /tmp/conf
+    {{- if .Values.config.gratuitousArp.enabled }}
+      - name: arping
+        image: {{ .Values.images.tags.tools | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        command: ["sh", "-xc"]
+        args:
+          - |
+            while true; do
+              # arping does not work - BESS graph is still disconnected
+              #arping -c 2 -I {{ index $accessConfig "ifname" }} {{ .Values.config.upf.access.gateway }}
+              #arping -c 2 -I {{ index $coreConfig "ifname" }} {{ .Values.config.upf.core.gateway }}
+              ping -c 2 {{ .Values.config.upf.access.gateway }}
+              ping -c 2 {{ .Values.config.upf.core.gateway }}
+              sleep {{ .Values.config.gratuitousArp.interval }}
+            done
+        resources:
+          limits:
+            cpu: 128m
+            memory: 64Mi
+          requests:
+            cpu: 128m
+            memory: 64Mi
+    {{- end }}
+      volumes:
+      - name: configs
+        configMap:
+          name: upf
+          defaultMode: 493
+      - name: shared-app
+        emptyDir: {}
+    {{- if .Values.config.upf.hugepage.enabled }}
+      - name: hugepages
+        emptyDir:
+          medium: HugePages
+    {{- end }}
+    {{- if .Values.config.coreDump.enabled }}
+      - name: host-rootfs
+        hostPath:
+          path: /
+      - name: coredump
+        hostPath:
+          path: {{ .Values.config.coreDump.path }}
+    {{- end }}
diff --git a/bess-upf/values.yaml b/bess-upf/values.yaml
new file mode 100644
index 0000000..764a025
--- /dev/null
+++ b/bess-upf/values.yaml
@@ -0,0 +1,134 @@
+# Copyright 2020-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+images:
+  tags:
+    bess: "registry.aetherproject.org/proxy/omecproject/upf-epc-bess:master-ada6849"
+    pfcpiface: "registry.aetherproject.org/proxy/omecproject/upf-epc-pfcpiface:master-ada6849"
+    tools: registry.aetherproject.org/tools/busybox:stable
+  pullPolicy: IfNotPresent
+  # Secrets must be manually created in the namespace.
+  pullSecrets:
+    - name: aether.registry
+
+nodeSelectors:
+  enabled: false
+  upf:
+    label: node-role.aetherproject.org
+    value: omec-upf
+
+resources:
+  enabled: true
+  bess:
+    requests:
+      cpu: 2
+      memory: 512Mi
+    limits:
+      cpu: 2
+      memory: 512Mi
+  routectl:
+    requests:
+      cpu: 256m
+      memory: 128Mi
+    limits:
+      cpu: 256m
+      memory: 128Mi
+  web:
+    requests:
+      cpu: 256m
+      memory: 128Mi
+    limits:
+      cpu: 256m
+      memory: 128Mi
+  cpiface:
+    requests:
+      cpu: 256m
+      memory: 128Mi
+    limits:
+      cpu: 256m
+      memory: 128Mi
+
+config:
+  coreDump:
+    enabled: false
+    path: /tmp/coredump
+  gratuitousArp:
+    enabled: true
+    interval: 10 # seconds
+  upf:
+    # Enable privileged when run from VM with sriov support
+    privileged: false
+    hugepage:
+      enabled: true
+    sriov:
+      enabled: true
+    # Dynamic IP allocation is not supported yet
+    ipam: static
+    cniPlugin: vfioveth
+    enb:
+      subnet: 192.168.251.0/24
+    access:
+      # Provide sriov resource name when sriov is enabled
+      resourceName: "intel.com/intel_sriov_vfio"
+      gateway: 192.168.252.1
+      ip: 192.168.252.3/24
+      #mac:
+      #vlan:
+      #iface:
+    core:
+      # Provide sriov resource name when sriov is enabled
+      resourceName: "intel.com/intel_sriov_vfio"
+      gateway: 192.168.250.1
+      ip: 192.168.250.3/24
+      #mac:
+      #vlan:
+      #iface:
+    cfgFiles:
+      upf.json:
+        mode: dpdk
+        workers: 1
+        max_sessions: 50000
+        table_sizes:
+          pdrLookup: 50000
+          appQERLookup: 200000
+          sessionQERLookup: 100000
+          farLookup: 150000
+        access:
+          ifname: access
+        core:
+          ifname: core
+        measure_upf: true
+        measure_flow: true
+        enable_notify_bess: true
+        notify_sockaddr: "/pod-share/notifycp"
+        cpiface:
+          dnn: "internet"
+          hostname: "upf"
+          http_port: "8080"
+        # Default global rate limits. Can be changed at runtime via BESS gRPC.
+        slice_rate_limit_config:
+          # Uplink
+          n6_bps: 1000000000 # 1Gbps
+          n6_burst_bytes: 12500000 # 10ms * 1Gbps
+          # Downlink
+          n3_bps: 1000000000 # 1Gbps
+          n3_burst_bytes: 12500000 # 10ms * 1Gbps
+        qci_qos_config:
+          - qci: 0 # Fallback QCI
+            cbs: 50000
+            ebs: 50000
+            pbs: 50000
+            burst_duration_ms: 10
+            priority: 7
+
+service:
+  type: ClusterIP
+  #externalIp:
+  #annotations:
+
+servicemonitor:
+  enabled: false
+
+podsecuritypolicy:
+  enabled: false
diff --git a/sdfabric/Chart.yaml b/sdfabric/Chart.yaml
index 96db8f4..c739aed 100644
--- a/sdfabric/Chart.yaml
+++ b/sdfabric/Chart.yaml
@@ -45,3 +45,7 @@
     repository: file://../di-metrics-exporter
     version: 0.0.2
     condition: import.di-metrics-exporter.enabled
+  - name: bess-upf
+    repository: file://../bess-upf
+    version: 0.0.1
+    condition: import.bess-upf.enabled
diff --git a/sdfabric/values.yaml b/sdfabric/values.yaml
index 70bd262..9aceb28 100644
--- a/sdfabric/values.yaml
+++ b/sdfabric/values.yaml
@@ -17,6 +17,10 @@
     enabled: false
   di-metrics-exporter:
     enabled: false
+  bess-upf:
+    enabled: false
+  bess-upf-cni:
+    enabled: false
 
 onos-classic:
   java_opts: -Xmx4G -Dlog4j2.formatMsgNoLookups=true -XX:+UnlockExperimentalVMOptions -XX:+UseZGC