summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/frr/patches/0002-zebra-Fixes-for-connected-routes.patch176
-rw-r--r--packages/frr/patches/0003-Fix-as-override-behavior.patch77
-rw-r--r--packages/keepalived/debian/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch129
-rw-r--r--packages/keepalived/debian/patches/series1
-rw-r--r--packages/keepalived/debian/source/format1
-rw-r--r--packages/linux-kernel/Jenkinsfile32
-rwxr-xr-xpackages/linux-kernel/build-driver-realtek-r8152.py113
-rwxr-xr-xpackages/linux-kernel/build-intel-ice.py75
-rwxr-xr-xpackages/linux-kernel/build-intel-qat.sh196
-rwxr-xr-xpackages/linux-kernel/build-linux-firmware.sh40
-rw-r--r--packages/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch22
-rw-r--r--packages/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch12
-rw-r--r--packages/linux-kernel/patches/kernel/0004-revert-net-sched-retire-tcindex-classifier.patch786
-rw-r--r--packages/linux-kernel/patches/vyos-drivers-realtek-r8152/0001-Fixed-compatibility-with-kernel-5.4.254.patch27
-rw-r--r--packages/linux-kernel/x86_64_vyos_defconfig6
-rw-r--r--packages/ocserv/Jenkinsfile4
16 files changed, 1578 insertions, 119 deletions
diff --git a/packages/frr/patches/0002-zebra-Fixes-for-connected-routes.patch b/packages/frr/patches/0002-zebra-Fixes-for-connected-routes.patch
new file mode 100644
index 00000000..6287e071
--- /dev/null
+++ b/packages/frr/patches/0002-zebra-Fixes-for-connected-routes.patch
@@ -0,0 +1,176 @@
+From 18b1c3c06eb69c8d10666c40f55be4926f888042 Mon Sep 17 00:00:00 2001
+From: zsdc <taras@vyos.io>
+Date: Wed, 24 May 2023 20:43:27 +0300
+Subject: [PATCH] zebra: Fixes for connected routes
+
+This is a cumulative backport of:
+92980561382fc04380414a6e2f6ca6746c2fe5e9
+7fb9825cf7e762add68f5108df4eddda1247f198
+e3d901f8638dec32eac4c2690912138963ae5a05
+---
+ lib/if.h | 3 ++
+ zebra/connected.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 75 insertions(+), 1 deletion(-)
+
+diff --git a/lib/if.h b/lib/if.h
+index a2a40d095..0c73ab63a 100644
+--- a/lib/if.h
++++ b/lib/if.h
+@@ -393,6 +393,7 @@ struct connected {
+ #define ZEBRA_IFC_REAL (1 << 0)
+ #define ZEBRA_IFC_CONFIGURED (1 << 1)
+ #define ZEBRA_IFC_QUEUED (1 << 2)
++#define ZEBRA_IFC_DOWN (1 << 3)
+ /*
+ The ZEBRA_IFC_REAL flag should be set if and only if this address
+ exists in the kernel and is actually usable. (A case where it exists
+@@ -406,6 +407,8 @@ struct connected {
+ in the kernel. It may and should be set although the address might
+ not be
+ usable yet. (compare with ZEBRA_IFC_REAL)
++ The ZEBRA_IFC_DOWN flag is used to record that an address is
++ present, but down/unavailable.
+ */
+
+ /* Flags for connected address. */
+diff --git a/zebra/connected.c b/zebra/connected.c
+index 8c4ba163b..fd3fefdd2 100644
+--- a/zebra/connected.c
++++ b/zebra/connected.c
+@@ -207,6 +207,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
+ };
+ struct zebra_vrf *zvrf;
+ uint32_t metric;
++ uint32_t count = 0;
++ struct listnode *cnode;
++ struct connected *c;
+
+ zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
+ if (!zvrf) {
+@@ -219,6 +222,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
+ if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
+ return;
+
++ /* Ensure 'down' flag is cleared */
++ UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
++
+ PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
+
+ /* Apply mask to the network. */
+@@ -251,6 +257,29 @@ void connected_up(struct interface *ifp, struct connected *ifc)
+
+ metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
+ ifc->metric : ifp->metric;
++
++ /*
++ * It's possible to add the same network and mask
++ * to an interface over and over. This would
++ * result in an equivalent number of connected
++ * routes. Just add one connected route in
++ * for all the addresses on an interface that
++ * resolve to the same network and mask
++ */
++ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
++ struct prefix cp;
++
++ PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
++ apply_mask(&cp);
++
++ if (prefix_same(&cp, &p) &&
++ !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
++ count++;
++
++ if (count >= 2)
++ return;
++ }
++
+ rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
+ 0, 0, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
+
+@@ -290,6 +319,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
+ /* If we get a notification from the kernel,
+ * we can safely assume the address is known to the kernel */
+ SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
++ if (!if_is_operative(ifp))
++ SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
+
+ /* Allocate new connected address. */
+ p = prefix_ipv4_new();
+@@ -350,12 +381,15 @@ void connected_down(struct interface *ifp, struct connected *ifc)
+ .vrf_id = ifp->vrf_id,
+ };
+ struct zebra_vrf *zvrf;
++ uint32_t count = 0;
++ struct listnode *cnode;
++ struct connected *c;
+
+ zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
+ if (!zvrf) {
+ flog_err(
+ EC_ZEBRA_VRF_NOT_FOUND,
+- "%s: Received Up for interface but no associated zvrf: %d",
++ "%s: Received Down for interface but no associated zvrf: %d",
+ __func__, ifp->vrf_id);
+ return;
+ }
+@@ -363,6 +397,17 @@ void connected_down(struct interface *ifp, struct connected *ifc)
+ if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
+ return;
+
++ /* Skip if we've already done this; this can happen if we have a
++ * config change that takes an interface down, then we receive kernel
++ * notifications about the downed interface and its addresses.
++ */
++ if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_DOWN)) {
++ if (IS_ZEBRA_DEBUG_RIB)
++ zlog_debug("%s: ifc %p, %pFX already DOWN",
++ __func__, ifc, ifc->address);
++ return;
++ }
++
+ PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
+
+ /* Apply mask to the network. */
+@@ -388,6 +433,30 @@ void connected_down(struct interface *ifp, struct connected *ifc)
+ break;
+ }
+
++ /* Mark the address as 'down' */
++ SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
++
++ /*
++ * It's possible to have X number of addresses
++ * on a interface that all resolve to the same
++ * network and mask. Find them and just
++ * allow the deletion when are removing the last
++ * one.
++ */
++ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
++ struct prefix cp;
++
++ PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
++ apply_mask(&cp);
++
++ if (prefix_same(&p, &cp) &&
++ !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
++ count++;
++
++ if (count >= 1)
++ return;
++ }
++
+ /*
+ * Same logic as for connected_up(): push the changes into the
+ * head.
+@@ -481,6 +550,8 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
+ /* If we get a notification from the kernel,
+ * we can safely assume the address is known to the kernel */
+ SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
++ if (!if_is_operative(ifp))
++ SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
+
+ /* Allocate new connected address. */
+ p = prefix_ipv6_new();
+--
+2.34.1
+
diff --git a/packages/frr/patches/0003-Fix-as-override-behavior.patch b/packages/frr/patches/0003-Fix-as-override-behavior.patch
new file mode 100644
index 00000000..e13ac3a7
--- /dev/null
+++ b/packages/frr/patches/0003-Fix-as-override-behavior.patch
@@ -0,0 +1,77 @@
+From 6320d4941777d317989209f26ca513379f729c30 Mon Sep 17 00:00:00 2001
+From: zsdc <taras@vyos.io>
+Date: Fri, 12 May 2023 13:56:20 +0300
+Subject: [PATCH] Fix as-override behavior
+
+Backported 9bbdb4572d3bb255211fecf1c756452ab27e91c2 from FRR 8.5
+---
+ bgpd/bgp_aspath.c | 22 ----------------------
+ bgpd/bgp_aspath.h | 1 -
+ bgpd/bgp_route.c | 4 +---
+ 3 files changed, 1 insertion(+), 26 deletions(-)
+
+diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
+index 5cf3c60fa..9595bae5f 100644
+--- a/bgpd/bgp_aspath.c
++++ b/bgpd/bgp_aspath.c
+@@ -1215,28 +1215,6 @@ bool aspath_private_as_check(struct aspath *aspath)
+ return true;
+ }
+
+-/* Return True if the entire ASPATH consist of the specified ASN */
+-bool aspath_single_asn_check(struct aspath *aspath, as_t asn)
+-{
+- struct assegment *seg;
+-
+- if (!(aspath && aspath->segments))
+- return false;
+-
+- seg = aspath->segments;
+-
+- while (seg) {
+- int i;
+-
+- for (i = 0; i < seg->length; i++) {
+- if (seg->as[i] != asn)
+- return false;
+- }
+- seg = seg->next;
+- }
+- return true;
+-}
+-
+ /* Replace all instances of the target ASN with our own ASN */
+ struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
+ as_t target_asn, as_t our_asn)
+diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
+index 9df352fcd..9bab5bb7b 100644
+--- a/bgpd/bgp_aspath.h
++++ b/bgpd/bgp_aspath.h
+@@ -108,7 +108,6 @@ extern unsigned int aspath_get_first_as(struct aspath *);
+ extern unsigned int aspath_get_last_as(struct aspath *);
+ extern int aspath_loop_check(struct aspath *, as_t);
+ extern bool aspath_private_as_check(struct aspath *);
+-extern bool aspath_single_asn_check(struct aspath *, as_t asn);
+ extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
+ as_t target_asn,
+ as_t our_asn);
+diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
+index 48ccb669b..6de3e2a7f 100644
+--- a/bgpd/bgp_route.c
++++ b/bgpd/bgp_route.c
+@@ -1571,11 +1571,9 @@ static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
+ struct peer *peer, struct attr *attr)
+ {
+ if (peer->sort == BGP_PEER_EBGP
+- && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
+- if (aspath_single_asn_check(attr->aspath, peer->as))
++ && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE))
+ attr->aspath = aspath_replace_specific_asn(
+ attr->aspath, peer->as, bgp->as);
+- }
+ }
+
+ void bgp_attr_add_gshut_community(struct attr *attr)
+--
+2.34.1
+
diff --git a/packages/keepalived/debian/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch b/packages/keepalived/debian/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch
new file mode 100644
index 00000000..b099dc7b
--- /dev/null
+++ b/packages/keepalived/debian/patches/0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch
@@ -0,0 +1,129 @@
+From af4aa758c3512bec8233549e138b03741c5404f9 Mon Sep 17 00:00:00 2001
+From: Quentin Armitage <quentin@armitage.org.uk>
+Date: Sat, 14 Oct 2023 15:37:19 +0100
+Subject: [PATCH] vrrp: Set sysctl arp_ignore to 1 on IPv6 VMACs
+
+Setting arp_ignore to 1 ensures that the VMAC interface does not respond
+to ARP requests for IPv4 addresses not configured on the VMAC.
+
+Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
+---
+ keepalived/include/vrrp_if_config.h | 2 +-
+ keepalived/vrrp/vrrp_if_config.c | 28 ++++++++++++++++++++--------
+ keepalived/vrrp/vrrp_vmac.c | 5 ++---
+ 3 files changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/keepalived/include/vrrp_if_config.h b/keepalived/include/vrrp_if_config.h
+index 35465cd..c35e56e 100644
+--- a/keepalived/include/vrrp_if_config.h
++++ b/keepalived/include/vrrp_if_config.h
+@@ -34,7 +34,7 @@ extern void set_promote_secondaries(interface_t*);
+ extern void reset_promote_secondaries(interface_t*);
+ #ifdef _HAVE_VRRP_VMAC_
+ extern void restore_rp_filter(void);
+-extern void set_interface_parameters(const interface_t*, interface_t*);
++extern void set_interface_parameters(const interface_t*, interface_t*, sa_family_t);
+ extern void reset_interface_parameters(interface_t*);
+ extern void link_set_ipv6(const interface_t*, bool);
+ #endif
+diff --git a/keepalived/vrrp/vrrp_if_config.c b/keepalived/vrrp/vrrp_if_config.c
+index cfce7e2..fbfd34c 100644
+--- a/keepalived/vrrp/vrrp_if_config.c
++++ b/keepalived/vrrp/vrrp_if_config.c
+@@ -81,6 +81,11 @@ static sysctl_opts_t vmac_sysctl[] = {
+ { 0, 0}
+ };
+
++static sysctl_opts_t vmac_sysctl_6[] = {
++ { IPV4_DEVCONF_ARP_IGNORE, 1 },
++ { 0, 0}
++};
++
+ #endif
+ #endif
+
+@@ -216,11 +221,14 @@ netlink_set_interface_flags(unsigned ifindex, const sysctl_opts_t *sys_opts)
+
+ #ifdef _HAVE_VRRP_VMAC_
+ static inline int
+-netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
++netlink_set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
+ {
+- if (netlink_set_interface_flags(ifp->ifindex, vmac_sysctl))
++ if (netlink_set_interface_flags(ifp->ifindex, family == AF_INET6 ? vmac_sysctl_6 : vmac_sysctl))
+ return -1;
+
++ if (family == AF_INET6)
++ return 0;
++
+ /* If the underlying interface is a MACVLAN that has been moved into
+ * a separate network namespace from the parent, we can't access the
+ * parent. */
+@@ -271,9 +279,9 @@ netlink_reset_interface_parameters(const interface_t* ifp)
+ }
+
+ static inline void
+-set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp)
++set_interface_parameters_devconf(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
+ {
+- if (netlink_set_interface_parameters(ifp, base_ifp))
++ if (netlink_set_interface_parameters(ifp, base_ifp, family))
+ log_message(LOG_INFO, "Unable to set parameters for %s", ifp->ifname);
+ }
+
+@@ -310,11 +318,15 @@ reset_promote_secondaries_devconf(interface_t *ifp)
+
+ #ifdef _HAVE_VRRP_VMAC_
+ static inline void
+-set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp)
++set_interface_parameters_sysctl(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
+ {
+ unsigned val;
+
+ set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 1);
++
++ if (family == AF_INET6)
++ return;
++
+ set_sysctl("net/ipv4/conf", ifp->ifname, "accept_local", 1);
+ set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0);
+
+@@ -524,15 +536,15 @@ restore_rp_filter(void)
+ }
+
+ void
+-set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
++set_interface_parameters(const interface_t *ifp, interface_t *base_ifp, sa_family_t family)
+ {
+ if (all_rp_filter == UINT_MAX)
+ clear_rp_filter();
+
+ #ifdef _HAVE_IPV4_DEVCONF_
+- set_interface_parameters_devconf(ifp, base_ifp);
++ set_interface_parameters_devconf(ifp, base_ifp, family);
+ #else
+- set_interface_parameters_sysctl(ifp, base_ifp);
++ set_interface_parameters_sysctl(ifp, base_ifp, family);
+ #endif
+ }
+
+diff --git a/keepalived/vrrp/vrrp_vmac.c b/keepalived/vrrp/vrrp_vmac.c
+index e5ff0e9..021953a 100644
+--- a/keepalived/vrrp/vrrp_vmac.c
++++ b/keepalived/vrrp/vrrp_vmac.c
+@@ -407,10 +407,9 @@ netlink_link_add_vmac(vrrp_t *vrrp, const interface_t *old_interface)
+ if (!ifp->ifindex)
+ return false;
+
+- if (vrrp->family == AF_INET && create_interface) {
++ if (create_interface) {
+ /* Set the necessary kernel parameters to make macvlans work for us */
+-// If this saves current base_ifp's settings, we need to be careful if multiple VMACs on same i/f
+- set_interface_parameters(ifp, ifp->base_ifp);
++ set_interface_parameters(ifp, ifp->base_ifp, vrrp->family);
+ }
+
+ #ifdef _WITH_FIREWALL_
+--
+2.34.1
+
diff --git a/packages/keepalived/debian/patches/series b/packages/keepalived/debian/patches/series
new file mode 100644
index 00000000..3504d7fa
--- /dev/null
+++ b/packages/keepalived/debian/patches/series
@@ -0,0 +1 @@
+0001-vrrp-Set-sysctl-arp_ignore-to-1-on-IPv6-VMACs.patch
diff --git a/packages/keepalived/debian/source/format b/packages/keepalived/debian/source/format
new file mode 100644
index 00000000..163aaf8d
--- /dev/null
+++ b/packages/keepalived/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/packages/linux-kernel/Jenkinsfile b/packages/linux-kernel/Jenkinsfile
index 75fb99fb..7825ce9d 100644
--- a/packages/linux-kernel/Jenkinsfile
+++ b/packages/linux-kernel/Jenkinsfile
@@ -236,6 +236,38 @@ pipeline {
}
}
}
+ stage('Intel ICE driver') {
+ when {
+ beforeOptions true
+ beforeAgent true
+ anyOf {
+ changeset pattern: "**/packages/linux-kernel/*"
+ changeset pattern: "**/data/defaults.json"
+ triggeredBy cause: "UserIdCause"
+ }
+ }
+ steps {
+ dir(env.BASE_DIR) {
+ sh "./build-intel-ice.py"
+ }
+ }
+ }
+ stage('Realtek r8152 driver') {
+ when {
+ beforeOptions true
+ beforeAgent true
+ anyOf {
+ changeset pattern: "**/packages/linux-kernel/*"
+ changeset pattern: "**/data/defaults.json"
+ triggeredBy cause: "UserIdCause"
+ }
+ }
+ steps {
+ dir(env.BASE_DIR) {
+ sh "./build-driver-realtek-r8152.py"
+ }
+ }
+ }
}
}
// This stage should not be run in the parallel section as it will call "make"
diff --git a/packages/linux-kernel/build-driver-realtek-r8152.py b/packages/linux-kernel/build-driver-realtek-r8152.py
new file mode 100755
index 00000000..3200bd9e
--- /dev/null
+++ b/packages/linux-kernel/build-driver-realtek-r8152.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+
+from json import loads as json_loads
+from requests import get
+from pathlib import Path
+from shutil import copy as copy_file
+from subprocess import run
+
+
+# dependency modifier
+def add_depends(package_dir: str, package_name: str, depends) -> None:
+ """Add dependencies to a package
+
+ Args:
+ package_dir (str): a directory where package sources are located
+ package_name (str): a name of package
+ depends (list[str]): a list of dependencies to add
+ """
+ depends_list: str = ', '.join(depends)
+ depends_line: str = f'misc:Depends={depends_list}\n'
+
+ substvars_file = Path(f'{package_dir}/debian/{package_name}.substvars')
+ substvars_file.write_text(depends_line)
+
+
+# copy patches
+def apply_deb_patches(package_name: str, sources_dir: str):
+ """Apply patches to sources directory
+
+ Args:
+ package_name (str): package name
+ sources_dir (str): sources dir
+ """
+ patches_dir = Path(f'patches/{package_name}')
+ if patches_dir.exists():
+ patches_list = list(patches_dir.iterdir())
+ patches_list.sort()
+ series_file = Path(f'{sources_dir}/debian/patches/series')
+ series_data = ''
+ for patch_file in patches_list:
+ print(f'Applying patch: {patch_file.name}')
+ copy_file(patch_file, f'{sources_dir}/debian/patches/')
+ if series_file.exists():
+ series_data = series_file.read_text()
+ series_data = f'{series_data}\n{patch_file.name}'
+ series_file.write_text(series_data)
+
+
+# find kernel version and source path
+defaults_file: str = Path('../../data/defaults.json').read_text()
+KERNEL_VER: str = json_loads(defaults_file).get('kernel_version')
+KERNEL_FLAVOR: str = json_loads(defaults_file).get('kernel_flavor')
+KERNEL_SRC: str = Path.cwd().as_posix() + '/linux'
+
+# define variables
+PACKAGE_NAME: str = 'vyos-drivers-realtek-r8152'
+PACKAGE_VERSION: str = '2.17.1'
+PACKAGE_DIR: str = f'{PACKAGE_NAME}-{PACKAGE_VERSION}'
+SOURCES_ARCHIVE: str = 'r8152-2.17.1.tar.bz2'
+SOURCES_URL: str = f'https://dev.packages.vyos.net/source-mirror/{SOURCES_ARCHIVE}'
+
+# download sources
+sources_archive = Path(SOURCES_ARCHIVE)
+sources_archive.write_bytes(get(SOURCES_URL).content)
+
+# prepare sources
+debmake_cmd = [
+ 'debmake', '-e', 'support@vyos.io', '-f', 'VyOS Support', '-p',
+ PACKAGE_NAME, '-u', PACKAGE_VERSION, '-a', SOURCES_ARCHIVE
+]
+run(debmake_cmd)
+
+# add kernel to dependencies
+add_depends(PACKAGE_DIR, PACKAGE_NAME,
+ [f'linux-image-{KERNEL_VER}-{KERNEL_FLAVOR}'])
+
+# configure build rules
+build_rules_text: str = f'''#!/usr/bin/make -f
+# config
+export KERNELDIR := {KERNEL_SRC}
+PACKAGE_BUILD_DIR := debian/{PACKAGE_NAME}
+KVER := {KERNEL_VER}-{KERNEL_FLAVOR}
+MODULES_DIR := updates/drivers/net/usb
+
+# main packaging script based on dh7 syntax
+%:
+ dh $@
+
+override_dh_clean:
+ dh_clean --exclude=debian/{PACKAGE_NAME}.substvars
+
+override_dh_prep:
+ dh_prep --exclude=debian/{PACKAGE_NAME}.substvars
+
+override_dh_auto_clean:
+ make clean
+
+override_dh_auto_build:
+ make modules
+
+override_dh_auto_install:
+ install -D -m 644 r8152.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/r8152.ko
+ install -D -m 644 50-usb-realtek-net.rules ${{PACKAGE_BUILD_DIR}}/etc/udev/rules.d/50-usb-realtek-net.rules
+'''
+bild_rules = Path(f'{PACKAGE_DIR}/debian/rules')
+bild_rules.write_text(build_rules_text)
+
+# apply patches
+apply_deb_patches(PACKAGE_NAME, PACKAGE_DIR)
+
+# build a package
+debuild_cmd = ['debuild']
+run(debuild_cmd, cwd=PACKAGE_DIR)
diff --git a/packages/linux-kernel/build-intel-ice.py b/packages/linux-kernel/build-intel-ice.py
new file mode 100755
index 00000000..03d83764
--- /dev/null
+++ b/packages/linux-kernel/build-intel-ice.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+
+from json import loads as json_loads
+from requests import get
+from pathlib import Path
+from subprocess import run
+
+# define variables
+DRIVER_VERSION: str = '1.11.14'
+DRIVER_URL: str = f'https://downloads.sourceforge.net/project/e1000/ice%20stable/{DRIVER_VERSION}/ice-{DRIVER_VERSION}.tar.gz'
+DRIVER_ARCHIVE: str = f'ice-{DRIVER_VERSION}.tar.gz'
+DRIVER_DIR: str = f'vyos-drivers-intel-ice-{DRIVER_VERSION}'
+
+# find kernel version ans source path
+default_file: str = Path('../../data/defaults.json').read_text()
+KERNEL_VER: str = json_loads(default_file).get('kernel_version')
+KERNEL_SRC: str = Path.cwd().as_posix() + '/linux'
+
+# download driver
+driver_archive = Path(DRIVER_ARCHIVE)
+driver_archive.write_bytes(get(DRIVER_URL).content)
+
+# prepare sources
+debmake_cmd = [
+ 'debmake', '-e', 'support@vyos.io', '-f', 'VyOS Support', '-p',
+ 'vyos-drivers-intel-ice', '-a', DRIVER_ARCHIVE
+]
+run(debmake_cmd)
+
+# fix build rules
+build_rules_text = f'''#!/usr/bin/make -f
+# config
+export KSRC := {KERNEL_SRC}
+INSTALL_DIR := debian/vyos-drivers-intel-ice
+DRIVER := ice
+KVER := {KERNEL_VER}-amd64-vyos
+KSRC_INSTALL := /lib/modules/${{KVER}}/build/
+INTEL_DIR := updates/drivers/net/ethernet/intel
+# DDP variables
+DDP_PKG_ORIGIN := $(shell ls ddp/${{DRIVER}}-[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\.pkg 2>/dev/null)
+DDP_PKG_NAME := $(shell basename ${{DDP_PKG_ORIGIN}} 2>/dev/null)
+DDP_PKG_DEST_PATH := ${{INSTALL_DIR}}/lib/firmware/updates/intel/${{DRIVER}}/ddp
+DDP_PKG_DEST := ${{DDP_PKG_DEST_PATH}}/${{DDP_PKG_NAME}}
+DDP_PKG_LINK := ${{DRIVER}}.pkg
+
+# main packaging script based on dh7 syntax
+%:
+ dh $@
+
+override_dh_auto_clean:
+ cd src && \
+ make clean
+
+override_dh_auto_build:
+ cd src && sed -e 's/#define NEED_ETH_HW_ADDR_SET/#undef NEED_ETH_HW_ADDR_SET/' -i kcompat_std_defs.h && make all
+
+override_dh_auto_install:
+ # DDP
+ install -D -m 644 ${{DDP_PKG_ORIGIN}} ${{DDP_PKG_DEST}}
+ (cd ${{DDP_PKG_DEST_PATH}} && ln -sf ${{DDP_PKG_NAME}} ${{DDP_PKG_LINK}})
+ install -D -m 644 ddp/LICENSE ${{DDP_PKG_DEST_PATH}}/LICENSE
+ # module
+ install -D -m 644 src/${{DRIVER}}.ko ${{INSTALL_DIR}}/lib/modules/${{KVER}}/${{INTEL_DIR}}/ice/${{DRIVER}}.ko
+ # AUX
+ install -D -m 644 src/intel_auxiliary.ko ${{INSTALL_DIR}}/lib/modules/${{KVER}}/${{INTEL_DIR}}/auxiliary/intel_auxiliary.ko
+ install -D -m 644 src/Module.symvers ${{INSTALL_DIR}}/lib/modules/${{KVER}}/extern-symvers/intel_auxiliary.symvers
+ install -D -m 644 src/linux/auxiliary_bus.h ${{INSTALL_DIR}}/${{KSRC_INSTALL}}/include/linux/auxiliary_bus.h
+
+'''
+bild_rules = Path(f'{DRIVER_DIR}/debian/rules')
+bild_rules.write_text(build_rules_text)
+
+# build a package
+debuild_cmd = ['debuild']
+run(debuild_cmd, cwd=DRIVER_DIR)
diff --git a/packages/linux-kernel/build-intel-qat.sh b/packages/linux-kernel/build-intel-qat.sh
index 795c4526..8e48337b 100755
--- a/packages/linux-kernel/build-intel-qat.sh
+++ b/packages/linux-kernel/build-intel-qat.sh
@@ -2,6 +2,11 @@
CWD=$(pwd)
KERNEL_VAR_FILE=${CWD}/kernel-vars
+if ! dpkg-architecture -iamd64; then
+ echo "Intel-QAT is only buildable on amd64 platforms"
+ exit 0
+fi
+
if [ ! -f ${KERNEL_VAR_FILE} ]; then
echo "Kernel variable file '${KERNEL_VAR_FILE}' does not exist, run ./build_kernel.sh first"
exit 1
@@ -9,98 +14,99 @@ fi
. ${KERNEL_VAR_FILE}
-declare -a intel=(
- "https://01.org/sites/default/files/downloads/qat1.7.l.4.9.0-00008.tar_0.gz"
-)
-
-for url in "${intel[@]}"
-do
- cd ${CWD}
-
- DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/)
- DRIVER_DIR="${DRIVER_FILE%.tar.gz}"
- DRIVER_NAME="qat"
- DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_NAME} '{print $2}')
- DRIVER_VERSION_EXTRA="-0"
-
- # Build up Debian related variables required for packaging
- DEBIAN_ARCH=$(dpkg --print-architecture)
- DEBIAN_DIR="${CWD}/vyos-intel-${DRIVER_NAME}_${DRIVER_VERSION}${DRIVER_VERSION_EXTRA}_${DEBIAN_ARCH}"
- DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control"
- DEBIAN_POSTINST="${CWD}/vyos-intel-qat.postinst"
-
- # Fetch Intel driver source from SourceForge
- if [ -e ${DRIVER_FILE} ]; then
- rm -f ${DRIVER_FILE}
- fi
- curl -L -o ${DRIVER_FILE} ${url}
- if [ "$?" -ne "0" ]; then
- exit 1
- fi
-
- # Unpack archive
- if [ -d ${DRIVER_DIR} ]; then
- rm -rf ${DRIVER_DIR}
- fi
- mkdir -p ${DRIVER_DIR}
- tar -C ${DRIVER_DIR} -xf ${DRIVER_FILE}
-
- cd ${DRIVER_DIR}
- if [ -z $KERNEL_DIR ]; then
- echo "KERNEL_DIR not defined"
- exit 1
- fi
-
- echo "I: Compile Kernel module for Intel ${DRIVER_NAME} driver"
- mkdir -p ${DEBIAN_DIR}/lib/firmware ${DEBIAN_DIR}/usr/local/bin ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu ${DEBIAN_DIR}/etc/init.d
- KERNEL_SOURCE_ROOT=${KERNEL_DIR} ./configure --enable-kapi --enable-qat-lkcf
- make -j $(getconf _NPROCESSORS_ONLN) all
- make INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} \
- qat-driver-install
-
- if [ "x$?" != "x0" ]; then
- exit 1
- fi
-
- cp build/*.bin ${DEBIAN_DIR}/lib/firmware
- cp build/*.so ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu
- cp build/qat_service ${DEBIAN_DIR}/etc/init.d
- cp build/adf_ctl ${DEBIAN_DIR}/usr/local/bin
- cp build/usdm_drv.ko ${DEBIAN_DIR}/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/updates/drivers
- chmod 644 ${DEBIAN_DIR}/lib/firmware/*
- chmod 755 ${DEBIAN_DIR}/etc/init.d/* ${DEBIAN_DIR}/usr/local/bin/*
-
- if [ -f ${DEBIAN_DIR}.deb ]; then
- rm ${DEBIAN_DIR}.deb
- fi
-
- # build Debian package
- echo "I: Building Debian package vyos-intel-${DRIVER_NAME}"
- cd ${CWD}
-
- # delete non required files which are also present in the kernel package
- # und thus lead to duplicated files
- find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f
-
- echo "#!/bin/sh" > ${DEBIAN_POSTINST}
- echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST}
-
- fpm --input-type dir --output-type deb --name vyos-intel-${DRIVER_NAME} \
- --version ${DRIVER_VERSION}${DRIVER_VERSION_EXTRA} --deb-compression gz \
- --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \
- --description "Vendor based driver for Intel ${DRIVER_NAME}" \
- --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \
- --license "GPL2" -C ${DEBIAN_DIR} --after-install ${DEBIAN_POSTINST}
-
- echo "I: Cleanup ${DRIVER_NAME} source"
- cd ${CWD}
- if [ -e ${DRIVER_FILE} ]; then
- rm -f ${DRIVER_FILE}
- fi
- if [ -d ${DRIVER_DIR} ]; then
- rm -rf ${DRIVER_DIR}
- fi
- if [ -d ${DEBIAN_DIR} ]; then
- rm -rf ${DEBIAN_DIR}
- fi
-done
+url="https://dev.packages.vyos.net/source-mirror/QAT1.7.l.4.9.0-00008.tar.gz"
+
+cd ${CWD}
+
+DRIVER_FILE=$(basename ${url} | sed -e s/tar_0/tar/)
+DRIVER_DIR="${DRIVER_FILE%.tar.gz}"
+DRIVER_NAME="QAT"
+DRIVER_VERSION=$(echo ${DRIVER_DIR} | awk -F${DRIVER_NAME} '{print $2}')
+DRIVER_VERSION_EXTRA="-0"
+
+# Build up Debian related variables required for packaging
+DEBIAN_ARCH=$(dpkg --print-architecture)
+DEBIAN_DIR="${CWD}/vyos-intel-${DRIVER_NAME}_${DRIVER_VERSION}${DRIVER_VERSION_EXTRA}_${DEBIAN_ARCH}"
+DEBIAN_CONTROL="${DEBIAN_DIR}/DEBIAN/control"
+DEBIAN_POSTINST="${CWD}/vyos-intel-qat.postinst"
+
+# Fetch Intel driver source from SourceForge
+if [ -e ${DRIVER_FILE} ]; then
+ rm -f ${DRIVER_FILE}
+fi
+curl -L -o ${DRIVER_FILE} ${url}
+if [ "$?" -ne "0" ]; then
+ exit 1
+fi
+
+# Unpack archive
+if [ -d ${DRIVER_DIR} ]; then
+ rm -rf ${DRIVER_DIR}
+fi
+mkdir -p ${DRIVER_DIR}
+tar -C ${DRIVER_DIR} -xf ${DRIVER_FILE}
+
+cd ${DRIVER_DIR}
+if [ -z $KERNEL_DIR ]; then
+ echo "KERNEL_DIR not defined"
+ exit 1
+fi
+
+echo "I: Compile Kernel module for Intel ${DRIVER_NAME} driver"
+mkdir -p \
+ ${DEBIAN_DIR}/lib/firmware \
+ ${DEBIAN_DIR}/usr/sbin \
+ ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu \
+ ${DEBIAN_DIR}/etc/init.d
+
+KERNEL_SOURCE_ROOT=${KERNEL_DIR} ./configure --enable-kapi --enable-qat-lkcf
+make -j $(getconf _NPROCESSORS_ONLN) all
+make INSTALL_MOD_PATH=${DEBIAN_DIR} INSTALL_FW_PATH=${DEBIAN_DIR} \
+ qat-driver-install adf-ctl-all
+
+if [ "x$?" != "x0" ]; then
+ exit 1
+fi
+
+cp quickassist/qat/fw/*.bin ${DEBIAN_DIR}/lib/firmware
+cp build/*.so ${DEBIAN_DIR}/usr/lib/x86_64-linux-gnu
+cp build/adf_ctl ${DEBIAN_DIR}/usr/sbin
+cp quickassist/build_system/build_files/qat_service ${DEBIAN_DIR}/etc/init.d
+cp build/usdm_drv.ko ${DEBIAN_DIR}/lib/modules/${KERNEL_VERSION}${KERNEL_SUFFIX}/updates/drivers
+
+chmod 644 ${DEBIAN_DIR}/lib/firmware/*
+chmod 755 ${DEBIAN_DIR}/etc/init.d/* ${DEBIAN_DIR}/usr/local/bin/*
+
+if [ -f ${DEBIAN_DIR}.deb ]; then
+ rm ${DEBIAN_DIR}.deb
+fi
+
+# build Debian package
+echo "I: Building Debian package vyos-intel-${DRIVER_NAME}"
+cd ${CWD}
+
+# delete non required files which are also present in the kernel package
+# und thus lead to duplicated files
+find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f
+
+echo "#!/bin/sh" > ${DEBIAN_POSTINST}
+echo "/sbin/depmod -a ${KERNEL_VERSION}${KERNEL_SUFFIX}" >> ${DEBIAN_POSTINST}
+
+fpm --input-type dir --output-type deb --name vyos-intel-${DRIVER_NAME} \
+ --version ${DRIVER_VERSION}${DRIVER_VERSION_EXTRA} --deb-compression gz \
+ --maintainer "VyOS Package Maintainers <maintainers@vyos.net>" \
+ --description "Vendor based driver for Intel ${DRIVER_NAME}" \
+ --depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \
+ --license "GPL2" -C ${DEBIAN_DIR} --after-install ${DEBIAN_POSTINST}
+
+echo "I: Cleanup ${DRIVER_NAME} source"
+cd ${CWD}
+if [ -e ${DRIVER_FILE} ]; then
+ rm -f ${DRIVER_FILE}
+fi
+if [ -d ${DRIVER_DIR} ]; then
+ rm -rf ${DRIVER_DIR}
+fi
+if [ -d ${DEBIAN_DIR} ]; then
+ rm -rf ${DEBIAN_DIR}
+fi
diff --git a/packages/linux-kernel/build-linux-firmware.sh b/packages/linux-kernel/build-linux-firmware.sh
index 3e5274fa..7b108195 100755
--- a/packages/linux-kernel/build-linux-firmware.sh
+++ b/packages/linux-kernel/build-linux-firmware.sh
@@ -38,15 +38,46 @@ if [ -d ${VYOS_FIRMWARE_DIR} ]; then
fi
mkdir -p ${VYOS_FIRMWARE_DIR}
-# Copy firmware file from linux firmware repository into
+# Install firmware files to build directory
+LINUX_FIRMWARE_BUILD_DIR="${LINUX_FIRMWARE}_${GIT_COMMIT}"
+
+if [ -d ${LINUX_FIRMWARE_BUILD_DIR} ]; then
+ rm -rf "${LINUX_FIRMWARE_BUILD_DIR}"
+fi
+
+mkdir -p "${LINUX_FIRMWARE_BUILD_DIR}"
+
+(
+ cd ${LINUX_FIRMWARE}
+ ./copy-firmware.sh "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}"
+)
+
+# Copy firmware file from linux firmware build directory into
# assembly folder for the vyos-firmware package
SED_REPLACE="s@${CWD}/${LINUX_FIRMWARE}/@@"
for FILE in ${FW_FILES}; do
- if [ -f ${LINUX_FIRMWARE}/${FILE} ]; then
+ # If file is a symlink install the symlink target as well
+ if [ -h "${LINUX_FIRMWARE_BUILD_DIR}/${FILE}" ]; then
+ TARGET="$(realpath --relative-to="${LINUX_FIRMWARE_BUILD_DIR}" "${LINUX_FIRMWARE_BUILD_DIR}/${FILE}")"
+ TARGET_DIR="${VYOS_FIRMWARE_DIR}/lib/firmware/$(dirname "${TARGET}")"
+
+ if [ ! -f "${TARGET_DIR}/$(basename "${TARGET}")" ]; then
+ if [ -f "${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" ]; then
+ mkdir -p "${TARGET_DIR}"
+
+ echo "I: install firmware: ${TARGET}"
+ cp "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${TARGET}" "${TARGET_DIR}"
+ else
+ echo "I: firmware file not found: ${TARGET}"
+ fi
+ fi
+ fi
+
+ if [ -f ${LINUX_FIRMWARE_BUILD_DIR}/${FILE} ]; then
FW_DIR="${VYOS_FIRMWARE_DIR}/lib/firmware/$(dirname ${FILE})"
- mkdir -p ${FW_DIR}
+ mkdir -p "${FW_DIR}"
echo "I: install firmware: ${FILE}"
- cp ${CWD}/${LINUX_FIRMWARE}/${FILE} ${FW_DIR}
+ cp -P "${CWD}/${LINUX_FIRMWARE_BUILD_DIR}/${FILE}" "${FW_DIR}"
else
echo "I: firmware file not found: ${FILE}"
fi
@@ -59,4 +90,5 @@ fpm --input-type dir --output-type deb --name ${VYOS_FIRMWARE_NAME} \
--description "Binary firmware for various drivers in the Linux kernel" \
--architecture all --version ${GIT_COMMIT} --deb-compression gz -C ${VYOS_FIRMWARE_DIR}
+rm -rf "${LINUX_FIRMWARE_BUILD_DIR}"
rm -rf ${VYOS_FIRMWARE_DIR}
diff --git a/packages/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch b/packages/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
index 2be1a3c8..fb94c163 100644
--- a/packages/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
+++ b/packages/linux-kernel/patches/kernel/0001-linkstate-ip-device-attribute.patch
@@ -19,7 +19,7 @@ Backport of earlier Vyatta patch.
8 files changed, 39 insertions(+)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
-index 8af3771a3ebf..93408cc52991 100644
+index 5cf601c94e35..12457ee20f22 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1245,6 +1245,19 @@ rp_filter - INTEGER
@@ -43,7 +43,7 @@ index 8af3771a3ebf..93408cc52991 100644
1 - Allows you to have multiple network interfaces on the same
subnet, and have the ARPs for each interface be answered
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
-index 3515ca64e638..dcae58193580 100644
+index b68fca08be27..9cdfccdbb9fb 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -133,6 +133,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
@@ -55,7 +55,7 @@ index 3515ca64e638..dcae58193580 100644
struct in_ifaddr {
struct hlist_node hash;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
-index ea7c7906591e..57f656ea2783 100644
+index d5c507311efb..066ad20f2b39 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -76,6 +76,7 @@ struct ipv6_devconf {
@@ -91,7 +91,7 @@ index 9c0f4a92bcff..619edd130cfd 100644
};
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
-index a27d034c85cc..b62b62abe907 100644
+index 4c013f8800f0..409050b2bc44 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2550,6 +2550,8 @@ static struct devinet_sysctl_table {
@@ -104,10 +104,10 @@ index a27d034c85cc..b62b62abe907 100644
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index 635b2482fa20..ce1405ecf6f6 100644
+index c523236d934e..1bd2b92a017f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
-@@ -5477,6 +5477,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
+@@ -5507,6 +5507,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
array[DEVCONF_DISABLE_POLICY] = cnf->disable_policy;
array[DEVCONF_NDISC_TCLASS] = cnf->ndisc_tclass;
@@ -115,7 +115,7 @@ index 635b2482fa20..ce1405ecf6f6 100644
}
static inline size_t inet6_ifla6_size(void)
-@@ -6849,6 +6850,14 @@ static const struct ctl_table addrconf_sysctl[] = {
+@@ -6879,6 +6880,14 @@ static const struct ctl_table addrconf_sysctl[] = {
.mode = 0644,
.proc_handler = addrconf_sysctl_disable_policy,
},
@@ -131,10 +131,10 @@ index 635b2482fa20..ce1405ecf6f6 100644
.procname = "ndisc_tclass",
.data = &ipv6_devconf.ndisc_tclass,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
-index 46df6345bb99..2b930a2c4fdb 100644
+index 209d52ebbd19..edf7b5e9466a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
-@@ -686,6 +686,15 @@ static inline void rt6_probe(struct fib6_nh *fib6_nh)
+@@ -687,6 +687,15 @@ static inline void rt6_probe(struct fib6_nh *fib6_nh)
}
#endif
@@ -150,7 +150,7 @@ index 46df6345bb99..2b930a2c4fdb 100644
/*
* Default Router Selection (RFC 2461 6.3.6)
*/
-@@ -727,6 +736,8 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif,
+@@ -728,6 +737,8 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif,
if (!m && (strict & RT6_LOOKUP_F_IFACE))
return RT6_NUD_FAIL_HARD;
@@ -160,5 +160,5 @@ index 46df6345bb99..2b930a2c4fdb 100644
m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(fib6_flags)) << 2;
#endif
--
-2.20.1
+2.39.2
diff --git a/packages/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch b/packages/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch
index 21f4cd60..8f4b003d 100644
--- a/packages/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch
+++ b/packages/linux-kernel/patches/kernel/0002-inotify-support-for-stackable-filesystems.patch
@@ -44,7 +44,7 @@ index 6736e47d94d8..84d9b31300c0 100644
+
+ If unsure, say N.
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
-index 81ffc8629fc4..cacedffa6534 100644
+index b949b2c02f4b..5bbb53db64a4 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -15,6 +15,7 @@
@@ -186,7 +186,7 @@ index 81ffc8629fc4..cacedffa6534 100644
struct inotify_inode_mark *i_mark)
{
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
-index d6b724beb304..380ac598f2e4 100644
+index f5cf0938f298..c3bb42c9d291 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -15,6 +15,7 @@
@@ -197,7 +197,7 @@ index d6b724beb304..380ac598f2e4 100644
#include "overlayfs.h"
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
-@@ -1758,6 +1759,18 @@ static void ovl_inode_init_once(void *foo)
+@@ -1767,6 +1768,18 @@ static void ovl_inode_init_once(void *foo)
inode_init_once(&oi->vfs_inode);
}
@@ -216,7 +216,7 @@ index d6b724beb304..380ac598f2e4 100644
static int __init ovl_init(void)
{
int err;
-@@ -1772,13 +1785,21 @@ static int __init ovl_init(void)
+@@ -1781,13 +1794,21 @@ static int __init ovl_init(void)
err = register_filesystem(&ovl_fs_type);
if (err)
@@ -239,7 +239,7 @@ index d6b724beb304..380ac598f2e4 100644
unregister_filesystem(&ovl_fs_type);
/*
-@@ -1787,7 +1808,6 @@ static void __exit ovl_exit(void)
+@@ -1796,7 +1817,6 @@ static void __exit ovl_exit(void)
*/
rcu_barrier();
kmem_cache_destroy(ovl_inode_cachep);
@@ -292,5 +292,5 @@ index 6a24905f6e1e..4484f0760588 100644
+
#endif /* _LINUX_INOTIFY_H */
--
-2.20.1
+2.39.2
diff --git a/packages/linux-kernel/patches/kernel/0004-revert-net-sched-retire-tcindex-classifier.patch b/packages/linux-kernel/patches/kernel/0004-revert-net-sched-retire-tcindex-classifier.patch
new file mode 100644
index 00000000..2eb806a7
--- /dev/null
+++ b/packages/linux-kernel/patches/kernel/0004-revert-net-sched-retire-tcindex-classifier.patch
@@ -0,0 +1,786 @@
+From 58559e68b5a93bebf630c5ac99981ec054612583 Mon Sep 17 00:00:00 2001
+From: Christian Breunig <christian@breunig.cc>
+Date: Fri, 24 Nov 2023 09:28:56 +0100
+Subject: [PATCH] Revert "net/sched: Retire tcindex classifier"
+
+This reverts commit 7a6fb69bbcb21e9ce13bdf18c008c268874f0480.
+---
+ net/sched/Kconfig | 11 +
+ net/sched/Makefile | 1 +
+ net/sched/cls_tcindex.c | 730 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 742 insertions(+)
+ create mode 100644 net/sched/cls_tcindex.c
+
+diff --git a/net/sched/Kconfig b/net/sched/Kconfig
+index 46f2847a071e..131e653e9945 100644
+--- a/net/sched/Kconfig
++++ b/net/sched/Kconfig
+@@ -469,6 +469,17 @@ config NET_CLS_BASIC
+ To compile this code as a module, choose M here: the
+ module will be called cls_basic.
+
++config NET_CLS_TCINDEX
++ tristate "Traffic-Control Index (TCINDEX)"
++ select NET_CLS
++ ---help---
++ Say Y here if you want to be able to classify packets based on
++ traffic control indices. You will want this feature if you want
++ to implement Differentiated Services together with DSMARK.
++
++ To compile this code as a module, choose M here: the
++ module will be called cls_tcindex.
++
+ config NET_CLS_ROUTE4
+ tristate "Routing decision (ROUTE)"
+ depends on INET
+diff --git a/net/sched/Makefile b/net/sched/Makefile
+index fb2b90648a20..b2dcc40d92da 100644
+--- a/net/sched/Makefile
++++ b/net/sched/Makefile
+@@ -65,6 +65,7 @@ obj-$(CONFIG_NET_SCH_TAPRIO) += sch_taprio.o
+ obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
+ obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
+ obj-$(CONFIG_NET_CLS_FW) += cls_fw.o
++obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o
+ obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o
+ obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o
+ obj-$(CONFIG_NET_CLS_CGROUP) += cls_cgroup.o
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+new file mode 100644
+index 000000000000..768cf7cf65b4
+--- /dev/null
++++ b/net/sched/cls_tcindex.c
+@@ -0,0 +1,730 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * net/sched/cls_tcindex.c Packet classifier for skb->tc_index
++ *
++ * Written 1998,1999 by Werner Almesberger, EPFL ICA
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/skbuff.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/refcount.h>
++#include <net/act_api.h>
++#include <net/netlink.h>
++#include <net/pkt_cls.h>
++#include <net/sch_generic.h>
++
++/*
++ * Passing parameters to the root seems to be done more awkwardly than really
++ * necessary. At least, u32 doesn't seem to use such dirty hacks. To be
++ * verified. FIXME.
++ */
++
++#define PERFECT_HASH_THRESHOLD 64 /* use perfect hash if not bigger */
++#define DEFAULT_HASH_SIZE 64 /* optimized for diffserv */
++
++
++struct tcindex_data;
++
++struct tcindex_filter_result {
++ struct tcf_exts exts;
++ struct tcf_result res;
++ struct tcindex_data *p;
++ struct rcu_work rwork;
++};
++
++struct tcindex_filter {
++ u16 key;
++ struct tcindex_filter_result result;
++ struct tcindex_filter __rcu *next;
++ struct rcu_work rwork;
++};
++
++
++struct tcindex_data {
++ struct tcindex_filter_result *perfect; /* perfect hash; NULL if none */
++ struct tcindex_filter __rcu **h; /* imperfect hash; */
++ struct tcf_proto *tp;
++ u16 mask; /* AND key with mask */
++ u32 shift; /* shift ANDed key to the right */
++ u32 hash; /* hash table size; 0 if undefined */
++ u32 alloc_hash; /* allocated size */
++ u32 fall_through; /* 0: only classify if explicit match */
++ refcount_t refcnt; /* a temporary refcnt for perfect hash */
++ struct rcu_work rwork;
++};
++
++static inline int tcindex_filter_is_set(struct tcindex_filter_result *r)
++{
++ return tcf_exts_has_actions(&r->exts) || r->res.classid;
++}
++
++static void tcindex_data_get(struct tcindex_data *p)
++{
++ refcount_inc(&p->refcnt);
++}
++
++static void tcindex_data_put(struct tcindex_data *p)
++{
++ if (refcount_dec_and_test(&p->refcnt)) {
++ kfree(p->perfect);
++ kfree(p->h);
++ kfree(p);
++ }
++}
++
++static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p,
++ u16 key)
++{
++ if (p->perfect) {
++ struct tcindex_filter_result *f = p->perfect + key;
++
++ return tcindex_filter_is_set(f) ? f : NULL;
++ } else if (p->h) {
++ struct tcindex_filter __rcu **fp;
++ struct tcindex_filter *f;
++
++ fp = &p->h[key % p->hash];
++ for (f = rcu_dereference_bh_rtnl(*fp);
++ f;
++ fp = &f->next, f = rcu_dereference_bh_rtnl(*fp))
++ if (f->key == key)
++ return &f->result;
++ }
++
++ return NULL;
++}
++
++
++static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp,
++ struct tcf_result *res)
++{
++ struct tcindex_data *p = rcu_dereference_bh(tp->root);
++ struct tcindex_filter_result *f;
++ int key = (skb->tc_index & p->mask) >> p->shift;
++
++ pr_debug("tcindex_classify(skb %p,tp %p,res %p),p %p\n",
++ skb, tp, res, p);
++
++ f = tcindex_lookup(p, key);
++ if (!f) {
++ struct Qdisc *q = tcf_block_q(tp->chain->block);
++
++ if (!p->fall_through)
++ return -1;
++ res->classid = TC_H_MAKE(TC_H_MAJ(q->handle), key);
++ res->class = 0;
++ pr_debug("alg 0x%x\n", res->classid);
++ return 0;
++ }
++ *res = f->res;
++ pr_debug("map 0x%x\n", res->classid);
++
++ return tcf_exts_exec(skb, &f->exts, res);
++}
++
++
++static void *tcindex_get(struct tcf_proto *tp, u32 handle)
++{
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ struct tcindex_filter_result *r;
++
++ pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle);
++ if (p->perfect && handle >= p->alloc_hash)
++ return NULL;
++ r = tcindex_lookup(p, handle);
++ return r && tcindex_filter_is_set(r) ? r : NULL;
++}
++
++static int tcindex_init(struct tcf_proto *tp)
++{
++ struct tcindex_data *p;
++
++ pr_debug("tcindex_init(tp %p)\n", tp);
++ p = kzalloc(sizeof(struct tcindex_data), GFP_KERNEL);
++ if (!p)
++ return -ENOMEM;
++
++ p->mask = 0xffff;
++ p->hash = DEFAULT_HASH_SIZE;
++ p->fall_through = 1;
++ refcount_set(&p->refcnt, 1); /* Paired with tcindex_destroy_work() */
++
++ rcu_assign_pointer(tp->root, p);
++ return 0;
++}
++
++static void __tcindex_destroy_rexts(struct tcindex_filter_result *r)
++{
++ tcf_exts_destroy(&r->exts);
++ tcf_exts_put_net(&r->exts);
++ tcindex_data_put(r->p);
++}
++
++static void tcindex_destroy_rexts_work(struct work_struct *work)
++{
++ struct tcindex_filter_result *r;
++
++ r = container_of(to_rcu_work(work),
++ struct tcindex_filter_result,
++ rwork);
++ rtnl_lock();
++ __tcindex_destroy_rexts(r);
++ rtnl_unlock();
++}
++
++static void __tcindex_destroy_fexts(struct tcindex_filter *f)
++{
++ tcf_exts_destroy(&f->result.exts);
++ tcf_exts_put_net(&f->result.exts);
++ kfree(f);
++}
++
++static void tcindex_destroy_fexts_work(struct work_struct *work)
++{
++ struct tcindex_filter *f = container_of(to_rcu_work(work),
++ struct tcindex_filter,
++ rwork);
++
++ rtnl_lock();
++ __tcindex_destroy_fexts(f);
++ rtnl_unlock();
++}
++
++static int tcindex_delete(struct tcf_proto *tp, void *arg, bool *last,
++ bool rtnl_held, struct netlink_ext_ack *extack)
++{
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ struct tcindex_filter_result *r = arg;
++ struct tcindex_filter __rcu **walk;
++ struct tcindex_filter *f = NULL;
++
++ pr_debug("tcindex_delete(tp %p,arg %p),p %p\n", tp, arg, p);
++ if (p->perfect) {
++ if (!r->res.class)
++ return -ENOENT;
++ } else {
++ int i;
++
++ for (i = 0; i < p->hash; i++) {
++ walk = p->h + i;
++ for (f = rtnl_dereference(*walk); f;
++ walk = &f->next, f = rtnl_dereference(*walk)) {
++ if (&f->result == r)
++ goto found;
++ }
++ }
++ return -ENOENT;
++
++found:
++ rcu_assign_pointer(*walk, rtnl_dereference(f->next));
++ }
++ tcf_unbind_filter(tp, &r->res);
++ /* all classifiers are required to call tcf_exts_destroy() after rcu
++ * grace period, since converted-to-rcu actions are relying on that
++ * in cleanup() callback
++ */
++ if (f) {
++ if (tcf_exts_get_net(&f->result.exts))
++ tcf_queue_work(&f->rwork, tcindex_destroy_fexts_work);
++ else
++ __tcindex_destroy_fexts(f);
++ } else {
++ tcindex_data_get(p);
++
++ if (tcf_exts_get_net(&r->exts))
++ tcf_queue_work(&r->rwork, tcindex_destroy_rexts_work);
++ else
++ __tcindex_destroy_rexts(r);
++ }
++
++ *last = false;
++ return 0;
++}
++
++static void tcindex_destroy_work(struct work_struct *work)
++{
++ struct tcindex_data *p = container_of(to_rcu_work(work),
++ struct tcindex_data,
++ rwork);
++
++ tcindex_data_put(p);
++}
++
++static inline int
++valid_perfect_hash(struct tcindex_data *p)
++{
++ return p->hash > (p->mask >> p->shift);
++}
++
++static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
++ [TCA_TCINDEX_HASH] = { .type = NLA_U32 },
++ [TCA_TCINDEX_MASK] = { .type = NLA_U16 },
++ [TCA_TCINDEX_SHIFT] = { .type = NLA_U32 },
++ [TCA_TCINDEX_FALL_THROUGH] = { .type = NLA_U32 },
++ [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 },
++};
++
++static int tcindex_filter_result_init(struct tcindex_filter_result *r,
++ struct tcindex_data *p,
++ struct net *net)
++{
++ memset(r, 0, sizeof(*r));
++ r->p = p;
++ return tcf_exts_init(&r->exts, net, TCA_TCINDEX_ACT,
++ TCA_TCINDEX_POLICE);
++}
++
++static void tcindex_free_perfect_hash(struct tcindex_data *cp);
++
++static void tcindex_partial_destroy_work(struct work_struct *work)
++{
++ struct tcindex_data *p = container_of(to_rcu_work(work),
++ struct tcindex_data,
++ rwork);
++
++ rtnl_lock();
++ if (p->perfect)
++ tcindex_free_perfect_hash(p);
++ kfree(p);
++ rtnl_unlock();
++}
++
++static void tcindex_free_perfect_hash(struct tcindex_data *cp)
++{
++ int i;
++
++ for (i = 0; i < cp->hash; i++)
++ tcf_exts_destroy(&cp->perfect[i].exts);
++ kfree(cp->perfect);
++}
++
++static int tcindex_alloc_perfect_hash(struct net *net, struct tcindex_data *cp)
++{
++ int i, err = 0;
++
++ cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result),
++ GFP_KERNEL | __GFP_NOWARN);
++ if (!cp->perfect)
++ return -ENOMEM;
++
++ for (i = 0; i < cp->hash; i++) {
++ err = tcf_exts_init(&cp->perfect[i].exts, net,
++ TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
++ if (err < 0)
++ goto errout;
++ cp->perfect[i].p = cp;
++ }
++
++ return 0;
++
++errout:
++ tcindex_free_perfect_hash(cp);
++ return err;
++}
++
++static int
++tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
++ u32 handle, struct tcindex_data *p,
++ struct tcindex_filter_result *r, struct nlattr **tb,
++ struct nlattr *est, bool ovr, struct netlink_ext_ack *extack)
++{
++ struct tcindex_filter_result new_filter_result;
++ struct tcindex_data *cp = NULL, *oldp;
++ struct tcindex_filter *f = NULL; /* make gcc behave */
++ struct tcf_result cr = {};
++ int err, balloc = 0;
++ struct tcf_exts e;
++
++ err = tcf_exts_init(&e, net, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
++ if (err < 0)
++ return err;
++ err = tcf_exts_validate(net, tp, tb, est, &e, ovr, true, extack);
++ if (err < 0)
++ goto errout;
++
++ err = -ENOMEM;
++ /* tcindex_data attributes must look atomic to classifier/lookup so
++ * allocate new tcindex data and RCU assign it onto root. Keeping
++ * perfect hash and hash pointers from old data.
++ */
++ cp = kzalloc(sizeof(*cp), GFP_KERNEL);
++ if (!cp)
++ goto errout;
++
++ cp->mask = p->mask;
++ cp->shift = p->shift;
++ cp->hash = p->hash;
++ cp->alloc_hash = p->alloc_hash;
++ cp->fall_through = p->fall_through;
++ cp->tp = tp;
++ refcount_set(&cp->refcnt, 1); /* Paired with tcindex_destroy_work() */
++
++ if (tb[TCA_TCINDEX_HASH])
++ cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
++
++ if (tb[TCA_TCINDEX_MASK])
++ cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
++
++ if (tb[TCA_TCINDEX_SHIFT]) {
++ cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
++ if (cp->shift > 16) {
++ err = -EINVAL;
++ goto errout;
++ }
++ }
++ if (!cp->hash) {
++ /* Hash not specified, use perfect hash if the upper limit
++ * of the hashing index is below the threshold.
++ */
++ if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
++ cp->hash = (cp->mask >> cp->shift) + 1;
++ else
++ cp->hash = DEFAULT_HASH_SIZE;
++ }
++
++ if (p->perfect) {
++ int i;
++
++ if (tcindex_alloc_perfect_hash(net, cp) < 0)
++ goto errout;
++ cp->alloc_hash = cp->hash;
++ for (i = 0; i < min(cp->hash, p->hash); i++)
++ cp->perfect[i].res = p->perfect[i].res;
++ balloc = 1;
++ }
++ cp->h = p->h;
++
++ err = tcindex_filter_result_init(&new_filter_result, cp, net);
++ if (err < 0)
++ goto errout_alloc;
++ if (r)
++ cr = r->res;
++
++ err = -EBUSY;
++
++ /* Hash already allocated, make sure that we still meet the
++ * requirements for the allocated hash.
++ */
++ if (cp->perfect) {
++ if (!valid_perfect_hash(cp) ||
++ cp->hash > cp->alloc_hash)
++ goto errout_alloc;
++ } else if (cp->h && cp->hash != cp->alloc_hash) {
++ goto errout_alloc;
++ }
++
++ err = -EINVAL;
++ if (tb[TCA_TCINDEX_FALL_THROUGH])
++ cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
++
++ if (!cp->perfect && !cp->h)
++ cp->alloc_hash = cp->hash;
++
++ /* Note: this could be as restrictive as if (handle & ~(mask >> shift))
++ * but then, we'd fail handles that may become valid after some future
++ * mask change. While this is extremely unlikely to ever matter,
++ * the check below is safer (and also more backwards-compatible).
++ */
++ if (cp->perfect || valid_perfect_hash(cp))
++ if (handle >= cp->alloc_hash)
++ goto errout_alloc;
++
++
++ err = -ENOMEM;
++ if (!cp->perfect && !cp->h) {
++ if (valid_perfect_hash(cp)) {
++ if (tcindex_alloc_perfect_hash(net, cp) < 0)
++ goto errout_alloc;
++ balloc = 1;
++ } else {
++ struct tcindex_filter __rcu **hash;
++
++ hash = kcalloc(cp->hash,
++ sizeof(struct tcindex_filter *),
++ GFP_KERNEL);
++
++ if (!hash)
++ goto errout_alloc;
++
++ cp->h = hash;
++ balloc = 2;
++ }
++ }
++
++ if (cp->perfect)
++ r = cp->perfect + handle;
++ else
++ r = tcindex_lookup(cp, handle) ? : &new_filter_result;
++
++ if (r == &new_filter_result) {
++ f = kzalloc(sizeof(*f), GFP_KERNEL);
++ if (!f)
++ goto errout_alloc;
++ f->key = handle;
++ f->next = NULL;
++ err = tcindex_filter_result_init(&f->result, cp, net);
++ if (err < 0) {
++ kfree(f);
++ goto errout_alloc;
++ }
++ }
++
++ if (tb[TCA_TCINDEX_CLASSID]) {
++ cr.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
++ tcf_bind_filter(tp, &cr, base);
++ }
++
++ oldp = p;
++ r->res = cr;
++ tcf_exts_change(&r->exts, &e);
++
++ rcu_assign_pointer(tp->root, cp);
++
++ if (r == &new_filter_result) {
++ struct tcindex_filter *nfp;
++ struct tcindex_filter __rcu **fp;
++
++ f->result.res = r->res;
++ tcf_exts_change(&f->result.exts, &r->exts);
++
++ fp = cp->h + (handle % cp->hash);
++ for (nfp = rtnl_dereference(*fp);
++ nfp;
++ fp = &nfp->next, nfp = rtnl_dereference(*fp))
++ ; /* nothing */
++
++ rcu_assign_pointer(*fp, f);
++ } else {
++ tcf_exts_destroy(&new_filter_result.exts);
++ }
++
++ if (oldp)
++ tcf_queue_work(&oldp->rwork, tcindex_partial_destroy_work);
++ return 0;
++
++errout_alloc:
++ if (balloc == 1)
++ tcindex_free_perfect_hash(cp);
++ else if (balloc == 2)
++ kfree(cp->h);
++ tcf_exts_destroy(&new_filter_result.exts);
++errout:
++ kfree(cp);
++ tcf_exts_destroy(&e);
++ return err;
++}
++
++static int
++tcindex_change(struct net *net, struct sk_buff *in_skb,
++ struct tcf_proto *tp, unsigned long base, u32 handle,
++ struct nlattr **tca, void **arg, bool ovr,
++ bool rtnl_held, struct netlink_ext_ack *extack)
++{
++ struct nlattr *opt = tca[TCA_OPTIONS];
++ struct nlattr *tb[TCA_TCINDEX_MAX + 1];
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ struct tcindex_filter_result *r = *arg;
++ int err;
++
++ pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
++ "p %p,r %p,*arg %p\n",
++ tp, handle, tca, arg, opt, p, r, arg ? *arg : NULL);
++
++ if (!opt)
++ return 0;
++
++ err = nla_parse_nested_deprecated(tb, TCA_TCINDEX_MAX, opt,
++ tcindex_policy, NULL);
++ if (err < 0)
++ return err;
++
++ return tcindex_set_parms(net, tp, base, handle, p, r, tb,
++ tca[TCA_RATE], ovr, extack);
++}
++
++static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker,
++ bool rtnl_held)
++{
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ struct tcindex_filter *f, *next;
++ int i;
++
++ pr_debug("tcindex_walk(tp %p,walker %p),p %p\n", tp, walker, p);
++ if (p->perfect) {
++ for (i = 0; i < p->hash; i++) {
++ if (!p->perfect[i].res.class)
++ continue;
++ if (walker->count >= walker->skip) {
++ if (walker->fn(tp, p->perfect + i, walker) < 0) {
++ walker->stop = 1;
++ return;
++ }
++ }
++ walker->count++;
++ }
++ }
++ if (!p->h)
++ return;
++ for (i = 0; i < p->hash; i++) {
++ for (f = rtnl_dereference(p->h[i]); f; f = next) {
++ next = rtnl_dereference(f->next);
++ if (walker->count >= walker->skip) {
++ if (walker->fn(tp, &f->result, walker) < 0) {
++ walker->stop = 1;
++ return;
++ }
++ }
++ walker->count++;
++ }
++ }
++}
++
++static void tcindex_destroy(struct tcf_proto *tp, bool rtnl_held,
++ struct netlink_ext_ack *extack)
++{
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ int i;
++
++ pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p);
++
++ if (p->perfect) {
++ for (i = 0; i < p->hash; i++) {
++ struct tcindex_filter_result *r = p->perfect + i;
++
++ /* tcf_queue_work() does not guarantee the ordering we
++ * want, so we have to take this refcnt temporarily to
++ * ensure 'p' is freed after all tcindex_filter_result
++ * here. Imperfect hash does not need this, because it
++ * uses linked lists rather than an array.
++ */
++ tcindex_data_get(p);
++
++ tcf_unbind_filter(tp, &r->res);
++ if (tcf_exts_get_net(&r->exts))
++ tcf_queue_work(&r->rwork,
++ tcindex_destroy_rexts_work);
++ else
++ __tcindex_destroy_rexts(r);
++ }
++ }
++
++ for (i = 0; p->h && i < p->hash; i++) {
++ struct tcindex_filter *f, *next;
++ bool last;
++
++ for (f = rtnl_dereference(p->h[i]); f; f = next) {
++ next = rtnl_dereference(f->next);
++ tcindex_delete(tp, &f->result, &last, rtnl_held, NULL);
++ }
++ }
++
++ tcf_queue_work(&p->rwork, tcindex_destroy_work);
++}
++
++
++static int tcindex_dump(struct net *net, struct tcf_proto *tp, void *fh,
++ struct sk_buff *skb, struct tcmsg *t, bool rtnl_held)
++{
++ struct tcindex_data *p = rtnl_dereference(tp->root);
++ struct tcindex_filter_result *r = fh;
++ struct nlattr *nest;
++
++ pr_debug("tcindex_dump(tp %p,fh %p,skb %p,t %p),p %p,r %p\n",
++ tp, fh, skb, t, p, r);
++ pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h);
++
++ nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
++ if (nest == NULL)
++ goto nla_put_failure;
++
++ if (!fh) {
++ t->tcm_handle = ~0; /* whatever ... */
++ if (nla_put_u32(skb, TCA_TCINDEX_HASH, p->hash) ||
++ nla_put_u16(skb, TCA_TCINDEX_MASK, p->mask) ||
++ nla_put_u32(skb, TCA_TCINDEX_SHIFT, p->shift) ||
++ nla_put_u32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through))
++ goto nla_put_failure;
++ nla_nest_end(skb, nest);
++ } else {
++ if (p->perfect) {
++ t->tcm_handle = r - p->perfect;
++ } else {
++ struct tcindex_filter *f;
++ struct tcindex_filter __rcu **fp;
++ int i;
++
++ t->tcm_handle = 0;
++ for (i = 0; !t->tcm_handle && i < p->hash; i++) {
++ fp = &p->h[i];
++ for (f = rtnl_dereference(*fp);
++ !t->tcm_handle && f;
++ fp = &f->next, f = rtnl_dereference(*fp)) {
++ if (&f->result == r)
++ t->tcm_handle = f->key;
++ }
++ }
++ }
++ pr_debug("handle = %d\n", t->tcm_handle);
++ if (r->res.class &&
++ nla_put_u32(skb, TCA_TCINDEX_CLASSID, r->res.classid))
++ goto nla_put_failure;
++
++ if (tcf_exts_dump(skb, &r->exts) < 0)
++ goto nla_put_failure;
++ nla_nest_end(skb, nest);
++
++ if (tcf_exts_dump_stats(skb, &r->exts) < 0)
++ goto nla_put_failure;
++ }
++
++ return skb->len;
++
++nla_put_failure:
++ nla_nest_cancel(skb, nest);
++ return -1;
++}
++
++static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl,
++ void *q, unsigned long base)
++{
++ struct tcindex_filter_result *r = fh;
++
++ if (r && r->res.classid == classid) {
++ if (cl)
++ __tcf_bind_filter(q, &r->res, base);
++ else
++ __tcf_unbind_filter(q, &r->res);
++ }
++}
++
++static struct tcf_proto_ops cls_tcindex_ops __read_mostly = {
++ .kind = "tcindex",
++ .classify = tcindex_classify,
++ .init = tcindex_init,
++ .destroy = tcindex_destroy,
++ .get = tcindex_get,
++ .change = tcindex_change,
++ .delete = tcindex_delete,
++ .walk = tcindex_walk,
++ .dump = tcindex_dump,
++ .bind_class = tcindex_bind_class,
++ .owner = THIS_MODULE,
++};
++
++static int __init init_tcindex(void)
++{
++ return register_tcf_proto_ops(&cls_tcindex_ops);
++}
++
++static void __exit exit_tcindex(void)
++{
++ unregister_tcf_proto_ops(&cls_tcindex_ops);
++}
++
++module_init(init_tcindex)
++module_exit(exit_tcindex)
++MODULE_LICENSE("GPL");
+--
+2.39.2
+
diff --git a/packages/linux-kernel/patches/vyos-drivers-realtek-r8152/0001-Fixed-compatibility-with-kernel-5.4.254.patch b/packages/linux-kernel/patches/vyos-drivers-realtek-r8152/0001-Fixed-compatibility-with-kernel-5.4.254.patch
new file mode 100644
index 00000000..d4e9321b
--- /dev/null
+++ b/packages/linux-kernel/patches/vyos-drivers-realtek-r8152/0001-Fixed-compatibility-with-kernel-5.4.254.patch
@@ -0,0 +1,27 @@
+From 65e00ae524f82cffb57abf3fa3f8dbac8a2bda7a Mon Sep 17 00:00:00 2001
+From: Taras Pudiak <taras@vyos.io>
+Date: Wed, 30 Aug 2023 14:59:38 +0300
+Subject: [PATCH] Fixed compatibility with kernel 5.4.254
+
+---
+ compatibility.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/compatibility.h b/compatibility.h
+index d1e044d..9eee6a9 100644
+--- a/compatibility.h
++++ b/compatibility.h
+@@ -612,10 +612,6 @@
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) */
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0) */
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) */
+- static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
+- {
+- memcpy(dev->dev_addr, addr, 6);
+- }
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) */
+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0) */
+
+--
+2.34.1
+
diff --git a/packages/linux-kernel/x86_64_vyos_defconfig b/packages/linux-kernel/x86_64_vyos_defconfig
index a6c72ed4..6e3ed66a 100644
--- a/packages/linux-kernel/x86_64_vyos_defconfig
+++ b/packages/linux-kernel/x86_64_vyos_defconfig
@@ -2642,7 +2642,11 @@ CONFIG_LIBIPW=m
CONFIG_IWLEGACY=m
CONFIG_IWL4965=m
CONFIG_IWL3945=m
-
+# stmicro driver
+CONFIG_NET_VENDOR_STMICRO=y
+CONFIG_STMMAC_ETH=m
+CONFIG_DWMAC_INTEL=m
+CONFIG_STMMAC_PCI=m
#
# iwl3945 / iwl4965 Debugging Options
#
diff --git a/packages/ocserv/Jenkinsfile b/packages/ocserv/Jenkinsfile
index 235e5b07..686cde80 100644
--- a/packages/ocserv/Jenkinsfile
+++ b/packages/ocserv/Jenkinsfile
@@ -22,9 +22,9 @@
def pkgList = [
['name': 'ocserv',
- 'scmCommit': 'debian/0.12.2-3',
+ 'scmCommit': 'debian/1.1.6-3',
'scmUrl': 'https://salsa.debian.org/debian/ocserv/',
- 'buildCmd': 'dpkg-buildpackage -uc -us -tc -b'],
+ 'buildCmd': 'dpkg-buildpackage -uc -us -tc -b -d'],
]
// Start package build using library function from https://github.com/vyos/vyos-build