OpenWrt – Blame information for rev 3
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Pablo Neira Ayuso <pablo@netfilter.org> |
2 | Date: Mon, 27 Nov 2017 22:50:26 +0100 |
||
3 | Subject: [PATCH] netfilter: move reroute indirection to struct nf_ipv6_ops |
||
4 | |||
5 | We cannot make a direct call to nf_ip6_reroute() because that would result |
||
6 | in autoloading the 'ipv6' module because of symbol dependencies. |
||
7 | Therefore, define reroute indirection in nf_ipv6_ops where this really |
||
8 | belongs to. |
||
9 | |||
10 | For IPv4, we can indeed make a direct function call, which is faster, |
||
11 | given IPv4 is built-in in the networking code by default. Still, |
||
12 | CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline |
||
13 | stub for IPv4 in such case. |
||
14 | |||
15 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
||
16 | --- |
||
17 | |||
18 | --- a/include/linux/netfilter.h |
||
19 | +++ b/include/linux/netfilter.h |
||
3 | office | 20 | @@ -274,8 +274,6 @@ struct nf_queue_entry; |
1 | office | 21 | |
22 | struct nf_afinfo { |
||
23 | unsigned short family; |
||
24 | - int (*reroute)(struct net *net, struct sk_buff *skb, |
||
25 | - const struct nf_queue_entry *entry); |
||
26 | int route_key_size; |
||
27 | }; |
||
28 | |||
3 | office | 29 | @@ -294,6 +292,7 @@ __sum16 nf_checksum_partial(struct sk_bu |
1 | office | 30 | u_int8_t protocol, unsigned short family); |
31 | int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, |
||
32 | bool strict, unsigned short family); |
||
33 | +int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); |
||
34 | |||
35 | int nf_register_afinfo(const struct nf_afinfo *afinfo); |
||
36 | void nf_unregister_afinfo(const struct nf_afinfo *afinfo); |
||
37 | --- a/include/linux/netfilter_ipv4.h |
||
38 | +++ b/include/linux/netfilter_ipv4.h |
||
39 | @@ -18,6 +18,8 @@ struct ip_rt_info { |
||
40 | |||
41 | int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); |
||
42 | |||
43 | +struct nf_queue_entry; |
||
44 | + |
||
45 | #ifdef CONFIG_INET |
||
46 | __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, |
||
47 | unsigned int dataoff, u_int8_t protocol); |
||
48 | @@ -26,6 +28,7 @@ __sum16 nf_ip_checksum_partial(struct sk |
||
49 | u_int8_t protocol); |
||
50 | int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl, |
||
51 | bool strict); |
||
52 | +int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry); |
||
53 | #else |
||
54 | static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, |
||
55 | unsigned int dataoff, u_int8_t protocol) |
||
56 | @@ -45,6 +48,11 @@ static inline int nf_ip_route(struct net |
||
57 | { |
||
58 | return -EOPNOTSUPP; |
||
59 | } |
||
60 | +static inline int nf_ip_reroute(struct sk_buff *skb, |
||
61 | + const struct nf_queue_entry *entry) |
||
62 | +{ |
||
63 | + return -EOPNOTSUPP; |
||
64 | +} |
||
65 | #endif /* CONFIG_INET */ |
||
66 | |||
67 | #endif /*__LINUX_IP_NETFILTER_H*/ |
||
68 | --- a/include/linux/netfilter_ipv6.h |
||
69 | +++ b/include/linux/netfilter_ipv6.h |
||
70 | @@ -18,6 +18,8 @@ struct ip6_rt_info { |
||
71 | u_int32_t mark; |
||
72 | }; |
||
73 | |||
74 | +struct nf_queue_entry; |
||
75 | + |
||
76 | /* |
||
77 | * Hook functions for ipv6 to allow xt_* modules to be built-in even |
||
78 | * if IPv6 is a module. |
||
79 | @@ -35,6 +37,7 @@ struct nf_ipv6_ops { |
||
80 | u_int8_t protocol); |
||
81 | int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl, |
||
82 | bool strict); |
||
83 | + int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry); |
||
84 | }; |
||
85 | |||
86 | #ifdef CONFIG_NETFILTER |
||
87 | --- a/net/bridge/netfilter/nf_tables_bridge.c |
||
88 | +++ b/net/bridge/netfilter/nf_tables_bridge.c |
||
89 | @@ -95,15 +95,8 @@ static const struct nf_chain_type filter |
||
90 | (1 << NF_BR_POST_ROUTING), |
||
91 | }; |
||
92 | |||
93 | -static int nf_br_reroute(struct net *net, struct sk_buff *skb, |
||
94 | - const struct nf_queue_entry *entry) |
||
95 | -{ |
||
96 | - return 0; |
||
97 | -} |
||
98 | - |
||
99 | static const struct nf_afinfo nf_br_afinfo = { |
||
100 | .family = AF_BRIDGE, |
||
101 | - .reroute = nf_br_reroute, |
||
102 | .route_key_size = 0, |
||
103 | }; |
||
104 | |||
105 | --- a/net/ipv4/netfilter.c |
||
106 | +++ b/net/ipv4/netfilter.c |
||
107 | @@ -80,8 +80,7 @@ int ip_route_me_harder(struct net *net, |
||
108 | } |
||
109 | EXPORT_SYMBOL(ip_route_me_harder); |
||
110 | |||
111 | -static int nf_ip_reroute(struct net *net, struct sk_buff *skb, |
||
112 | - const struct nf_queue_entry *entry) |
||
113 | +int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry) |
||
114 | { |
||
115 | const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); |
||
116 | |||
117 | @@ -92,10 +91,12 @@ static int nf_ip_reroute(struct net *net |
||
118 | skb->mark == rt_info->mark && |
||
119 | iph->daddr == rt_info->daddr && |
||
120 | iph->saddr == rt_info->saddr)) |
||
121 | - return ip_route_me_harder(net, skb, RTN_UNSPEC); |
||
122 | + return ip_route_me_harder(entry->state.net, skb, |
||
123 | + RTN_UNSPEC); |
||
124 | } |
||
125 | return 0; |
||
126 | } |
||
127 | +EXPORT_SYMBOL_GPL(nf_ip_reroute); |
||
128 | |||
129 | __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, |
||
130 | unsigned int dataoff, u_int8_t protocol) |
||
131 | @@ -163,7 +164,6 @@ EXPORT_SYMBOL_GPL(nf_ip_route); |
||
132 | |||
133 | static const struct nf_afinfo nf_ip_afinfo = { |
||
134 | .family = AF_INET, |
||
135 | - .reroute = nf_ip_reroute, |
||
136 | .route_key_size = sizeof(struct ip_rt_info), |
||
137 | }; |
||
138 | |||
139 | --- a/net/ipv6/netfilter.c |
||
140 | +++ b/net/ipv6/netfilter.c |
||
3 | office | 141 | @@ -69,7 +69,7 @@ int ip6_route_me_harder(struct net *net, |
1 | office | 142 | } |
143 | EXPORT_SYMBOL(ip6_route_me_harder); |
||
144 | |||
145 | -static int nf_ip6_reroute(struct net *net, struct sk_buff *skb, |
||
146 | +static int nf_ip6_reroute(struct sk_buff *skb, |
||
147 | const struct nf_queue_entry *entry) |
||
148 | { |
||
149 | struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); |
||
3 | office | 150 | @@ -79,7 +79,7 @@ static int nf_ip6_reroute(struct net *ne |
1 | office | 151 | if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || |
152 | !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) || |
||
153 | skb->mark != rt_info->mark) |
||
154 | - return ip6_route_me_harder(net, skb); |
||
155 | + return ip6_route_me_harder(entry->state.net, skb); |
||
156 | } |
||
157 | return 0; |
||
158 | } |
||
3 | office | 159 | @@ -172,11 +172,11 @@ static const struct nf_ipv6_ops ipv6ops |
1 | office | 160 | .checksum = nf_ip6_checksum, |
161 | .checksum_partial = nf_ip6_checksum_partial, |
||
162 | .route = nf_ip6_route, |
||
163 | + .reroute = nf_ip6_reroute, |
||
164 | }; |
||
165 | |||
166 | static const struct nf_afinfo nf_ip6_afinfo = { |
||
167 | .family = AF_INET6, |
||
168 | - .reroute = nf_ip6_reroute, |
||
169 | .route_key_size = sizeof(struct ip6_rt_info), |
||
170 | }; |
||
171 | |||
172 | --- a/net/netfilter/nf_queue.c |
||
173 | +++ b/net/netfilter/nf_queue.c |
||
3 | office | 174 | @@ -250,7 +250,6 @@ void nf_reinject(struct nf_queue_entry * |
1 | office | 175 | const struct nf_hook_entry *hook_entry; |
176 | const struct nf_hook_entries *hooks; |
||
177 | struct sk_buff *skb = entry->skb; |
||
178 | - const struct nf_afinfo *afinfo; |
||
179 | const struct net *net; |
||
180 | unsigned int i; |
||
181 | int err; |
||
3 | office | 182 | @@ -277,8 +276,7 @@ void nf_reinject(struct nf_queue_entry * |
1 | office | 183 | verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state); |
184 | |||
185 | if (verdict == NF_ACCEPT) { |
||
186 | - afinfo = nf_get_afinfo(entry->state.pf); |
||
187 | - if (!afinfo || afinfo->reroute(entry->state.net, skb, entry) < 0) |
||
188 | + if (nf_reroute(skb, entry) < 0) |
||
189 | verdict = NF_DROP; |
||
190 | } |
||
191 | |||
192 | --- a/net/netfilter/utils.c |
||
193 | +++ b/net/netfilter/utils.c |
||
194 | @@ -2,6 +2,7 @@ |
||
195 | #include <linux/netfilter.h> |
||
196 | #include <linux/netfilter_ipv4.h> |
||
197 | #include <linux/netfilter_ipv6.h> |
||
198 | +#include <net/netfilter/nf_queue.h> |
||
199 | |||
200 | __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, |
||
201 | unsigned int dataoff, u_int8_t protocol, |
||
202 | @@ -69,3 +70,21 @@ int nf_route(struct net *net, struct dst |
||
203 | return ret; |
||
204 | } |
||
205 | EXPORT_SYMBOL_GPL(nf_route); |
||
206 | + |
||
207 | +int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry) |
||
208 | +{ |
||
209 | + const struct nf_ipv6_ops *v6ops; |
||
210 | + int ret = 0; |
||
211 | + |
||
212 | + switch (entry->state.pf) { |
||
213 | + case AF_INET: |
||
214 | + ret = nf_ip_reroute(skb, entry); |
||
215 | + break; |
||
216 | + case AF_INET6: |
||
217 | + v6ops = rcu_dereference(nf_ipv6_ops); |
||
218 | + if (v6ops) |
||
219 | + ret = v6ops->reroute(skb, entry); |
||
220 | + break; |
||
221 | + } |
||
222 | + return ret; |
||
223 | +} |