From 589de56c3dbde6aa45c0c49c3c5165d344fed723 Mon Sep 17 00:00:00 2001 From: gl-yangweiping Date: Tue, 7 Jun 2022 21:57:04 -0400 Subject: [PATCH] A1300 adapt 21.02.2 --- feeds.conf.default | 1 - include/image-commands.mk | 17 +- .../ipq-wifi/board-glinet_gl-a1300.qca4019 | Bin 48596 -> 24308 bytes .../src/gpio-button-hotplug.c | 1 + .../patches/300-remove-limit-hostname.patch | 11 + package/network/services/ppp/files/ppp.sh | 1 + .../arm/boot/dts/qcom-ipq4018-gl-a1300.dts | 23 +- target/linux/ipq40xx/image/generic.mk | 4 +- .../patches-5.4/320-add_spi_nor_write.patch | 11 + .../patches-5.4/700-add-modem-support.patch | 280 ++++++++++++++++ ...k-events-support-multiple-registrant.patch | 313 ++++++++++++++++++ ...-linux-kernel-to-support-shortcut-fe.patch | 253 ++++++++++++++ 12 files changed, 902 insertions(+), 13 deletions(-) create mode 100644 package/network/services/dnsmasq/patches/300-remove-limit-hostname.patch create mode 100644 target/linux/ipq40xx/patches-5.4/320-add_spi_nor_write.patch create mode 100644 target/linux/ipq40xx/patches-5.4/700-add-modem-support.patch create mode 100644 target/linux/ipq40xx/patches-5.4/952-net-conntrack-events-support-multiple-registrant.patch create mode 100644 target/linux/ipq40xx/patches-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch diff --git a/feeds.conf.default b/feeds.conf.default index c07b0bcc1e..3dfca3a7df 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,4 +1,3 @@ -src-git gl_feeds https://github.com/gl-inet/gl-feeds.git;21.02.2 src-git packages https://git.openwrt.org/feed/packages.git^b0ccc356900f6e1e1dc613d0ea980d5572f553dd src-git luci https://git.openwrt.org/project/luci.git^cc582ebfb3cb2782db841ad2a4e908d1df4046f9 src-git routing https://git.openwrt.org/feed/routing.git^10d3ffd8b30186b49538167bac1fa1bf9c88f860 diff --git a/include/image-commands.mk b/include/image-commands.mk index 6908f5b5c1..5c416dfc28 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -66,8 +66,13 @@ endef metadata_gl_json = \ '{ $(if $(IMAGE_METADATA),$(IMAGE_METADATA)$(comma)) \ - "metadata_version": "1.0", \ - "supported_devices":[$(call metadata_devices,$(1))], \ + "metadata_version": "1.1", \ + "compat_version": "$(call json_quote,$(compat_version))", \ + $(if $(DEVICE_COMPAT_MESSAGE),"compat_message": "$(call json_quote,$(DEVICE_COMPAT_MESSAGE))"$(comma)) \ + $(if $(filter-out 1.0,$(compat_version)),"new_supported_devices": \ + [$(call metadata_devices,$(SUPPORTED_DEVICES))]$(comma) \ + "supported_devices": ["$(call json_quote,$(legacy_supported_message))"]$(comma)) \ + $(if $(filter 1.0,$(compat_version)),"supported_devices":[$(call metadata_devices,$(SUPPORTED_DEVICES))]$(comma)) \ "version": { \ "release": "$(shell cat $(TOPDIR)/release)", \ "date": "$(shell TZ='Asia/Chongqing' date '+%Y%m%d%H%M%S')", \ @@ -77,15 +82,15 @@ metadata_gl_json = \ "target": "$(call json_quote,$(TARGETID))", \ "board": "$(call json_quote,$(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)))" \ }, \ + "upgrade_control":"$(shell python3 $(TOPDIR)/make_gl_metadata.py)", \ + "release_note":"$(shell sed ':a;N;s/\n/\\n/g;s/\r/\\r/g;ta' $(TOPDIR)/gl_release_note)" \ }' define Build/append-gl-metadata $(if $(SUPPORTED_DEVICES),-echo $(call metadata_gl_json,$(SUPPORTED_DEVICES)) | fwtool -I - $@) - [ ! -s "$(BUILD_KEY)" -o ! -s "$(BUILD_KEY).ucert" -o ! -s "$@" ] || { \ - cp "$(BUILD_KEY).ucert" "$@.ucert" ;\ + [ ! -s "$(BUILD_KEY)" -o ! -s "$@" ] || { \ usign -S -m "$@" -s "$(BUILD_KEY)" -x "$@.sig" ;\ - ucert -A -c "$@.ucert" -x "$@.sig" ;\ - fwtool -S "$@.ucert" "$@" ;\ + fwtool -S "$@.sig" "$@" ;\ } endef diff --git a/package/firmware/ipq-wifi/board-glinet_gl-a1300.qca4019 b/package/firmware/ipq-wifi/board-glinet_gl-a1300.qca4019 index 0b9a908bcdd0f86f1de1100b98556e353085fcef..d8695c983641b25f4e059f65a0ce8b4f2501338c 100644 GIT binary patch delta 2274 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[len] = 0; +- if (legal_hostname(daemon->dhcp_buff)) ++ //if (legal_hostname(daemon->dhcp_buff)) + client_hostname = daemon->dhcp_buff; + } + diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh index b553effd88..78a712b41a 100755 --- a/package/network/services/ppp/files/ppp.sh +++ b/package/network/services/ppp/files/ppp.sh @@ -140,6 +140,7 @@ ppp_generic_setup() { ${localip:+$localip:} \ ${lcp_failure:+lcp-echo-interval $lcp_interval lcp-echo-failure $lcp_failure $lcp_adaptive} \ ${ipv6:++ipv6} \ + ${ipv6:-noipv6} \ ${autoipv6:+set AUTOIPV6=1} \ ${ip6table:+set IP6TABLE=$ip6table} \ ${peerdns:+set PEERDNS=$peerdns} \ diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-gl-a1300.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-gl-a1300.dts index a6d662e6da..39c9032ac9 100644 --- a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-gl-a1300.dts +++ b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4018-gl-a1300.dts @@ -22,14 +22,19 @@ #address-cells = <1>; #size-cells = <1>; model = "a1300"; - wan = "etho"; - lan = "eth1"; + wan = "eth1"; + lan = "eth0"; + usb-port = "1-1"; + flash_size = <128>; reset-button = "gpio-63"; + switch-button = "gpio-0"; + radio = "radio0"; factory_data { - device_mac = "ART", "0"; + device_mac = "ART", "0x0"; device_ddns = "ART", "0x10"; device_sn_bak = "ART", "0x20"; device_sn = "ART", "0x30"; + country_code = "ART", "0x88"; }; }; @@ -116,6 +121,12 @@ gpios = <&tlmm 63 GPIO_ACTIVE_LOW>; linux,code = ; }; + + switch { + label = "switch-button"; + gpios = <&tlmm 0 GPIO_ACTIVE_LOW>; + linux,code = ; + }; }; leds { @@ -136,7 +147,7 @@ compatible = "gpio-export"; usb { - gpio-export,name = "usb-power"; + gpio-export,name = "usb_power"; gpio-export,output = <1>; gpios = <&tlmm 4 GPIO_ACTIVE_HIGH>; }; @@ -216,6 +227,10 @@ reg = <0x00170000 0x00010000>; read-only; }; + partition@180000 { + label = "log"; + reg = <0x00180000 0x00020000>; + }; }; }; diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk index da6a2ce2eb..d9ace7711c 100644 --- a/target/linux/ipq40xx/image/generic.mk +++ b/target/linux/ipq40xx/image/generic.mk @@ -23,8 +23,8 @@ endef define Device/UbiFit KERNEL_IN_UBI := 1 - IMAGES := nand-factory.ubi nand-sysupgrade.bin - IMAGE/nand-factory.ubi := append-ubi + IMAGES := nand-factory.img nand-sysupgrade.bin + IMAGE/nand-factory.img := append-ubi IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata endef diff --git a/target/linux/ipq40xx/patches-5.4/320-add_spi_nor_write.patch b/target/linux/ipq40xx/patches-5.4/320-add_spi_nor_write.patch new file mode 100644 index 0000000000..2f1d4ad139 --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/320-add_spi_nor_write.patch @@ -0,0 +1,11 @@ +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -5025,6 +5025,8 @@ int spi_nor_scan(struct spi_nor *nor, co + else + mtd->_write = spi_nor_write; + ++ mtd->_panic_write = spi_nor_write; ++ + if (info->flags & USE_FSR) + nor->flags |= SNOR_F_USE_FSR; + if (info->flags & SPI_NOR_HAS_TB) diff --git a/target/linux/ipq40xx/patches-5.4/700-add-modem-support.patch b/target/linux/ipq40xx/patches-5.4/700-add-modem-support.patch new file mode 100644 index 0000000000..4accdeae0c --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/700-add-modem-support.patch @@ -0,0 +1,280 @@ +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -507,6 +507,25 @@ static const u8 default_modem_addr[ETH_A + + static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}; + ++#if 1 //Added by Quectel ++#include ++struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C)) ++ return skb; ++ // Skip Ethernet header from message ++ if (skb_pull(skb, ETH_HLEN)) { ++ return skb; ++ } else { ++ dev_err(&dev->intf->dev, "Packet Dropped "); ++ } ++ // Filter the packet out, release it ++ dev_kfree_skb_any(skb); ++ return NULL; ++} ++#endif ++ ++ + /* Make up an ethernet header if the packet doesn't have one. + * + * A firmware bug common among several devices cause them to send raw +@@ -801,6 +820,20 @@ static int qmi_wwan_bind(struct usbnet * + } + dev->net->netdev_ops = &qmi_wwan_netdev_ops; + dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group; ++#if 1 //Added by Quectel ++ if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { ++ dev_info(&intf->dev, "QuectelEC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96&AG35 work on RawIP mode\n"); ++ dev->net->flags |= IFF_NOARP; ++ usb_control_msg( ++ interface_to_usbdev(intf), ++ usb_sndctrlpipe(interface_to_usbdev(intf), 0), ++ 0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE ++ 0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE ++ 1, //active CDC DTR ++ intf->cur_altsetting->desc.bInterfaceNumber, ++ NULL, 0, 100); ++ } ++#endif + err: + return status; + } +@@ -891,7 +924,10 @@ static const struct driver_info qmi_wwan + .bind = qmi_wwan_bind, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, +- .rx_fixup = qmi_wwan_rx_fixup, ++ #if 1 //Added by Quectel ++ .tx_fixup = qmi_wwan_tx_fixup, ++ .rx_fixup = qmi_wwan_rx_fixup, ++ #endif + }; + + static const struct driver_info qmi_wwan_info_quirk_dtr = { +@@ -938,6 +974,17 @@ static const struct driver_info qmi_wwan + .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr + + static const struct usb_device_id products[] = { ++#if 1 //Added by Quectel ++ { QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0121, 4) }, /* Quectel EC21 */ ++ { QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0191, 4) }, /* Quectel EG91 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0195, 4) }, /* Quectel EG95 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0306, 4) }, /* Quectel EG06/EP06/EM06 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0296, 4) }, /* Quectel BG96 */ ++ { QMI_FIXED_INTF(0x2C7C, 0x0435, 4) }, /* Quectel AG35 */ ++#endif + /* 1. CDC ECM like devices match on the control interface */ + { /* Huawei E392, E398 and possibly others sharing both device id and more... */ + USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9), +@@ -1357,6 +1404,7 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ + {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ + {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */ ++ {QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */ + {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */ + {QMI_QUIRK_SET_DTR(0x1e0e, 0x9001, 5)}, /* SIMCom 7100E, 7230E, 7600E ++ */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ +@@ -1396,7 +1444,6 @@ static const struct usb_device_id produc + {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ + {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ + {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ +- {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */ + {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ + {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -565,6 +565,22 @@ static void option_instat_callback(struc + #define WETELECOM_PRODUCT_6802 0x6802 + #define WETELECOM_PRODUCT_WMD300 0x6803 + ++#define LONGSUNG_PRODUCT_U9300C 0x9b3c ++ ++/* FORGE PRODUCT */ ++#define FORGE_VENDOR_ID 0x05c6 ++ ++#define FORGE_PRODUCT_SLM750 0xf601 ++ ++/* NODECOM PRODUCT */ ++#define NODECOM_VENDOR_ID 0x1508 ++ ++#define NODECOM_PRODUCT_NL660 0x1001 ++ ++/* NEOWAY PRODUCT */ ++#define NEOWAY_VENDOR_ID 0x2949 ++ ++#define NEOWAY_PRODUCT_N720 0x8243 + + /* Device flags */ + +@@ -585,6 +601,29 @@ static void option_instat_callback(struc + + + static const struct usb_device_id option_ids[] = { ++#if 1 //Added by Quectel ++ { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */ ++ { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */ ++ { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */ ++ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ ++ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ ++ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */ ++ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */ ++ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */ ++ { USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95 */ ++ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */ ++ { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */ ++ { USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200t */ ++#endif ++ { USB_DEVICE(0x19d2, 0x0536) },/* MZ386 */ ++ { USB_DEVICE(0x19d2, 0x0117) }, ++ { USB_DEVICE(0x19d2, 0x0199) }, ++ { USB_DEVICE(0x19d2, 0x1476) }, ++ { USB_DEVICE(LONGCHEER_VENDOR_ID, LONGSUNG_PRODUCT_U9300C) }, ++ { USB_DEVICE(FORGE_VENDOR_ID, FORGE_PRODUCT_SLM750) }, ++ { USB_DEVICE(NODECOM_VENDOR_ID, NODECOM_PRODUCT_NL660) }, ++ { USB_DEVICE(NEOWAY_VENDOR_ID, NEOWAY_PRODUCT_N720) }, ++ + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, +@@ -2146,6 +2185,9 @@ static struct usb_serial_driver option_1 + #ifdef CONFIG_PM + .suspend = usb_wwan_suspend, + .resume = usb_wwan_resume, ++#if 1 //Added by Quectel ++ .reset_resume = usb_wwan_resume, ++#endif + #endif + }; + +@@ -2189,9 +2231,84 @@ static int option_probe(struct usb_seria + if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2) + return -ENODEV; + +- /* Store the device flags so we can use them during attach. */ +- usb_set_serial_data(serial, (void *)device_flags); +- ++#if 1 //Added by Quectel ++ //Quectel UC20's interface 4 can be used as USB network device ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && \ ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003) \ ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) ++ return -ENODEV; ++ //Quectel EC20's interface 4 can be used as USB network device ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && \ ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215) \ ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) ++ return -ENODEV; ++ //Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && \ ++ serial->dev->descriptor.idProduct != cpu_to_le16(0x6026) \ ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) ++ return -ENODEV; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) && \ ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x6026) \ ++ && serial->interface->cur_altsetting->desc.bInterfaceNumber<= 1) ++ return -ENODEV; ++#endif ++#if 0 //Added by Quectel ++ //For USB Auto Suspend ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) { ++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000); ++ usb_enable_autosuspend(serial->dev); ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) { ++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000); ++ usb_enable_autosuspend(serial->dev); ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) { ++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000); ++ usb_set_serial_data(serial, (void *)device_flags); ++ usb_enable_autosuspend(serial->dev); ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { ++ pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000); ++ usb_enable_autosuspend(serial->dev); ++ } ++#endif ++#if 0 //Added by Quectel ++ //For USB Remote Wakeup ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) { ++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) { ++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) { ++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup ++ } ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) { ++ device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup ++ } ++#endif ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1476) && ++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 3) ++ return -ENODEV; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1476) && ++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 4) ++ return -ENODEV; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1509) && ++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 4) ++ return -ENODEV; ++ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x19d2) && ++ serial->dev->descriptor.idProduct == cpu_to_le16(0x1509) && ++ serial->interface->cur_altsetting->desc. bInterfaceNumber == 5) ++ return -ENODEV; + return 0; + } + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -88,7 +88,6 @@ static const struct usb_device_id id_tab + {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ + {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ + {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ +- {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ + {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ + {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ +--- a/drivers/usb/serial/usb_wwan.c ++++ b/drivers/usb/serial/usb_wwan.c +@@ -476,6 +476,19 @@ static struct urb *usb_wwan_setup_urb(st + usb_fill_bulk_urb(urb, serial->dev, + usb_sndbulkpipe(serial->dev, endpoint) | dir, + buf, len, callback, ctx); ++#if 1 //Added by Quectel for zero packet ++ if (dir == USB_DIR_OUT) { ++ struct usb_device_descriptor *desc = &serial->dev->descriptor; ++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ if (desc->idVendor == cpu_to_le16(0x2C7C)) ++ urb->transfer_flags |= URB_ZERO_PACKET; ++ } ++#endif + + if (intfdata->use_zlp && dir == USB_DIR_OUT) + urb->transfer_flags |= URB_ZERO_PACKET; diff --git a/target/linux/ipq40xx/patches-5.4/952-net-conntrack-events-support-multiple-registrant.patch b/target/linux/ipq40xx/patches-5.4/952-net-conntrack-events-support-multiple-registrant.patch new file mode 100644 index 0000000000..c763449594 --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/952-net-conntrack-events-support-multiple-registrant.patch @@ -0,0 +1,313 @@ +From 42824d4b753f84ccf885eca602c5037338b546c8 Mon Sep 17 00:00:00 2001 +From: Zhi Chen +Date: Tue, 13 Jan 2015 14:28:18 -0800 +Subject: [PATCH 3/3] net: conntrack events, support multiple registrant + +Merging this patch from kernel 3.4: +This was supported by old (.28) kernel versions but removed +because of it's overhead. +But we need this feature for NA connection manager. Both ipv4 +and ipv6 modules needs to register themselves to ct events. + +Change-Id: Iebfb254590fb594f5baf232f849d1b7ae45ef757 +Signed-off-by: Zhi Chen +--- + include/net/netfilter/nf_conntrack_ecache.h | 42 ++++++++++++++++++- + include/net/netns/conntrack.h | 4 ++ + net/netfilter/Kconfig | 8 ++++ + net/netfilter/nf_conntrack_core.c | 4 ++ + net/netfilter/nf_conntrack_ecache.c | 63 +++++++++++++++++++++++++++++ + net/netfilter/nf_conntrack_netlink.c | 17 ++++++++ + 6 files changed, 137 insertions(+), 1 deletion(-) + +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -72,6 +72,10 @@ struct nf_ct_event { + int report; + }; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb); ++extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb); ++#else + struct nf_ct_event_notifier { + int (*fcn)(unsigned int events, struct nf_ct_event *item); + }; +@@ -80,6 +84,7 @@ int nf_conntrack_register_notifier(struc + struct nf_ct_event_notifier *nb); + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *nb); ++#endif + + void nf_ct_deliver_cached_events(struct nf_conn *ct); + int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, +@@ -105,11 +110,13 @@ static inline void + nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- struct net *net = nf_ct_net(ct); + struct nf_conntrack_ecache *e; ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return; ++#endif + + e = nf_ct_ecache_find(ct); + if (e == NULL) +@@ -124,10 +131,12 @@ nf_conntrack_event_report(enum ip_conntr + u32 portid, int report) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; ++#endif + + return nf_conntrack_eventmask_report(1 << event, ct, portid, report); + #else +@@ -139,10 +148,12 @@ static inline int + nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) + { + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + const struct net *net = nf_ct_net(ct); + + if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) + return 0; ++#endif + + return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); + #else +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -112,7 +112,11 @@ struct netns_ct { + + struct ct_pcpu __percpu *pcpu_lists; + struct ip_conntrack_stat __percpu *stat; ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct atomic_notifier_head nf_conntrack_chain; ++#else + struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; ++#endif + struct nf_exp_event_notifier __rcu *nf_expect_event_cb; + struct nf_ip_net nf_ct_proto; + #if defined(CONFIG_NF_CONNTRACK_LABELS) +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -136,6 +136,14 @@ config NF_CONNTRACK_EVENTS + + If unsure, say `N'. + ++config NF_CONNTRACK_CHAIN_EVENTS ++ bool "Register multiple callbacks to ct events" ++ depends on NF_CONNTRACK_EVENTS ++ help ++ Support multiple registrations. ++ ++ If unsure, say `N'. ++ + config NF_CONNTRACK_TIMEOUT + bool 'Connection tracking timeout' + depends on NETFILTER_ADVANCED +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -2572,6 +2572,9 @@ int nf_conntrack_init_net(struct net *ne + nf_conntrack_helper_pernet_init(net); + nf_conntrack_proto_pernet_init(net); + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain); ++#endif + return 0; + + err_expect: +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -17,6 +17,9 @@ + #include + #include + #include ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++#include ++#endif + #include + #include + #include +@@ -116,7 +119,35 @@ static void ecache_work(struct work_stru + if (delay >= 0) + schedule_delayed_work(&ctnet->ecache_dwork, delay); + } ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, ++ u32 portid, int report) ++{ ++ struct nf_conntrack_ecache *e; ++ struct net *net = nf_ct_net(ct); ++ ++ e = nf_ct_ecache_find(ct); ++ if (e == NULL) ++ return 0; ++ ++ if (nf_ct_is_confirmed(ct)) { ++ struct nf_ct_event item = { ++ .ct = ct, ++ .portid = e->portid ? e->portid : portid, ++ .report = report ++ }; ++ /* This is a resent of a destroy event? If so, skip missed */ ++ unsigned long missed = e->portid ? 0 : e->missed; ++ ++ if (!((eventmask | missed) & e->ctmask)) ++ return 0; + ++ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item); ++ } ++ ++ return 0; ++} ++#else + int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, + u32 portid, int report) + { +@@ -171,10 +202,52 @@ out_unlock: + rcu_read_unlock(); + return ret; + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report); + + /* deliver cached events and clear cache entry - must be called with locally + * disabled softirqs */ ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++void nf_ct_deliver_cached_events(struct nf_conn *ct) ++{ ++ unsigned long events, missed; ++ struct nf_conntrack_ecache *e; ++ struct nf_ct_event item; ++ struct net *net = nf_ct_net(ct); ++ ++ e = nf_ct_ecache_find(ct); ++ if (e == NULL) ++ return; ++ ++ events = xchg(&e->cache, 0); ++ ++ if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events) ++ return; ++ ++ /* We make a copy of the missed event cache without taking ++ * the lock, thus we may send missed events twice. However, ++ * this does not harm and it happens very rarely. */ ++ missed = e->missed; ++ ++ if (!((events | missed) & e->ctmask)) ++ return; ++ ++ item.ct = ct; ++ item.portid = 0; ++ item.report = 0; ++ ++ atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ events | missed, ++ &item); ++ ++ if (likely(!missed)) ++ return; ++ ++ spin_lock_bh(&ct->lock); ++ e->missed &= ~missed; ++ spin_unlock_bh(&ct->lock); ++} ++#else + void nf_ct_deliver_cached_events(struct nf_conn *ct) + { + struct net *net = nf_ct_net(ct); +@@ -225,6 +298,7 @@ void nf_ct_deliver_cached_events(struct + out_unlock: + rcu_read_unlock(); + } ++#endif + EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); + + void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, +@@ -257,6 +331,13 @@ out_unlock: + rcu_read_unlock(); + } + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int nf_conntrack_register_notifier(struct net *net, ++ struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); ++} ++#else + int nf_conntrack_register_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +@@ -277,8 +358,15 @@ out_unlock: + mutex_unlock(&nf_ct_ecache_mutex); + return ret; + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); ++} ++#else + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *new) + { +@@ -292,6 +380,7 @@ void nf_conntrack_unregister_notifier(st + mutex_unlock(&nf_ct_ecache_mutex); + /* synchronize_rcu() is called from ctnetlink_exit. */ + } ++#endif + EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); + + int nf_ct_expect_register_notifier(struct net *net, +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -680,13 +680,20 @@ static size_t ctnetlink_nlmsg_size(const + } + + static int ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ctnetlink_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr) ++#else + ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) ++#endif + { + const struct nf_conntrack_zone *zone; + struct net *net; + struct nlmsghdr *nlh; + struct nfgenmsg *nfmsg; + struct nlattr *nest_parms; ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ struct nf_ct_event *item = (struct nf_ct_event *)ptr; ++#endif + struct nf_conn *ct = item->ct; + struct sk_buff *skb; + unsigned int type; +@@ -3508,9 +3515,15 @@ static int ctnetlink_stat_exp_cpu(struct + } + + #ifdef CONFIG_NF_CONNTRACK_EVENTS ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++static struct notifier_block ctnl_notifier = { ++ .notifier_call = ctnetlink_conntrack_event, ++}; ++#else + static struct nf_ct_event_notifier ctnl_notifier = { + .fcn = ctnetlink_conntrack_event, + }; ++#endif + + static struct nf_exp_event_notifier ctnl_notifier_exp = { + .fcn = ctnetlink_expect_event, diff --git a/target/linux/ipq40xx/patches-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/ipq40xx/patches-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch new file mode 100644 index 0000000000..57b4029298 --- /dev/null +++ b/target/linux/ipq40xx/patches-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -0,0 +1,253 @@ +--- a/include/linux/if_bridge.h ++++ b/include/linux/if_bridge.h +@@ -52,6 +52,9 @@ struct br_ip_list { + + extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); + ++extern void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats); ++ + #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) + int br_multicast_list_adjacent(struct net_device *dev, + struct list_head *br_ip_list); +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -826,6 +826,10 @@ struct sk_buff { + #endif + __u8 gro_skip:1; + ++#ifdef CONFIG_SHORTCUT_FE ++ __u8 fast_forwarded:1; ++#endif ++ + #ifdef CONFIG_NET_SCHED + __u16 tc_index; /* traffic control index */ + #endif +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -18,6 +18,10 @@ struct timer_list { + void (*function)(struct timer_list *); + u32 flags; + ++#ifdef CONFIG_SHORTCUT_FE ++ unsigned long cust_data; ++#endif ++ + #ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; + #endif +--- a/include/net/netfilter/nf_conntrack_ecache.h ++++ b/include/net/netfilter/nf_conntrack_ecache.h +@@ -75,6 +75,8 @@ struct nf_ct_event { + #ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS + extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb); + extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb); ++extern int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb); ++extern int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb); + #else + struct nf_ct_event_notifier { + int (*fcn)(unsigned int events, struct nf_ct_event *item); +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -763,6 +763,28 @@ void br_port_flags_change(struct net_bri + br_recalculate_neigh_suppress_enabled(br); + } + ++void br_dev_update_stats(struct net_device *dev, ++ struct rtnl_link_stats64 *nlstats) ++{ ++ struct net_bridge *br; ++ struct pcpu_sw_netstats *stats; ++ ++ /* Is this a bridge? */ ++ if (!(dev->priv_flags & IFF_EBRIDGE)) ++ return; ++ ++ br = netdev_priv(dev); ++ stats = this_cpu_ptr(br->stats); ++ ++ u64_stats_update_begin(&stats->syncp); ++ stats->rx_packets += nlstats->rx_packets; ++ stats->rx_bytes += nlstats->rx_bytes; ++ stats->tx_packets += nlstats->tx_packets; ++ stats->tx_bytes += nlstats->tx_bytes; ++ u64_stats_update_end(&stats->syncp); ++} ++EXPORT_SYMBOL_GPL(br_dev_update_stats); ++ + bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) + { + struct net_bridge_port *p; +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3197,9 +3197,17 @@ static int xmit_one(struct sk_buff *skb, + unsigned int len; + int rc; + ++#ifdef CONFIG_SHORTCUT_FE ++ /* If this skb has been fast forwarded then we don't want it to ++ * go to any taps (by definition we're trying to bypass them). ++ */ ++ if (!skb->fast_forwarded) { ++#endif + if (dev_nit_active(dev)) + dev_queue_xmit_nit(skb, dev); +- ++#ifdef CONFIG_SHORTCUT_FE ++ } ++#endif + #ifdef CONFIG_ETHERNET_PACKET_MANGLE + if (!dev->eth_mangle_tx || + (skb = dev->eth_mangle_tx(dev, skb)) != NULL) +@@ -4714,6 +4722,11 @@ void netdev_rx_handler_unregister(struct + } + EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); + ++#ifdef CONFIG_SHORTCUT_FE ++int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly; ++EXPORT_SYMBOL_GPL(athrs_fast_nat_recv); ++#endif ++ + /* + * Limit the use of PFMEMALLOC reserves to those protocols that implement + * the special handling of PFMEMALLOC skbs. +@@ -4764,6 +4777,10 @@ static int __netif_receive_skb_core(stru + int ret = NET_RX_DROP; + __be16 type; + ++#ifdef CONFIG_SHORTCUT_FE ++ int (*fast_recv)(struct sk_buff *skb); ++#endif ++ + net_timestamp_check(!netdev_tstamp_prequeue, skb); + + trace_netif_receive_skb(skb); +@@ -4803,6 +4820,16 @@ another_round: + goto out; + } + ++#ifdef CONFIG_SHORTCUT_FE ++ fast_recv = rcu_dereference(athrs_fast_nat_recv); ++ if (fast_recv) { ++ if (fast_recv(skb)) { ++ ret = NET_RX_SUCCESS; ++ goto out; ++ } ++ } ++#endif ++ + if (skb_skip_tc_classify(skb)) + goto skip_classify; + +--- a/net/Kconfig ++++ b/net/Kconfig +@@ -473,3 +473,6 @@ config HAVE_CBPF_JIT + # Extended BPF JIT (eBPF) + config HAVE_EBPF_JIT + bool ++ ++config SHORTCUT_FE ++ bool "Enables kernel network stack path for Shortcut Forwarding Engine +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -34,11 +34,19 @@ + /* Do not check the TCP window for incoming packets */ + static int nf_ct_tcp_no_window_check __read_mostly = 1; + ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check); ++#endif ++ + /* "Be conservative in what you do, + be liberal in what you accept from others." + If it's non-zero, we mark only out of window RST segments as INVALID. */ + static int nf_ct_tcp_be_liberal __read_mostly = 0; + ++#ifdef CONFIG_SHORTCUT_FE ++EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal); ++#endif ++ + /* If it is set to zero, we disable picking up already established + connections. */ + static int nf_ct_tcp_loose __read_mostly = 1; +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -158,7 +158,11 @@ int nf_conntrack_eventmask_report(unsign + + rcu_read_lock(); + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ if (!notify && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head)) ++#else + if (!notify) ++#endif + goto out_unlock; + + e = nf_ct_ecache_find(ct); +@@ -177,7 +181,14 @@ int nf_conntrack_eventmask_report(unsign + if (!((eventmask | missed) & e->ctmask)) + goto out_unlock; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ eventmask | missed, &item); ++ if (notify) ++ ret = notify->fcn(eventmask | missed, &item); ++#else + ret = notify->fcn(eventmask | missed, &item); ++#endif + if (unlikely(ret < 0 || missed)) { + spin_lock_bh(&ct->lock); + if (ret < 0) { +@@ -259,7 +270,11 @@ void nf_ct_deliver_cached_events(struct + + rcu_read_lock(); + notify = rcu_dereference(net->ct.nf_conntrack_event_cb); ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ if ((notify == NULL) && !rcu_dereference_raw(net->ct.nf_conntrack_chain.head)) ++#else + if (notify == NULL) ++#endif + goto out_unlock; + + e = nf_ct_ecache_find(ct); +@@ -283,7 +298,15 @@ void nf_ct_deliver_cached_events(struct + item.portid = 0; + item.report = 0; + ++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS ++ ret = atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, ++ events | missed, ++ &item); ++ if (notify != NULL) ++ ret = notify->fcn(events | missed, &item); ++#else + ret = notify->fcn(events | missed, &item); ++#endif + + if (likely(ret == 0 && !missed)) + goto out_unlock; +@@ -337,6 +360,11 @@ int nf_conntrack_register_notifier(struc + { + return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); + } ++int nf_conntrack_register_chain_notifier(struct net *net, struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb); ++} ++EXPORT_SYMBOL_GPL(nf_conntrack_register_chain_notifier); + #else + int nf_conntrack_register_notifier(struct net *net, + struct nf_ct_event_notifier *new) +@@ -366,6 +394,11 @@ int nf_conntrack_unregister_notifier(str + { + return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); + } ++int nf_conntrack_unregister_chain_notifier(struct net *net, struct notifier_block *nb) ++{ ++ return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb); ++} ++EXPORT_SYMBOL_GPL(nf_conntrack_unregister_chain_notifier); + #else + void nf_conntrack_unregister_notifier(struct net *net, + struct nf_ct_event_notifier *new) -- 2.17.1