Changeset efa4154 for npl/kernel/linux_src/linux-4.14-imq.diff
- Timestamp:
- 03/06/20 11:28:58 (5 years ago)
- Branches:
- master
- Children:
- e856512
- Parents:
- f6630dd
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
npl/kernel/linux_src/linux-4.14-imq.diff
rf6630dd refa4154 1 diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig 2 index 95c32f2..93fada5 100644 3 --- a/drivers/net/Kconfig 4 +++ b/drivers/net/Kconfig 5 @@ -260,6 +260,125 @@ config RIONET_RX_SIZE 6 depends on RIONET 7 default "128" 8 9 +config IMQ 10 + tristate "IMQ (intermediate queueing device) support" 11 + depends on NETDEVICES && NETFILTER 12 + ---help--- 13 + The IMQ device(s) is used as placeholder for QoS queueing 14 + disciplines. Every packet entering/leaving the IP stack can be 15 + directed through the IMQ device where it's enqueued/dequeued to the 16 + attached qdisc. This allows you to treat network devices as classes 17 + and distribute bandwidth among them. Iptables is used to specify 18 + through which IMQ device, if any, packets travel. 19 + 20 + More information at: https://github.com/imq/linuximq 21 + 22 + To compile this driver as a module, choose M here: the module 23 + will be called imq. If unsure, say N. 24 + 25 +choice 26 + prompt "IMQ behavior (PRE/POSTROUTING)" 27 + depends on IMQ 28 + default IMQ_BEHAVIOR_AB 29 + help 30 + This setting defines how IMQ behaves in respect to its 31 + hooking in PREROUTING and POSTROUTING. 32 + 33 + IMQ can work in any of the following ways: 34 + 35 + PREROUTING | POSTROUTING 36 + -----------------|------------------- 37 + #1 After NAT | After NAT 38 + #2 After NAT | Before NAT 39 + #3 Before NAT | After NAT 40 + #4 Before NAT | Before NAT 41 + 42 + The default behavior is to hook before NAT on PREROUTING 43 + and after NAT on POSTROUTING (#3). 44 + 45 + This settings are specially usefull when trying to use IMQ 46 + to shape NATed clients. 47 + 48 + More information can be found at: https://github.com/imq/linuximq 49 + 50 + If not sure leave the default settings alone. 51 + 52 +config IMQ_BEHAVIOR_AA 53 + bool "IMQ AA" 54 + help 55 + This setting defines how IMQ behaves in respect to its 56 + hooking in PREROUTING and POSTROUTING. 57 + 58 + Choosing this option will make IMQ hook like this: 59 + 60 + PREROUTING: After NAT 61 + POSTROUTING: After NAT 62 + 63 + More information can be found at: https://github.com/imq/linuximq 64 + 65 + If not sure leave the default settings alone. 66 + 67 +config IMQ_BEHAVIOR_AB 68 + bool "IMQ AB" 69 + help 70 + This setting defines how IMQ behaves in respect to its 71 + hooking in PREROUTING and POSTROUTING. 72 + 73 + Choosing this option will make IMQ hook like this: 74 + 75 + PREROUTING: After NAT 76 + POSTROUTING: Before NAT 77 + 78 + More information can be found at: https://github.com/imq/linuximq 79 + 80 + If not sure leave the default settings alone. 81 + 82 +config IMQ_BEHAVIOR_BA 83 + bool "IMQ BA" 84 + help 85 + This setting defines how IMQ behaves in respect to its 86 + hooking in PREROUTING and POSTROUTING. 87 + 88 + Choosing this option will make IMQ hook like this: 89 + 90 + PREROUTING: Before NAT 91 + POSTROUTING: After NAT 92 + 93 + More information can be found at: https://github.com/imq/linuximq 94 + 95 + If not sure leave the default settings alone. 96 + 97 +config IMQ_BEHAVIOR_BB 98 + bool "IMQ BB" 99 + help 100 + This setting defines how IMQ behaves in respect to its 101 + hooking in PREROUTING and POSTROUTING. 102 + 103 + Choosing this option will make IMQ hook like this: 104 + 105 + PREROUTING: Before NAT 106 + POSTROUTING: Before NAT 107 + 108 + More information can be found at: https://github.com/imq/linuximq 109 + 110 + If not sure leave the default settings alone. 111 + 112 +endchoice 113 + 114 +config IMQ_NUM_DEVS 115 + int "Number of IMQ devices" 116 + range 2 16 117 + depends on IMQ 118 + default "16" 119 + help 120 + This setting defines how many IMQ devices will be created. 121 + 122 + The default value is 16. 123 + 124 + More information can be found at: https://github.com/imq/linuximq 125 + 126 + If not sure leave the default settings alone. 127 + 128 config TUN 129 tristate "Universal TUN/TAP device driver support" 130 depends on INET 131 diff --git a/drivers/net/Makefile b/drivers/net/Makefile 132 index 7336cbd..d6d7ad4 100644 133 --- a/drivers/net/Makefile 134 +++ b/drivers/net/Makefile 135 @@ -11,6 +11,7 @@ obj-$(CONFIG_DUMMY) += dummy.o 136 obj-$(CONFIG_EQUALIZER) += eql.o 137 obj-$(CONFIG_IFB) += ifb.o 138 obj-$(CONFIG_MACSEC) += macsec.o 139 +obj-$(CONFIG_IMQ) += imq.o 140 obj-$(CONFIG_MACVLAN) += macvlan.o 141 obj-$(CONFIG_MACVTAP) += macvtap.o 142 obj-$(CONFIG_MII) += mii.o 143 diff --git a/drivers/net/imq.c b/drivers/net/imq.c 144 new file mode 100644 145 index 0000000..bc3b997 146 --- /dev/null 147 +++ b/drivers/net/imq.c 148 @@ -0,0 +1,907 @@ 1 diff -Naupr linux-4.14_orig/drivers/net/imq.c linux-4.14/drivers/net/imq.c 2 --- linux-4.14_orig/drivers/net/imq.c 1970-01-01 07:00:00.000000000 +0700 3 +++ linux-4.14/drivers/net/imq.c 2017-11-13 11:46:45.844089945 +0700 4 @@ -0,0 +1,962 @@ 149 5 +/* 150 6 + * Pseudo-driver for the intermediate queue device. … … 159 15 + * The first version was written by Martin Devera, <devik@cdi.cz> 160 16 + * 161 + * See Credit is.txt17 + * See Credits.txt 162 18 + */ 163 19 + … … 174 30 +#include <linux/netfilter_ipv4.h> 175 31 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 176 + 32 +#include <linux/netfilter_ipv6.h> 177 33 +#endif 178 34 +#include <linux/imq.h> … … 465 321 + struct nf_queue_entry *entry = skb->nf_queue_entry; 466 322 + 323 + rcu_read_lock(); 324 + 467 325 + skb->nf_queue_entry = NULL; 468 326 + netif_trans_update(dev); … … 492 350 + dev_kfree_skb(skb); 493 351 + 352 + rcu_read_unlock(); 494 353 + return NETDEV_TX_OK; 495 354 + } … … 504 363 + nf_reinject(entry, NF_ACCEPT); 505 364 + 365 + rcu_read_unlock(); 506 366 + return NETDEV_TX_OK; 507 367 +} … … 539 399 + if (entry) { 540 400 + nf_queue_entry_get_refs(entry); 541 + 401 + return entry; 542 402 + } 543 403 + return NULL; … … 751 611 + spin_lock(root_lock); 752 612 + 753 + users = atomic_read(&skb->users);613 + users = refcount_read(&skb->users); 754 614 + 755 615 + skb_shared = skb_get(skb); /* increase reference count by one */ … … 758 618 + skb_save_cb(skb_shared); 759 619 + qdisc_enqueue_root(skb_shared, q, &to_free); /* might kfree_skb */ 760 + if (likely( atomic_read(&skb_shared->users) == users + 1)) {620 + if (likely(refcount_read(&skb_shared->users) == users + 1)) { 761 621 + bool validate; 762 622 + … … 858 718 +} 859 719 + 720 +static struct device_type imq_device_type = { 721 + .name = "imq", 722 +}; 723 + 860 724 +static const struct net_device_ops imq_netdev_ops = { 861 725 + .ndo_open = imq_open, … … 879 743 +} 880 744 + 881 +static int imq_validate(struct nlattr *tb[], struct nlattr *data[]) 745 +static int imq_validate(struct nlattr *tb[], struct nlattr *data[], 746 + struct netlink_ext_ack *extack) 882 747 +{ 883 748 + int ret = 0; … … 910 775 +}; 911 776 + 912 +static int __init imq_init_hooks(void) 777 +static int __net_init imq_nf_register(struct net *net) 778 +{ 779 + return nf_register_net_hooks(net, imq_ops, 780 + ARRAY_SIZE(imq_ops)); 781 +}; 782 + 783 +static void __net_exit imq_nf_unregister(struct net *net) 784 +{ 785 + nf_unregister_net_hooks(net, imq_ops, 786 + ARRAY_SIZE(imq_ops)); 787 +}; 788 + 789 +static struct pernet_operations imq_net_ops = { 790 + .init = imq_nf_register, 791 + .exit = imq_nf_unregister, 792 +}; 793 + 794 +static int __net_init imq_init_hooks(void) 913 795 +{ 914 796 + int ret; 915 +916 797 + nf_register_queue_imq_handler(&imq_nfqh); 917 798 + 918 + ret = nf_register_hooks(imq_ops, ARRAY_SIZE(imq_ops));799 + ret = register_pernet_subsys(&imq_net_ops); 919 800 + if (ret < 0) 920 801 + nf_unregister_queue_imq_handler(); … … 922 803 + return ret; 923 804 +} 805 + 806 +#ifdef CONFIG_LOCKDEP 807 + static struct lock_class_key imq_netdev_addr_lock_key; 808 + 809 + static void __init imq_dev_set_lockdep_one(struct net_device *dev, 810 + struct netdev_queue *txq, void *arg) 811 + { 812 + /* 813 + * the IMQ transmit locks can be taken recursively, 814 + * for example with one IMQ rule for input- and one for 815 + * output network devices in iptables! 816 + * until we find a better solution ignore them. 817 + */ 818 + lockdep_set_novalidate_class(&txq->_xmit_lock); 819 + } 820 + 821 + static void imq_dev_set_lockdep_class(struct net_device *dev) 822 + { 823 + lockdep_set_class_and_name(&dev->addr_list_lock, 824 + &imq_netdev_addr_lock_key, "_xmit_addr_IMQ"); 825 + netdev_for_each_tx_queue(dev, imq_dev_set_lockdep_one, NULL); 826 +} 827 +#else 828 + static inline void imq_dev_set_lockdep_class(struct net_device *dev) 829 + { 830 + } 831 +#endif 924 832 + 925 833 +static int __init imq_init_one(int index) … … 937 845 + 938 846 + dev->rtnl_link_ops = &imq_link_ops; 847 + SET_NETDEV_DEVTYPE(dev, &imq_device_type); 939 848 + ret = register_netdevice(dev); 940 849 + if (ret < 0) 941 850 + goto fail; 851 + 852 + imq_dev_set_lockdep_class(dev); 942 853 + 943 854 + return 0; … … 1023 934 +static void __exit imq_unhook(void) 1024 935 +{ 1025 + nf_unregister_hooks(imq_ops, ARRAY_SIZE(imq_ops));936 + unregister_pernet_subsys(&imq_net_ops); 1026 937 + nf_unregister_queue_imq_handler(); 1027 938 +} … … 1054 965 +MODULE_LICENSE("GPL"); 1055 966 +MODULE_ALIAS_RTNL_LINK("imq"); 1056 diff --git a/include/linux/imq.h b/include/linux/imq.h 1057 new file mode 100644 1058 index 0000000..1babb09 1059 --- /dev/null 1060 +++ b/include/linux/imq.h 967 diff -Naupr linux-4.14_orig/drivers/net/Kconfig linux-4.14/drivers/net/Kconfig 968 --- linux-4.14_orig/drivers/net/Kconfig 2017-11-13 01:46:13.000000000 +0700 969 +++ linux-4.14/drivers/net/Kconfig 2017-11-13 11:46:45.844089945 +0700 970 @@ -277,6 +277,125 @@ config RIONET_RX_SIZE 971 depends on RIONET 972 default "128" 973 974 +config IMQ 975 + tristate "IMQ (intermediate queueing device) support" 976 + depends on NETDEVICES && NETFILTER 977 + ---help--- 978 + The IMQ device(s) is used as placeholder for QoS queueing 979 + disciplines. Every packet entering/leaving the IP stack can be 980 + directed through the IMQ device where it's enqueued/dequeued to the 981 + attached qdisc. This allows you to treat network devices as classes 982 + and distribute bandwidth among them. Iptables is used to specify 983 + through which IMQ device, if any, packets travel. 984 + 985 + More information at: https://github.com/imq/linuximq 986 + 987 + To compile this driver as a module, choose M here: the module 988 + will be called imq. If unsure, say N. 989 + 990 +choice 991 + prompt "IMQ behavior (PRE/POSTROUTING)" 992 + depends on IMQ 993 + default IMQ_BEHAVIOR_AB 994 + help 995 + This setting defines how IMQ behaves in respect to its 996 + hooking in PREROUTING and POSTROUTING. 997 + 998 + IMQ can work in any of the following ways: 999 + 1000 + PREROUTING | POSTROUTING 1001 + -----------------|------------------- 1002 + #1 After NAT | After NAT 1003 + #2 After NAT | Before NAT 1004 + #3 Before NAT | After NAT 1005 + #4 Before NAT | Before NAT 1006 + 1007 + The default behavior is to hook before NAT on PREROUTING 1008 + and after NAT on POSTROUTING (#3). 1009 + 1010 + This settings are specially usefull when trying to use IMQ 1011 + to shape NATed clients. 1012 + 1013 + More information can be found at: https://github.com/imq/linuximq 1014 + 1015 + If not sure leave the default settings alone. 1016 + 1017 +config IMQ_BEHAVIOR_AA 1018 + bool "IMQ AA" 1019 + help 1020 + This setting defines how IMQ behaves in respect to its 1021 + hooking in PREROUTING and POSTROUTING. 1022 + 1023 + Choosing this option will make IMQ hook like this: 1024 + 1025 + PREROUTING: After NAT 1026 + POSTROUTING: After NAT 1027 + 1028 + More information can be found at: https://github.com/imq/linuximq 1029 + 1030 + If not sure leave the default settings alone. 1031 + 1032 +config IMQ_BEHAVIOR_AB 1033 + bool "IMQ AB" 1034 + help 1035 + This setting defines how IMQ behaves in respect to its 1036 + hooking in PREROUTING and POSTROUTING. 1037 + 1038 + Choosing this option will make IMQ hook like this: 1039 + 1040 + PREROUTING: After NAT 1041 + POSTROUTING: Before NAT 1042 + 1043 + More information can be found at: https://github.com/imq/linuximq 1044 + 1045 + If not sure leave the default settings alone. 1046 + 1047 +config IMQ_BEHAVIOR_BA 1048 + bool "IMQ BA" 1049 + help 1050 + This setting defines how IMQ behaves in respect to its 1051 + hooking in PREROUTING and POSTROUTING. 1052 + 1053 + Choosing this option will make IMQ hook like this: 1054 + 1055 + PREROUTING: Before NAT 1056 + POSTROUTING: After NAT 1057 + 1058 + More information can be found at: https://github.com/imq/linuximq 1059 + 1060 + If not sure leave the default settings alone. 1061 + 1062 +config IMQ_BEHAVIOR_BB 1063 + bool "IMQ BB" 1064 + help 1065 + This setting defines how IMQ behaves in respect to its 1066 + hooking in PREROUTING and POSTROUTING. 1067 + 1068 + Choosing this option will make IMQ hook like this: 1069 + 1070 + PREROUTING: Before NAT 1071 + POSTROUTING: Before NAT 1072 + 1073 + More information can be found at: https://github.com/imq/linuximq 1074 + 1075 + If not sure leave the default settings alone. 1076 + 1077 +endchoice 1078 + 1079 +config IMQ_NUM_DEVS 1080 + int "Number of IMQ devices" 1081 + range 2 16 1082 + depends on IMQ 1083 + default "16" 1084 + help 1085 + This setting defines how many IMQ devices will be created. 1086 + 1087 + The default value is 16. 1088 + 1089 + More information can be found at: https://github.com/imq/linuximq 1090 + 1091 + If not sure leave the default settings alone. 1092 + 1093 config TUN 1094 tristate "Universal TUN/TAP device driver support" 1095 depends on INET 1096 diff -Naupr linux-4.14_orig/drivers/net/Makefile linux-4.14/drivers/net/Makefile 1097 --- linux-4.14_orig/drivers/net/Makefile 2017-11-13 01:46:13.000000000 +0700 1098 +++ linux-4.14/drivers/net/Makefile 2017-11-13 11:46:45.844089945 +0700 1099 @@ -13,6 +13,7 @@ obj-$(CONFIG_DUMMY) += dummy.o 1100 obj-$(CONFIG_EQUALIZER) += eql.o 1101 obj-$(CONFIG_IFB) += ifb.o 1102 obj-$(CONFIG_MACSEC) += macsec.o 1103 +obj-$(CONFIG_IMQ) += imq.o 1104 obj-$(CONFIG_MACVLAN) += macvlan.o 1105 obj-$(CONFIG_MACVTAP) += macvtap.o 1106 obj-$(CONFIG_MII) += mii.o 1107 diff -Naupr linux-4.14_orig/include/linux/imq.h linux-4.14/include/linux/imq.h 1108 --- linux-4.14_orig/include/linux/imq.h 1970-01-01 07:00:00.000000000 +0700 1109 +++ linux-4.14/include/linux/imq.h 2017-11-13 11:46:45.844089945 +0700 1061 1110 @@ -0,0 +1,13 @@ 1062 1111 +#ifndef _IMQ_H … … 1073 1122 +#endif /* _IMQ_H */ 1074 1123 + 1075 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h 1076 index e16a2a9..4a1090a 100644 1077 --- a/include/linux/netdevice.h 1078 +++ b/include/linux/netdevice.h 1079 @@ -3669,6 +3669,19 @@ static inline void netif_tx_unlock_bh(struct net_device *dev) 1124 diff -Naupr linux-4.14_orig/include/linux/netdevice.h linux-4.14/include/linux/netdevice.h 1125 --- linux-4.14_orig/include/linux/netdevice.h 2017-11-13 01:46:13.000000000 +0700 1126 +++ linux-4.14/include/linux/netdevice.h 2017-11-13 11:46:45.844089945 +0700 1127 @@ -1771,6 +1771,11 @@ struct net_device { 1128 /* 1129 * Cache lines mostly used on receive path (including eth_type_trans()) 1130 */ 1131 + 1132 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1133 + unsigned long last_rx; 1134 +#endif 1135 + 1136 /* Interface address info used in eth_type_trans() */ 1137 unsigned char *dev_addr; 1138 1139 @@ -3631,6 +3636,19 @@ static inline void netif_tx_unlock_bh(st 1080 1140 } \ 1081 1141 } … … 1097 1157 { 1098 1158 unsigned int i; 1099 diff --git a/include/linux/netfilter/xt_IMQ.h b/include/linux/netfilter/xt_IMQ.h 1100 new file mode 100644 1101 index 0000000..9b07230 1102 --- /dev/null 1103 +++ b/include/linux/netfilter/xt_IMQ.h 1159 diff -Naupr linux-4.14_orig/include/linux/netfilter/xt_IMQ.h linux-4.14/include/linux/netfilter/xt_IMQ.h 1160 --- linux-4.14_orig/include/linux/netfilter/xt_IMQ.h 1970-01-01 07:00:00.000000000 +0700 1161 +++ linux-4.14/include/linux/netfilter/xt_IMQ.h 2017-11-13 11:46:45.847423298 +0700 1104 1162 @@ -0,0 +1,9 @@ 1105 1163 +#ifndef _XT_IMQ_H … … 1112 1170 +#endif /* _XT_IMQ_H */ 1113 1171 + 1114 diff --git a/include/linux/netfilter_ipv4/ipt_IMQ.h b/include/linux/netfilter_ipv4/ipt_IMQ.h 1115 new file mode 100644 1116 index 0000000..7af320f 1117 --- /dev/null 1118 +++ b/include/linux/netfilter_ipv4/ipt_IMQ.h 1172 diff -Naupr linux-4.14_orig/include/linux/netfilter_ipv4/ipt_IMQ.h linux-4.14/include/linux/netfilter_ipv4/ipt_IMQ.h 1173 --- linux-4.14_orig/include/linux/netfilter_ipv4/ipt_IMQ.h 1970-01-01 07:00:00.000000000 +0700 1174 +++ linux-4.14/include/linux/netfilter_ipv4/ipt_IMQ.h 2017-11-13 11:46:45.847423298 +0700 1119 1175 @@ -0,0 +1,10 @@ 1120 1176 +#ifndef _IPT_IMQ_H … … 1128 1184 +#endif /* _IPT_IMQ_H */ 1129 1185 + 1130 diff --git a/include/linux/netfilter_ipv6/ip6t_IMQ.h b/include/linux/netfilter_ipv6/ip6t_IMQ.h 1131 new file mode 100644 1132 index 0000000..198ac01 1133 --- /dev/null 1134 +++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h 1186 diff -Naupr linux-4.14_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-4.14/include/linux/netfilter_ipv6/ip6t_IMQ.h 1187 --- linux-4.14_orig/include/linux/netfilter_ipv6/ip6t_IMQ.h 1970-01-01 07:00:00.000000000 +0700 1188 +++ linux-4.14/include/linux/netfilter_ipv6/ip6t_IMQ.h 2017-11-13 11:46:45.847423298 +0700 1135 1189 @@ -0,0 +1,10 @@ 1136 1190 +#ifndef _IP6T_IMQ_H … … 1144 1198 +#endif /* _IP6T_IMQ_H */ 1145 1199 + 1146 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h 1147 index c8f9fa6..6c425c2 100644 1148 --- a/include/linux/skbuff.h 1149 +++ b/include/linux/skbuff.h 1150 @@ -39,6 +39,10 @@ 1200 diff -Naupr linux-4.14_orig/include/linux/skbuff.h linux-4.14/include/linux/skbuff.h 1201 --- linux-4.14_orig/include/linux/skbuff.h 2017-11-13 01:46:13.000000000 +0700 1202 +++ linux-4.14/include/linux/skbuff.h 2017-11-13 11:46:45.847423298 +0700 1203 @@ -41,6 +41,10 @@ 1151 1204 #include <linux/in6.h> 1152 1205 #include <linux/if_packet.h> … … 1159 1212 /* The interface for checksum offload between the stack and networking drivers 1160 1213 * is as follows... 1161 @@ -654,6 +658,9 @@ struct sk_buff { 1214 @@ -581,7 +585,7 @@ typedef unsigned int sk_buff_data_t; 1215 typedef unsigned char *sk_buff_data_t; 1216 #endif 1217 1218 -/** 1219 +/** 1220 * struct sk_buff - socket buffer 1221 * @next: Next buffer in list 1222 * @prev: Previous buffer in list 1223 @@ -684,6 +688,9 @@ struct sk_buff { 1162 1224 * first. This is owned by whoever has the skb queued ATM. 1163 1225 */ … … 1169 1231 unsigned long _skb_refdst; 1170 1232 void (*destructor)(struct sk_buff *skb); 1171 @@ -6 63,6 +670,9 @@ struct sk_buff {1233 @@ -693,6 +700,9 @@ struct sk_buff { 1172 1234 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 1173 struct nf_conntrack *nfct;1235 unsigned long _nfct; 1174 1236 #endif 1175 1237 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) … … 1179 1241 struct nf_bridge_info *nf_bridge; 1180 1242 #endif 1181 @@ -743,6 +753,9 @@ struct sk_buff { 1243 @@ -772,6 +782,9 @@ struct sk_buff { 1244 #ifdef CONFIG_NET_SWITCHDEV 1182 1245 __u8 offload_fwd_mark:1; 1183 1246 #endif 1184 /* 2, 4 or 5 bit hole */1185 1247 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1186 1248 + __u8 imq_flags:IMQ_F_BITS; 1187 1249 +#endif 1188 1189 #ifdef CONFIG_NET_SCHED 1190 __u16 tc_index; /* traffic control index */ 1191 @@ -903,6 +916,12 @@ void kfree_skb_list(struct sk_buff *segs); 1192 void skb_tx_error(struct sk_buff *skb); 1250 #ifdef CONFIG_NET_CLS_ACT 1251 __u8 tc_skip_classify:1; 1252 __u8 tc_at_ingress:1; 1253 @@ -870,7 +883,7 @@ static inline bool skb_pfmemalloc(const 1254 */ 1255 static inline struct dst_entry *skb_dst(const struct sk_buff *skb) 1256 { 1257 - /* If refdst was not refcounted, check we still are in a 1258 + /* If refdst was not refcounted, check we still are in a 1259 * rcu_read_lock section 1260 */ 1261 WARN_ON((skb->_skb_refdst & SKB_DST_NOREF) && 1262 @@ -960,6 +973,12 @@ void skb_tx_error(struct sk_buff *skb); 1193 1263 void consume_skb(struct sk_buff *skb); 1264 void __consume_stateless_skb(struct sk_buff *skb); 1194 1265 void __kfree_skb(struct sk_buff *skb); 1195 1266 + … … 1202 1273 1203 1274 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); 1204 @@ -3 594,6 +3613,10 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src,1205 if (copy)1206 dst->nfctinfo = src->nfctinfo;1275 @@ -3785,8 +3804,12 @@ static inline void __nf_copy(struct sk_b 1276 dst->_nfct = src->_nfct; 1277 nf_conntrack_get(skb_nfct(src)); 1207 1278 #endif 1208 1279 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1209 + 1210 + 1280 + dst->imq_flags = src->imq_flags; 1281 + dst->nf_queue_entry = src->nf_queue_entry; 1211 1282 +#endif 1212 1283 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 1213 dst->nf_bridge = src->nf_bridge; 1284 - dst->nf_bridge = src->nf_bridge; 1285 + dst->nf_bridge = src->nf_bridge; 1214 1286 nf_bridge_get(src->nf_bridge); 1215 diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h 1216 index 2280cfe..ec8fa51 100644 1217 --- a/include/net/netfilter/nf_queue.h 1218 +++ b/include/net/netfilter/nf_queue.h 1219 @@ -30,6 +30,12 @@ struct nf_queue_handler { 1287 #endif 1288 #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES) 1289 diff -Naupr linux-4.14_orig/include/net/netfilter/nf_queue.h linux-4.14/include/net/netfilter/nf_queue.h 1290 --- linux-4.14_orig/include/net/netfilter/nf_queue.h 2017-11-13 01:46:13.000000000 +0700 1291 +++ linux-4.14/include/net/netfilter/nf_queue.h 2017-11-13 11:46:45.847423298 +0700 1292 @@ -31,6 +31,12 @@ struct nf_queue_handler { 1220 1293 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh); 1221 1294 void nf_unregister_queue_handler(struct net *net); … … 1230 1303 void nf_queue_entry_get_refs(struct nf_queue_entry *entry); 1231 1304 void nf_queue_entry_release_refs(struct nf_queue_entry *entry); 1232 diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h 1233 index cd334c9..6757228 100644 1234 --- a/include/net/pkt_sched.h 1235 +++ b/include/net/pkt_sched.h 1236 @@ -105,6 +105,8 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, 1305 diff -Naupr linux-4.14_orig/include/net/pkt_sched.h linux-4.14/include/net/pkt_sched.h 1306 --- linux-4.14_orig/include/net/pkt_sched.h 2017-11-13 01:46:13.000000000 +0700 1307 +++ linux-4.14/include/net/pkt_sched.h 2017-11-13 11:46:45.850756651 +0700 1308 @@ -109,6 +109,8 @@ int sch_direct_xmit(struct sk_buff *skb, 1237 1309 1238 1310 void __qdisc_run(struct Qdisc *q); … … 1243 1315 { 1244 1316 if (qdisc_run_begin(q)) 1245 diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h 1246 index e6aa0a2..08b37dc 100644 1247 --- a/include/net/sch_generic.h 1248 +++ b/include/net/sch_generic.h 1249 @@ -518,6 +518,13 @@ static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, 1317 diff -Naupr linux-4.14_orig/include/net/sch_generic.h linux-4.14/include/net/sch_generic.h 1318 --- linux-4.14_orig/include/net/sch_generic.h 2017-11-13 01:46:13.000000000 +0700 1319 +++ linux-4.14/include/net/sch_generic.h 2017-11-13 11:46:45.850756651 +0700 1320 @@ -567,6 +567,13 @@ static inline int qdisc_enqueue(struct s 1250 1321 return sch->enqueue(skb, sch, to_free); 1251 1322 } … … 1261 1332 { 1262 1333 return q->flags & TCQ_F_CPUSTATS; 1263 diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h 1264 index d93f949..23fb6d1 100644 1265 --- a/include/uapi/linux/netfilter.h 1266 +++ b/include/uapi/linux/netfilter.h 1334 diff -Naupr linux-4.14_orig/include/uapi/linux/netfilter.h linux-4.14/include/uapi/linux/netfilter.h 1335 --- linux-4.14_orig/include/uapi/linux/netfilter.h 2017-11-13 01:46:13.000000000 +0700 1336 +++ linux-4.14/include/uapi/linux/netfilter.h 2017-11-13 11:46:45.850756651 +0700 1267 1337 @@ -14,7 +14,8 @@ 1268 1338 #define NF_QUEUE 3 1269 1339 #define NF_REPEAT 4 1270 #define NF_STOP 5 1340 #define NF_STOP 5 /* Deprecated, for userspace nf_queue compatibility. */ 1271 1341 -#define NF_MAX_VERDICT NF_STOP 1272 1342 +#define NF_IMQ_QUEUE 6 … … 1275 1345 /* we overload the higher bits for encoding auxiliary data such as the queue 1276 1346 * number or errno values. Not nice, but better than additional function 1277 diff - -git a/net/core/dev.c b/net/core/dev.c1278 index 6666b28..3e12add 100644 1279 --- a/net/core/dev.c 1280 +++ b/net/core/dev.c 1281 @@ -141,6 +141,9 @@ 1347 diff -Naupr linux-4.14_orig/net/core/dev.c linux-4.14/net/core/dev.c 1348 --- linux-4.14_orig/net/core/dev.c 2017-11-13 01:46:13.000000000 +0700 1349 +++ linux-4.14/net/core/dev.c 2017-11-13 11:46:45.854090004 +0700 1350 @@ -143,6 +143,9 @@ 1351 #include <linux/hrtimer.h> 1282 1352 #include <linux/netfilter_ingress.h> 1283 #include <linux/sctp.h>1284 1353 #include <linux/crash_dump.h> 1285 1354 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1286 1355 +#include <linux/imq.h> 1287 1356 +#endif 1288 1289 #include "net-sysfs.h"1290 1291 @@ -29 06,7 +2909,12 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev,1357 #include <linux/sctp.h> 1358 #include <net/udp_tunnel.h> 1359 1360 @@ -2971,7 +2974,12 @@ static int xmit_one(struct sk_buff *skb, 1292 1361 unsigned int len; 1293 1362 int rc; … … 1302 1371 1303 1372 len = skb->len; 1304 @@ - 2945,6 +2953,8 @@ struct sk_buff *dev_hard_start_xmit(struct sk_buff *first, struct net_device *de1373 @@ -3010,6 +3018,8 @@ out: 1305 1374 return skb; 1306 1375 } … … 1311 1380 netdev_features_t features) 1312 1381 { 1313 diff --git a/net/core/skbuff.c b/net/core/skbuff.c 1314 index 9bf1289..e3fcf17 100644 1315 --- a/net/core/skbuff.c 1316 +++ b/net/core/skbuff.c 1317 @@ -82,6 +82,87 @@ struct kmem_cache *skbuff_head_cache __read_mostly; 1382 diff -Naupr linux-4.14_orig/net/core/skbuff.c linux-4.14/net/core/skbuff.c 1383 --- linux-4.14_orig/net/core/skbuff.c 2017-11-13 01:46:13.000000000 +0700 1384 +++ linux-4.14/net/core/skbuff.c 2017-11-13 11:46:45.854090004 +0700 1385 @@ -82,6 +82,87 @@ struct kmem_cache *skbuff_head_cache __r 1318 1386 static struct kmem_cache *skbuff_fclone_cache __read_mostly; 1319 1387 int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS; … … 1403 1471 /** 1404 1472 * skb_panic - private function for out-of-line support 1405 @@ -6 54,6 +735,28 @@ static void skb_release_head_state(struct sk_buff *skb)1473 @@ -615,6 +696,28 @@ void skb_release_head_state(struct sk_bu 1406 1474 WARN_ON(in_irq()); 1407 1475 skb->destructor(skb); … … 1430 1498 +#endif 1431 1499 #if IS_ENABLED(CONFIG_NF_CONNTRACK) 1432 nf_conntrack_put(skb ->nfct);1500 nf_conntrack_put(skb_nfct(skb)); 1433 1501 #endif 1434 @@ -8 43,6 +946,10 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)1502 @@ -804,6 +907,10 @@ static void __copy_skb_header(struct sk_ 1435 1503 new->sp = secpath_get(old->sp); 1436 1504 #endif … … 1443 1511 /* Note : this field could be in headers_start/headers_end section 1444 1512 * It is not yet because we do not want to have a 16 bit hole 1445 @@ -3 464,6 +3571,13 @@ void __init skb_init(void)1513 @@ -3902,6 +4009,13 @@ void __init skb_init(void) 1446 1514 0, 1447 1515 SLAB_HWCACHE_ALIGN|SLAB_PANIC, … … 1456 1524 } 1457 1525 1458 /** 1459 diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c 1460 index 59eb4ed..8020b07 100644 1461 --- a/net/ipv6/ip6_output.c 1462 +++ b/net/ipv6/ip6_output.c 1463 @@ -66,9 +66,6 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * 1464 struct in6_addr *nexthop; 1465 int ret; 1466 1467 - skb->protocol = htons(ETH_P_IPV6); 1468 - skb->dev = dev; 1469 - 1470 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { 1471 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 1472 1473 @@ -150,6 +147,13 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) 1474 return 0; 1475 } 1476 1477 + /* 1478 + * IMQ-patch: moved setting skb->dev and skb->protocol from 1479 + * ip6_finish_output2 to fix crashing at netif_skb_features(). 1480 + */ 1481 + skb->protocol = htons(ETH_P_IPV6); 1482 + skb->dev = dev; 1483 + 1484 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, 1485 net, sk, skb, NULL, dev, 1486 ip6_finish_output, 1487 diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig 1488 index 4a2e5a3..fc5cc9a 100644 1489 --- a/net/netfilter/Kconfig 1490 +++ b/net/netfilter/Kconfig 1491 @@ -833,6 +833,18 @@ config NETFILTER_XT_TARGET_LOG 1526 static int 1527 diff -Naupr linux-4.14_orig/net/netfilter/core.c linux-4.14/net/netfilter/core.c 1528 --- linux-4.14_orig/net/netfilter/core.c 2017-11-13 01:46:13.000000000 +0700 1529 +++ linux-4.14/net/netfilter/core.c 2017-11-13 14:16:05.896850774 +0700 1530 @@ -474,6 +474,11 @@ int nf_hook_slow(struct sk_buff *skb, st 1531 if (ret == 0) 1532 ret = -EPERM; 1533 return ret; 1534 + case NF_IMQ_QUEUE: 1535 + ret = nf_queue(skb, state, e, s, verdict); 1536 + if (ret == -ECANCELED) 1537 + continue; 1538 + return ret; 1539 case NF_QUEUE: 1540 ret = nf_queue(skb, state, e, s, verdict); 1541 if (ret == 1) 1542 diff -Naupr linux-4.14_orig/net/netfilter/Kconfig linux-4.14/net/netfilter/Kconfig 1543 --- linux-4.14_orig/net/netfilter/Kconfig 2017-11-13 01:46:13.000000000 +0700 1544 +++ linux-4.14/net/netfilter/Kconfig 2017-11-13 11:46:45.857423358 +0700 1545 @@ -867,6 +867,18 @@ config NETFILTER_XT_TARGET_LOG 1492 1546 1493 1547 To compile it as a module, choose M here. If unsure, say N. … … 1508 1562 tristate '"MARK" target support' 1509 1563 depends on NETFILTER_ADVANCED 1510 diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile 1511 index e5c5e1e..3128bc5 100644 1512 --- a/net/netfilter/Makefile 1513 +++ b/net/netfilter/Makefile 1514 @@ -119,6 +119,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o 1564 diff -Naupr linux-4.14_orig/net/netfilter/Makefile linux-4.14/net/netfilter/Makefile 1565 --- linux-4.14_orig/net/netfilter/Makefile 2017-11-13 01:46:13.000000000 +0700 1566 +++ linux-4.14/net/netfilter/Makefile 2017-11-13 11:46:45.857423358 +0700 1567 @@ -125,6 +125,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += 1515 1568 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 1516 1569 obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o … … 1520 1573 obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o 1521 1574 obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o 1522 diff --git a/net/netfilter/core.c b/net/netfilter/core.c 1523 index 004af03..768a08b 100644 1524 --- a/net/netfilter/core.c 1525 +++ b/net/netfilter/core.c 1526 @@ -360,8 +360,11 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state) 1527 ret = NF_DROP_GETERR(verdict); 1528 if (ret == 0) 1529 ret = -EPERM; 1530 - } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { 1531 + } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE || 1532 + (verdict & NF_VERDICT_MASK) == NF_IMQ_QUEUE) { 1533 ret = nf_queue(skb, state, &entry, verdict); 1534 + if (ret == -ECANCELED) 1535 + goto next_hook; 1536 if (ret == 1 && entry) 1537 goto next_hook; 1538 } 1539 diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c 1540 index 8f08d75..c12c9eb 100644 1541 --- a/net/netfilter/nf_queue.c 1542 +++ b/net/netfilter/nf_queue.c 1575 diff -Naupr linux-4.14_orig/net/netfilter/nf_queue.c linux-4.14/net/netfilter/nf_queue.c 1576 --- linux-4.14_orig/net/netfilter/nf_queue.c 2017-11-13 01:46:13.000000000 +0700 1577 +++ linux-4.14/net/netfilter/nf_queue.c 2017-11-13 14:25:21.436864671 +0700 1578 @@ -1,4 +1,4 @@ 1579 -/* 1580 + /* 1581 * Rusty Russell (C)2000 -- This code is GPL. 1582 * Patrick McHardy (c) 2006-2012 1583 */ 1543 1584 @@ -27,6 +27,23 @@ 1544 1585 * receives, no matter what. … … 1565 1606 * same handler is registered, return 0 in case of success. */ 1566 1607 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh) 1567 @@ -108,16 +125,28 @@ void nf_queue_nf_hook_drop(struct net *net, const struct nf_hook_entry *entry) 1568 } 1608 @@ -113,16 +130,29 @@ EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop) 1569 1609 1570 1610 static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, 1571 - unsigned int queuenum) 1572 + unsigned int verdict) 1611 const struct nf_hook_entries *entries, 1612 - unsigned int index, unsigned int queuenum) 1613 + unsigned int index, unsigned int verdict) 1573 1614 { 1574 1615 int status = -ENOENT; … … 1582 1623 /* QUEUE == DROP if no one is waiting, to be safe. */ 1583 1624 - qh = rcu_dereference(net->nf.queue_handler); 1625 + 1584 1626 + if (queuetype == NF_IMQ_QUEUE) { 1585 1627 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1586 + 1628 + qh = rcu_dereference(queue_imq_handler); 1587 1629 +#else 1588 + 1589 + 1630 + BUG(); 1631 + goto err_unlock; 1590 1632 +#endif 1591 1633 + } else { … … 1596 1638 status = -ESRCH; 1597 1639 goto err; 1598 @@ -164,8 +193,14 @@ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, 1640 @@ -169,8 +199,16 @@ int nf_queue(struct sk_buff *skb, struct 1641 { 1599 1642 int ret; 1600 1643 1601 RCU_INIT_POINTER(state->hook_entries, entry); 1602 - ret = __nf_queue(skb, state, verdict >> NF_VERDICT_QBITS); 1603 + ret = __nf_queue(skb, state, verdict); 1644 - ret = __nf_queue(skb, state, entries, index, verdict >> NF_VERDICT_QBITS); 1645 + ret = __nf_queue(skb, state, entries, index, verdict); 1604 1646 if (ret < 0) { 1647 + 1605 1648 +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 1606 + if (ret == -ECANCELED && skb->imq_flags == 0) { // down interface 1607 + *entryp = rcu_dereference(entry->next); 1608 + return 1; 1609 + } 1610 +#endif 1649 + /* IMQ Bypass */ 1650 + if (ret == -ECANCELED && skb->imq_flags == 0) { 1651 + return 1; 1652 + } 1653 +#endif 1654 + 1611 1655 if (ret == -ESRCH && 1612 (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) {1613 *entryp = rcu_dereference(entry->next);1614 @@ -2 18,6 +253,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)1656 (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) 1657 return 1; 1658 @@ -256,6 +294,7 @@ next_hook: 1615 1659 local_bh_enable(); 1616 1660 break; 1617 1661 case NF_QUEUE: 1618 1662 + case NF_IMQ_QUEUE: 1619 err = nf_queue(skb, &entry->state, &hook_entry, verdict); 1620 if (err == 1) { 1621 if (hook_entry) 1622 diff --git a/net/netfilter/xt_IMQ.c b/net/netfilter/xt_IMQ.c 1623 new file mode 100644 1624 index 0000000..f9c5817 1625 --- /dev/null 1626 +++ b/net/netfilter/xt_IMQ.c 1663 err = nf_queue(skb, &entry->state, hooks, i, verdict); 1664 if (err == 1) 1665 goto next_hook; 1666 diff -Naupr linux-4.14_orig/net/netfilter/xt_IMQ.c linux-4.14/net/netfilter/xt_IMQ.c 1667 --- linux-4.14_orig/net/netfilter/xt_IMQ.c 1970-01-01 07:00:00.000000000 +0700 1668 +++ linux-4.14/net/netfilter/xt_IMQ.c 2017-11-13 11:46:45.857423358 +0700 1627 1669 @@ -0,0 +1,72 @@ 1628 1670 +/* … … 1698 1740 +MODULE_ALIAS("ip6t_IMQ"); 1699 1741 + 1700 diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c 1701 index 6cfb6e9..4c675e9 100644 1702 --- a/net/sched/sch_generic.c 1703 +++ b/net/sched/sch_generic.c 1704 @@ -154,6 +154,14 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, 1742 diff -Naupr linux-4.14_orig/net/sched/sch_generic.c linux-4.14/net/sched/sch_generic.c 1743 --- linux-4.14_orig/net/sched/sch_generic.c 2017-11-13 01:46:13.000000000 +0700 1744 +++ linux-4.14/net/sched/sch_generic.c 2017-11-13 11:46:45.857423358 +0700 1745 @@ -158,6 +158,14 @@ trace: 1705 1746 return skb; 1706 1747 }
Note: See TracChangeset
for help on using the changeset viewer.