Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • firmware/gluon
  • 0x4A6F/gluon
  • patrick/gluon
3 results
Select Git revision
Show changes
Showing
with 0 additions and 2850 deletions
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 24 Jan 2018 21:34:54 +0100
Subject: ar71xx: add unaligned access hacks for VXLAN
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
index 374f9be3b4b76984842d3673ea78b70aadc9476a..3b6ed31556cbd1fa81bb6b616fc78e19b56099c4 100644
--- a/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
+++ b/target/linux/ar71xx/patches-4.4/910-unaligned_access_hacks.patch
@@ -929,3 +929,119 @@
};
if (skb->ip_summed != CHECKSUM_PARTIAL) {
*sum = csum_fold(csum_partial(diff, sizeof(diff),
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1759,8 +1759,8 @@ static int vxlan6_xmit_skb(struct dst_en
+ }
+
+ vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
+- vxh->vx_flags = htonl(VXLAN_HF_VNI);
+- vxh->vx_vni = vni;
++ net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
++ net_hdr_word(&vxh->vx_vni) = vni;
+
+ if (type & SKB_GSO_TUNNEL_REMCSUM) {
+ u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
+@@ -1769,8 +1769,8 @@ static int vxlan6_xmit_skb(struct dst_en
+ if (skb->csum_offset == offsetof(struct udphdr, check))
+ data |= VXLAN_RCO_UDP;
+
+- vxh->vx_vni |= htonl(data);
+- vxh->vx_flags |= htonl(VXLAN_HF_RCO);
++ net_hdr_word(&vxh->vx_vni) |= htonl(data);
++ net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
+
+ if (!skb_is_gso(skb)) {
+ skb->ip_summed = CHECKSUM_NONE;
+@@ -1838,8 +1838,8 @@ static int vxlan_xmit_skb(struct rtable
+ return PTR_ERR(skb);
+
+ vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
+- vxh->vx_flags = htonl(VXLAN_HF_VNI);
+- vxh->vx_vni = vni;
++ net_hdr_word(&vxh->vx_flags) = htonl(VXLAN_HF_VNI);
++ net_hdr_word(&vxh->vx_vni) = vni;
+
+ if (type & SKB_GSO_TUNNEL_REMCSUM) {
+ u32 data = (skb_checksum_start_offset(skb) - hdrlen) >>
+@@ -1848,8 +1848,8 @@ static int vxlan_xmit_skb(struct rtable
+ if (skb->csum_offset == offsetof(struct udphdr, check))
+ data |= VXLAN_RCO_UDP;
+
+- vxh->vx_vni |= htonl(data);
+- vxh->vx_flags |= htonl(VXLAN_HF_RCO);
++ net_hdr_word(&vxh->vx_vni) |= htonl(data);
++ net_hdr_word(&vxh->vx_flags) |= htonl(VXLAN_HF_RCO);
+
+ if (!skb_is_gso(skb)) {
+ skb->ip_summed = CHECKSUM_NONE;
+--- a/include/linux/etherdevice.h
++++ b/include/linux/etherdevice.h
+@@ -409,7 +409,7 @@ static inline bool is_etherdev_addr(cons
+ * @b: Pointer to Ethernet header
+ *
+ * Compare two Ethernet headers, returns 0 if equal.
+- * This assumes that the network header (i.e., IP header) is 4-byte
++ * This assumes that the network header (i.e., IP header) is 2-byte
+ * aligned OR the platform can handle unaligned access. This is the
+ * case for all packets coming into netif_receive_skb or similar
+ * entry points.
+@@ -432,11 +432,12 @@ static inline unsigned long compare_ethe
+ fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
+ return fold;
+ #else
+- u32 *a32 = (u32 *)((u8 *)a + 2);
+- u32 *b32 = (u32 *)((u8 *)b + 2);
++ const u16 *a16 = a;
++ const u16 *b16 = b;
+
+- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
+- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
++ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
++ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
++ (a16[6] ^ b16[6]);
+ #endif
+ }
+
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -221,7 +221,7 @@ struct sk_buff **tcp_gro_receive(struct
+
+ th2 = tcp_hdr(p);
+
+- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
++ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
+ NAPI_GRO_CB(p)->same_flow = 0;
+ continue;
+ }
+@@ -239,8 +239,8 @@ found:
+ ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
+ flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
+ for (i = sizeof(*th); i < thlen; i += 4)
+- flush |= *(u32 *)((u8 *)th + i) ^
+- *(u32 *)((u8 *)th2 + i);
++ flush |= net_hdr_word((u8 *)th + i) ^
++ net_hdr_word((u8 *)th2 + i);
+
+ mss = skb_shinfo(p)->gso_size;
+
+--- a/net/ipv6/netfilter/ip6table_mangle.c
++++ b/net/ipv6/netfilter/ip6table_mangle.c
+@@ -55,7 +55,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
+ hop_limit = ipv6_hdr(skb)->hop_limit;
+
+ /* flowlabel and prio (includes version, which shouldn't change either */
+- flowlabel = *((u_int32_t *)ipv6_hdr(skb));
++ flowlabel = net_hdr_word(ipv6_hdr(skb));
+
+ ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle);
+
+@@ -64,7 +64,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
+ !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
+ skb->mark != mark ||
+ ipv6_hdr(skb)->hop_limit != hop_limit ||
+- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
++ flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
+ err = ip6_route_me_harder(state->net, skb);
+ if (err < 0)
+ ret = NF_DROP_ERR(err);
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 24 Jan 2018 20:53:32 +0100
Subject: netifd: system-linux: VXLAN: add options to enable and disable UDP checksums
diff --git a/package/network/config/netifd/patches/0002-system-linux-VXLAN-add-options-to-enable-and-disable.patch b/package/network/config/netifd/patches/0002-system-linux-VXLAN-add-options-to-enable-and-disable.patch
new file mode 100644
index 0000000000000000000000000000000000000000..67a8bb864be37fa97dfcce4dd841bacafefcd0fc
--- /dev/null
+++ b/package/network/config/netifd/patches/0002-system-linux-VXLAN-add-options-to-enable-and-disable.patch
@@ -0,0 +1,65 @@
+From af3cadb6a46ba93e8a729e71d82b176275931e62 Mon Sep 17 00:00:00 2001
+Message-Id: <af3cadb6a46ba93e8a729e71d82b176275931e62.1516821520.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Wed, 24 Jan 2018 13:21:44 +0100
+Subject: [PATCH] system-linux: VXLAN: add options to enable and disable UDP
+ checksums
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ system-linux.c | 11 +++++++++++
+ system.c | 2 ++
+ system.h | 2 ++
+ 3 files changed, 15 insertions(+)
+
+diff --git a/system-linux.c b/system-linux.c
+index 32d6ffc..0277886 100644
+--- a/system-linux.c
++++ b/system-linux.c
+@@ -2841,6 +2841,17 @@ static int system_add_vxlan(const char *name, const unsigned int link, struct bl
+ }
+ nla_put_u16(msg, IFLA_VXLAN_PORT, htons(port));
+
++ if ((cur = tb_data[VXLAN_DATA_ATTR_RXCSUM])) {
++ bool rxcsum = blobmsg_get_bool(cur);
++ nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, !rxcsum);
++ }
++
++ if ((cur = tb_data[VXLAN_DATA_ATTR_TXCSUM])) {
++ bool txcsum = blobmsg_get_bool(cur);
++ nla_put_u8(msg, IFLA_VXLAN_UDP_CSUM, txcsum);
++ nla_put_u8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, !txcsum);
++ }
++
+ if ((cur = tb[TUNNEL_ATTR_TOS])) {
+ char *str = blobmsg_get_string(cur);
+ unsigned tos = 1;
+diff --git a/system.c b/system.c
+index 5555272..e236e96 100644
+--- a/system.c
++++ b/system.c
+@@ -36,6 +36,8 @@ static const struct blobmsg_policy vxlan_data_attrs[__VXLAN_DATA_ATTR_MAX] = {
+ [VXLAN_DATA_ATTR_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
+ [VXLAN_DATA_ATTR_PORT] = { .name = "port", .type = BLOBMSG_TYPE_INT32 },
+ [VXLAN_DATA_ATTR_MACADDR] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING },
++ [VXLAN_DATA_ATTR_RXCSUM] = { .name = "rxcsum", .type = BLOBMSG_TYPE_BOOL },
++ [VXLAN_DATA_ATTR_TXCSUM] = { .name = "txcsum", .type = BLOBMSG_TYPE_BOOL },
+ };
+
+ const struct uci_blob_param_list vxlan_data_attr_list = {
+diff --git a/system.h b/system.h
+index 61c72c2..371a524 100644
+--- a/system.h
++++ b/system.h
+@@ -41,6 +41,8 @@ enum vxlan_data {
+ VXLAN_DATA_ATTR_ID,
+ VXLAN_DATA_ATTR_PORT,
+ VXLAN_DATA_ATTR_MACADDR,
++ VXLAN_DATA_ATTR_RXCSUM,
++ VXLAN_DATA_ATTR_TXCSUM,
+ __VXLAN_DATA_ATTR_MAX
+ };
+
+--
+2.16.1
+
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Wed, 24 Jan 2018 13:51:45 +0100
Subject: vxlan: add options to enable and disable UDP checksums
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/network/config/vxlan/Makefile b/package/network/config/vxlan/Makefile
index a471d4e90cbe30c1d1dd01dbf7553995d8c0485e..aeceb9cd884e517b2f274925637b62a538bfa70e 100644
--- a/package/network/config/vxlan/Makefile
+++ b/package/network/config/vxlan/Makefile
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=vxlan
-PKG_VERSION:=1
+PKG_VERSION:=2
PKG_LICENSE:=GPL-2.0
include $(INCLUDE_DIR)/package.mk
diff --git a/package/network/config/vxlan/files/vxlan.sh b/package/network/config/vxlan/files/vxlan.sh
index 27ccd8f12759f69c7c226cac0c923335b8ccc6a8..d055d41edc59f50c0c132849bbcd0235edeef5b9 100755
--- a/package/network/config/vxlan/files/vxlan.sh
+++ b/package/network/config/vxlan/files/vxlan.sh
@@ -15,8 +15,8 @@ vxlan_generic_setup() {
local link="$cfg"
- local port vid ttl tos mtu macaddr zone
- json_get_vars port vid ttl tos mtu macaddr zone
+ local port vid ttl tos mtu macaddr zone rxcsum txcsum
+ json_get_vars port vid ttl tos mtu macaddr zone rxcsum txcsum
proto_init_update "$link" 1
@@ -36,6 +36,8 @@ vxlan_generic_setup() {
[ -n "$port" ] && json_add_int port "$port"
[ -n "$vid" ] && json_add_int id "$vid"
[ -n "$macaddr" ] && json_add_string macaddr "$macaddr"
+ [ -n "$rxcsum" ] && json_add_boolean rxcsum "$rxcsum"
+ [ -n "$txcsum" ] && json_add_boolean txcsum "$txcsum"
json_close_object
proto_close_tunnel
From: Vincent Wiemann <me@bibbl.com>
Date: Sat, 6 Jan 2018 04:33:09 +0100
Subject: ramips: mtd: spi-nor: add support for switching between 3-byte and 4-byte addressing on w25q256 flash
CAUTION! NEEDS TESTING!
Tries to backport switching between 3-byte and 4-byte addressing on w25q256 flash from Lede master (62ede4f78389c313a8004e79330a7d055eda2f7d) by Felix Fietkau.
Applied patches:
mtd: spi-nor: rename SPINOR_OP_* macros of the 4-byte address op codes
mtd: spi-nor: add a stateless method to support memory size above 128Mib
mtd: spi-nor: add w25q256 3b-mode-switch
mtd: add chunked read-io to m25p80
On some devices the flash chip needs to be in 3-byte addressing mode during
reboot, otherwise the boot loader will fail to start.
This mode however does not allow regular reads/writes onto the upper 16M
half. W25Q256 has separate read commands for reading from >16M, however
it does not have any separate write commands.
This patch changes the code to leave the chip in 3-byte mode most of the
time and only switch during erase/write cycles that go to >16M
addresses.
Signed-off-by: Vincent Wiemann (me@bibbl.com)
diff --git a/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch b/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5399f547e4edd0eb1cfee8c1ec5b35e69c692ee9
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch
@@ -0,0 +1,399 @@
+--- a/drivers/mtd/devices/serial_flash_cmds.h
++++ b/drivers/mtd/devices/serial_flash_cmds.h
+@@ -18,19 +18,12 @@
+ #define SPINOR_OP_RDVCR 0x85
+
+ /* JEDEC Standard - Serial Flash Discoverable Parmeters (SFDP) Commands */
+-#define SPINOR_OP_READ_1_2_2 0xbb /* DUAL I/O READ */
+-#define SPINOR_OP_READ_1_4_4 0xeb /* QUAD I/O READ */
+-
+ #define SPINOR_OP_WRITE 0x02 /* PAGE PROGRAM */
+ #define SPINOR_OP_WRITE_1_1_2 0xa2 /* DUAL INPUT PROGRAM */
+ #define SPINOR_OP_WRITE_1_2_2 0xd2 /* DUAL INPUT EXT PROGRAM */
+ #define SPINOR_OP_WRITE_1_1_4 0x32 /* QUAD INPUT PROGRAM */
+ #define SPINOR_OP_WRITE_1_4_4 0x12 /* QUAD INPUT EXT PROGRAM */
+
+-/* READ commands with 32-bit addressing */
+-#define SPINOR_OP_READ4_1_2_2 0xbc
+-#define SPINOR_OP_READ4_1_4_4 0xec
+-
+ /* Configuration flags */
+ #define FLASH_FLAG_SINGLE 0x000000ff
+ #define FLASH_FLAG_READ_WRITE 0x00000001
+--- a/drivers/mtd/devices/st_spi_fsm.c
++++ b/drivers/mtd/devices/st_spi_fsm.c
+@@ -507,13 +507,13 @@ static struct seq_rw_config n25q_read3_c
+ * - 'FAST' variants configured for 8 dummy cycles (see note above.)
+ */
+ static struct seq_rw_config n25q_read4_configs[] = {
+- {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ4_1_4_4, 0, 4, 4, 0x00, 0, 8},
+- {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ4_1_1_4, 0, 1, 4, 0x00, 0, 8},
+- {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ4_1_2_2, 0, 2, 2, 0x00, 0, 8},
+- {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ4_1_1_2, 0, 1, 2, 0x00, 0, 8},
+- {FLASH_FLAG_READ_FAST, SPINOR_OP_READ4_FAST, 0, 1, 1, 0x00, 0, 8},
+- {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ4, 0, 1, 1, 0x00, 0, 0},
+- {0x00, 0, 0, 0, 0, 0x00, 0, 0},
++ {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B, 0, 4, 4, 0x00, 0, 8},
++ {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B, 0, 1, 4, 0x00, 0, 8},
++ {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B, 0, 2, 2, 0x00, 0, 8},
++ {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B, 0, 1, 2, 0x00, 0, 8},
++ {FLASH_FLAG_READ_FAST, SPINOR_OP_READ_FAST_4B, 0, 1, 1, 0x00, 0, 8},
++ {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ_4B, 0, 1, 1, 0x00, 0, 0},
++ {0x00, 0, 0, 0, 0, 0x00, 0, 0},
+ };
+
+ /*
+@@ -553,13 +553,13 @@ static int stfsm_mx25_en_32bit_addr_seq(
+ * entering a state that is incompatible with the SPIBoot Controller.
+ */
+ static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
+- {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ4_1_4_4, 0, 4, 4, 0x00, 2, 4},
+- {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ4_1_1_4, 0, 1, 4, 0x00, 0, 8},
+- {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ4_1_2_2, 0, 2, 2, 0x00, 4, 0},
+- {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ4_1_1_2, 0, 1, 2, 0x00, 0, 8},
+- {FLASH_FLAG_READ_FAST, SPINOR_OP_READ4_FAST, 0, 1, 1, 0x00, 0, 8},
+- {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ4, 0, 1, 1, 0x00, 0, 0},
+- {0x00, 0, 0, 0, 0, 0x00, 0, 0},
++ {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B, 0, 4, 4, 0x00, 2, 4},
++ {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B, 0, 1, 4, 0x00, 0, 8},
++ {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B, 0, 2, 2, 0x00, 4, 0},
++ {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B, 0, 1, 2, 0x00, 0, 8},
++ {FLASH_FLAG_READ_FAST, SPINOR_OP_READ_FAST_4B, 0, 1, 1, 0x00, 0, 8},
++ {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ_4B, 0, 1, 1, 0x00, 0, 0},
++ {0x00, 0, 0, 0, 0, 0x00, 0, 0},
+ };
+
+ static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -69,6 +69,14 @@ struct flash_info {
+ #define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */
+ #define USE_FSR 0x80 /* use flag status register */
+ #define SPI_NOR_HAS_LOCK 0x100 /* Flash supports lock/unlock via SR */
++#define SPI_NOR_4B_OPCODES 0x200 /*
++ * Use dedicated 4byte address op codes
++ * to support memory size above 128Mib.
++ */
++#define SPI_NOR_4B_READ_OP 0x400 /*
++ * Like SPI_NOR_4B_OPCODES, but for read
++ * op code only.
++ */
+ };
+
+ #define JEDEC_MFR(info) ((info)->id[0])
+@@ -182,6 +190,89 @@ static inline struct spi_nor *mtd_to_spi
+ return mtd->priv;
+ }
+
++
++static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
++{
++ size_t i;
++
++ for (i = 0; i < size; i++)
++ if (table[i][0] == opcode)
++ return table[i][1];
++
++ /* No conversion found, keep input op code. */
++ return opcode;
++}
++
++static inline u8 spi_nor_convert_3to4_read(u8 opcode)
++{
++ static const u8 spi_nor_3to4_read[][2] = {
++ { SPINOR_OP_READ, SPINOR_OP_READ_4B },
++ { SPINOR_OP_READ_FAST, SPINOR_OP_READ_FAST_4B },
++ { SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B },
++ { SPINOR_OP_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B },
++ { SPINOR_OP_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B },
++ { SPINOR_OP_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B },
++ };
++
++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
++ ARRAY_SIZE(spi_nor_3to4_read));
++}
++
++static inline u8 spi_nor_convert_3to4_program(u8 opcode)
++{
++ static const u8 spi_nor_3to4_program[][2] = {
++ { SPINOR_OP_PP, SPINOR_OP_PP_4B },
++ { SPINOR_OP_PP_1_1_4, SPINOR_OP_PP_1_1_4_4B },
++ { SPINOR_OP_PP_1_4_4, SPINOR_OP_PP_1_4_4_4B },
++ };
++
++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_program,
++ ARRAY_SIZE(spi_nor_3to4_program));
++}
++
++static inline u8 spi_nor_convert_3to4_erase(u8 opcode)
++{
++ static const u8 spi_nor_3to4_erase[][2] = {
++ { SPINOR_OP_BE_4K, SPINOR_OP_BE_4K_4B },
++ { SPINOR_OP_BE_32K, SPINOR_OP_BE_32K_4B },
++ { SPINOR_OP_SE, SPINOR_OP_SE_4B },
++ };
++
++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase,
++ ARRAY_SIZE(spi_nor_3to4_erase));
++}
++
++static void spi_nor_set_4byte_read(struct spi_nor *nor,
++ const struct flash_info *info)
++{
++ nor->addr_width = 3;
++ nor->ext_addr = 0;
++ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
++ nor->flags |= SNOR_F_4B_EXT_ADDR;
++}
++
++
++
++static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
++ const struct flash_info *info)
++{
++ /* Do some manufacturer fixups first */
++ switch (JEDEC_MFR(info)) {
++ case SNOR_MFR_SPANSION:
++ /* No small sector erase for 4-byte command set */
++ nor->erase_opcode = SPINOR_OP_SE;
++ nor->mtd.erasesize = info->sector_size;
++ break;
++
++ default:
++ break;
++ }
++
++ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
++ nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode);
++ nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode);
++}
++
+ /* Enable/disable 4-byte addressing mode. */
+ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
+ int enable)
+@@ -313,6 +404,36 @@ static void spi_nor_unlock_and_unprep(st
+ mutex_unlock(&nor->lock);
+ }
+
++static int spi_nor_check_ext_addr(struct spi_nor *nor, u32 addr)
++{
++ bool ext_addr;
++ int ret;
++ u8 cmd;
++
++ if (!(nor->flags & SNOR_F_4B_EXT_ADDR))
++ return 0;
++
++ ext_addr = !!(addr & 0xff000000);
++ if (nor->ext_addr == ext_addr)
++ return 0;
++
++ cmd = ext_addr ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
++ write_enable(nor);
++ ret = nor->write_reg(nor, cmd, NULL, 0);
++ if (ret)
++ return ret;
++
++ cmd = 0;
++ ret = nor->write_reg(nor, SPINOR_OP_WREAR, &cmd, 1);
++ if (ret)
++ return ret;
++
++ nor->addr_width = 3 + ext_addr;
++ nor->ext_addr = ext_addr;
++ write_disable(nor);
++ return 0;
++}
++
+ /*
+ * Erase an address range on the nor chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+@@ -338,6 +459,10 @@ static int spi_nor_erase(struct mtd_info
+ if (ret)
+ return ret;
+
++ ret = spi_nor_check_ext_addr(nor, addr + len);
++ if (ret)
++ return ret;
++
+ /* whole-chip erase? */
+ if (len == mtd->size) {
+ unsigned long timeout;
+@@ -396,6 +521,7 @@ static int spi_nor_erase(struct mtd_info
+ return ret;
+
+ erase_err:
++ spi_nor_check_ext_addr(nor, 0);
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
+ instr->state = MTD_ERASE_FAILED;
+ return ret;
+@@ -585,7 +711,9 @@ static int spi_nor_lock(struct mtd_info
+ if (ret)
+ return ret;
+
++ spi_nor_check_ext_addr(nor, ofs + len);
+ ret = nor->flash_lock(nor, ofs, len);
++ spi_nor_check_ext_addr(nor, 0);
+
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
+ return ret;
+@@ -600,7 +728,9 @@ static int spi_nor_unlock(struct mtd_inf
+ if (ret)
+ return ret;
+
++ spi_nor_check_ext_addr(nor, ofs + len);
+ ret = nor->flash_unlock(nor, ofs, len);
++ spi_nor_check_ext_addr(nor, 0);
+
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
+ return ret;
+@@ -851,7 +981,7 @@ static const struct flash_info spi_nor_i
+ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
+ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_READ_OP) },
+
+ /* Catalyst / On Semiconductor -- non-JEDEC */
+ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+@@ -898,8 +1028,23 @@ static int spi_nor_read(struct mtd_info
+ if (ret)
+ return ret;
+
++ if (nor->flags & SNOR_F_4B_EXT_ADDR)
++ nor->addr_width = 4;
++
+ ret = nor->read(nor, from, len, retlen, buf);
+
++ if (nor->flags & SNOR_F_4B_EXT_ADDR) {
++ u8 val = 0;
++
++ if ((from + len) & 0xff000000) {
++ write_enable(nor);
++ nor->write_reg(nor, SPINOR_OP_WREAR, &val, 1);
++ write_disable(nor);
++ }
++
++ nor->addr_width = 3;
++ }
++
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
+ return ret;
+ }
+@@ -988,6 +1133,10 @@ static int spi_nor_write(struct mtd_info
+ if (ret)
+ return ret;
+
++ ret = spi_nor_check_ext_addr(nor, to + len);
++ if (ret < 0)
++ return ret;
++
+ write_enable(nor);
+
+ page_offset = to & (nor->page_size - 1);
+@@ -1018,6 +1167,7 @@ static int spi_nor_write(struct mtd_info
+
+ ret = spi_nor_wait_till_ready(nor);
+ write_err:
++ spi_nor_check_ext_addr(nor, 0);
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+ return ret;
+ }
+@@ -1366,27 +1516,12 @@ int spi_nor_scan(struct spi_nor *nor, co
+ else if (mtd->size > 0x1000000) {
+ /* enable 4-byte addressing if the device exceeds 16MiB */
+ nor->addr_width = 4;
+- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) {
+- /* Dedicated 4-byte command set */
+- switch (nor->flash_read) {
+- case SPI_NOR_QUAD:
+- nor->read_opcode = SPINOR_OP_READ4_1_1_4;
+- break;
+- case SPI_NOR_DUAL:
+- nor->read_opcode = SPINOR_OP_READ4_1_1_2;
+- break;
+- case SPI_NOR_FAST:
+- nor->read_opcode = SPINOR_OP_READ4_FAST;
+- break;
+- case SPI_NOR_NORMAL:
+- nor->read_opcode = SPINOR_OP_READ4;
+- break;
+- }
+- nor->program_opcode = SPINOR_OP_PP_4B;
+- /* No small sector erase for 4-byte command set */
+- nor->erase_opcode = SPINOR_OP_SE_4B;
+- mtd->erasesize = info->sector_size;
+- } else
++ if (info->flags & SPI_NOR_4B_READ_OP)
++ spi_nor_set_4byte_read(nor, info);
++ else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
++ info->flags & SPI_NOR_4B_OPCODES)
++ spi_nor_set_4byte_opcodes(nor, info);
++ else
+ set_4byte(nor, info, 1);
+ } else {
+ nor->addr_width = 3;
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -42,9 +42,13 @@
+ #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */
+ #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */
+ #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
+-#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
+-#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
++#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */
++#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */
++#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */
++#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */
+ #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
++#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */
++#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */
+ #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
+ #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
+ #define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */
+@@ -55,11 +59,17 @@
+ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
+
+ /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
+-#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */
+-#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
+-#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
+-#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
++#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */
++#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */
++#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */
++#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */
++#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */
++#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */
+ #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
++#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */
++#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */
++#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */
++#define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */
+ #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
+
+ /* Used for SST flashes only. */
+@@ -70,6 +80,7 @@
+ /* Used for Macronix and Winbond flashes. */
+ #define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */
+ #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */
++#define SPINOR_OP_WREAR 0xc5 /* Write extended address register */
+
+ /* Used for Spansion flashes only. */
+ #define SPINOR_OP_BRWR 0x17 /* Bank register write */
+@@ -117,6 +128,7 @@ enum spi_nor_ops {
+ enum spi_nor_option_flags {
+ SNOR_F_USE_FSR = BIT(0),
+ SNOR_F_SST = BIT(1),
++ SNOR_F_4B_EXT_ADDR = BIT(5),
+ };
+
+ /**
+@@ -166,6 +178,7 @@ struct spi_nor {
+ enum read_mode flash_read;
+ bool sst_write_second;
+ u32 flags;
++ u8 ext_addr;
+ u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+
+ int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
diff --git a/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch b/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b6111abad7063951c07688c66854fa743daeb6c6
--- /dev/null
+++ b/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch
@@ -0,0 +1,21 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -1176,6 +1176,7 @@ static int spi_nor_chunked_write(struct
+ size_t *_retlen, const u_char *_buf)
+ {
+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
++ u32 addr_width = nor->addr_width + !!(nor->flags & SNOR_F_4B_EXT_ADDR);
+ int chunk_size;
+ int retlen = 0;
+ int ret;
+@@ -1184,8 +1185,8 @@ static int spi_nor_chunked_write(struct
+ if (!chunk_size)
+ chunk_size = _len;
+
+- if (nor->addr_width > 3)
+- chunk_size -= nor->addr_width - 3;
++ if (addr_width > 3)
++ chunk_size -= addr_width - 3;
+
+ while (retlen < _len) {
+ size_t len = min_t(int, chunk_size, _len - retlen);
From: Mathias Kresin <dev@kresin.me>
Date: Fri, 7 Apr 2017 23:52:27 +0200
Subject: ramips: prepare ZBT-WG3526 for hardware variants
The ZBT-WG3526 is available with 16 or 32 MByte of flash. Rename the
current supported 16MByte version to indicate which flash size variant
is supported.
Signed-off-by: Mathias Kresin <dev@kresin.me>
Conflicts (Resolved):
target/linux/ramips/image/mt7621.mk
Signed-off-by: Vincent Wiemann <me@bibbl.com>
further adjustments for backport to lede-17.01 branch
Signed-off-by: Andreas Ziegler <github@andreas-ziegler.de>
diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
index b1091f66b2897a19bd01d4a26a1b3647656fa62b..8e27a79fc1744d6bed9db8d930207c418899cab1 100755
--- a/target/linux/ramips/base-files/lib/ramips.sh
+++ b/target/linux/ramips/base-files/lib/ramips.sh
@@ -637,8 +637,8 @@ ramips_board_detect() {
*"ZBT-WG2626")
name="zbt-wg2626"
;;
- *"ZBT-WG3526")
- name="zbt-wg3526"
+ *"ZBT-WG3526 (16M)")
+ name="zbt-wg3526-16M"
;;
*"ZBT-WR8305RT")
name="zbt-wr8305rt"
diff --git a/target/linux/ramips/dts/ZBT-WG3526-16M.dts b/target/linux/ramips/dts/ZBT-WG3526-16M.dts
new file mode 100644
index 0000000000000000000000000000000000000000..fb644502071d6641194c66baf552035937f35669
--- /dev/null
+++ b/target/linux/ramips/dts/ZBT-WG3526-16M.dts
@@ -0,0 +1,15 @@
+/dts-v1/;
+
+#include "ZBT-WG3526.dtsi"
+
+/ {
+ model = "ZBT-WG3526 (16M)";
+};
+
+&firmware {
+ reg = <0x50000 0xfb0000>;
+};
+
+&status_led {
+ label = "zbt-wg3526:green:status";
+};
diff --git a/target/linux/ramips/dts/ZBT-WG3526.dts b/target/linux/ramips/dts/ZBT-WG3526.dts
deleted file mode 100644
index c361bdd827bffdc24405b1a1b191403ebeec46d0..0000000000000000000000000000000000000000
--- a/target/linux/ramips/dts/ZBT-WG3526.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/dts-v1/;
-
-#include "ZBT-WG3526.dtsi"
-
-/ {
- model = "ZBT-WG3526";
-};
-
-&firmware {
- reg = <0x50000 0xfb0000>;
-};
-
-&status_led {
- label = "zbt-wg3526:green:status";
-};
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index 8218bea84410536151a216cd2cc0300369ad977a..cabc86b28eb040f0d1e58d917e6edc4a97e80db7 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -226,13 +226,14 @@ define Device/zbt-wg2626
endef
TARGET_DEVICES += zbt-wg2626
-define Device/zbt-wg3526
- DTS := ZBT-WG3526
+define Device/zbt-wg3526-16M
+ DTS := ZBT-WG3526-16M
IMAGE_SIZE := $(ralink_default_fw_size_16M)
- DEVICE_TITLE := ZBT WG3526
+ SUPPORTED_DEVICES += zbt-wg3526
+ DEVICE_TITLE := ZBT WG3526 (16MB flash)
DEVICE_PACKAGES := kmod-usb3 kmod-usb-ledtrig-usbport kmod-ata-core kmod-ata-ahci
endef
-TARGET_DEVICES += zbt-wg3526
+TARGET_DEVICES += zbt-wg3526-16M
# FIXME: is this still needed?
define Image/Prepare
From: Mathias Kresin <dev@kresin.me>
Date: Sat, 1 Apr 2017 10:46:44 +0200
Subject: ramips: rename Digineo AC1200 Pro to ZBT-WG3526 32MB
The Digineo AC1200 Pro is the 32MB flash variant of the ZBT-WG3526 with
unpopulated/exposed sdhci slot. Rename to board to the OEM/ODM name and
add the sdhci kernel module to use it for multiple clones.
Signed-off-by: Mathias Kresin <dev@kresin.me>
Conflicts (Resolved):
target/linux/ramips/base-files/etc/diag.sh
Signed-off-by: Vincent Wiemann <me@bibbl.com>
further adjustments for backport to lede-17.01 branch
Signed-off-by: Andreas Ziegler <github@andreas-ziegler.de>
diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
index 5a4042339c6761703578e014612062ac78babd9d..b9c8fe774fedab34267a8635033b9235d9d6c3aa 100755
--- a/target/linux/ramips/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/base-files/etc/board.d/02_network
@@ -70,7 +70,6 @@ ramips_setup_interfaces()
ucidef_set_interface_lan "eth0.2"
;;
3g-6200n|\
- ac1200pro|\
ai-br100|\
d240|\
db-wrt01|\
diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh
index 9dbd6c4141d7facef2108cbb5cf3a7057522c88e..c4f521954c74635c61f42558f0d9b71f0f671c22 100644
--- a/target/linux/ramips/base-files/etc/diag.sh
+++ b/target/linux/ramips/base-files/etc/diag.sh
@@ -59,7 +59,10 @@ get_status_led() {
wn3000rpv3)
status_led="$board:red:power"
;;
- ac1200pro|\
+ ai-br100|\
+ ht-tm02)
+ status_led="$board:blue:wlan"
+ ;;
all0239-3g|\
dcs-930|\
dir-300-b1|\
@@ -85,10 +88,6 @@ get_status_led() {
zbt-wg3526)
status_led="$board:green:status"
;;
- ai-br100|\
- ht-tm02)
- status_led="$board:blue:wlan"
- ;;
atp-52b|\
ip2202)
status_led="$board:green:run"
diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
index 8e27a79fc1744d6bed9db8d930207c418899cab1..b9279a5a1e9baf55ca7f59dbb22ac0b0b7b01db4 100755
--- a/target/linux/ramips/base-files/lib/ramips.sh
+++ b/target/linux/ramips/base-files/lib/ramips.sh
@@ -130,9 +130,6 @@ ramips_board_detect() {
*"DCS-930L B1")
name="dcs-930l-b1"
;;
- *"Digineo AC1200 Pro")
- name="ac1200pro"
- ;;
*"DIR-300 B1")
name="dir-300-b1"
;;
@@ -640,6 +637,9 @@ ramips_board_detect() {
*"ZBT-WG3526 (16M)")
name="zbt-wg3526-16M"
;;
+ *"ZBT-WG3526 (32M)")
+ name="zbt-wg3526-32M"
+ ;;
*"ZBT-WR8305RT")
name="zbt-wr8305rt"
;;
diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
index d3efc2dd37ed855a1c0e966e448b67ae73324d5f..a45275077df8fa317c38adc8f0ab12fd4b0ecb83 100755
--- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
@@ -17,7 +17,6 @@ platform_check_image() {
3g150b|\
3g300m|\
a5-v11|\
- ac1200pro|\
ai-br100|\
air3gii|\
all0239-3g|\
diff --git a/target/linux/ramips/dts/AC1200pro.dts b/target/linux/ramips/dts/AC1200pro.dts
deleted file mode 100644
index fbec81844025cf2a6544dec8dfeca02fce89fdc1..0000000000000000000000000000000000000000
--- a/target/linux/ramips/dts/AC1200pro.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/dts-v1/;
-
-#include "ZBT-WG3526.dtsi"
-
-/ {
- model = "Digineo AC1200 Pro";
-};
-
-&firmware {
- reg = <0x50000 0x1fb0000>;
-};
-
-&status_led {
- label = "ac1200pro:green:status";
-};
diff --git a/target/linux/ramips/dts/ZBT-WG3526-16M.dts b/target/linux/ramips/dts/ZBT-WG3526-16M.dts
index fb644502071d6641194c66baf552035937f35669..1e2f1525028f69468257cd8af8d5bad0319bc551 100644
--- a/target/linux/ramips/dts/ZBT-WG3526-16M.dts
+++ b/target/linux/ramips/dts/ZBT-WG3526-16M.dts
@@ -9,7 +9,3 @@
&firmware {
reg = <0x50000 0xfb0000>;
};
-
-&status_led {
- label = "zbt-wg3526:green:status";
-};
diff --git a/target/linux/ramips/dts/ZBT-WG3526-32M.dts b/target/linux/ramips/dts/ZBT-WG3526-32M.dts
new file mode 100644
index 0000000000000000000000000000000000000000..99a4b45824ba4ee6c1a1c81615291c8efde1a7ac
--- /dev/null
+++ b/target/linux/ramips/dts/ZBT-WG3526-32M.dts
@@ -0,0 +1,11 @@
+/dts-v1/;
+
+#include "ZBT-WG3526.dtsi"
+
+/ {
+ model = "ZBT-WG3526 (32M)";
+};
+
+&firmware {
+ reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/ZBT-WG3526.dtsi b/target/linux/ramips/dts/ZBT-WG3526.dtsi
index 582e42083920c465588f14e59e10eafe735640fb..5e195fb8120d3a66f19acf83c9f76bb4b1ec3e7e 100644
--- a/target/linux/ramips/dts/ZBT-WG3526.dtsi
+++ b/target/linux/ramips/dts/ZBT-WG3526.dtsi
@@ -35,7 +35,8 @@
gpio-leds {
compatible = "gpio-leds";
- status_led: status {
+ status {
+ label = "zbt-wg3526:green:status";
gpios = <&gpio0 24 1>;
};
};
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index cabc86b28eb040f0d1e58d917e6edc4a97e80db7..aa84d78b9e42259cbee7de6c052fa7ab500a040a 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -34,14 +34,6 @@ define Device/11acnas
endef
TARGET_DEVICES += 11acnas
-define Device/ac1200pro
- DTS := AC1200pro
- IMAGE_SIZE := $(ralink_default_fw_size_32M)
- DEVICE_TITLE := Digineo AC1200 Pro
- DEVICE_PACKAGES := kmod-usb3 kmod-ata-core kmod-ata-ahci
-endef
-TARGET_DEVICES += ac1200pro
-
define Device/dir-860l-b1
DTS := DIR-860L-B1
BLOCKSIZE := 64k
@@ -235,6 +227,15 @@ define Device/zbt-wg3526-16M
endef
TARGET_DEVICES += zbt-wg3526-16M
+define Device/zbt-wg3526-32M
+ DTS := ZBT-WG3526-32M
+ IMAGE_SIZE := $(ralink_default_fw_size_32M)
+ SUPPORTED_DEVICES += ac1200pro
+ DEVICE_TITLE := ZBT WG3526 (32MB flash)
+ DEVICE_PACKAGES := kmod-usb3 kmod-usb-ledtrig-usbport kmod-ata-core kmod-ata-ahci kmod-sdhci-mt7620
+endef
+TARGET_DEVICES += zbt-wg3526-32M
+
# FIXME: is this still needed?
define Image/Prepare
#define Build/Compile
From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Sun, 26 Nov 2017 05:19:21 +0100
Subject: kernel: bridge: ebtables: Avoid resetting limit rule state
Link: https://patchwork.ozlabs.org/patch/841210/
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
diff --git a/target/linux/generic/patches-4.4/121-bridge-ebtables-Avoid-resetting-limit-rule-state.patch b/target/linux/generic/patches-4.4/121-bridge-ebtables-Avoid-resetting-limit-rule-state.patch
new file mode 100644
index 0000000000000000000000000000000000000000..417fdd75e543ebb6a3fdd56cb97fc83324eeb104
--- /dev/null
+++ b/target/linux/generic/patches-4.4/121-bridge-ebtables-Avoid-resetting-limit-rule-state.patch
@@ -0,0 +1,50 @@
+From 535097827e437bfa1906ed3210e6504750f4342b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Sat, 25 Nov 2017 00:36:13 +0100
+Subject: [PATCH] bridge: ebtables: Avoid resetting limit rule state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far any changes with ebtables will reset the state of limit rules,
+leading to spikes in traffic. This is especially noticeable if changes
+are done frequently, for instance via a daemon.
+
+This patch fixes this by bailing out from (re)setting if the limit
+rule was initialized before.
+
+When sending packets every 250ms for 600s, with a
+"--limit 1/sec --limit-burst 50" rule and a command like this
+in the background:
+
+$ ebtables -N VOIDCHAIN
+$ while true; do ebtables -F VOIDCHAIN; sleep 30; done
+
+The results are:
+
+Before: ~1600 packets
+After: 650 packets
+
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+---
+ net/bridge/netfilter/ebt_limit.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
+index 61a9f1be1263..f74b48633feb 100644
+--- a/net/bridge/netfilter/ebt_limit.c
++++ b/net/bridge/netfilter/ebt_limit.c
+@@ -69,6 +69,10 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
+ {
+ struct ebt_limit_info *info = par->matchinfo;
+
++ /* Do not reset state on unrelated table changes */
++ if (info->prev)
++ return 0;
++
+ /* Check for overflow. */
+ if (info->burst == 0 ||
+ user2credits(info->avg * info->burst) < user2credits(info->avg)) {
+--
+2.11.0
+
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Sun, 4 Mar 2018 10:26:34 +0100
Subject: ebtables: add support for ICMP/IGMP type matches
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/network/utils/ebtables/patches/301-0001-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch b/package/network/utils/ebtables/patches/301-0001-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b6f42c6a4affc9bb04a6ac9269698e751a932f2a
--- /dev/null
+++ b/package/network/utils/ebtables/patches/301-0001-include-sync-linux-netfilter_bridge-ebt_ip.h-with-ke.patch
@@ -0,0 +1,56 @@
+From 44fcc3392bb7d52df2ad52b8e9437255b8c29d5a Mon Sep 17 00:00:00 2001
+Message-Id: <44fcc3392bb7d52df2ad52b8e9437255b8c29d5a.1520151963.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 3 Mar 2018 12:14:48 +0100
+Subject: [PATCH ebtables 1/4] include: sync linux/netfilter_bridge/ebt_ip.h
+ with kernel
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ include/linux/netfilter_bridge/ebt_ip.h | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/linux/netfilter_bridge/ebt_ip.h
+index c4bbc41b0ea4..46d6261370b0 100644
+--- a/include/linux/netfilter_bridge/ebt_ip.h
++++ b/include/linux/netfilter_bridge/ebt_ip.h
+@@ -1,3 +1,4 @@
++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+ /*
+ * ebt_ip
+ *
+@@ -23,8 +24,10 @@
+ #define EBT_IP_PROTO 0x08
+ #define EBT_IP_SPORT 0x10
+ #define EBT_IP_DPORT 0x20
++#define EBT_IP_ICMP 0x40
++#define EBT_IP_IGMP 0x80
+ #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
+- EBT_IP_SPORT | EBT_IP_DPORT )
++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
+ #define EBT_IP_MATCH "ip"
+
+ /* the same values are used for the invflags */
+@@ -37,8 +40,15 @@ struct ebt_ip_info {
+ __u8 protocol;
+ __u8 bitmask;
+ __u8 invflags;
+- __u16 sport[2];
+- __u16 dport[2];
++ union {
++ __u16 sport[2];
++ __u8 icmp_type[2];
++ __u8 igmp_type[2];
++ };
++ union {
++ __u16 dport[2];
++ __u8 icmp_code[2];
++ };
+ };
+
+ #endif
+--
+2.16.2
+
diff --git a/package/network/utils/ebtables/patches/301-0002-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch b/package/network/utils/ebtables/patches/301-0002-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c3eaec4412fcaebffa84b409a0a66e2f714a0e8d
--- /dev/null
+++ b/package/network/utils/ebtables/patches/301-0002-Move-ICMP-type-handling-functions-from-ebt_ip6-to-us.patch
@@ -0,0 +1,465 @@
+From e40c68fcf13e2244ab6c87844126167e998ccb56 Mon Sep 17 00:00:00 2001
+Message-Id: <e40c68fcf13e2244ab6c87844126167e998ccb56.1520151963.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sun, 4 Mar 2018 08:18:18 +0100
+Subject: [PATCH ebtables 2/4] Move ICMP type handling functions from ebt_ip6
+ to useful_functions.c
+
+Allow using these functions for ebt_ip as well.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ extensions/ebt_ip6.c | 165 +++------------------------------------------------
+ include/ebtables_u.h | 17 +++++-
+ useful_functions.c | 151 +++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 174 insertions(+), 159 deletions(-)
+
+diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c
+index dd48547b0010..347797b4afe1 100644
+--- a/extensions/ebt_ip6.c
++++ b/extensions/ebt_ip6.c
+@@ -11,9 +11,6 @@
+ *
+ */
+
+-#include <errno.h>
+-#include <inttypes.h>
+-#include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -51,13 +48,7 @@ static const struct option opts[] =
+ };
+
+
+-struct icmpv6_names {
+- const char *name;
+- uint8_t type;
+- uint8_t code_min, code_max;
+-};
+-
+-static const struct icmpv6_names icmpv6_codes[] = {
++static const struct ebt_icmp_names icmpv6_codes[] = {
+ { "destination-unreachable", 1, 0, 0xFF },
+ { "no-route", 1, 0, 0 },
+ { "communication-prohibited", 1, 1, 1 },
+@@ -141,97 +132,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
+ free(buffer);
+ }
+
+-static char*
+-parse_num(const char *str, long min, long max, long *num)
+-{
+- char *end;
+-
+- errno = 0;
+- *num = strtol(str, &end, 10);
+- if (errno && (*num == LONG_MIN || *num == LONG_MAX)) {
+- ebt_print_error("Invalid number %s: %s", str, strerror(errno));
+- return NULL;
+- }
+- if (min <= max) {
+- if (*num > max || *num < min) {
+- ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max);
+- return NULL;
+- }
+- }
+- if (*num == 0 && str == end)
+- return NULL;
+- return end;
+-}
+-
+-static char *
+-parse_range(const char *str, long min, long max, long num[])
+-{
+- char *next;
+-
+- next = parse_num(str, min, max, num);
+- if (next == NULL)
+- return NULL;
+- if (next && *next == ':')
+- next = parse_num(next+1, min, max, &num[1]);
+- else
+- num[1] = num[0];
+- return next;
+-}
+-
+-static int
+-parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[])
+-{
+- static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
+- unsigned int match = limit;
+- unsigned int i;
+- long number[2];
+-
+- for (i = 0; i < limit; i++) {
+- if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)))
+- continue;
+- if (match != limit)
+- ebt_print_error("Ambiguous ICMPv6 type `%s':"
+- " `%s' or `%s'?",
+- icmpv6type, icmpv6_codes[match].name,
+- icmpv6_codes[i].name);
+- match = i;
+- }
+-
+- if (match < limit) {
+- type[0] = type[1] = icmpv6_codes[match].type;
+- code[0] = icmpv6_codes[match].code_min;
+- code[1] = icmpv6_codes[match].code_max;
+- } else {
+- char *next = parse_range(icmpv6type, 0, 255, number);
+- if (!next) {
+- ebt_print_error("Unknown ICMPv6 type `%s'",
+- icmpv6type);
+- return -1;
+- }
+- type[0] = (uint8_t) number[0];
+- type[1] = (uint8_t) number[1];
+- switch (*next) {
+- case 0:
+- code[0] = 0;
+- code[1] = 255;
+- return 0;
+- case '/':
+- next = parse_range(next+1, 0, 255, number);
+- code[0] = (uint8_t) number[0];
+- code[1] = (uint8_t) number[1];
+- if (next == NULL)
+- return -1;
+- if (next && *next == 0)
+- return 0;
+- /* fallthrough */
+- default:
+- ebt_print_error("unknown character %c", *next);
+- return -1;
+- }
+- }
+- return 0;
+-}
+-
+ static void print_port_range(uint16_t *ports)
+ {
+ if (ports[0] == ports[1])
+@@ -240,58 +140,6 @@ static void print_port_range(uint16_t *ports)
+ printf("%d:%d ", ports[0], ports[1]);
+ }
+
+-static void print_icmp_code(uint8_t *code)
+-{
+- if (code[0] == code[1])
+- printf("/%"PRIu8 " ", code[0]);
+- else
+- printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
+-}
+-
+-static void print_icmp_type(uint8_t *type, uint8_t *code)
+-{
+- unsigned int i;
+-
+- if (type[0] != type[1]) {
+- printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
+- print_icmp_code(code);
+- return;
+- }
+-
+- for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) {
+- if (icmpv6_codes[i].type != type[0])
+- continue;
+-
+- if (icmpv6_codes[i].code_min == code[0] &&
+- icmpv6_codes[i].code_max == code[1]) {
+- printf("%s ", icmpv6_codes[i].name);
+- return;
+- }
+- }
+- printf("%"PRIu8, type[0]);
+- print_icmp_code(code);
+-}
+-
+-static void print_icmpv6types(void)
+-{
+- unsigned int i;
+- printf("Valid ICMPv6 Types:");
+-
+- for (i=0; i < ARRAY_SIZE(icmpv6_codes); i++) {
+- if (i && icmpv6_codes[i].type == icmpv6_codes[i-1].type) {
+- if (icmpv6_codes[i].code_min == icmpv6_codes[i-1].code_min
+- && (icmpv6_codes[i].code_max
+- == icmpv6_codes[i-1].code_max))
+- printf(" (%s)", icmpv6_codes[i].name);
+- else
+- printf("\n %s", icmpv6_codes[i].name);
+- }
+- else
+- printf("\n%s", icmpv6_codes[i].name);
+- }
+- printf("\n");
+-}
+-
+ static void print_help()
+ {
+ printf(
+@@ -303,7 +151,9 @@ static void print_help()
+ "--ip6-sport [!] port[:port] : tcp/udp source port or port range\n"
+ "--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n"
+ "--ip6-icmp-type [!] type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n");
+-print_icmpv6types();
++
++ printf("\nValid ICMPv6 Types:\n");
++ ebt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes));
+ }
+
+ static void init(struct ebt_entry_match *match)
+@@ -374,7 +224,9 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ ipinfo->bitmask |= EBT_IP6_ICMP6;
+ if (ebt_check_inverse2(optarg))
+ ipinfo->invflags |= EBT_IP6_ICMP6;
+- if (parse_icmpv6(optarg, ipinfo->icmpv6_type, ipinfo->icmpv6_code))
++ if (ebt_parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes),
++ optarg, ipinfo->icmpv6_type,
++ ipinfo->icmpv6_code))
+ return 0;
+ break;
+
+@@ -493,7 +345,8 @@ static void print(const struct ebt_u_entry *entry,
+ printf("--ip6-icmp-type ");
+ if (ipinfo->invflags & EBT_IP6_ICMP6)
+ printf("! ");
+- print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code);
++ ebt_print_icmp_type(icmpv6_codes, ARRAY_SIZE(icmpv6_codes),
++ ipinfo->icmpv6_type, ipinfo->icmpv6_code);
+ }
+ }
+
+diff --git a/include/ebtables_u.h b/include/ebtables_u.h
+index 35a5bcc54c86..17afa9487f5a 100644
+--- a/include/ebtables_u.h
++++ b/include/ebtables_u.h
+@@ -222,6 +222,15 @@ struct ebt_u_target
+ struct ebt_u_target *next;
+ };
+
++
++struct ebt_icmp_names {
++ const char *name;
++ uint8_t type;
++ uint8_t code_min, code_max;
++};
++
++
++
+ /* libebtc.c */
+
+ extern struct ebt_u_table *ebt_tables;
+@@ -300,11 +309,17 @@ void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
+ int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask);
+ void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk);
+ char *ebt_mask_to_dotted(uint32_t mask);
+-void ebt_parse_ip6_address(char *address, struct in6_addr *addr,
++void ebt_parse_ip6_address(char *address, struct in6_addr *addr,
+ struct in6_addr *msk);
+ char *ebt_ip6_to_numeric(const struct in6_addr *addrp);
+ char *ebt_ip6_mask_to_string(const struct in6_addr *msk);
+
++int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
++ const char *icmptype, uint8_t type[], uint8_t code[]);
++void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes,
++ size_t n_codes, uint8_t *type, uint8_t *code);
++void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes,
++ size_t n_codes);
+
+ int do_command(int argc, char *argv[], int exec_style,
+ struct ebt_u_replace *replace_);
+diff --git a/useful_functions.c b/useful_functions.c
+index d14cbe9dbdba..8f54bae83fae 100644
+--- a/useful_functions.c
++++ b/useful_functions.c
+@@ -24,6 +24,9 @@
+ */
+ #include "include/ebtables_u.h"
+ #include "include/ethernetdb.h"
++#include <errno.h>
++#include <inttypes.h>
++#include <limits.h>
+ #include <stdio.h>
+ #include <netinet/ether.h>
+ #include <string.h>
+@@ -34,6 +37,7 @@
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+
++
+ const unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0};
+ const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0};
+ const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
+@@ -188,7 +192,7 @@ static int undot_ip(char *ip, unsigned char *ip2)
+ return -1;
+ *q = '\0';
+ onebyte = strtol(p, &end, 10);
+- if (*end != '\0' || onebyte > 255 || onebyte < 0)
++ if (*end != '\0' || onebyte > 255 || onebyte < 0)
+ return -1;
+ ip2[i] = (unsigned char)onebyte;
+ p = q + 1;
+@@ -275,7 +279,7 @@ char *ebt_mask_to_dotted(uint32_t mask)
+ *buf = '\0';
+ else
+ /* Mask was not a decent combination of 1's and 0's */
+- sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0],
++ sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0],
+ ((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2],
+ ((unsigned char *)&mask)[3]);
+
+@@ -424,3 +428,146 @@ char *ebt_ip6_mask_to_string(const struct in6_addr *msk)
+ sprintf(buf, "/%s", ebt_ip6_to_numeric(msk));
+ return buf;
+ }
++
++static char*
++parse_num(const char *str, long min, long max, long *num)
++{
++ char *end;
++
++ errno = 0;
++ *num = strtol(str, &end, 10);
++ if (errno && (*num == LONG_MIN || *num == LONG_MAX)) {
++ ebt_print_error("Invalid number %s: %s", str, strerror(errno));
++ return NULL;
++ }
++ if (min <= max) {
++ if (*num > max || *num < min) {
++ ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max);
++ return NULL;
++ }
++ }
++ if (*num == 0 && str == end)
++ return NULL;
++ return end;
++}
++
++static char *
++parse_range(const char *str, long min, long max, long num[])
++{
++ char *next;
++
++ next = parse_num(str, min, max, num);
++ if (next == NULL)
++ return NULL;
++ if (next && *next == ':')
++ next = parse_num(next+1, min, max, &num[1]);
++ else
++ num[1] = num[0];
++ return next;
++}
++
++int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
++ const char *icmptype, uint8_t type[], uint8_t code[])
++{
++ unsigned int match = n_codes;
++ unsigned int i;
++ long number[2];
++
++ for (i = 0; i < n_codes; i++) {
++ if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype)))
++ continue;
++ if (match != n_codes)
++ ebt_print_error("Ambiguous ICMP type `%s':"
++ " `%s' or `%s'?",
++ icmptype, icmp_codes[match].name,
++ icmp_codes[i].name);
++ match = i;
++ }
++
++ if (match < n_codes) {
++ type[0] = type[1] = icmp_codes[match].type;
++ code[0] = icmp_codes[match].code_min;
++ code[1] = icmp_codes[match].code_max;
++ } else {
++ char *next = parse_range(icmptype, 0, 255, number);
++ if (!next) {
++ ebt_print_error("Unknown ICMP type `%s'",
++ icmptype);
++ return -1;
++ }
++ type[0] = (uint8_t) number[0];
++ type[1] = (uint8_t) number[1];
++ switch (*next) {
++ case 0:
++ code[0] = 0;
++ code[1] = 255;
++ return 0;
++ case '/':
++ next = parse_range(next+1, 0, 255, number);
++ code[0] = (uint8_t) number[0];
++ code[1] = (uint8_t) number[1];
++ if (next == NULL)
++ return -1;
++ if (next && *next == 0)
++ return 0;
++ /* fallthrough */
++ default:
++ ebt_print_error("unknown character %c", *next);
++ return -1;
++ }
++ }
++ return 0;
++}
++
++static void print_icmp_code(uint8_t *code)
++{
++ if (code[0] == code[1])
++ printf("/%"PRIu8 " ", code[0]);
++ else
++ printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
++}
++
++void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes,
++ size_t n_codes, uint8_t *type, uint8_t *code)
++{
++ unsigned int i;
++
++ if (type[0] != type[1]) {
++ printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
++ print_icmp_code(code);
++ return;
++ }
++
++ for (i = 0; i < n_codes; i++) {
++ if (icmp_codes[i].type != type[0])
++ continue;
++
++ if (icmp_codes[i].code_min == code[0] &&
++ icmp_codes[i].code_max == code[1]) {
++ printf("%s ", icmp_codes[i].name);
++ return;
++ }
++ }
++ printf("%"PRIu8, type[0]);
++ print_icmp_code(code);
++}
++
++void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes,
++ size_t n_codes)
++{
++ unsigned int i;
++
++ for (i = 0; i < n_codes; i++) {
++ if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
++ if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
++ && (icmp_codes[i].code_max
++ == icmp_codes[i-1].code_max))
++ printf(" (%s)", icmp_codes[i].name);
++ else
++ printf("\n %s", icmp_codes[i].name);
++ }
++ else
++ printf("\n%s", icmp_codes[i].name);
++ }
++ printf("\n");
++}
+--
+2.16.2
+
diff --git a/package/network/utils/ebtables/patches/301-0003-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch b/package/network/utils/ebtables/patches/301-0003-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2c83168933d88535747f0bc18d3ebbe03c6b1f30
--- /dev/null
+++ b/package/network/utils/ebtables/patches/301-0003-ebt_ip-add-support-for-matching-ICMP-type-and-code.patch
@@ -0,0 +1,182 @@
+From 76bc7b4ede217228e782a6d4dfaa67f772a08441 Mon Sep 17 00:00:00 2001
+Message-Id: <76bc7b4ede217228e782a6d4dfaa67f772a08441.1520151963.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 3 Mar 2018 12:42:46 +0100
+Subject: [PATCH ebtables 3/4] ebt_ip: add support for matching ICMP type and
+ code
+
+We already have ICMPv6 type/code matches. This adds support for IPv4 ICMP
+matches in the same way.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ extensions/ebt_ip.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 94 insertions(+), 2 deletions(-)
+
+diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c
+index 59559feffa50..42660d4564fb 100644
+--- a/extensions/ebt_ip.c
++++ b/extensions/ebt_ip.c
+@@ -24,6 +24,7 @@
+ #define IP_PROTO '4'
+ #define IP_SPORT '5'
+ #define IP_DPORT '6'
++#define IP_ICMP '7'
+
+ static const struct option opts[] =
+ {
+@@ -38,9 +39,64 @@ static const struct option opts[] =
+ { "ip-sport" , required_argument, 0, IP_SPORT },
+ { "ip-destination-port" , required_argument, 0, IP_DPORT },
+ { "ip-dport" , required_argument, 0, IP_DPORT },
++ { "ip-icmp-type" , required_argument, 0, IP_ICMP },
+ { 0 }
+ };
+
++static const struct ebt_icmp_names icmp_codes[] = {
++ { "echo-reply", 0, 0, 0xFF },
++ /* Alias */ { "pong", 0, 0, 0xFF },
++
++ { "destination-unreachable", 3, 0, 0xFF },
++ { "network-unreachable", 3, 0, 0 },
++ { "host-unreachable", 3, 1, 1 },
++ { "protocol-unreachable", 3, 2, 2 },
++ { "port-unreachable", 3, 3, 3 },
++ { "fragmentation-needed", 3, 4, 4 },
++ { "source-route-failed", 3, 5, 5 },
++ { "network-unknown", 3, 6, 6 },
++ { "host-unknown", 3, 7, 7 },
++ { "network-prohibited", 3, 9, 9 },
++ { "host-prohibited", 3, 10, 10 },
++ { "TOS-network-unreachable", 3, 11, 11 },
++ { "TOS-host-unreachable", 3, 12, 12 },
++ { "communication-prohibited", 3, 13, 13 },
++ { "host-precedence-violation", 3, 14, 14 },
++ { "precedence-cutoff", 3, 15, 15 },
++
++ { "source-quench", 4, 0, 0xFF },
++
++ { "redirect", 5, 0, 0xFF },
++ { "network-redirect", 5, 0, 0 },
++ { "host-redirect", 5, 1, 1 },
++ { "TOS-network-redirect", 5, 2, 2 },
++ { "TOS-host-redirect", 5, 3, 3 },
++
++ { "echo-request", 8, 0, 0xFF },
++ /* Alias */ { "ping", 8, 0, 0xFF },
++
++ { "router-advertisement", 9, 0, 0xFF },
++
++ { "router-solicitation", 10, 0, 0xFF },
++
++ { "time-exceeded", 11, 0, 0xFF },
++ /* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
++ { "ttl-zero-during-transit", 11, 0, 0 },
++ { "ttl-zero-during-reassembly", 11, 1, 1 },
++
++ { "parameter-problem", 12, 0, 0xFF },
++ { "ip-header-bad", 12, 0, 0 },
++ { "required-option-missing", 12, 1, 1 },
++
++ { "timestamp-request", 13, 0, 0xFF },
++
++ { "timestamp-reply", 14, 0, 0xFF },
++
++ { "address-mask-request", 17, 0, 0xFF },
++
++ { "address-mask-reply", 18, 0, 0xFF }
++};
++
+ /* put the mask into 4 bytes */
+ /* transform a protocol and service name into a port number */
+ static uint16_t parse_port(const char *protocol, const char *name)
+@@ -105,7 +161,11 @@ static void print_help()
+ "--ip-tos [!] tos : ip tos specification\n"
+ "--ip-proto [!] protocol : ip protocol specification\n"
+ "--ip-sport [!] port[:port] : tcp/udp source port or port range\n"
+-"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n");
++"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n"
++"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n");
++
++ printf("\nValid ICMP Types:\n");
++ ebt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
+ }
+
+ static void init(struct ebt_entry_match *match)
+@@ -122,6 +182,7 @@ static void init(struct ebt_entry_match *match)
+ #define OPT_PROTO 0x08
+ #define OPT_SPORT 0x10
+ #define OPT_DPORT 0x20
++#define OPT_ICMP 0x40
+ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ unsigned int *flags, struct ebt_entry_match **match)
+ {
+@@ -170,6 +231,16 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ parse_port_range(NULL, optarg, ipinfo->dport);
+ break;
+
++ case IP_ICMP:
++ ebt_check_option2(flags, OPT_ICMP);
++ ipinfo->bitmask |= EBT_IP_ICMP;
++ if (ebt_check_inverse2(optarg))
++ ipinfo->invflags |= EBT_IP_ICMP;
++ if (ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg,
++ ipinfo->icmp_type, ipinfo->icmp_code))
++ return 0;
++ break;
++
+ case IP_myTOS:
+ ebt_check_option2(flags, OPT_TOS);
+ if (ebt_check_inverse2(optarg))
+@@ -219,10 +290,17 @@ static void final_check(const struct ebt_u_entry *entry,
+ (ipinfo->protocol!=IPPROTO_TCP &&
+ ipinfo->protocol!=IPPROTO_UDP &&
+ ipinfo->protocol!=IPPROTO_SCTP &&
+- ipinfo->protocol!=IPPROTO_DCCP)))
++ ipinfo->protocol!=IPPROTO_DCCP))) {
+ ebt_print_error("For port filtering the IP protocol must be "
+ "either 6 (tcp), 17 (udp), 33 (dccp) or "
+ "132 (sctp)");
++ } else if ((ipinfo->bitmask & EBT_IP_ICMP) &&
++ (!(ipinfo->bitmask & EBT_IP_PROTO) ||
++ ipinfo->invflags & EBT_IP_PROTO ||
++ ipinfo->protocol != IPPROTO_ICMP)) {
++ ebt_print_error("For ICMP filtering the IP protocol must be "
++ "1 (icmp)");
++ }
+ }
+
+ static void print(const struct ebt_u_entry *entry,
+@@ -280,6 +358,13 @@ static void print(const struct ebt_u_entry *entry,
+ printf("! ");
+ print_port_range(ipinfo->dport);
+ }
++ if (ipinfo->bitmask & EBT_IP_ICMP) {
++ printf("--ip-icmp-type ");
++ if (ipinfo->invflags & EBT_IP_ICMP)
++ printf("! ");
++ ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes),
++ ipinfo->icmp_type, ipinfo->icmp_code);
++ }
+ }
+
+ static int compare(const struct ebt_entry_match *m1,
+@@ -322,6 +407,13 @@ static int compare(const struct ebt_entry_match *m1,
+ ipinfo1->dport[1] != ipinfo2->dport[1])
+ return 0;
+ }
++ if (ipinfo1->bitmask & EBT_IP_ICMP) {
++ if (ipinfo1->icmp_type[0] != ipinfo2->icmp_type[0] ||
++ ipinfo1->icmp_type[1] != ipinfo2->icmp_type[1] ||
++ ipinfo1->icmp_code[0] != ipinfo2->icmp_code[0] ||
++ ipinfo1->icmp_code[1] != ipinfo2->icmp_code[1])
++ return 0;
++ }
+ return 1;
+ }
+
+--
+2.16.2
+
diff --git a/package/network/utils/ebtables/patches/301-0004-ebt_ip-add-support-for-matching-IGMP-type.patch b/package/network/utils/ebtables/patches/301-0004-ebt_ip-add-support-for-matching-IGMP-type.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1a7fe6d2ffcd0baf620dd36d6d3ba200f8b823e9
--- /dev/null
+++ b/package/network/utils/ebtables/patches/301-0004-ebt_ip-add-support-for-matching-IGMP-type.patch
@@ -0,0 +1,207 @@
+From b20e495bdf0c5eec3244cf7f98bae24316ffc3ab Mon Sep 17 00:00:00 2001
+Message-Id: <b20e495bdf0c5eec3244cf7f98bae24316ffc3ab.1520151963.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 3 Mar 2018 13:50:23 +0100
+Subject: [PATCH ebtables 4/4] ebt_ip: add support for matching IGMP type
+
+We already have ICMPv6 type/code matches (which can be used to distinguish
+different types of MLD packets). Add support for IPv4 IGMP matches in the
+same way.
+
+To reuse as much code as possible, the ICMP type/code handling functions
+are extended to allow passing a NULL code range.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ extensions/ebt_ip.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
+ useful_functions.c | 35 ++++++++++++++++++++++-------------
+ 2 files changed, 65 insertions(+), 14 deletions(-)
+
+diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c
+index 42660d4564fb..1ffdb95f156d 100644
+--- a/extensions/ebt_ip.c
++++ b/extensions/ebt_ip.c
+@@ -25,6 +25,7 @@
+ #define IP_SPORT '5'
+ #define IP_DPORT '6'
+ #define IP_ICMP '7'
++#define IP_IGMP '8'
+
+ static const struct option opts[] =
+ {
+@@ -40,6 +41,7 @@ static const struct option opts[] =
+ { "ip-destination-port" , required_argument, 0, IP_DPORT },
+ { "ip-dport" , required_argument, 0, IP_DPORT },
+ { "ip-icmp-type" , required_argument, 0, IP_ICMP },
++ { "ip-igmp-type" , required_argument, 0, IP_IGMP },
+ { 0 }
+ };
+
+@@ -97,6 +99,14 @@ static const struct ebt_icmp_names icmp_codes[] = {
+ { "address-mask-reply", 18, 0, 0xFF }
+ };
+
++static const struct ebt_icmp_names igmp_types[] = {
++ { "membership-query", 0x11 },
++ { "membership-report-v1", 0x12 },
++ { "membership-report-v2", 0x16 },
++ { "leave-group", 0x17 },
++ { "membership-report-v3", 0x22 },
++};
++
+ /* put the mask into 4 bytes */
+ /* transform a protocol and service name into a port number */
+ static uint16_t parse_port(const char *protocol, const char *name)
+@@ -162,10 +172,13 @@ static void print_help()
+ "--ip-proto [!] protocol : ip protocol specification\n"
+ "--ip-sport [!] port[:port] : tcp/udp source port or port range\n"
+ "--ip-dport [!] port[:port] : tcp/udp destination port or port range\n"
+-"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n");
++"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n"
++"--ip-igmp-type [!] type[:type] : igmp type or type range\n");
+
+ printf("\nValid ICMP Types:\n");
+ ebt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
++ printf("\nValid IGMP Types:\n");
++ ebt_print_icmp_types(igmp_types, ARRAY_SIZE(igmp_types));
+ }
+
+ static void init(struct ebt_entry_match *match)
+@@ -183,6 +196,7 @@ static void init(struct ebt_entry_match *match)
+ #define OPT_SPORT 0x10
+ #define OPT_DPORT 0x20
+ #define OPT_ICMP 0x40
++#define OPT_IGMP 0x80
+ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ unsigned int *flags, struct ebt_entry_match **match)
+ {
+@@ -241,6 +255,16 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ return 0;
+ break;
+
++ case IP_IGMP:
++ ebt_check_option2(flags, OPT_IGMP);
++ ipinfo->bitmask |= EBT_IP_IGMP;
++ if (ebt_check_inverse2(optarg))
++ ipinfo->invflags |= EBT_IP_IGMP;
++ if (ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg,
++ ipinfo->igmp_type, NULL))
++ return 0;
++ break;
++
+ case IP_myTOS:
+ ebt_check_option2(flags, OPT_TOS);
+ if (ebt_check_inverse2(optarg))
+@@ -300,6 +324,12 @@ static void final_check(const struct ebt_u_entry *entry,
+ ipinfo->protocol != IPPROTO_ICMP)) {
+ ebt_print_error("For ICMP filtering the IP protocol must be "
+ "1 (icmp)");
++ } else if ((ipinfo->bitmask & EBT_IP_IGMP) &&
++ (!(ipinfo->bitmask & EBT_IP_PROTO) ||
++ ipinfo->invflags & EBT_IP_PROTO ||
++ ipinfo->protocol != IPPROTO_IGMP)) {
++ ebt_print_error("For IGMP filtering the IP protocol must be "
++ "2 (igmp)");
+ }
+ }
+
+@@ -365,6 +395,13 @@ static void print(const struct ebt_u_entry *entry,
+ ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes),
+ ipinfo->icmp_type, ipinfo->icmp_code);
+ }
++ if (ipinfo->bitmask & EBT_IP_IGMP) {
++ printf("--ip-igmp-type ");
++ if (ipinfo->invflags & EBT_IP_IGMP)
++ printf("! ");
++ ebt_print_icmp_type(igmp_types, ARRAY_SIZE(igmp_types),
++ ipinfo->igmp_type, NULL);
++ }
+ }
+
+ static int compare(const struct ebt_entry_match *m1,
+@@ -414,6 +451,11 @@ static int compare(const struct ebt_entry_match *m1,
+ ipinfo1->icmp_code[1] != ipinfo2->icmp_code[1])
+ return 0;
+ }
++ if (ipinfo1->bitmask & EBT_IP_IGMP) {
++ if (ipinfo1->igmp_type[0] != ipinfo2->igmp_type[0] ||
++ ipinfo1->igmp_type[1] != ipinfo2->igmp_type[1])
++ return 0;
++ }
+ return 1;
+ }
+
+diff --git a/useful_functions.c b/useful_functions.c
+index 8f54bae83fae..8a34f820f230 100644
+--- a/useful_functions.c
++++ b/useful_functions.c
+@@ -486,8 +486,10 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
+
+ if (match < n_codes) {
+ type[0] = type[1] = icmp_codes[match].type;
+- code[0] = icmp_codes[match].code_min;
+- code[1] = icmp_codes[match].code_max;
++ if (code) {
++ code[0] = icmp_codes[match].code_min;
++ code[1] = icmp_codes[match].code_max;
++ }
+ } else {
+ char *next = parse_range(icmptype, 0, 255, number);
+ if (!next) {
+@@ -499,17 +501,21 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
+ type[1] = (uint8_t) number[1];
+ switch (*next) {
+ case 0:
+- code[0] = 0;
+- code[1] = 255;
++ if (code) {
++ code[0] = 0;
++ code[1] = 255;
++ }
+ return 0;
+ case '/':
+- next = parse_range(next+1, 0, 255, number);
+- code[0] = (uint8_t) number[0];
+- code[1] = (uint8_t) number[1];
+- if (next == NULL)
+- return -1;
+- if (next && *next == 0)
+- return 0;
++ if (code) {
++ next = parse_range(next+1, 0, 255, number);
++ code[0] = (uint8_t) number[0];
++ code[1] = (uint8_t) number[1];
++ if (next == NULL)
++ return -1;
++ if (next && *next == 0)
++ return 0;
++ }
+ /* fallthrough */
+ default:
+ ebt_print_error("unknown character %c", *next);
+@@ -521,6 +527,9 @@ int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
+
+ static void print_icmp_code(uint8_t *code)
+ {
++ if (!code)
++ return;
++
+ if (code[0] == code[1])
+ printf("/%"PRIu8 " ", code[0]);
+ else
+@@ -542,8 +551,8 @@ void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes,
+ if (icmp_codes[i].type != type[0])
+ continue;
+
+- if (icmp_codes[i].code_min == code[0] &&
+- icmp_codes[i].code_max == code[1]) {
++ if (!code || (icmp_codes[i].code_min == code[0] &&
++ icmp_codes[i].code_max == code[1])) {
+ printf("%s ", icmp_codes[i].name);
+ return;
+ }
+--
+2.16.2
+
diff --git a/target/linux/generic/patches-4.4/614-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch b/target/linux/generic/patches-4.4/614-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1f3d1a2fea50154238c03707b0d7a96db8d1f5d9
--- /dev/null
+++ b/target/linux/generic/patches-4.4/614-0001-ebtables-add-support-for-matching-ICMP-type-and-code.patch
@@ -0,0 +1,139 @@
+From 4f8fa78149e0921c8efdc1adc5e12686ffe7667f Mon Sep 17 00:00:00 2001
+Message-Id: <4f8fa78149e0921c8efdc1adc5e12686ffe7667f.1520150717.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 3 Mar 2018 11:55:21 +0100
+Subject: [PATCH nf-next 1/2] ebtables: add support for matching ICMP type and
+ code
+
+We already have ICMPv6 type/code matches. This adds support for IPv4 ICMP
+matches in the same way.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ include/uapi/linux/netfilter_bridge/ebt_ip.h | 13 +++++++--
+ net/bridge/netfilter/ebt_ip.c | 43 +++++++++++++++++++++-------
+ 2 files changed, 43 insertions(+), 13 deletions(-)
+
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
+@@ -23,8 +23,9 @@
+ #define EBT_IP_PROTO 0x08
+ #define EBT_IP_SPORT 0x10
+ #define EBT_IP_DPORT 0x20
++#define EBT_IP_ICMP 0x40
+ #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
+- EBT_IP_SPORT | EBT_IP_DPORT )
++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP)
+ #define EBT_IP_MATCH "ip"
+
+ /* the same values are used for the invflags */
+@@ -37,8 +38,14 @@ struct ebt_ip_info {
+ __u8 protocol;
+ __u8 bitmask;
+ __u8 invflags;
+- __u16 sport[2];
+- __u16 dport[2];
++ union {
++ __u16 sport[2];
++ __u8 icmp_type[2];
++ };
++ union {
++ __u16 dport[2];
++ __u8 icmp_code[2];
++ };
+ };
+
+ #endif
+--- a/net/bridge/netfilter/ebt_ip.c
++++ b/net/bridge/netfilter/ebt_ip.c
+@@ -19,9 +19,15 @@
+ #include <linux/netfilter_bridge/ebtables.h>
+ #include <linux/netfilter_bridge/ebt_ip.h>
+
+-struct tcpudphdr {
+- __be16 src;
+- __be16 dst;
++union pkthdr {
++ struct {
++ __be16 src;
++ __be16 dst;
++ } tcpudphdr;
++ struct {
++ u8 type;
++ u8 code;
++ } icmphdr;
+ };
+
+ static bool
+@@ -30,8 +36,8 @@ ebt_ip_mt(const struct sk_buff *skb, str
+ const struct ebt_ip_info *info = par->matchinfo;
+ const struct iphdr *ih;
+ struct iphdr _iph;
+- const struct tcpudphdr *pptr;
+- struct tcpudphdr _ports;
++ const union pkthdr *pptr;
++ union pkthdr _pkthdr;
+
+ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
+ if (ih == NULL)
+@@ -50,29 +56,38 @@ ebt_ip_mt(const struct sk_buff *skb, str
+ if (info->bitmask & EBT_IP_PROTO) {
+ if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
+ return false;
+- if (!(info->bitmask & EBT_IP_DPORT) &&
+- !(info->bitmask & EBT_IP_SPORT))
++ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
++ EBT_IP_ICMP)))
+ return true;
+ if (ntohs(ih->frag_off) & IP_OFFSET)
+ return false;
++
++ /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */
+ pptr = skb_header_pointer(skb, ih->ihl*4,
+- sizeof(_ports), &_ports);
++ sizeof(_pkthdr), &_pkthdr);
+ if (pptr == NULL)
+ return false;
+ if (info->bitmask & EBT_IP_DPORT) {
+- u32 dst = ntohs(pptr->dst);
++ u32 dst = ntohs(pptr->tcpudphdr.dst);
+ if (FWINV(dst < info->dport[0] ||
+ dst > info->dport[1],
+ EBT_IP_DPORT))
+ return false;
+ }
+ if (info->bitmask & EBT_IP_SPORT) {
+- u32 src = ntohs(pptr->src);
++ u32 src = ntohs(pptr->tcpudphdr.src);
+ if (FWINV(src < info->sport[0] ||
+ src > info->sport[1],
+ EBT_IP_SPORT))
+ return false;
+ }
++ if ((info->bitmask & EBT_IP_ICMP) &&
++ FWINV(pptr->icmphdr.type < info->icmp_type[0] ||
++ pptr->icmphdr.type > info->icmp_type[1] ||
++ pptr->icmphdr.code < info->icmp_code[0] ||
++ pptr->icmphdr.code > info->icmp_code[1],
++ EBT_IP_ICMP))
++ return false;
+ }
+ return true;
+ }
+@@ -101,6 +116,14 @@ static int ebt_ip_mt_check(const struct
+ return -EINVAL;
+ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
+ return -EINVAL;
++ if (info->bitmask & EBT_IP_ICMP) {
++ if ((info->invflags & EBT_IP_PROTO) ||
++ info->protocol != IPPROTO_ICMP)
++ return -EINVAL;
++ if (info->icmp_type[0] > info->icmp_type[1] ||
++ info->icmp_code[0] > info->icmp_code[1])
++ return -EINVAL;
++ }
+ return 0;
+ }
+
diff --git a/target/linux/generic/patches-4.4/614-0002-ebtables-add-support-for-matching-IGMP-type.patch b/target/linux/generic/patches-4.4/614-0002-ebtables-add-support-for-matching-IGMP-type.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3c8760dbebefddb9bb6a0b9bb724210c573d854c
--- /dev/null
+++ b/target/linux/generic/patches-4.4/614-0002-ebtables-add-support-for-matching-IGMP-type.patch
@@ -0,0 +1,92 @@
+From 68c6d1b60803e9690f2a6168b80a92ae45c6578b Mon Sep 17 00:00:00 2001
+Message-Id: <68c6d1b60803e9690f2a6168b80a92ae45c6578b.1520150717.git.mschiffer@universe-factory.net>
+In-Reply-To: <cover.1520150717.git.mschiffer@universe-factory.net>
+References: <cover.1520150717.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Sat, 3 Mar 2018 12:02:21 +0100
+Subject: [PATCH nf-next 2/2] ebtables: add support for matching IGMP type
+
+We already have ICMPv6 type/code matches (which can be used to distinguish
+different types of MLD packets). Add support for IPv4 IGMP matches in the
+same way.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ include/uapi/linux/netfilter_bridge/ebt_ip.h | 4 +++-
+ net/bridge/netfilter/ebt_ip.c | 19 +++++++++++++++++--
+ 2 files changed, 20 insertions(+), 3 deletions(-)
+
+--- a/include/uapi/linux/netfilter_bridge/ebt_ip.h
++++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
+@@ -24,8 +24,9 @@
+ #define EBT_IP_SPORT 0x10
+ #define EBT_IP_DPORT 0x20
+ #define EBT_IP_ICMP 0x40
++#define EBT_IP_IGMP 0x80
+ #define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
+- EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP)
++ EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
+ #define EBT_IP_MATCH "ip"
+
+ /* the same values are used for the invflags */
+@@ -41,6 +42,7 @@ struct ebt_ip_info {
+ union {
+ __u16 sport[2];
+ __u8 icmp_type[2];
++ __u8 igmp_type[2];
+ };
+ union {
+ __u16 dport[2];
+--- a/net/bridge/netfilter/ebt_ip.c
++++ b/net/bridge/netfilter/ebt_ip.c
+@@ -28,6 +28,9 @@ union pkthdr {
+ u8 type;
+ u8 code;
+ } icmphdr;
++ struct {
++ u8 type;
++ } igmphdr;
+ };
+
+ static bool
+@@ -57,12 +60,12 @@ ebt_ip_mt(const struct sk_buff *skb, str
+ if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
+ return false;
+ if (!(info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT |
+- EBT_IP_ICMP)))
++ EBT_IP_ICMP | EBT_IP_IGMP)))
+ return true;
+ if (ntohs(ih->frag_off) & IP_OFFSET)
+ return false;
+
+- /* min icmp headersize is 4, so sizeof(_pkthdr) is ok. */
++ /* min icmp/igmp headersize is 4, so sizeof(_pkthdr) is ok. */
+ pptr = skb_header_pointer(skb, ih->ihl*4,
+ sizeof(_pkthdr), &_pkthdr);
+ if (pptr == NULL)
+@@ -88,6 +91,11 @@ ebt_ip_mt(const struct sk_buff *skb, str
+ pptr->icmphdr.code > info->icmp_code[1],
+ EBT_IP_ICMP))
+ return false;
++ if ((info->bitmask & EBT_IP_IGMP) &&
++ FWINV(pptr->igmphdr.type < info->igmp_type[0] ||
++ pptr->igmphdr.type > info->igmp_type[1],
++ EBT_IP_IGMP))
++ return false;
+ }
+ return true;
+ }
+@@ -124,6 +132,13 @@ static int ebt_ip_mt_check(const struct
+ info->icmp_code[0] > info->icmp_code[1])
+ return -EINVAL;
+ }
++ if (info->bitmask & EBT_IP_IGMP) {
++ if ((info->invflags & EBT_IP_PROTO) ||
++ info->protocol != IPPROTO_IGMP)
++ return -EINVAL;
++ if (info->igmp_type[0] > info->igmp_type[1])
++ return -EINVAL;
++ }
+ return 0;
+ }
+
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 12 Apr 2018 17:30:16 +0200
Subject: base-files: remove /etc/uci-defaults/11_migrate-sysctl
11_migrate-sysctl has not been updated with new file hashes since 2012.
Let's get rid of it.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/etc/uci-defaults/11_migrate-sysctl b/package/base-files/files/etc/uci-defaults/11_migrate-sysctl
deleted file mode 100644
index 464e275779ceec1d99a7323b6cbf7901aaa9fbb4..0000000000000000000000000000000000000000
--- a/package/base-files/files/etc/uci-defaults/11_migrate-sysctl
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if [ ! -f "/rom/etc/sysctl.conf" ] || cmp -s "/rom/etc/sysctl.conf" "/etc/sysctl.conf"; then
- exit 0
-fi
-
-fingerprint="$(md5sum /etc/sysctl.conf)"
-fingerprint="${fingerprint%% *}"
-
-if [ "$fingerprint" = "1b05ebb41f72cb84e5510573cd4aca26" ] || \
- [ "$fingerprint" = "62deb895be1a7f496040187b7c930e4e" ]; then
- logger -t migrate-sysctl "Updating sysctl.conf to use current defaults"
- cp "/rom/etc/sysctl.conf" "/etc/sysctl.conf"
-fi
-
-exit 0
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 12 Apr 2018 17:33:51 +0200
Subject: base-files: evaluate /etc/sysctl.d/* before /etc/sysctl.conf
We can use /etc/sysctl.d/* for package-supplied sysctl snippets, giving
admins the option to use /etc/sysctl.conf to override settings.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/etc/hotplug.d/net/00-sysctl b/package/base-files/files/etc/hotplug.d/net/00-sysctl
index 7a71652c44f8bd1fb9f2e5643e7baa5d5d76c369..8abe7f8bbd698dc58716b770fe8bc7f8bd475b58 100644
--- a/package/base-files/files/etc/hotplug.d/net/00-sysctl
+++ b/package/base-files/files/etc/hotplug.d/net/00-sysctl
@@ -1,7 +1,7 @@
#!/bin/sh
if [ "$ACTION" = add ]; then
- for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
+ for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do
[ ! -f "$CONF" ] && continue;
sed -ne "/^[[:space:]]*net\..*\.$DEVICENAME\./p" "$CONF" | \
sysctl -e -p - | logger -t sysctl
diff --git a/package/base-files/files/etc/init.d/sysctl b/package/base-files/files/etc/init.d/sysctl
index 65e6aa99250d09a3ccd9d023cb8f8205be86eee8..8722126a6612d67a3f615166a7fbec146207e97f 100755
--- a/package/base-files/files/etc/init.d/sysctl
+++ b/package/base-files/files/etc/init.d/sysctl
@@ -30,7 +30,7 @@ apply_defaults() {
start() {
apply_defaults
- for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
+ for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do
[ -f "$CONF" ] && sysctl -p "$CONF" -e >&-
done
}
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 12 Apr 2018 17:37:29 +0200
Subject: base-files: move sysctl defaults to /etc/sysctl.d/10-default.conf
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/etc/sysctl.conf b/package/base-files/files/etc/sysctl.conf
index 91a3ac9a02d4344cf8c4c8f93a36193120fc4b95..ae04212f420b185ce525dae444b563128ddf0e11 100644
--- a/package/base-files/files/etc/sysctl.conf
+++ b/package/base-files/files/etc/sysctl.conf
@@ -1,30 +1 @@
-kernel.panic=3
-kernel.core_pattern=/tmp/%e.%t.%p.%s.core
-
-net.ipv4.conf.default.arp_ignore=1
-net.ipv4.conf.all.arp_ignore=1
-net.ipv4.ip_forward=1
-net.ipv4.icmp_echo_ignore_broadcasts=1
-net.ipv4.icmp_ignore_bogus_error_responses=1
-net.ipv4.igmp_max_memberships=100
-net.ipv4.tcp_fin_timeout=30
-net.ipv4.tcp_keepalive_time=120
-net.ipv4.tcp_syncookies=1
-net.ipv4.tcp_timestamps=1
-net.ipv4.tcp_sack=1
-net.ipv4.tcp_dsack=1
-
-net.ipv6.conf.default.forwarding=1
-net.ipv6.conf.all.forwarding=1
-
-net.netfilter.nf_conntrack_acct=1
-net.netfilter.nf_conntrack_checksum=0
-net.netfilter.nf_conntrack_max=16384
-net.netfilter.nf_conntrack_tcp_timeout_established=7440
-net.netfilter.nf_conntrack_udp_timeout=60
-net.netfilter.nf_conntrack_udp_timeout_stream=180
-
-# disable bridge firewalling by default
-net.bridge.bridge-nf-call-arptables=0
-net.bridge.bridge-nf-call-ip6tables=0
-net.bridge.bridge-nf-call-iptables=0
+# Defaults are configured in /etc/sysctl.d/* and can be customized in this file
diff --git a/package/base-files/files/etc/sysctl.d/10-default.conf b/package/base-files/files/etc/sysctl.d/10-default.conf
new file mode 100644
index 0000000000000000000000000000000000000000..7c3344dba339514c023c3b13c592e9ce9ca1ff55
--- /dev/null
+++ b/package/base-files/files/etc/sysctl.d/10-default.conf
@@ -0,0 +1,34 @@
+# Do not edit, changes to this file will be lost on upgrades
+# /etc/sysctl.conf can be used to customize sysctl settings
+
+kernel.panic=3
+kernel.core_pattern=/tmp/%e.%t.%p.%s.core
+fs.suid_dumpable=2
+
+net.ipv4.conf.default.arp_ignore=1
+net.ipv4.conf.all.arp_ignore=1
+net.ipv4.ip_forward=1
+net.ipv4.icmp_echo_ignore_broadcasts=1
+net.ipv4.icmp_ignore_bogus_error_responses=1
+net.ipv4.igmp_max_memberships=100
+net.ipv4.tcp_fin_timeout=30
+net.ipv4.tcp_keepalive_time=120
+net.ipv4.tcp_syncookies=1
+net.ipv4.tcp_timestamps=1
+net.ipv4.tcp_sack=1
+net.ipv4.tcp_dsack=1
+
+net.ipv6.conf.default.forwarding=1
+net.ipv6.conf.all.forwarding=1
+
+net.netfilter.nf_conntrack_acct=1
+net.netfilter.nf_conntrack_checksum=0
+net.netfilter.nf_conntrack_max=16384
+net.netfilter.nf_conntrack_tcp_timeout_established=7440
+net.netfilter.nf_conntrack_udp_timeout=60
+net.netfilter.nf_conntrack_udp_timeout_stream=180
+
+# disable bridge firewalling by default
+net.bridge.bridge-nf-call-arptables=0
+net.bridge.bridge-nf-call-ip6tables=0
+net.bridge.bridge-nf-call-iptables=0
diff --git a/package/base-files/files/etc/sysctl.d/local.conf b/package/base-files/files/etc/sysctl.d/local.conf
deleted file mode 100644
index 891da73df8d61e0c47069d4c6c8cc090f693c0b2..0000000000000000000000000000000000000000
--- a/package/base-files/files/etc/sysctl.d/local.conf
+++ /dev/null
@@ -1 +0,0 @@
-# local sysctl settings can be stored in this directory
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 12 Apr 2018 17:57:44 +0200
Subject: base-files: move netfilter sysctl defaults to specific kmod packages
Avoid warnings when applying settings for uninstalled kmods. See also
FS#1073.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/etc/sysctl.d/10-default.conf b/package/base-files/files/etc/sysctl.d/10-default.conf
index 7c3344dba339514c023c3b13c592e9ce9ca1ff55..98867b7c7ba1d1ce181f721cdfd17517069fcdf2 100644
--- a/package/base-files/files/etc/sysctl.d/10-default.conf
+++ b/package/base-files/files/etc/sysctl.d/10-default.conf
@@ -20,15 +20,3 @@ net.ipv4.tcp_dsack=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
-
-net.netfilter.nf_conntrack_acct=1
-net.netfilter.nf_conntrack_checksum=0
-net.netfilter.nf_conntrack_max=16384
-net.netfilter.nf_conntrack_tcp_timeout_established=7440
-net.netfilter.nf_conntrack_udp_timeout=60
-net.netfilter.nf_conntrack_udp_timeout_stream=180
-
-# disable bridge firewalling by default
-net.bridge.bridge-nf-call-arptables=0
-net.bridge.bridge-nf-call-ip6tables=0
-net.bridge.bridge-nf-call-iptables=0
diff --git a/package/kernel/linux/files/sysctl-br-netfilter.conf b/package/kernel/linux/files/sysctl-br-netfilter.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b10ddc0874b6d393458e646e396716bd67b6b381
--- /dev/null
+++ b/package/kernel/linux/files/sysctl-br-netfilter.conf
@@ -0,0 +1,7 @@
+# Do not edit, changes to this file will be lost on upgrades
+# /etc/sysctl.conf can be used to customize sysctl settings
+
+# disable bridge firewalling by default
+net.bridge.bridge-nf-call-arptables=0
+net.bridge.bridge-nf-call-ip6tables=0
+net.bridge.bridge-nf-call-iptables=0
diff --git a/package/kernel/linux/files/sysctl-nf-conntrack.conf b/package/kernel/linux/files/sysctl-nf-conntrack.conf
new file mode 100644
index 0000000000000000000000000000000000000000..37baf5fd6ff9d99d37554f5e38bf1d749a7f21e2
--- /dev/null
+++ b/package/kernel/linux/files/sysctl-nf-conntrack.conf
@@ -0,0 +1,9 @@
+# Do not edit, changes to this file will be lost on upgrades
+# /etc/sysctl.conf can be used to customize sysctl settings
+
+net.netfilter.nf_conntrack_acct=1
+net.netfilter.nf_conntrack_checksum=0
+net.netfilter.nf_conntrack_max=16384
+net.netfilter.nf_conntrack_tcp_timeout_established=7440
+net.netfilter.nf_conntrack_udp_timeout=60
+net.netfilter.nf_conntrack_udp_timeout_stream=180
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index 3b26ad1fbf3e261d84ae18216c51c87c53579c06..bb882363f3df4df733424ca6bba72badc96f06f8 100644
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -74,6 +74,11 @@ define KernelPackage/nf-conntrack
AUTOLOAD:=$(call AutoProbe,$(notdir $(NF_CONNTRACK-m)))
endef
+define KernelPackage/nf-conntrack/install
+ $(INSTALL_DIR) $(1)/etc/sysctl.d
+ $(INSTALL_DATA) ./files/sysctl-nf-conntrack.conf $(1)/etc/sysctl.d/11-nf-conntrack.conf
+endef
+
$(eval $(call KernelPackage,nf-conntrack))
@@ -674,6 +679,11 @@ define KernelPackage/br-netfilter
AUTOLOAD:=$(call AutoProbe,br_netfilter)
endef
+define KernelPackage/br-netfilter/install
+ $(INSTALL_DIR) $(1)/etc/sysctl.d
+ $(INSTALL_DATA) ./files/sysctl-br-netfilter.conf $(1)/etc/sysctl.d/11-br-netfilter.conf
+endef
+
$(eval $(call KernelPackage,br-netfilter))
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Fri, 13 Apr 2018 14:36:43 +0200
Subject: base-files: remove /etc/sysctl.d/ from conffiles
Let's use /etc/sysctl.d for package-provided snippets and leave
/etc/sysctl.conf to the admin. Don't backup /etc/sysctl.d on upgrades, so
old defaults get replaced properly.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index c971de4deee7cd331ddcad6b87eb9fefd7af6a64..55e67a97d03df7d96cf8a4aac3c5325ce7105c80 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -59,8 +59,6 @@ define Package/base-files/conffiles
/etc/shadow
/etc/shells
/etc/sysctl.conf
-/etc/sysctl.d/
-/etc/sysctl.d/local.conf
/etc/sysupgrade.conf
$(call $(TARGET)/conffiles)
endef
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Thu, 12 Apr 2018 22:14:56 +0200
Subject: kernel: disable accept_ra by default
Our commands setting accept_ra to 0 on all interfaces got lost in the
transition to procd. This remained unnoticed for a long time, as we also
enable forwarding on all interfaces, which prevents RA handling by default.
Restore the commands, while also fixing a possible race condition in the
old version.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/base-files/files/etc/init.d/sysctl b/package/base-files/files/etc/init.d/sysctl
index 8722126a6612d67a3f615166a7fbec146207e97f..a236a0194b665ff56c8330930bfd44709d1b0d3d 100755
--- a/package/base-files/files/etc/init.d/sysctl
+++ b/package/base-files/files/etc/init.d/sysctl
@@ -26,6 +26,14 @@ apply_defaults() {
net.ipv6.ip6frag_high_thresh="$frag_high_thresh" \
net.netfilter.nf_conntrack_frag6_low_thresh="$frag_low_thresh" \
net.netfilter.nf_conntrack_frag6_high_thresh="$frag_high_thresh"
+
+ # first set default, then all interfaces to avoid races with appearing interfaces
+ if [ -d /proc/sys/net/ipv6/conf ]; then
+ echo 0 > /proc/sys/net/ipv6/conf/default/accept_ra
+ for iface in /proc/sys/net/ipv6/conf/*/accept_ra; do
+ echo 0 > "$iface"
+ done
+ fi
}
start() {
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Mon, 9 Apr 2018 18:51:57 +0200
Subject: kernel: change dependency of kmod-ebtables-* on kmod-ebtables to selecting
Non-selecting dependencies easily lead to Kconfig failures due to recursive
dependencies. We hit such an issue in Gluon; the easiest fix is to make
the dependency selecting.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index bb882363f3df4df733424ca6bba72badc96f06f8..c1d08a54037e6b33834566dac58308f64a427ecd 100644
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -707,7 +707,7 @@ $(eval $(call KernelPackage,ebtables))
define AddDepends/ebtables
SUBMENU:=$(NF_MENU)
- DEPENDS+=kmod-ebtables $(1)
+ DEPENDS+= +kmod-ebtables $(1)
endef
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Mon, 9 Apr 2018 18:56:53 +0200
Subject: kernel: unhide kmod-br-netfilter
kmod-br-netfilter is not only a support module, but can be useful on its
own, using the net.bridge.bridge-nf-call-* sysctls.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index c1d08a54037e6b33834566dac58308f64a427ecd..275147b8757a42c00de14502a072c8384a0526ab 100644
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -672,7 +672,6 @@ $(eval $(call KernelPackage,arptables))
define KernelPackage/br-netfilter
SUBMENU:=$(NF_MENU)
TITLE:=Bridge netfilter support modules
- HIDDEN:=1
DEPENDS:=+kmod-ipt-core +kmod-bridge
FILES:=$(LINUX_DIR)/net/bridge/br_netfilter.ko
KCONFIG:=CONFIG_BRIDGE_NETFILTER
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Mon, 9 Apr 2018 19:01:56 +0200
Subject: kernel: kmod-ebtables: do not depend on kmod-br-netfilter
While ebtables can be combined with br-netfilter, there is no good reason
to make it a dependency.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index 275147b8757a42c00de14502a072c8384a0526ab..34eefcd892b9e8b3157603fa47578d0afc65dc4b 100644
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -689,7 +689,7 @@ $(eval $(call KernelPackage,br-netfilter))
define KernelPackage/ebtables
SUBMENU:=$(NF_MENU)
TITLE:=Bridge firewalling modules
- DEPENDS:=+kmod-ipt-core +kmod-bridge +kmod-br-netfilter
+ DEPENDS:=+kmod-ipt-core +kmod-bridge
FILES:=$(foreach mod,$(EBTABLES-m),$(LINUX_DIR)/net/$(mod).ko)
KCONFIG:=$(KCONFIG_EBTABLES)
AUTOLOAD:=$(call AutoProbe,$(notdir $(EBTABLES-m)))
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Mon, 9 Apr 2018 19:41:26 +0200
Subject: iptables: split physdev match out as a separate package
Split physdev match out of ipt-extra to allow installing ipt-extra without
pulling in br-netfilter.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/include/netfilter.mk b/include/netfilter.mk
index 39c8e7c90fab2ba14cd75c80d1e357dd23ae6a1b..79ae3d5343ed77b559f50f40bb8a73a33dd13314 100644
--- a/include/netfilter.mk
+++ b/include/netfilter.mk
@@ -89,12 +89,14 @@ $(eval $(if $(NF_KMOD),,$(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_CO
$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_ADDRTYPE, $(if $(NF_KMOD),$(P_XT)xt_addrtype,$(P_XT)ipt_addrtype)))
$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_OWNER, $(P_XT)xt_owner))
-$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PKTTYPE, $(P_XT)xt_pkttype))
$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_QUOTA, $(P_XT)xt_quota))
#$(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_ROUTE, $(P_V4)ipt_ROUTE))
+# physdev
+
+$(eval $(call nf_add,IPT_PHYSDEV,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
# filter
@@ -347,6 +349,7 @@ IPT_BUILTIN += $(NF_CONNTRACK6-y)
IPT_BUILTIN += $(IPT_CONNTRACK-y)
IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
IPT_BUILTIN += $(IPT_EXTRA-y)
+IPT_BUILTIN += $(IPT_PHYSDEV-y)
IPT_BUILTIN += $(IPT_FILTER-y)
IPT_BUILTIN += $(IPT_IPOPT-y)
IPT_BUILTIN += $(IPT_IPRANGE-y)
diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
index 34eefcd892b9e8b3157603fa47578d0afc65dc4b..a71904673ae53bffcc9fd88291520aacb4a4f8d7 100644
--- a/package/kernel/linux/modules/netfilter.mk
+++ b/package/kernel/linux/modules/netfilter.mk
@@ -604,7 +604,7 @@ define KernelPackage/ipt-extra
KCONFIG:=$(KCONFIG_IPT_EXTRA)
FILES:=$(foreach mod,$(IPT_EXTRA-m),$(LINUX_DIR)/net/$(mod).ko)
AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_EXTRA-m)))
- $(call AddDepends/ipt,+kmod-br-netfilter)
+ $(call AddDepends/ipt)
endef
define KernelPackage/ipt-extra/description
@@ -612,7 +612,6 @@ define KernelPackage/ipt-extra/description
Includes:
- addrtype
- owner
- - physdev (if bridge support was enabled in kernel)
- pkttype
- quota
endef
@@ -620,6 +619,21 @@ endef
$(eval $(call KernelPackage,ipt-extra))
+define KernelPackage/ipt-physdev
+ TITLE:=physdev module
+ KCONFIG:=$(KCONFIG_IPT_PHYSDEV)
+ FILES:=$(foreach mod,$(IPT_PHYSDEV-m),$(LINUX_DIR)/net/$(mod).ko)
+ AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_PHYSDEV-m)))
+ $(call AddDepends/ipt,+kmod-br-netfilter)
+endef
+
+define KernelPackage/ipt-physdev/description
+ The iptables physdev kernel module
+endef
+
+$(eval $(call KernelPackage,ipt-physdev))
+
+
define KernelPackage/ip6tables
SUBMENU:=$(NF_MENU)
TITLE:=IPv6 modules
diff --git a/package/network/utils/iptables/Makefile b/package/network/utils/iptables/Makefile
index 9761ed1820b5c092292d25aef28f8f9a8ffa91a6..af5ed8c6245a9d52f5aea695e71b08ac6f3e6eca 100644
--- a/package/network/utils/iptables/Makefile
+++ b/package/network/utils/iptables/Makefile
@@ -321,12 +321,20 @@ Other extra iptables extensions.
- addrtype
- condition
- owner
- - physdev (if ebtables is enabled)
- pkttype
- quota
endef
+define Package/iptables-mod-physdev
+$(call Package/iptables/Module, +kmod-ipt-physdev)
+ TITLE:=physdev iptables extension
+endef
+
+define Package/iptables-mod-physdev/description
+The iptables physdev match.
+endef
+
define Package/iptables-mod-led
$(call Package/iptables/Module, +kmod-ipt-led)
TITLE:=LED trigger iptables extension
@@ -561,6 +569,7 @@ endef
$(eval $(call BuildPackage,iptables))
$(eval $(call BuildPlugin,iptables-mod-conntrack-extra,$(IPT_CONNTRACK_EXTRA-m)))
$(eval $(call BuildPlugin,iptables-mod-extra,$(IPT_EXTRA-m)))
+$(eval $(call BuildPlugin,iptables-mod-physdev,$(IPT_PHYSDEV-m)))
$(eval $(call BuildPlugin,iptables-mod-filter,$(IPT_FILTER-m)))
$(eval $(call BuildPlugin,iptables-mod-ipopt,$(IPT_IPOPT-m)))
$(eval $(call BuildPlugin,iptables-mod-ipsec,$(IPT_IPSEC-m)))
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Tue, 10 Apr 2018 15:19:52 +0200
Subject: ar71xx: increase kernel partition size for UniFi AP Pro and Outdoor+
Tested on UAP Outdoor+.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/target/linux/ar71xx/image/ubnt.mk b/target/linux/ar71xx/image/ubnt.mk
index 899d5d030e44e64bc945f03babf8820d87451177..84bf13d2829c3e8cd250fe9a069245d0098b864d 100644
--- a/target/linux/ar71xx/image/ubnt.mk
+++ b/target/linux/ar71xx/image/ubnt.mk
@@ -254,9 +254,9 @@ TARGET_DEVICES += ubnt-rs ubnt-rspro ubnt-ls-sr71
define Device/ubnt-uap-pro
DEVICE_TITLE := Ubiquiti UAP Pro
- KERNEL_SIZE := 1536k
+ KERNEL_SIZE := 1792k
IMAGE_SIZE := 15744k
- MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1536k(kernel),14208k(rootfs),256k(cfg)ro,64k(EEPROM)ro,15744k@0x50000(firmware)
+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1792k(kernel),13952k(rootfs),256k(cfg)ro,64k(EEPROM)ro,15744k@0x50000(firmware)
UBNT_TYPE := BZ
UBNT_CHIP := ar934x
BOARDNAME := UAP-PRO
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Tue, 10 Apr 2018 17:26:34 +0200
Subject: firmware-utils: tplink-safeloader: move CPE/WBS 210/510 version metainfo to the end
Having the metainfo between kernel and rootfs prevents us from resizing
the kernel partition as necessary.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c
index 11ff2e56e19ec3780f988baf7257810530165b23..2a2329d1f188ea8520b6a4aeef25937e05d48a06 100644
--- a/tools/firmware-utils/src/tplink-safeloader.c
+++ b/tools/firmware-utils/src/tplink-safeloader.c
@@ -139,10 +139,10 @@ static struct device_info boards[] = {
{"default-mac", 0x30000, 0x00020},
{"product-info", 0x31100, 0x00100},
{"signature", 0x32000, 0x00400},
- {"os-image", 0x40000, 0x170000},
- {"soft-version", 0x1b0000, 0x00100},
- {"support-list", 0x1b1000, 0x00400},
- {"file-system", 0x1c0000, 0x600000},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0x5f0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
{"user-config", 0x7c0000, 0x10000},
{"default-config", 0x7d0000, 0x10000},
{"log", 0x7e0000, 0x10000},
@@ -151,7 +151,7 @@ static struct device_info boards[] = {
},
.first_sysupgrade_partition = "os-image",
- .last_sysupgrade_partition = "file-system",
+ .last_sysupgrade_partition = "support-list",
},
/** Firmware layout for the CPE510/520 */
@@ -177,10 +177,10 @@ static struct device_info boards[] = {
{"default-mac", 0x30000, 0x00020},
{"product-info", 0x31100, 0x00100},
{"signature", 0x32000, 0x00400},
- {"os-image", 0x40000, 0x170000},
- {"soft-version", 0x1b0000, 0x00100},
- {"support-list", 0x1b1000, 0x00400},
- {"file-system", 0x1c0000, 0x600000},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0x5f0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
{"user-config", 0x7c0000, 0x10000},
{"default-config", 0x7d0000, 0x10000},
{"log", 0x7e0000, 0x10000},
@@ -189,7 +189,7 @@ static struct device_info boards[] = {
},
.first_sysupgrade_partition = "os-image",
- .last_sysupgrade_partition = "file-system",
+ .last_sysupgrade_partition = "support-list",
},
{
@@ -209,10 +209,10 @@ static struct device_info boards[] = {
{"default-mac", 0x30000, 0x00020},
{"product-info", 0x31100, 0x00100},
{"signature", 0x32000, 0x00400},
- {"os-image", 0x40000, 0x170000},
- {"soft-version", 0x1b0000, 0x00100},
- {"support-list", 0x1b1000, 0x00400},
- {"file-system", 0x1c0000, 0x600000},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0x5f0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
{"user-config", 0x7c0000, 0x10000},
{"default-config", 0x7d0000, 0x10000},
{"log", 0x7e0000, 0x10000},
@@ -221,7 +221,7 @@ static struct device_info boards[] = {
},
.first_sysupgrade_partition = "os-image",
- .last_sysupgrade_partition = "file-system",
+ .last_sysupgrade_partition = "support-list",
},
{
@@ -241,10 +241,10 @@ static struct device_info boards[] = {
{"default-mac", 0x30000, 0x00020},
{"product-info", 0x31100, 0x00100},
{"signature", 0x32000, 0x00400},
- {"os-image", 0x40000, 0x170000},
- {"soft-version", 0x1b0000, 0x00100},
- {"support-list", 0x1b1000, 0x00400},
- {"file-system", 0x1c0000, 0x600000},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0x5f0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
{"user-config", 0x7c0000, 0x10000},
{"default-config", 0x7d0000, 0x10000},
{"log", 0x7e0000, 0x10000},
@@ -253,7 +253,7 @@ static struct device_info boards[] = {
},
.first_sysupgrade_partition = "os-image",
- .last_sysupgrade_partition = "file-system",
+ .last_sysupgrade_partition = "support-list",
},
/** Firmware layout for the C2600 */