Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package iproute2 for openSUSE:Factory checked in at 2025-04-11 16:44:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/iproute2 (Old) and /work/SRC/openSUSE:Factory/.iproute2.new.1907 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "iproute2" Fri Apr 11 16:44:27 2025 rev:143 rq:1268396 version:6.14 Changes: -------- --- /work/SRC/openSUSE:Factory/iproute2/iproute2.changes 2025-01-23 17:56:58.579240209 +0100 +++ /work/SRC/openSUSE:Factory/.iproute2.new.1907/iproute2.changes 2025-04-11 16:44:38.985851867 +0200 @@ -1,0 +2,8 @@ +Thu Apr 10 12:40:43 UTC 2025 - Jan Engelhardt <jeng...@inai.de> + +- Update to release 6.14 + * Add IPv6 flow label support to `ip route` and `ip rule` + * Add `ip monitor maddress` support + * ss: Display seq counters as decimal for mptcp subflows + +------------------------------------------------------------------- Old: ---- iproute2-6.13.0.tar.sign iproute2-6.13.0.tar.xz New: ---- iproute2-6.14.0.tar.sign iproute2-6.14.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ iproute2.spec ++++++ --- /var/tmp/diff_new_pack.soXsbs/_old 2025-04-11 16:44:39.825887200 +0200 +++ /var/tmp/diff_new_pack.soXsbs/_new 2025-04-11 16:44:39.829887367 +0200 @@ -1,7 +1,7 @@ # # spec file for package iproute2 # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,14 +18,13 @@ %define _buildshell /bin/bash Name: iproute2 -Version: 6.13 +Version: 6.14 Release: 0 Summary: Linux network configuration utilities License: GPL-2.0-only Group: Productivity/Networking/Routing URL: https://wiki.linuxfoundation.org/networking/iproute2 # Using GPL-2.0 instead of GPL-2.0+ because of tc_skbedit.h and tc/q_multiq.c - #DL-URL: https://kernel.org/pub/linux/utils/net/iproute2/ #Git-Clone: https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/ #Git-Mirror: https://github.com/shemminger/iproute2 ## not regularly updated @@ -136,7 +135,7 @@ cp -an README* examples/bpf "$b/%_docdir/%name/" # bugzilla.opensuse.org/1205632 -# You can't parse routel output anyway so it does not matter what we output +# You can't parse routel output anyway so it does not matter what our replacement program outputs rm -v "$b/%_mandir/man8/routel.8" cat >"$b/%_sbindir/routel" <<-EOF #!/bin/sh ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.soXsbs/_old 2025-04-11 16:44:39.885889723 +0200 +++ /var/tmp/diff_new_pack.soXsbs/_new 2025-04-11 16:44:39.885889723 +0200 @@ -1,5 +1,5 @@ -mtime: 1737539123 -commit: 524ffd7314b37478222a5610348528a0c712506223e9651a6614d622d7223a43 +mtime: 1744289064 +commit: ebba5448a66f5f0ac2924da0a02ed3abf57d40084fb580ff579df97919605695 url: https://src.opensuse.org/jengelh/iproute2 revision: master ++++++ build.specials.obscpio ++++++ ++++++ iproute2-6.13.0.tar.xz -> iproute2-6.14.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/README.devel new/iproute2-6.14.0/README.devel --- old/iproute2-6.13.0/README.devel 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/README.devel 2025-03-24 17:04:44.000000000 +0100 @@ -1,8 +1,12 @@ Iproute2 development is closely tied to Linux kernel networking development. Most new features require a kernel and a utility component. -Please submit both to the Linux networking mailing list - <net...@vger.kernel.org> +Please submit both kernel and iproute changes to the Linux networking mailing list + <net...@vger.kernel.org> + +Patch submitting rules are similar to the kernel. +See: + https://www.kernel.org/doc/html/latest/process/submitting-patches.html The current source for the stable version is in the git repository: git://git.kernel.org/pub/scm/network/iproute2/iproute2.git @@ -16,3 +20,7 @@ The iproute2-next repository tracks the code intended for the next release; it corresponds with networking development tree (net-next) in the kernel. + +Patches should be prefixed with iproute2 or iproute2-next as appropriate. +For example: + Subject: [PATCH iproute2-next] ip: fix syntax for rules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/bpf.h new/iproute2-6.14.0/include/uapi/linux/bpf.h --- old/iproute2-6.13.0/include/uapi/linux/bpf.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/bpf.h 2025-03-24 17:04:44.000000000 +0100 @@ -1573,6 +1573,16 @@ * If provided, prog_flags should have BPF_F_TOKEN_FD flag set. */ __s32 prog_token_fd; + /* The fd_array_cnt can be used to pass the length of the + * fd_array array. In this case all the [map] file descriptors + * passed in this array will be bound to the program, even if + * the maps are not referenced directly. The functionality is + * similar to the BPF_PROG_BIND_MAP syscall, but maps can be + * used by the verifier during the program load. If provided, + * then the fd_array[0,...,fd_array_cnt-1] is expected to be + * continuous. + */ + __u32 fd_array_cnt; }; struct { /* anonymous struct used by BPF_OBJ_* commands */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/fib_rules.h new/iproute2-6.14.0/include/uapi/linux/fib_rules.h --- old/iproute2-6.13.0/include/uapi/linux/fib_rules.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/fib_rules.h 2025-03-24 17:04:44.000000000 +0100 @@ -68,6 +68,8 @@ FRA_SPORT_RANGE, /* sport */ FRA_DPORT_RANGE, /* dport */ FRA_DSCP, /* dscp */ + FRA_FLOWLABEL, /* flowlabel */ + FRA_FLOWLABEL_MASK, /* flowlabel mask */ __FRA_MAX }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/if_link.h new/iproute2-6.14.0/include/uapi/linux/if_link.h --- old/iproute2-6.13.0/include/uapi/linux/if_link.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/if_link.h 2025-03-24 17:04:44.000000000 +0100 @@ -1313,6 +1313,8 @@ IFLA_NETKIT_MODE, IFLA_NETKIT_SCRUB, IFLA_NETKIT_PEER_SCRUB, + IFLA_NETKIT_HEADROOM, + IFLA_NETKIT_TAILROOM, __IFLA_NETKIT_MAX, }; #define IFLA_NETKIT_MAX (__IFLA_NETKIT_MAX - 1) @@ -1392,6 +1394,7 @@ IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */ IFLA_VXLAN_LOCALBYPASS, IFLA_VXLAN_LABEL_POLICY, /* IPv6 flow label policy; ifla_vxlan_label_policy */ + IFLA_VXLAN_RESERVED_BITS, __IFLA_VXLAN_MAX }; #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/in.h new/iproute2-6.14.0/include/uapi/linux/in.h --- old/iproute2-6.13.0/include/uapi/linux/in.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/in.h 2025-03-24 17:04:44.000000000 +0100 @@ -79,6 +79,8 @@ #define IPPROTO_MPLS IPPROTO_MPLS IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation */ #define IPPROTO_ETHERNET IPPROTO_ETHERNET + IPPROTO_AGGFRAG = 144, /* AGGFRAG in ESP (RFC 9347) */ +#define IPPROTO_AGGFRAG IPPROTO_AGGFRAG IPPROTO_RAW = 255, /* Raw IP packets */ #define IPPROTO_RAW IPPROTO_RAW IPPROTO_SMC = 256, /* Shared Memory Communications */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/ip.h new/iproute2-6.14.0/include/uapi/linux/ip.h --- old/iproute2-6.13.0/include/uapi/linux/ip.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/ip.h 2025-03-24 17:04:44.000000000 +0100 @@ -137,6 +137,22 @@ __u8 reserved; }; +struct ip_iptfs_hdr { + __u8 subtype; /* 0*: basic, 1: CC */ + __u8 flags; + __be16 block_offset; +}; + +struct ip_iptfs_cc_hdr { + __u8 subtype; /* 0: basic, 1*: CC */ + __u8 flags; + __be16 block_offset; + __be32 loss_rate; + __be64 rtt_adelay_xdelay; + __be32 tval; + __be32 techo; +}; + /* index values for the variables in ipv4_devconf */ enum { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/ipsec.h new/iproute2-6.14.0/include/uapi/linux/ipsec.h --- old/iproute2-6.13.0/include/uapi/linux/ipsec.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/ipsec.h 2025-03-24 17:04:44.000000000 +0100 @@ -14,7 +14,8 @@ IPSEC_MODE_ANY = 0, /* We do not support this for SA */ IPSEC_MODE_TRANSPORT = 1, IPSEC_MODE_TUNNEL = 2, - IPSEC_MODE_BEET = 3 + IPSEC_MODE_BEET = 3, + IPSEC_MODE_IPTFS = 4 }; enum { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/rtnetlink.h new/iproute2-6.14.0/include/uapi/linux/rtnetlink.h --- old/iproute2-6.13.0/include/uapi/linux/rtnetlink.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/rtnetlink.h 2025-03-24 17:04:44.000000000 +0100 @@ -93,10 +93,18 @@ RTM_NEWPREFIX = 52, #define RTM_NEWPREFIX RTM_NEWPREFIX - RTM_GETMULTICAST = 58, + RTM_NEWMULTICAST = 56, +#define RTM_NEWMULTICAST RTM_NEWMULTICAST + RTM_DELMULTICAST, +#define RTM_DELMULTICAST RTM_DELMULTICAST + RTM_GETMULTICAST, #define RTM_GETMULTICAST RTM_GETMULTICAST - RTM_GETANYCAST = 62, + RTM_NEWANYCAST = 60, +#define RTM_NEWANYCAST RTM_NEWANYCAST + RTM_DELANYCAST, +#define RTM_DELANYCAST RTM_DELANYCAST + RTM_GETANYCAST, #define RTM_GETANYCAST RTM_GETANYCAST RTM_NEWNEIGHTBL = 64, @@ -389,6 +397,7 @@ RTA_SPORT, RTA_DPORT, RTA_NH_ID, + RTA_FLOWLABEL, __RTA_MAX }; @@ -772,6 +781,12 @@ #define RTNLGRP_TUNNEL RTNLGRP_TUNNEL RTNLGRP_STATS, #define RTNLGRP_STATS RTNLGRP_STATS + RTNLGRP_IPV4_MCADDR, +#define RTNLGRP_IPV4_MCADDR RTNLGRP_IPV4_MCADDR + RTNLGRP_IPV6_MCADDR, +#define RTNLGRP_IPV6_MCADDR RTNLGRP_IPV6_MCADDR + RTNLGRP_IPV6_ACADDR, +#define RTNLGRP_IPV6_ACADDR RTNLGRP_IPV6_ACADDR __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/snmp.h new/iproute2-6.14.0/include/uapi/linux/snmp.h --- old/iproute2-6.13.0/include/uapi/linux/snmp.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/snmp.h 2025-03-24 17:04:44.000000000 +0100 @@ -186,6 +186,7 @@ LINUX_MIB_TIMEWAITKILLED, /* TimeWaitKilled */ LINUX_MIB_PAWSACTIVEREJECTED, /* PAWSActiveRejected */ LINUX_MIB_PAWSESTABREJECTED, /* PAWSEstabRejected */ + LINUX_MIB_PAWS_OLD_ACK, /* PAWSOldAck */ LINUX_MIB_DELAYEDACKS, /* DelayedACKs */ LINUX_MIB_DELAYEDACKLOCKED, /* DelayedACKLocked */ LINUX_MIB_DELAYEDACKLOST, /* DelayedACKLost */ @@ -339,6 +340,8 @@ LINUX_MIB_XFRMACQUIREERROR, /* XfrmAcquireError */ LINUX_MIB_XFRMOUTSTATEDIRERROR, /* XfrmOutStateDirError */ LINUX_MIB_XFRMINSTATEDIRERROR, /* XfrmInStateDirError */ + LINUX_MIB_XFRMINIPTFSERROR, /* XfrmInIptfsError */ + LINUX_MIB_XFRMOUTNOQSPACE, /* XfrmOutNoQueueSpace */ __LINUX_MIB_XFRMMAX }; @@ -358,6 +361,11 @@ LINUX_MIB_TLSRXDEVICERESYNC, /* TlsRxDeviceResync */ LINUX_MIB_TLSDECRYPTRETRY, /* TlsDecryptRetry */ LINUX_MIB_TLSRXNOPADVIOL, /* TlsRxNoPadViolation */ + LINUX_MIB_TLSRXREKEYOK, /* TlsRxRekeyOk */ + LINUX_MIB_TLSRXREKEYERROR, /* TlsRxRekeyError */ + LINUX_MIB_TLSTXREKEYOK, /* TlsTxRekeyOk */ + LINUX_MIB_TLSTXREKEYERROR, /* TlsTxRekeyError */ + LINUX_MIB_TLSRXREKEYRECEIVED, /* TlsRxRekeyReceived */ __LINUX_MIB_TLSMAX }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/uapi/linux/xfrm.h new/iproute2-6.14.0/include/uapi/linux/xfrm.h --- old/iproute2-6.13.0/include/uapi/linux/xfrm.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/uapi/linux/xfrm.h 2025-03-24 17:04:44.000000000 +0100 @@ -158,7 +158,8 @@ #define XFRM_MODE_ROUTEOPTIMIZATION 2 #define XFRM_MODE_IN_TRIGGER 3 #define XFRM_MODE_BEET 4 -#define XFRM_MODE_MAX 5 +#define XFRM_MODE_IPTFS 5 +#define XFRM_MODE_MAX 6 /* Netlink configuration messages. */ enum { @@ -323,6 +324,12 @@ XFRMA_SA_DIR, /* __u8 */ XFRMA_NAT_KEEPALIVE_INTERVAL, /* __u32 in seconds for NAT keepalive */ XFRMA_SA_PCPU, /* __u32 */ + XFRMA_IPTFS_DROP_TIME, /* __u32 in: usec to wait for next seq */ + XFRMA_IPTFS_REORDER_WINDOW, /* __u16 in: reorder window size (pkts) */ + XFRMA_IPTFS_DONT_FRAG, /* out: don't use fragmentation */ + XFRMA_IPTFS_INIT_DELAY, /* __u32 out: initial packet wait delay (usec) */ + XFRMA_IPTFS_MAX_QSIZE, /* __u32 out: max ingress queue size (octets) */ + XFRMA_IPTFS_PKT_SIZE, /* __u32 out: size of outer packet, 0 for PMTU */ __XFRMA_MAX #define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/include/version.h new/iproute2-6.14.0/include/version.h --- old/iproute2-6.13.0/include/version.h 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/include/version.h 2025-03-24 17:04:44.000000000 +0100 @@ -1 +1 @@ -static const char version[] = "6.13.0"; +static const char version[] = "6.14.0"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/ipaddress.c new/iproute2-6.14.0/ip/ipaddress.c --- old/iproute2-6.13.0/ip/ipaddress.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/ipaddress.c 2025-03-24 17:04:44.000000000 +0100 @@ -1504,7 +1504,12 @@ SPRINT_BUF(b1); - if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) + if (n->nlmsg_type != RTM_NEWADDR && + n->nlmsg_type != RTM_DELADDR && + n->nlmsg_type != RTM_NEWMULTICAST && + n->nlmsg_type != RTM_DELMULTICAST && + n->nlmsg_type != RTM_NEWANYCAST && + n->nlmsg_type != RTM_DELANYCAST) return 0; len -= NLMSG_LENGTH(sizeof(*ifa)); if (len < 0) { @@ -1564,7 +1569,9 @@ print_headers(fp, "[ADDR]"); - if (n->nlmsg_type == RTM_DELADDR) + if (n->nlmsg_type == RTM_DELADDR || + n->nlmsg_type == RTM_DELMULTICAST || + n->nlmsg_type == RTM_DELANYCAST) print_bool(PRINT_ANY, "deleted", "Deleted ", true); if (!brief) { @@ -1639,6 +1646,16 @@ rta_tb[IFA_ANYCAST])); } + if (rta_tb[IFA_MULTICAST]) { + print_string(PRINT_FP, NULL, "%s ", "mcast"); + print_color_string(PRINT_ANY, + ifa_family_color(ifa->ifa_family), + "multicast", + "%s ", + format_host_rta(ifa->ifa_family, + rta_tb[IFA_MULTICAST])); + } + print_string(PRINT_ANY, "scope", "scope %s ", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/iplink_rmnet.c new/iproute2-6.14.0/ip/iplink_rmnet.c --- old/iproute2-6.13.0/ip/iplink_rmnet.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/iplink_rmnet.c 2025-03-24 17:04:44.000000000 +0100 @@ -16,6 +16,12 @@ { fprintf(f, "Usage: ... rmnet mux_id MUXID\n" + " [ ingress-deaggregation { on | off } ]\n" + " [ ingress-commands { on | off } ]\n" + " [ ingress-mapv4-checksum { on | off } ]\n" + " [ egress-mapv4-checksum { on | off } ]\n" + " [ ingress-mapv5-checksum { on | off } ]\n" + " [ egress-mapv5-checksum { on | off } ]\n" "\n" "MUXID := 1-254\n" ); @@ -29,15 +35,95 @@ static int rmnet_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { + struct ifla_rmnet_flags flags = { 0 }; __u16 mux_id; + int ret; while (argc > 0) { - if (matches(*argv, "mux_id") == 0) { + if (strcmp(*argv, "mux_id") == 0) { NEXT_ARG(); if (get_u16(&mux_id, *argv, 0)) invarg("mux_id is invalid", *argv); addattr16(n, 1024, IFLA_RMNET_MUX_ID, mux_id); - } else if (matches(*argv, "help") == 0) { + } else if (strcmp(*argv, "ingress-deaggregation") == 0) { + bool deaggregation; + + NEXT_ARG(); + deaggregation = parse_on_off("ingress-deaggregation", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_INGRESS_DEAGGREGATION; + if (deaggregation) + flags.flags |= RMNET_FLAGS_INGRESS_DEAGGREGATION; + else + flags.flags &= ~RMNET_FLAGS_INGRESS_DEAGGREGATION; + } else if (strcmp(*argv, "ingress-commands") == 0) { + bool commands; + + NEXT_ARG(); + commands = parse_on_off("ingress-commands", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_INGRESS_MAP_COMMANDS; + if (commands) + flags.flags |= RMNET_FLAGS_INGRESS_MAP_COMMANDS; + else + flags.flags &= ~RMNET_FLAGS_INGRESS_MAP_COMMANDS; + } else if (strcmp(*argv, "ingress-mapv4-checksum") == 0) { + bool mapv4_checksum; + + NEXT_ARG(); + mapv4_checksum = parse_on_off("ingress-mapv4-checksum", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_INGRESS_MAP_CKSUMV4; + if (mapv4_checksum) + flags.flags |= RMNET_FLAGS_INGRESS_MAP_CKSUMV4; + else + flags.flags &= ~RMNET_FLAGS_INGRESS_MAP_CKSUMV4; + } else if (strcmp(*argv, "egress-mapv4-checksum") == 0) { + bool mapv4_checksum; + + NEXT_ARG(); + mapv4_checksum = parse_on_off("egress-mapv4-checksum", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_EGRESS_MAP_CKSUMV4; + if (mapv4_checksum) + flags.flags |= RMNET_FLAGS_EGRESS_MAP_CKSUMV4; + else + flags.flags &= ~RMNET_FLAGS_EGRESS_MAP_CKSUMV4; + } else if (strcmp(*argv, "ingress-mapv5-checksum") == 0) { + bool mapv5_checksum; + + NEXT_ARG(); + mapv5_checksum = parse_on_off("ingress-mapv5-checksum", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_INGRESS_MAP_CKSUMV5; + if (mapv5_checksum) + flags.flags |= RMNET_FLAGS_INGRESS_MAP_CKSUMV5; + else + flags.flags &= ~RMNET_FLAGS_INGRESS_MAP_CKSUMV5; + } else if (strcmp(*argv, "egress-mapv5-checksum") == 0) { + bool mapv5_checksum; + + NEXT_ARG(); + mapv5_checksum = parse_on_off("egress-mapv5-checksum", *argv, &ret); + if (ret) + return ret; + + flags.mask |= RMNET_FLAGS_EGRESS_MAP_CKSUMV5; + if (mapv5_checksum) + flags.flags |= RMNET_FLAGS_EGRESS_MAP_CKSUMV5; + else + flags.flags &= ~RMNET_FLAGS_EGRESS_MAP_CKSUMV5; + } else if (strcmp(*argv, "help") == 0) { explain(); return -1; } else { @@ -48,11 +134,34 @@ argc--, argv++; } + if (flags.mask) + addattr_l(n, 1024, IFLA_RMNET_FLAGS, &flags, sizeof(flags)); + return 0; } +static void rmnet_print_flags(FILE *fp, __u32 flags) +{ + open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<"); +#define _PF(f) if (flags & RMNET_FLAGS_##f) { \ + flags &= ~RMNET_FLAGS_##f; \ + print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); \ + } + _PF(INGRESS_DEAGGREGATION); + _PF(INGRESS_MAP_COMMANDS); + _PF(INGRESS_MAP_CKSUMV4); + _PF(EGRESS_MAP_CKSUMV4); + _PF(INGRESS_MAP_CKSUMV5); + _PF(EGRESS_MAP_CKSUMV5); +#undef _PF + if (flags) + print_hex(PRINT_ANY, NULL, "%x", flags); + close_json_array(PRINT_ANY, "> "); +} static void rmnet_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { + struct ifla_rmnet_flags *flags; + if (!tb) return; @@ -64,6 +173,13 @@ "mux_id", "mux_id %u ", rta_getattr_u16(tb[IFLA_RMNET_MUX_ID])); + + if (tb[IFLA_RMNET_FLAGS]) { + if (RTA_PAYLOAD(tb[IFLA_RMNET_FLAGS]) < sizeof(*flags)) + return; + flags = RTA_DATA(tb[IFLA_RMNET_FLAGS]); + rmnet_print_flags(f, flags->flags); + } } static void rmnet_print_help(struct link_util *lu, int argc, char **argv, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/iplink_vxlan.c new/iproute2-6.14.0/ip/iplink_vxlan.c --- old/iproute2-6.13.0/ip/iplink_vxlan.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/iplink_vxlan.c 2025-03-24 17:04:44.000000000 +0100 @@ -52,6 +52,7 @@ " [ dev PHYS_DEV ]\n" " [ dstport PORT ]\n" " [ srcport MIN MAX ]\n" + " [ reserved_bits VALUE ]\n" " [ [no]learning ]\n" " [ [no]proxy ]\n" " [ [no]rsc ]\n" @@ -337,6 +338,17 @@ check_duparg(&attrs, IFLA_VXLAN_LOCALBYPASS, *argv, *argv); addattr8(n, 1024, IFLA_VXLAN_LOCALBYPASS, 0); + } else if (strcmp(*argv, "reserved_bits") == 0) { + NEXT_ARG(); + __be64 bits; + + check_duparg(&attrs, IFLA_VXLAN_RESERVED_BITS, + *argv, *argv); + if (get_be64(&bits, *argv, 0)) + invarg("reserved_bits", *argv); + addattr_l(n, 1024, IFLA_VXLAN_RESERVED_BITS, + &bits, sizeof(bits)); + } else if (!matches(*argv, "external")) { check_duparg(&attrs, IFLA_VXLAN_COLLECT_METADATA, *argv, *argv); @@ -601,6 +613,14 @@ ((maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT])) != 0)) print_uint(PRINT_ANY, "limit", "maxaddr %u ", maxaddr); + if (tb[IFLA_VXLAN_RESERVED_BITS]) { + __be64 reserved_bits = + rta_getattr_u64(tb[IFLA_VXLAN_RESERVED_BITS]); + + print_0xhex(PRINT_ANY, "reserved_bits", + "reserved_bits %#llx ", ntohll(reserved_bits)); + } + if (tb[IFLA_VXLAN_GBP]) print_null(PRINT_ANY, "gbp", "gbp ", NULL); if (tb[IFLA_VXLAN_GPE]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/ipmonitor.c new/iproute2-6.14.0/ip/ipmonitor.c --- old/iproute2-6.13.0/ip/ipmonitor.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/ipmonitor.c 2025-03-24 17:04:44.000000000 +0100 @@ -30,8 +30,8 @@ fprintf(stderr, "Usage: ip monitor [ all | OBJECTS ] [ FILE ] [ label ] [ all-nsid ]\n" " [ dev DEVICE ]\n" - "OBJECTS := address | link | mroute | neigh | netconf |\n" - " nexthop | nsid | prefix | route | rule | stats\n" + "OBJECTS := address | link | mroute | maddress | acaddress | neigh |\n" + " netconf | nexthop | nsid | prefix | route | rule | stats\n" "FILE := file FILENAME\n"); exit(-1); } @@ -152,6 +152,13 @@ ipstats_print(n, arg); return 0; + case RTM_DELMULTICAST: + case RTM_NEWMULTICAST: + case RTM_DELANYCAST: + case RTM_NEWANYCAST: + print_addrinfo(n, arg); + return 0; + case NLMSG_ERROR: case NLMSG_NOOP: case NLMSG_DONE: @@ -178,6 +185,8 @@ #define IPMON_LRULE BIT(8) #define IPMON_LNSID BIT(9) #define IPMON_LNEXTHOP BIT(10) +#define IPMON_LMADDR BIT(11) +#define IPMON_LACADDR BIT(12) #define IPMON_L_ALL (~0) @@ -202,6 +211,10 @@ lmask |= IPMON_LLINK; } else if (matches(*argv, "address") == 0) { lmask |= IPMON_LADDR; + } else if (matches(*argv, "maddress") == 0) { + lmask |= IPMON_LMADDR; + } else if (strcmp(*argv, "acaddress") == 0) { + lmask |= IPMON_LACADDR; } else if (matches(*argv, "route") == 0) { lmask |= IPMON_LROUTE; } else if (matches(*argv, "mroute") == 0) { @@ -326,6 +339,30 @@ exit(1); } + if (lmask & IPMON_LMADDR) { + if ((!preferred_family || preferred_family == AF_INET) && + rtnl_add_nl_group(&rth, RTNLGRP_IPV4_MCADDR) < 0) { + fprintf(stderr, + "Failed to add ipv4 mcaddr group to list\n"); + exit(1); + } + if ((!preferred_family || preferred_family == AF_INET6) && + rtnl_add_nl_group(&rth, RTNLGRP_IPV6_MCADDR) < 0) { + fprintf(stderr, + "Failed to add ipv6 mcaddr group to list\n"); + exit(1); + } + } + + if (lmask & IPMON_LACADDR) { + if ((!preferred_family || preferred_family == AF_INET6) && + rtnl_add_nl_group(&rth, RTNLGRP_IPV6_ACADDR) < 0) { + fprintf(stderr, + "Failed to add ipv6 acaddr group to list\n"); + exit(1); + } + } + if (listen_all_nsid && rtnl_listen_all_nsid(&rth) < 0) exit(1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/iproute.c new/iproute2-6.14.0/ip/iproute.c --- old/iproute2-6.13.0/ip/iproute.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/iproute.c 2025-03-24 17:04:44.000000000 +0100 @@ -67,7 +67,7 @@ " [ mark NUMBER ] [ vrf NAME ]\n" " [ uid NUMBER ] [ ipproto PROTOCOL ]\n" " [ sport NUMBER ] [ dport NUMBER ]\n" - " [ as ADDRESS ]\n" + " [ as ADDRESS ] [ flowlabel FLOWLABEL ]\n" " ip route { add | del | change | append | replace } ROUTE\n" "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n" " [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n" @@ -2129,6 +2129,14 @@ invarg("Invalid \"ipproto\" value\n", *argv); addattr8(&req.n, sizeof(req), RTA_IP_PROTO, ipproto); + } else if (strcmp(*argv, "flowlabel") == 0) { + __be32 flowlabel; + + NEXT_ARG(); + if (get_be32(&flowlabel, *argv, 0)) + invarg("invalid flowlabel", *argv); + addattr32(&req.n, sizeof(req), RTA_FLOWLABEL, + flowlabel); } else { inet_prefix addr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/ip/iprule.c new/iproute2-6.14.0/ip/iprule.c --- old/iproute2-6.13.0/ip/iprule.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/ip/iprule.c 2025-03-24 17:04:44.000000000 +0100 @@ -46,7 +46,7 @@ " [ ipproto PROTOCOL ]\n" " [ sport [ NUMBER | NUMBER-NUMBER ]\n" " [ dport [ NUMBER | NUMBER-NUMBER ] ]\n" - " [ dscp DSCP ]\n" + " [ dscp DSCP ] [ flowlabel FLOWLABEL[/MASK] ]\n" "ACTION := [ table TABLE_ID ]\n" " [ protocol PROTO ]\n" " [ nat ADDRESS ]\n" @@ -69,6 +69,7 @@ unsigned int pref, prefmask; unsigned int fwmark, fwmask; unsigned int dscp, dscpmask; + __u32 flowlabel, flowlabel_mask; uint64_t tun_id; char iif[IFNAMSIZ]; char oif[IFNAMSIZ]; @@ -232,6 +233,19 @@ } } + if (filter.flowlabel_mask) { + __u32 flowlabel, flowlabel_mask; + + if (!tb[FRA_FLOWLABEL] || !tb[FRA_FLOWLABEL_MASK]) + return false; + flowlabel = rta_getattr_be32(tb[FRA_FLOWLABEL]); + flowlabel_mask = rta_getattr_be32(tb[FRA_FLOWLABEL_MASK]); + + if (filter.flowlabel != flowlabel || + filter.flowlabel_mask != flowlabel_mask) + return false; + } + table = frh_get_table(frh, tb); if (filter.tb > 0 && filter.tb ^ table) return false; @@ -489,6 +503,23 @@ rtnl_dscp_n2a(dscp, b1, sizeof(b1))); } + /* The kernel will either provide both attributes, or none */ + if (tb[FRA_FLOWLABEL] && tb[FRA_FLOWLABEL_MASK]) { + __u32 flowlabel, flowlabel_mask; + + flowlabel = rta_getattr_be32(tb[FRA_FLOWLABEL]); + flowlabel_mask = rta_getattr_be32(tb[FRA_FLOWLABEL_MASK]); + + print_0xhex(PRINT_ANY, "flowlabel", " flowlabel %#llx", + flowlabel); + if (flowlabel_mask == LABEL_MAX_MASK) + print_0xhex(PRINT_JSON, "flowlabel_mask", NULL, + flowlabel_mask); + else + print_0xhex(PRINT_ANY, "flowlabel_mask", "/%#llx", + flowlabel_mask); + } + print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); fflush(fp); @@ -569,6 +600,24 @@ return 0; } +static void iprule_flowlabel_parse(char *arg, __u32 *flowlabel, + __u32 *flowlabel_mask) +{ + char *slash; + + slash = strchr(arg, '/'); + if (slash != NULL) + *slash = '\0'; + if (get_u32(flowlabel, arg, 0)) + invarg("invalid flowlabel", arg); + if (slash) { + if (get_u32(flowlabel_mask, slash + 1, 0)) + invarg("invalid flowlabel mask", slash + 1); + } else { + *flowlabel_mask = LABEL_MAX_MASK; + } +} + static int iprule_list_flush_or_save(int argc, char **argv, int action) { rtnl_filter_t filter_fn; @@ -726,6 +775,11 @@ invarg("invalid dscp\n", *argv); filter.dscp = dscp; filter.dscpmask = 1; + } else if (strcmp(*argv, "flowlabel") == 0) { + NEXT_ARG(); + + iprule_flowlabel_parse(*argv, &filter.flowlabel, + &filter.flowlabel_mask); } else { if (matches(*argv, "dst") == 0 || matches(*argv, "to") == 0) { @@ -1011,6 +1065,16 @@ if (rtnl_dscp_a2n(&dscp, *argv)) invarg("invalid dscp\n", *argv); addattr8(&req.n, sizeof(req), FRA_DSCP, dscp); + } else if (strcmp(*argv, "flowlabel") == 0) { + __u32 flowlabel, flowlabel_mask; + + NEXT_ARG(); + iprule_flowlabel_parse(*argv, &flowlabel, + &flowlabel_mask); + addattr32(&req.n, sizeof(req), FRA_FLOWLABEL, + htonl(flowlabel)); + addattr32(&req.n, sizeof(req), FRA_FLOWLABEL_MASK, + htonl(flowlabel_mask)); } else { int type; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/lib/fs.c new/iproute2-6.14.0/lib/fs.c --- old/iproute2-6.13.0/lib/fs.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/lib/fs.c 2025-03-24 17:04:44.000000000 +0100 @@ -223,7 +223,8 @@ fd = open_by_handle_at(mnt_fd, fhp, 0); if (fd < 0) { - fprintf(stderr, "Failed to open cgroup2 by ID\n"); + if (errno != ESTALE) + fprintf(stderr, "Failed to open cgroup2 by ID\n"); goto out; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/man/man8/ip-link.8.in new/iproute2-6.14.0/man/man8/ip-link.8.in --- old/iproute2-6.13.0/man/man8/ip-link.8.in 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/man/man8/ip-link.8.in 2025-03-24 17:04:44.000000000 +0100 @@ -632,6 +632,8 @@ ] [ .BI srcport " MIN MAX " ] [ +.BI reserved_bits " VALUE " +] [ .RB [ no ] learning ] [ .RB [ no ] proxy @@ -726,6 +728,13 @@ source ports to communicate to the remote VXLAN tunnel endpoint. .sp +.BI reserved_bits " VALUE " +- by default the kernel rejects packets that have bits set outside of the fields +required by the features enabled on the VXLAN netdevice. \fBreserved_bits\fR is +a 64-bit quantity specifying which bits it should be possible to set in a VXLAN +header. Each bit set in the value is a tolerated bit set in a packet. + +.sp .RB [ no ] learning - specifies if unknown source link layer addresses and IP addresses are entered into the VXLAN device forwarding database. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/man/man8/ip-monitor.8 new/iproute2-6.14.0/man/man8/ip-monitor.8 --- old/iproute2-6.13.0/man/man8/ip-monitor.8 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/man/man8/ip-monitor.8 2025-03-24 17:04:44.000000000 +0100 @@ -54,8 +54,9 @@ .I OBJECT-LIST is the list of object types that we want to monitor. It may contain -.BR link ", " address ", " route ", " mroute ", " prefix ", " -.BR neigh ", " netconf ", " rule ", " stats ", " nsid " and " nexthop "." +.BR link ", " address ", " route ", " mroute ", " maddress ", " acaddress ", " +.BR prefix ", "neigh ", " netconf ", " rule ", " stats ", " nsid " and " +.BR nexthop "." If no .B file argument is given, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/man/man8/ip-route.8.in new/iproute2-6.14.0/man/man8/ip-route.8.in --- old/iproute2-6.13.0/man/man8/ip-route.8.in 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/man/man8/ip-route.8.in 2025-03-24 17:04:44.000000000 +0100 @@ -47,7 +47,9 @@ .B dport .IR NUMBER " ] [" .B as -.IR ADDRESS " ]" +.IR ADDRESS " ] [" +.B flowlabel +.IR FLOWLABEL " ] .ti -8 .BR "ip route" " { " add " | " del " | " change " | " append " | "\ @@ -214,7 +216,13 @@ .B tos .IR TOS " ] [" .B ttl -.IR TTL " ]" +.IR TTL " ] [" +.BR key " ] [" +.BR csum " ] [" +.BR seq " ] [" +.IR GENEVE_OPTS " | " +.IR VXLAN_OPTS " | " +.IR ERSPAN_OPTS " ]" .ti -8 .IR ENCAP_BPF " := " @@ -781,15 +789,58 @@ .in +2 .B id .I TUNNEL_ID +- Tunnel ID (for example VNI in VXLAN tunnel) +.sp + .B dst -.IR REMOTE_IP " [ " +.I REMOTE_IP +- Outer header destination IP address (IPv4 or IPv6) +.sp + .B src -.IR SRC " ] [" +.I SRC +- Outer header source IP address (IPv4 or IPv6) +.sp + .B tos -.IR TOS " ] [" -.B ttl -.IR TTL " ] [ " -.BR key " ] [ " csum " ] [ " seq " ] " +.I TOS +- Outer header TOS +.sp + +.B ttl +.I TTL +- Outer header TTL +.sp + +.B key +- Outer header flags with key in GRE tunnel +.sp + +.B csum +- Outer header flags with csum in GRE tunnel +.sp + +.B seq +- Outer header flags with seq in GRE tunnel +.sp + +.I GENEVE_OPTS +- Specified in the form CLASS:TYPE:DATA, where CLASS is represented as a +16bit hexadecimal value, TYPE as an 8bit hexadecimal value and DATA as a +variable length hexadecimal value. Additionally multiple options may be +listed using a comma delimiter. +.sp + +.I VXLAN_OPTS +- Specified in the form GBP, as a 32bit number. Multiple options is not +supported. +.sp + +.I ERSPAN_OPTS +- Specified in the form VERSION:INDEX:DIR:HWID, where VERSION is represented +as a 8bit number, INDEX as an 32bit number, DIR and HWID as a 8bit number. +Multiple options is not supported. Note INDEX is used when VERSION is 1, +and DIR and HWID are used when VERSION is 2. .in -2 .sp @@ -1316,6 +1367,10 @@ address received from the first lookup. If policy routing is used, it may be a different route. +.TP +.BI flowlabel " FLOWLABEL" +ipv6 flow label as seen by the route lookup + .P Note that this operation is not equivalent to .BR "ip route show" . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/man/man8/ip-rule.8.in new/iproute2-6.14.0/man/man8/ip-rule.8.in --- old/iproute2-6.13.0/man/man8/ip-rule.8.in 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/man/man8/ip-rule.8.in 2025-03-24 17:04:44.000000000 +0100 @@ -58,7 +58,9 @@ .IR NUMBER " | " .IR NUMBER "-" NUMBER " ] ] [ " .B tun_id -.IR TUN_ID " ]" +.IR TUN_ID " ] [ " +.B flowlabel +.IR FLOWLABEL\fR[\fB/\fIMASK "] ]" .BR @@ -322,6 +324,10 @@ masquerades them to this address. Using map-to instead of nat means the same thing. +.TP +.BI flowlabel " FLOWLABEL\fR[\fB/\fIMASK\fR]" +select the IPv6 flow label to match with an optional mask. + .B Warning: Changes to the RPDB made with these commands do not become active immediately. It is assumed that after a script finishes a batch of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/misc/ss.c new/iproute2-6.14.0/misc/ss.c --- old/iproute2-6.13.0/misc/ss.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/misc/ss.c 2025-03-24 17:04:44.000000000 +0100 @@ -3055,16 +3055,16 @@ rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_TOKEN_LOC]), rta_getattr_u8(tb[MPTCP_SUBFLOW_ATTR_ID_LOC])); if (tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ]) - out(" seq:%llx", + out(" seq:%llu", rta_getattr_u64(tb[MPTCP_SUBFLOW_ATTR_MAP_SEQ])); if (tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ]) - out(" sfseq:%x", + out(" sfseq:%u", rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_SFSEQ])); if (tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET]) - out(" ssnoff:%x", + out(" ssnoff:%u", rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_SSN_OFFSET])); if (tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN]) - out(" maplen:%x", + out(" maplen:%u", rta_getattr_u32(tb[MPTCP_SUBFLOW_ATTR_MAP_DATALEN])); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/tc/m_nat.c new/iproute2-6.14.0/tc/m_nat.c --- old/iproute2-6.13.0/tc/m_nat.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/tc/m_nat.c 2025-03-24 17:04:44.000000000 +0100 @@ -55,7 +55,7 @@ goto bad_val; sel->old_addr = addr.data[0]; - sel->mask = htonl(~0u << (32 - addr.bitlen)); + sel->mask = htonl(~(uint64_t)0 << (32 - addr.bitlen)); NEXT_ARG(); @@ -156,7 +156,7 @@ } sel = RTA_DATA(tb[TCA_NAT_PARMS]); - len = ffs(sel->mask); + len = ffs(ntohl(sel->mask)); len = len ? 33 - len : 0; print_string(PRINT_ANY, "direction", "%s", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iproute2-6.13.0/tc/q_fq.c new/iproute2-6.14.0/tc/q_fq.c --- old/iproute2-6.13.0/tc/q_fq.c 2025-01-20 19:49:12.000000000 +0100 +++ new/iproute2-6.14.0/tc/q_fq.c 2025-03-24 17:04:44.000000000 +0100 @@ -32,7 +32,8 @@ " [ timer_slack TIME]\n" " [ ce_threshold TIME ]\n" " [ horizon TIME ]\n" - " [ horizon_{cap|drop} ]\n"); + " [ horizon_{cap|drop} ]\n" + " [ offload_horizon TIME ]\n"); } static unsigned int ilog2(unsigned int val) @@ -64,6 +65,7 @@ unsigned int ce_threshold; unsigned int timer_slack; unsigned int horizon; + unsigned int offload_horizon; __u8 horizon_drop = 255; bool set_plimit = false; bool set_flow_plimit = false; @@ -79,6 +81,7 @@ bool set_horizon = false; bool set_priomap = false; bool set_weights = false; + bool set_offload_horizon = false; int weights[FQ_BANDS]; int pacing = -1; struct rtattr *tail; @@ -155,6 +158,13 @@ return -1; } set_horizon = true; + } else if (strcmp(*argv, "offload_horizon") == 0) { + NEXT_ARG(); + if (get_time(&offload_horizon, *argv)) { + fprintf(stderr, "Illegal \"offload_horizon\"\n"); + return -1; + } + set_offload_horizon = true; } else if (strcmp(*argv, "defrate") == 0) { NEXT_ARG(); if (strchr(*argv, '%')) { @@ -333,6 +343,9 @@ if (set_weights) addattr_l(n, 1024, TCA_FQ_WEIGHTS, weights, sizeof(weights)); + if (set_offload_horizon) + addattr_l(n, 1024, TCA_FQ_OFFLOAD_HORIZON, + &offload_horizon, sizeof(offload_horizon)); addattr_nest_end(n, tail); return 0; } @@ -348,6 +361,7 @@ unsigned int orphan_mask; unsigned int ce_threshold; unsigned int timer_slack; + __u32 offload_horizon; unsigned int horizon; __u8 horizon_drop; @@ -487,6 +501,14 @@ print_null(PRINT_ANY, "horizon_drop", "horizon_drop ", NULL); } + if (tb[TCA_FQ_OFFLOAD_HORIZON] && + RTA_PAYLOAD(tb[TCA_FQ_OFFLOAD_HORIZON]) >= sizeof(__u32)) { + offload_horizon = rta_getattr_u32(tb[TCA_FQ_OFFLOAD_HORIZON]); + print_uint(PRINT_JSON, "offload_horizon", NULL, offload_horizon); + print_string(PRINT_FP, NULL, "offload_horizon %s ", + sprint_time(offload_horizon, b1)); + } + return 0; }