History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains the first batch of Netfilter updates for your net-next tree. 1) Define pr_fmt() in nf_conntrack, from Weongyo Jeong. 2) Define and register netfilter's afinfo for the bridge family, this comes in preparation for native nfqueue's bridge for nft, from Stephane Bryant. 3) Add new attributes to store layer 2 and VLAN headers to nfqueue, also from Stephane Bryant. 4) Parse new NFQA_VLAN and NFQA_L2HDR nfqueue netlink attributes coming from userspace, from Stephane Bryant. 5) Use net->ipv6.devconf_all->hop_limit instead of hardcoded hop_limit in IPv6 SYNPROXY, from Liping Zhang. 6) Remove unnecessary check for dst == NULL in nf_reject_ipv6, from Haishuang Yan. 7) Deinline ctnetlink event report functions, from Florian Westphal. ====================

David S. Miller committed 10 years ago

Commit da0caad2 parents 69fb781 ecdfb488 files · +298 −129Browse files

Unified · Split

8 files
  1. include/net/netfilter/nf_conntrack_ecache.h +15 −93
  2. include/uapi/linux/netfilter/nfnetlink_queue.h +10 −0
  3. net/bridge/netfilter/nf_tables_bridge.c +45 −2
  4. net/ipv6/netfilter/ip6t_SYNPROXY.c +30 −26
  5. net/ipv6/netfilter/nf_reject_ipv6.c +1 −1
  6. net/netfilter/nf_conntrack_core.c +8 −7
  7. net/netfilter/nf_conntrack_ecache.c +84 −0
  8. net/netfilter/nfnetlink_queue.c +105 −0
include/net/netfilter/nf_conntrack_ecache.h+15−93
@@ -73,6 +73,8 @@ void nf_conntrack_unregister_notifier(struct net *net, · 72 unmodified lines
7373 struct nf_ct_event_notifier *nb);
7474
7575 void nf_ct_deliver_cached_events(struct nf_conn *ct);
76+int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
77+ u32 portid, int report);
7678
7779 static inline void
7880 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
@@ -90,70 +92,26 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) · 11 unmodified lines
9092 set_bit(event, &e->cache);
9193 }
9294
93−static inline int
94−nf_conntrack_eventmask_report(unsigned int eventmask,
95− struct nf_conn *ct,
96− u32 portid,
97− int report)
98−{
99− int ret = 0;
100− struct net *net = nf_ct_net(ct);
101− struct nf_ct_event_notifier *notify;
102− struct nf_conntrack_ecache *e;
103−
104− rcu_read_lock();
105− notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
106− if (notify == NULL)
107− goto out_unlock;
108−
109− e = nf_ct_ecache_find(ct);
110− if (e == NULL)
111− goto out_unlock;
112−
113− if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
114− struct nf_ct_event item = {
115− .ct = ct,
116− .portid = e->portid ? e->portid : portid,
117− .report = report
118− };
119− /* This is a resent of a destroy event? If so, skip missed */
120− unsigned long missed = e->portid ? 0 : e->missed;
121−
122− if (!((eventmask | missed) & e->ctmask))
123− goto out_unlock;
124−
125− ret = notify->fcn(eventmask | missed, &item);
126− if (unlikely(ret < 0 || missed)) {
127− spin_lock_bh(&ct->lock);
128− if (ret < 0) {
129− /* This is a destroy event that has been
130− * triggered by a process, we store the PORTID
131− * to include it in the retransmission. */
132− if (eventmask & (1 << IPCT_DESTROY) &&
133− e->portid == 0 && portid != 0)
134− e->portid = portid;
135− else
136− e->missed |= eventmask;
137− } else
138− e->missed &= ~missed;
139− spin_unlock_bh(&ct->lock);
140− }
141− }
142−out_unlock:
143− rcu_read_unlock();
144− return ret;
145−}
146−
14795 static inline int
14896 nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
14997 u32 portid, int report)
15098 {
99+ const struct net *net = nf_ct_net(ct);
100+
101+ if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
102+ return 0;
103+
151104 return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
152105 }
153106
154107 static inline int
155108 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
156109 {
110+ const struct net *net = nf_ct_net(ct);
111+
112+ if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
113+ return 0;
114+
157115 return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
158116 }
159117
@@ -172,43 +130,9 @@ int nf_ct_expect_register_notifier(struct net *net, · 12 unmodified lines
172130 void nf_ct_expect_unregister_notifier(struct net *net,
173131 struct nf_exp_event_notifier *nb);
174132
175−static inline void
176−nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
177− struct nf_conntrack_expect *exp,
178− u32 portid,
179− int report)
180−{
181− struct net *net = nf_ct_exp_net(exp);
182− struct nf_exp_event_notifier *notify;
183− struct nf_conntrack_ecache *e;
184−
185− rcu_read_lock();
186− notify = rcu_dereference(net->ct.nf_expect_event_cb);
187− if (notify == NULL)
188− goto out_unlock;
189−
190− e = nf_ct_ecache_find(exp->master);
191− if (e == NULL)
192− goto out_unlock;
193−
194− if (e->expmask & (1 << event)) {
195− struct nf_exp_event item = {
196− .exp = exp,
197− .portid = portid,
198− .report = report
199− };
200− notify->fcn(1 << event, &item);
201− }
202−out_unlock:
203− rcu_read_unlock();
204−}
205−
206−static inline void
207−nf_ct_expect_event(enum ip_conntrack_expect_events event,
208− struct nf_conntrack_expect *exp)
209−{
210− nf_ct_expect_event_report(event, exp, 0, 0);
211−}
133+void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
134+ struct nf_conntrack_expect *exp,
135+ u32 portid, int report);
212136
213137 int nf_conntrack_ecache_pernet_init(struct net *net);
214138 void nf_conntrack_ecache_pernet_fini(struct net *net);
@@ -245,8 +169,6 @@ static inline int nf_conntrack_event_report(enum ip_conntrack_events event, · 30 unmodified lines
245169 u32 portid,
246170 int report) { return 0; }
247171 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
248−static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
249− struct nf_conntrack_expect *exp) {}
250172 static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
251173 struct nf_conntrack_expect *exp,
252174 u32 portid,
include/uapi/linux/netfilter/nfnetlink_queue.h+10−0
@@ -30,6 +30,14 @@ struct nfqnl_msg_packet_timestamp { · 29 unmodified lines
3030 __aligned_be64 usec;
3131 };
3232
33+enum nfqnl_vlan_attr {
34+ NFQA_VLAN_UNSPEC,
35+ NFQA_VLAN_PROTO, /* __be16 skb vlan_proto */
36+ NFQA_VLAN_TCI, /* __be16 skb htons(vlan_tci) */
37+ __NFQA_VLAN_MAX,
38+};
39+#define NFQA_VLAN_MAX (__NFQA_VLAN_MAX + 1)
40+
3341 enum nfqnl_attr_type {
3442 NFQA_UNSPEC,
3543 NFQA_PACKET_HDR,
@@ -50,6 +58,8 @@ enum nfqnl_attr_type { · 14 unmodified lines
5058 NFQA_UID, /* __u32 sk uid */
5159 NFQA_GID, /* __u32 sk gid */
5260 NFQA_SECCTX, /* security context string */
61+ NFQA_VLAN, /* nested attribute: packet vlan info */
62+ NFQA_L2HDR, /* full L2 header */
5363
5464 __NFQA_MAX
5565 };
net/bridge/netfilter/nf_tables_bridge.c+45−2
@@ -162,15 +162,57 @@ static const struct nf_chain_type filter_bridge = { · 161 unmodified lines
162162 (1 << NF_BR_POST_ROUTING),
163163 };
164164
165+static void nf_br_saveroute(const struct sk_buff *skb,
166+ struct nf_queue_entry *entry)
167+{
168+}
169+
170+static int nf_br_reroute(struct net *net, struct sk_buff *skb,
171+ const struct nf_queue_entry *entry)
172+{
173+ return 0;
174+}
175+
176+static __sum16 nf_br_checksum(struct sk_buff *skb, unsigned int hook,
177+ unsigned int dataoff, u_int8_t protocol)
178+{
179+ return 0;
180+}
181+
182+static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook,
183+ unsigned int dataoff, unsigned int len,
184+ u_int8_t protocol)
185+{
186+ return 0;
187+}
188+
189+static int nf_br_route(struct net *net, struct dst_entry **dst,
190+ struct flowi *fl, bool strict __always_unused)
191+{
192+ return 0;
193+}
194+
195+static const struct nf_afinfo nf_br_afinfo = {
196+ .family = AF_BRIDGE,
197+ .checksum = nf_br_checksum,
198+ .checksum_partial = nf_br_checksum_partial,
199+ .route = nf_br_route,
200+ .saveroute = nf_br_saveroute,
201+ .reroute = nf_br_reroute,
202+ .route_key_size = 0,
203+};
204+
165205 static int __init nf_tables_bridge_init(void)
166206 {
167207 int ret;
168208
209+ nf_register_afinfo(&nf_br_afinfo);
169210 nft_register_chain_type(&filter_bridge);
170211 ret = register_pernet_subsys(&nf_tables_bridge_net_ops);
171− if (ret < 0)
212+ if (ret < 0) {
172213 nft_unregister_chain_type(&filter_bridge);
173−
214+ nf_unregister_afinfo(&nf_br_afinfo);
215+ }
174216 return ret;
175217 }
176218
@@ -178,6 +220,7 @@ static void __exit nf_tables_bridge_exit(void) · 1 unmodified line
178220 {
179221 unregister_pernet_subsys(&nf_tables_bridge_net_ops);
180222 nft_unregister_chain_type(&filter_bridge);
223+ nf_unregister_afinfo(&nf_br_afinfo);
181224 }
182225
183226 module_init(nf_tables_bridge_init);
net/ipv6/netfilter/ip6t_SYNPROXY.c+30−26
@@ -20,15 +20,16 @@ · 19 unmodified lines
2020 #include <net/netfilter/nf_conntrack_synproxy.h>
2121
2222 static struct ipv6hdr *
23−synproxy_build_ip(struct sk_buff *skb, const struct in6_addr *saddr,
24− const struct in6_addr *daddr)
23+synproxy_build_ip(struct net *net, struct sk_buff *skb,
24+ const struct in6_addr *saddr,
25+ const struct in6_addr *daddr)
2526 {
2627 struct ipv6hdr *iph;
2728
2829 skb_reset_network_header(skb);
2930 iph = (struct ipv6hdr *)skb_put(skb, sizeof(*iph));
3031 ip6_flow_hdr(iph, 0, 0);
31− iph->hop_limit = 64; //XXX
32+ iph->hop_limit = net->ipv6.devconf_all->hop_limit;
3233 iph->nexthdr = IPPROTO_TCP;
3334 iph->saddr = *saddr;
3435 iph->daddr = *daddr;
@@ -37,13 +38,12 @@ synproxy_build_ip(struct sk_buff *skb, const struct in6_addr *saddr, · 2 unmodified lines
3738 }
3839
3940 static void
40−synproxy_send_tcp(const struct synproxy_net *snet,
41+synproxy_send_tcp(struct net *net,
4142 const struct sk_buff *skb, struct sk_buff *nskb,
4243 struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo,
4344 struct ipv6hdr *niph, struct tcphdr *nth,
4445 unsigned int tcp_hdr_size)
4546 {
46− struct net *net = nf_ct_net(snet->tmpl);
4747 struct dst_entry *dst;
4848 struct flowi6 fl6;
4949
@@ -84,7 +84,7 @@ free_nskb: · 34 unmodified lines
8484 }
8585
8686 static void
87−synproxy_send_client_synack(const struct synproxy_net *snet,
87+synproxy_send_client_synack(struct net *net,
8888 const struct sk_buff *skb, const struct tcphdr *th,
8989 const struct synproxy_options *opts)
9090 {
@@ -103,7 +103,7 @@ synproxy_send_client_synack(const struct synproxy_net *snet, · 12 unmodified lines
103103 return;
104104 skb_reserve(nskb, MAX_TCP_HEADER);
105105
106− niph = synproxy_build_ip(nskb, &iph->daddr, &iph->saddr);
106+ niph = synproxy_build_ip(net, nskb, &iph->daddr, &iph->saddr);
107107
108108 skb_reset_transport_header(nskb);
109109 nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size);
@@ -121,15 +121,16 @@ synproxy_send_client_synack(const struct synproxy_net *snet, · 11 unmodified lines
121121
122122 synproxy_build_options(nth, opts);
123123
124− synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
124+ synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
125125 niph, nth, tcp_hdr_size);
126126 }
127127
128128 static void
129−synproxy_send_server_syn(const struct synproxy_net *snet,
129+synproxy_send_server_syn(struct net *net,
130130 const struct sk_buff *skb, const struct tcphdr *th,
131131 const struct synproxy_options *opts, u32 recv_seq)
132132 {
133+ struct synproxy_net *snet = synproxy_pernet(net);
133134 struct sk_buff *nskb;
134135 struct ipv6hdr *iph, *niph;
135136 struct tcphdr *nth;
@@ -144,7 +145,7 @@ synproxy_send_server_syn(const struct synproxy_net *snet, · 8 unmodified lines
144145 return;
145146 skb_reserve(nskb, MAX_TCP_HEADER);
146147
147− niph = synproxy_build_ip(nskb, &iph->saddr, &iph->daddr);
148+ niph = synproxy_build_ip(net, nskb, &iph->saddr, &iph->daddr);
148149
149150 skb_reset_transport_header(nskb);
150151 nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size);
@@ -165,12 +166,12 @@ synproxy_send_server_syn(const struct synproxy_net *snet, · 14 unmodified lines
165166
166167 synproxy_build_options(nth, opts);
167168
168− synproxy_send_tcp(snet, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW,
169+ synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW,
169170 niph, nth, tcp_hdr_size);
170171 }
171172
172173 static void
173−synproxy_send_server_ack(const struct synproxy_net *snet,
174+synproxy_send_server_ack(struct net *net,
174175 const struct ip_ct_tcp *state,
175176 const struct sk_buff *skb, const struct tcphdr *th,
176177 const struct synproxy_options *opts)
@@ -189,7 +190,7 @@ synproxy_send_server_ack(const struct synproxy_net *snet, · 12 unmodified lines
189190 return;
190191 skb_reserve(nskb, MAX_TCP_HEADER);
191192
192− niph = synproxy_build_ip(nskb, &iph->daddr, &iph->saddr);
193+ niph = synproxy_build_ip(net, nskb, &iph->daddr, &iph->saddr);
193194
194195 skb_reset_transport_header(nskb);
195196 nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size);
@@ -205,11 +206,11 @@ synproxy_send_server_ack(const struct synproxy_net *snet, · 9 unmodified lines
205206
206207 synproxy_build_options(nth, opts);
207208
208− synproxy_send_tcp(snet, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
209+ synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size);
209210 }
210211
211212 static void
212−synproxy_send_client_ack(const struct synproxy_net *snet,
213+synproxy_send_client_ack(struct net *net,
213214 const struct sk_buff *skb, const struct tcphdr *th,
214215 const struct synproxy_options *opts)
215216 {
@@ -227,7 +228,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, · 11 unmodified lines
227228 return;
228229 skb_reserve(nskb, MAX_TCP_HEADER);
229230
230− niph = synproxy_build_ip(nskb, &iph->saddr, &iph->daddr);
231+ niph = synproxy_build_ip(net, nskb, &iph->saddr, &iph->daddr);
231232
232233 skb_reset_transport_header(nskb);
233234 nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size);
@@ -243,15 +244,16 @@ synproxy_send_client_ack(const struct synproxy_net *snet, · 9 unmodified lines
243244
244245 synproxy_build_options(nth, opts);
245246
246− synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
247+ synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY,
247248 niph, nth, tcp_hdr_size);
248249 }
249250
250251 static bool
251−synproxy_recv_client_ack(const struct synproxy_net *snet,
252+synproxy_recv_client_ack(struct net *net,
252253 const struct sk_buff *skb, const struct tcphdr *th,
253254 struct synproxy_options *opts, u32 recv_seq)
254255 {
256+ struct synproxy_net *snet = synproxy_pernet(net);
255257 int mss;
256258
257259 mss = __cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1);
@@ -267,7 +269,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, · 9 unmodified lines
267269 if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP)
268270 synproxy_check_timestamp_cookie(opts);
269271
270− synproxy_send_server_syn(snet, skb, th, opts, recv_seq);
272+ synproxy_send_server_syn(net, skb, th, opts, recv_seq);
271273 return true;
272274 }
273275
@@ -275,7 +277,8 @@ static unsigned int · 1 unmodified line
275277 synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par)
276278 {
277279 const struct xt_synproxy_info *info = par->targinfo;
278− struct synproxy_net *snet = synproxy_pernet(par->net);
280+ struct net *net = par->net;
281+ struct synproxy_net *snet = synproxy_pernet(net);
279282 struct synproxy_options opts = {};
280283 struct tcphdr *th, _th;
281284
@@ -304,12 +307,12 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) · 22 unmodified lines
304307 XT_SYNPROXY_OPT_SACK_PERM |
305308 XT_SYNPROXY_OPT_ECN);
306309
307− synproxy_send_client_synack(snet, skb, th, &opts);
310+ synproxy_send_client_synack(net, skb, th, &opts);
308311 return NF_DROP;
309312
310313 } else if (th->ack && !(th->fin || th->rst || th->syn)) {
311314 /* ACK from client */
312− synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq));
315+ synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq));
313316 return NF_DROP;
314317 }
315318
@@ -320,7 +323,8 @@ static unsigned int ipv6_synproxy_hook(void *priv, · 4 unmodified lines
320323 struct sk_buff *skb,
321324 const struct nf_hook_state *nhs)
322325 {
323− struct synproxy_net *snet = synproxy_pernet(nhs->net);
326+ struct net *net = nhs->net;
327+ struct synproxy_net *snet = synproxy_pernet(net);
324328 enum ip_conntrack_info ctinfo;
325329 struct nf_conn *ct;
326330 struct nf_conn_synproxy *synproxy;
@@ -384,7 +388,7 @@ static unsigned int ipv6_synproxy_hook(void *priv, · 57 unmodified lines
384388 * therefore we need to add 1 to make the SYN sequence
385389 * number match the one of first SYN.
386390 */
387− if (synproxy_recv_client_ack(snet, skb, th, &opts,
391+ if (synproxy_recv_client_ack(net, skb, th, &opts,
388392 ntohl(th->seq) + 1))
389393 this_cpu_inc(snet->stats->cookie_retrans);
390394
@@ -410,12 +414,12 @@ static unsigned int ipv6_synproxy_hook(void *priv, · 19 unmodified lines
410414 XT_SYNPROXY_OPT_SACK_PERM);
411415
412416 swap(opts.tsval, opts.tsecr);
413− synproxy_send_server_ack(snet, state, skb, th, &opts);
417+ synproxy_send_server_ack(net, state, skb, th, &opts);
414418
415419 nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq));
416420
417421 swap(opts.tsval, opts.tsecr);
418− synproxy_send_client_ack(snet, skb, th, &opts);
422+ synproxy_send_client_ack(net, skb, th, &opts);
419423
420424 consume_skb(skb);
421425 return NF_STOLEN;
net/ipv6/netfilter/nf_reject_ipv6.c+1−1
@@ -158,7 +158,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook) · 157 unmodified lines
158158 fl6.fl6_dport = otcph->source;
159159 security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
160160 dst = ip6_route_output(net, NULL, &fl6);
161− if (dst == NULL || dst->error) {
161+ if (dst->error) {
162162 dst_release(dst);
163163 return;
164164 }
net/netfilter/nf_conntrack_core.c+8−7
@@ -12,6 +12,8 @@ · 11 unmodified lines
1212 * published by the Free Software Foundation.
1313 */
1414
15+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16+
1517 #include <linux/types.h>
1618 #include <linux/netfilter.h>
1719 #include <linux/module.h>
@@ -966,7 +968,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, · 948 unmodified lines
966968
967969 if (!l4proto->new(ct, skb, dataoff, timeouts)) {
968970 nf_conntrack_free(ct);
969− pr_debug("init conntrack: can't track with proto module\n");
971+ pr_debug("can't track with proto module\n");
970972 return NULL;
971973 }
972974
@@ -988,7 +990,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, · 15 unmodified lines
988990 spin_lock(&nf_conntrack_expect_lock);
989991 exp = nf_ct_find_expectation(net, zone, tuple);
990992 if (exp) {
991− pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
993+ pr_debug("expectation arrives ct=%p exp=%p\n",
992994 ct, exp);
993995 /* Welcome, Mr. Bond. We've been expecting you... */
994996 __set_bit(IPS_EXPECTED_BIT, &ct->status);
@@ -1053,7 +1055,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, · 58 unmodified lines
10531055 if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
10541056 dataoff, l3num, protonum, net, &tuple, l3proto,
10551057 l4proto)) {
1056− pr_debug("resolve_normal_ct: Can't get tuple\n");
1058+ pr_debug("Can't get tuple\n");
10571059 return NULL;
10581060 }
10591061
@@ -1079,14 +1081,13 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, · 19 unmodified lines
10791081 } else {
10801082 /* Once we've had two way comms, always ESTABLISHED. */
10811083 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
1082− pr_debug("nf_conntrack_in: normal packet for %p\n", ct);
1084+ pr_debug("normal packet for %p\n", ct);
10831085 *ctinfo = IP_CT_ESTABLISHED;
10841086 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
1085− pr_debug("nf_conntrack_in: related packet for %p\n",
1086− ct);
1087+ pr_debug("related packet for %p\n", ct);
10871088 *ctinfo = IP_CT_RELATED;
10881089 } else {
1089− pr_debug("nf_conntrack_in: new packet for %p\n", ct);
1090+ pr_debug("new packet for %p\n", ct);
10901091 *ctinfo = IP_CT_NEW;
10911092 }
10921093 *set_reply = 0;
net/netfilter/nf_conntrack_ecache.c+84−0
@@ -113,6 +113,60 @@ static void ecache_work(struct work_struct *work) · 112 unmodified lines
113113 schedule_delayed_work(&ctnet->ecache_dwork, delay);
114114 }
115115
116+int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
117+ u32 portid, int report)
118+{
119+ int ret = 0;
120+ struct net *net = nf_ct_net(ct);
121+ struct nf_ct_event_notifier *notify;
122+ struct nf_conntrack_ecache *e;
123+
124+ rcu_read_lock();
125+ notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
126+ if (!notify)
127+ goto out_unlock;
128+
129+ e = nf_ct_ecache_find(ct);
130+ if (!e)
131+ goto out_unlock;
132+
133+ if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
134+ struct nf_ct_event item = {
135+ .ct = ct,
136+ .portid = e->portid ? e->portid : portid,
137+ .report = report
138+ };
139+ /* This is a resent of a destroy event? If so, skip missed */
140+ unsigned long missed = e->portid ? 0 : e->missed;
141+
142+ if (!((eventmask | missed) & e->ctmask))
143+ goto out_unlock;
144+
145+ ret = notify->fcn(eventmask | missed, &item);
146+ if (unlikely(ret < 0 || missed)) {
147+ spin_lock_bh(&ct->lock);
148+ if (ret < 0) {
149+ /* This is a destroy event that has been
150+ * triggered by a process, we store the PORTID
151+ * to include it in the retransmission.
152+ */
153+ if (eventmask & (1 << IPCT_DESTROY) &&
154+ e->portid == 0 && portid != 0)
155+ e->portid = portid;
156+ else
157+ e->missed |= eventmask;
158+ } else {
159+ e->missed &= ~missed;
160+ }
161+ spin_unlock_bh(&ct->lock);
162+ }
163+ }
164+out_unlock:
165+ rcu_read_unlock();
166+ return ret;
167+}
168+EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
169+
116170 /* deliver cached events and clear cache entry - must be called with locally
117171 * disabled softirqs */
118172 void nf_ct_deliver_cached_events(struct nf_conn *ct)
@@ -167,6 +221,36 @@ out_unlock: · 48 unmodified lines
167221 }
168222 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
169223
224+void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
225+ struct nf_conntrack_expect *exp,
226+ u32 portid, int report)
227+
228+{
229+ struct net *net = nf_ct_exp_net(exp);
230+ struct nf_exp_event_notifier *notify;
231+ struct nf_conntrack_ecache *e;
232+
233+ rcu_read_lock();
234+ notify = rcu_dereference(net->ct.nf_expect_event_cb);
235+ if (!notify)
236+ goto out_unlock;
237+
238+ e = nf_ct_ecache_find(exp->master);
239+ if (!e)
240+ goto out_unlock;
241+
242+ if (e->expmask & (1 << event)) {
243+ struct nf_exp_event item = {
244+ .exp = exp,
245+ .portid = portid,
246+ .report = report
247+ };
248+ notify->fcn(1 << event, &item);
249+ }
250+out_unlock:
251+ rcu_read_unlock();
252+}
253+
170254 int nf_conntrack_register_notifier(struct net *net,
171255 struct nf_ct_event_notifier *new)
172256 {
net/netfilter/nfnetlink_queue.c+105−0
@@ -295,6 +295,59 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) · 294 unmodified lines
295295 return seclen;
296296 }
297297
298+static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
299+{
300+ struct sk_buff *entskb = entry->skb;
301+ u32 nlalen = 0;
302+
303+ if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
304+ return 0;
305+
306+ if (skb_vlan_tag_present(entskb))
307+ nlalen += nla_total_size(nla_total_size(sizeof(__be16)) +
308+ nla_total_size(sizeof(__be16)));
309+
310+ if (entskb->network_header > entskb->mac_header)
311+ nlalen += nla_total_size((entskb->network_header -
312+ entskb->mac_header));
313+
314+ return nlalen;
315+}
316+
317+static int nfqnl_put_bridge(struct nf_queue_entry *entry, struct sk_buff *skb)
318+{
319+ struct sk_buff *entskb = entry->skb;
320+
321+ if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
322+ return 0;
323+
324+ if (skb_vlan_tag_present(entskb)) {
325+ struct nlattr *nest;
326+
327+ nest = nla_nest_start(skb, NFQA_VLAN | NLA_F_NESTED);
328+ if (!nest)
329+ goto nla_put_failure;
330+
331+ if (nla_put_be16(skb, NFQA_VLAN_TCI, htons(entskb->vlan_tci)) ||
332+ nla_put_be16(skb, NFQA_VLAN_PROTO, entskb->vlan_proto))
333+ goto nla_put_failure;
334+
335+ nla_nest_end(skb, nest);
336+ }
337+
338+ if (entskb->mac_header < entskb->network_header) {
339+ int len = (int)(entskb->network_header - entskb->mac_header);
340+
341+ if (nla_put(skb, NFQA_L2HDR, len, skb_mac_header(entskb)))
342+ goto nla_put_failure;
343+ }
344+
345+ return 0;
346+
347+nla_put_failure:
348+ return -1;
349+}
350+
298351 static struct sk_buff *
299352 nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
300353 struct nf_queue_entry *entry,
@@ -334,6 +387,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, · 33 unmodified lines
334387 if (entskb->tstamp.tv64)
335388 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
336389
390+ size += nfqnl_get_bridge_size(entry);
391+
337392 if (entry->state.hook <= NF_INET_FORWARD ||
338393 (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
339394 csum_verify = !skb_csum_unnecessary(entskb);
@@ -497,6 +552,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, · 157 unmodified lines
497552 }
498553 }
499554
555+ if (nfqnl_put_bridge(entry, skb) < 0)
556+ goto nla_put_failure;
557+
500558 if (entskb->tstamp.tv64) {
501559 struct nfqnl_msg_packet_timestamp ts;
502560 struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
@@ -911,12 +969,18 @@ static struct notifier_block nfqnl_rtnl_notifier = { · 408 unmodified lines
911969 .notifier_call = nfqnl_rcv_nl_event,
912970 };
913971
972+static const struct nla_policy nfqa_vlan_policy[NFQA_VLAN_MAX + 1] = {
973+ [NFQA_VLAN_TCI] = { .type = NLA_U16},
974+ [NFQA_VLAN_PROTO] = { .type = NLA_U16},
975+};
976+
914977 static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
915978 [NFQA_VERDICT_HDR] = { .len = sizeof(struct nfqnl_msg_verdict_hdr) },
916979 [NFQA_MARK] = { .type = NLA_U32 },
917980 [NFQA_PAYLOAD] = { .type = NLA_UNSPEC },
918981 [NFQA_CT] = { .type = NLA_UNSPEC },
919982 [NFQA_EXP] = { .type = NLA_UNSPEC },
983+ [NFQA_VLAN] = { .type = NLA_NESTED },
920984 };
921985
922986 static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
@@ -1030,6 +1094,40 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct, · 107 unmodified lines
10301094 return ct;
10311095 }
10321096
1097+static int nfqa_parse_bridge(struct nf_queue_entry *entry,
1098+ const struct nlattr * const nfqa[])
1099+{
1100+ if (nfqa[NFQA_VLAN]) {
1101+ struct nlattr *tb[NFQA_VLAN_MAX + 1];
1102+ int err;
1103+
1104+ err = nla_parse_nested(tb, NFQA_VLAN_MAX, nfqa[NFQA_VLAN],
1105+ nfqa_vlan_policy);
1106+ if (err < 0)
1107+ return err;
1108+
1109+ if (!tb[NFQA_VLAN_TCI] || !tb[NFQA_VLAN_PROTO])
1110+ return -EINVAL;
1111+
1112+ entry->skb->vlan_tci = ntohs(nla_get_be16(tb[NFQA_VLAN_TCI]));
1113+ entry->skb->vlan_proto = nla_get_be16(tb[NFQA_VLAN_PROTO]);
1114+ }
1115+
1116+ if (nfqa[NFQA_L2HDR]) {
1117+ int mac_header_len = entry->skb->network_header -
1118+ entry->skb->mac_header;
1119+
1120+ if (mac_header_len != nla_len(nfqa[NFQA_L2HDR]))
1121+ return -EINVAL;
1122+ else if (mac_header_len > 0)
1123+ memcpy(skb_mac_header(entry->skb),
1124+ nla_data(nfqa[NFQA_L2HDR]),
1125+ mac_header_len);
1126+ }
1127+
1128+ return 0;
1129+}
1130+
10331131 static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
10341132 struct sk_buff *skb,
10351133 const struct nlmsghdr *nlh,
@@ -1045,6 +1143,7 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl, · 9 unmodified lines
10451143 struct nfnl_ct_hook *nfnl_ct;
10461144 struct nf_conn *ct = NULL;
10471145 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
1146+ int err;
10481147
10491148 queue = instance_lookup(q, queue_num);
10501149 if (!queue)
@@ -1071,6 +1170,12 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl, · 20 unmodified lines
10711170 ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
10721171 }
10731172
1173+ if (entry->state.pf == PF_BRIDGE) {
1174+ err = nfqa_parse_bridge(entry, nfqa);
1175+ if (err < 0)
1176+ return err;
1177+ }
1178+
10741179 if (nfqa[NFQA_PAYLOAD]) {
10751180 u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]);
10761181 int diff = payload_len - entry->skb->len;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t