Skip to content
Snippets Groups Projects
Select Git revision
  • d0fbb81a658aa8f9add60e42e71f1d7046ddfd34
  • v2018.2.x default protected
  • 0x4A6F-rpi4
  • 0x4A6F-master
  • master
  • v2018.2.2-ffs
  • v2016.2.4-batmanbug
  • radv-filterd
  • v2016.2.x
  • hoodselector
  • v2016.1.x
  • babel
  • v2015.1.x
  • 2014.4.x
  • 2014.3.x
  • v2018.2.2-ffs0.1
  • v2018.2.1-ffs0.1
  • v2018.2.1
  • v2018.2-ffs0.1
  • v2018.2
  • v2018.1.4
  • v2018.1.3
  • v2018.1.2
  • v2018.1.1
  • v2018.1
  • v2017.1.8
  • v2017.1.7
  • v2017.1.6
  • v2017.1.5
  • v2017.1.4
  • v2017.1.3
  • v2017.1.2
  • v2016.2.7
  • v2017.1.1
  • v2017.1
35 results

0015-base-files-always-use-staged-sysupgrade.patch

Blame
  • Forked from firmware / FFS Gluon
    Source project has a limited visibility.
    • Matthias Schiffer's avatar
      d0fbb81a
      modules: update LEDE · d0fbb81a
      Matthias Schiffer authored
      9b0a4bafbce7 base-files: tune fragment queue thresholds for available system memory
      b47094ce96ff include/package-defaults.mk: fix default Build/Prepare with empty ./src
      75be005e8bdc include/rootfs.mk: retain list of conffiles with CONFIG_CLEAN_IPKG
      696c6325a3a7 include/rootfs.mk: do not remove opkg prerm scripts during rootfs preparation
      17c0362178ca base-files: sysupgrade: do not rely on opkg to list changed conffiles
      2ae9ebf37402 kernel: bump 4.4 to 4.4.120 for 17.01
      571d3def6baf x86: add preinit hook to reload microcode
      681aaaf719ec firmware: add microcode package for Intel
      c6314ee06f94 firmware: add microcode package for AMD
      222521d5937a tools: add iucode-tool
      f7a6b6724a63 x86: enable microcode loading for Intel and AMD
      dfe620cb93c0 odhcpd: fix interop with wide DHCPv6 client (FS#1377)
      18c999a6ff33 base-files: fix off-by-one in counting seconds for factory reset
      92ea65b36aa7 sunxi: disable LPAE to allow kernel to run on A13
      7dcbe0e22dbb bcm53xx: fix fallback code for picking status LED
      4db583b9c2ab mountd: update to the latest version from 2018-02-26
      modules: update LEDE
      Matthias Schiffer authored
      9b0a4bafbce7 base-files: tune fragment queue thresholds for available system memory
      b47094ce96ff include/package-defaults.mk: fix default Build/Prepare with empty ./src
      75be005e8bdc include/rootfs.mk: retain list of conffiles with CONFIG_CLEAN_IPKG
      696c6325a3a7 include/rootfs.mk: do not remove opkg prerm scripts during rootfs preparation
      17c0362178ca base-files: sysupgrade: do not rely on opkg to list changed conffiles
      2ae9ebf37402 kernel: bump 4.4 to 4.4.120 for 17.01
      571d3def6baf x86: add preinit hook to reload microcode
      681aaaf719ec firmware: add microcode package for Intel
      c6314ee06f94 firmware: add microcode package for AMD
      222521d5937a tools: add iucode-tool
      f7a6b6724a63 x86: enable microcode loading for Intel and AMD
      dfe620cb93c0 odhcpd: fix interop with wide DHCPv6 client (FS#1377)
      18c999a6ff33 base-files: fix off-by-one in counting seconds for factory reset
      92ea65b36aa7 sunxi: disable LPAE to allow kernel to run on A13
      7dcbe0e22dbb bcm53xx: fix fallback code for picking status LED
      4db583b9c2ab mountd: update to the latest version from 2018-02-26
    gluon-simple-tc.c 6.82 KiB
    /*
      Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
      All rights reserved.
    
      Redistribution and use in source and binary forms, with or without
      modification, are permitted provided that the following conditions are met:
    
        1. Redistributions of source code must retain the above copyright notice,
           this list of conditions and the following disclaimer.
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
    
      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
      FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
      CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
      OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    
    #define _GNU_SOURCE
    
    #include <errno.h>
    #include <error.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <arpa/inet.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    
    #include <net/if.h>
    
    #include <linux/if_ether.h>
    #include <linux/pkt_cls.h>
    #include <linux/pkt_sched.h>
    #include <linux/rtnetlink.h>
    
    
    #include <netlink/msg.h>
    #include <netlink/attr.h>
    #include <netlink/socket.h>
    
    
    static struct nl_cb *cb;
    static struct nl_sock *sock;
    static double ticks;
    
    static unsigned ifindex;
    
    static bool nlexpect;
    static int nlerror;
    
    
    static inline void exit_errno(const char *message) {
    	error(1, errno, "error: %s", message);
    }
    
    static inline void warn_errno(const char *message) {
    	error(0, errno, "warning: %s", message);
    }
    
    
    static void read_psched(void) {
    	uint32_t clock_res;
    	uint32_t t2us;
    	uint32_t us2t;
    
    	FILE *f = fopen("/proc/net/psched", "r");
    	if (!f || fscanf(f, "%08x %08x %08x", &t2us, &us2t, &clock_res) != 3)
    		exit_errno("error reading /proc/net/psched");
    	fclose(f);
    
    	/* compatibility hack from iproute... */
    	if (clock_res == 1000000000)
    		t2us = us2t;
    
    	ticks = (double)t2us / us2t * clock_res;
    }
    
    
    static struct nl_msg * prepare_tcmsg(int type, int flags, uint32_t parent, uint32_t handle, uint32_t info) {
    	struct nl_msg *msg = nlmsg_alloc_simple(type, flags);
    	if (!msg)
    		exit_errno("nlmsg_alloc_simple");
    
    	struct tcmsg tcmsg;
    	memset(&tcmsg, 0, sizeof(tcmsg));
    
    	tcmsg.tcm_family = AF_UNSPEC;
    	tcmsg.tcm_ifindex = ifindex;
    	tcmsg.tcm_parent = parent;
    	tcmsg.tcm_handle = handle;
    	tcmsg.tcm_info = info;
    
    	nlmsg_append(msg, &tcmsg, sizeof(tcmsg), NLMSG_ALIGNTO);
    
    	return msg;
    }
    
    
    static int error_handler(struct sockaddr_nl *nla __attribute__((unused)), struct nlmsgerr *nlerr, void *arg __attribute__((unused))) {
    	if (!nlexpect || (nlerr->error != -ENOENT && nlerr->error != -EINVAL))
    		nlerror = -nlerr->error;
    
    	return NL_STOP;
    }
    
    static bool do_send(struct nl_msg *msg, bool expect) {
    	nlerror = 0;
    	nlexpect = expect;
    
    	nl_send_auto_complete(sock, msg);
    	nlmsg_free(msg);
    	nl_wait_for_ack(sock);
    
    	if (nlerror) {
    		error(0, nlerror, "netlink");
    		errno = nlerror;
    		return false;
    	}
    
    	return true;
    }
    
    
    static inline unsigned get_xmittime(double rate, unsigned size) {
    	return ticks * (size/rate);
    }
    
    
    static void complete_rate(struct tc_ratespec *r, uint32_t rtab[256]) {
    	r->linklayer = TC_LINKLAYER_ETHERNET;
    	r->cell_align = -1;
    	r->cell_log = 3;
    
    	unsigned i;
    	for (i = 0; i < 256; i++)
    		rtab[i] = get_xmittime(r->rate, (i + 1) << 3);
    }
    
    
    static void do_ingress(double rate) {
    	if (!do_send(prepare_tcmsg(RTM_DELQDISC, 0, TC_H_INGRESS, 0xffff0000, 0), true))
    		return;
    
    	if (rate < 0)
    		return;
    
    
    	struct nl_msg *msg = prepare_tcmsg(RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, TC_H_INGRESS, 0xffff0000, 0);
    	nla_put_string(msg, TCA_KIND, "ingress");
    
    	if (!do_send(msg, false))
    		return;
    
    
    	msg = prepare_tcmsg(RTM_NEWTFILTER, NLM_F_CREATE | NLM_F_EXCL, 0xffff0000, 0, TC_H_MAKE(0, htons(ETH_P_ALL)));
    
    	const unsigned buffer = 10240;
    
    	struct tc_police p;
    	memset(&p, 0, sizeof(p));
    
    	/* Range check has been done in main() */
    	p.rate.rate = rate;
    	p.burst = get_xmittime(p.rate.rate, buffer);
    	p.action = TC_POLICE_SHOT;
    
    	uint32_t rtab[256];
    	complete_rate(&p.rate, rtab);
    
    	nla_put_string(msg, TCA_KIND, "basic");
    
    	struct nlattr *opts = nla_nest_start(msg, TCA_OPTIONS);
    	struct nlattr *police = nla_nest_start(msg, TCA_BASIC_POLICE);
    
    	nla_put(msg, TCA_POLICE_TBF, sizeof(p), &p);
    	nla_put(msg, TCA_POLICE_RATE, sizeof(rtab), rtab);
    
    	nla_nest_end(msg, police);
    	nla_nest_end(msg, opts);
    
    	do_send(msg, false);
    }
    
    static void do_egress(double rate) {
    	if (!do_send(prepare_tcmsg(RTM_DELQDISC, 0, TC_H_ROOT, 0, 0), true))
    		return;
    
    	if (rate < 0)
    		return;
    
    
    	struct nl_msg *msg = prepare_tcmsg(RTM_NEWQDISC, NLM_F_CREATE | NLM_F_EXCL, TC_H_ROOT, 0, 0);
    	const unsigned buffer = 2048;
    
    	struct tc_tbf_qopt opt;
    	memset(&opt, 0, sizeof(opt));
    
    	/* Range check has been done in main() */
    	opt.rate.rate = rate;
    	opt.limit = 0.05*rate + buffer;
    	opt.buffer = get_xmittime(opt.rate.rate, buffer);
    
    	uint32_t rtab[256];
    	complete_rate(&opt.rate, rtab);
    
    	nla_put_string(msg, TCA_KIND, "tbf");
    
    	struct nlattr *opts = nla_nest_start(msg, TCA_OPTIONS);
    	nla_put(msg, TCA_TBF_PARMS, sizeof(opt), &opt);
    	nla_put(msg, TCA_TBF_BURST, sizeof(buffer), &buffer);
    	nla_put(msg, TCA_TBF_RTAB, sizeof(rtab), rtab);
    	nla_nest_end(msg, opts);
    
    	do_send(msg, false);
    }
    
    
    static inline void usage(void) {
    	fprintf(stderr, "Usage: gluon-simple-tc <interface> <ingress Kbit/s>|- <egress Kbit/s>|-\n");
    	exit(1);
    }
    
    static inline void maxrate(void) {
    	error(1, 0, "error: maximum allowed rate it about 2^25 Kbit/s");
    }
    
    
    int main(int argc, char *argv[]) {
    	if (argc != 4)
    		usage();
    
    	double ingress = -1, egress = -1;
    	char *end;
    
    	ifindex = if_nametoindex(argv[1]);
    	if (!ifindex)
    		error(1, 0, "invalid interface: %s", argv[1]);
    
    	if (strcmp(argv[2], "-") != 0) {
    		ingress = strtod(argv[2], &end);
    		if (*end || ingress < 0)
    			usage();
    
    		ingress *= 125;
    
    		if (ingress >= (1ull << 32))
    			maxrate();
    	}
    
    	if (strcmp(argv[3], "-") != 0) {
    		egress = strtod(argv[3], &end);
    		if (*end || egress < 0)
    			usage();
    
    		egress *= 125;
    
    		if (egress >= (1ull << 32))
    			maxrate();
    	}
    
    	read_psched();
    
    	cb = nl_cb_alloc(NL_CB_DEFAULT);
    	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
    
    	sock = nl_socket_alloc_cb(cb);
    	if (!sock)
    		exit_errno("nl_socket_alloc");
    
    	if (nl_connect(sock, NETLINK_ROUTE))
    		exit_errno("nl_connect");
    
    	do_ingress(ingress);
    	do_egress(egress);
    
    	nl_socket_free(sock);
    	nl_cb_put(cb);
    
    	return 0;
    }