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 Netfilter updates for net-next: 1) Remove #ifdef pollution around nf_ingress(), from Lukas Wunner. 2) Document ingress hook in netdevice, also from Lukas. 3) Remove htons() in tunnel metadata port netlink attributes, from Xin Long. 4) Missing erspan netlink attribute validation also from Xin Long. 5) Missing erspan version in tunnel, from Xin Long. 6) Missing attribute nest in NFTA_TUNNEL_KEY_OPTS_{VXLAN,ERSPAN} Patch from Xin Long. 7) Missing nla_nest_cancel() in tunnel netlink dump path, from Xin Long. 8) Remove two exported conntrack symbols with no clients, from Florian Westphal. 9) Add nft_meta_get_eval_time() helper to nft_meta, from Florian. 10) Add nft_meta_pkttype helper for loopback, also from Florian. 11) Add nft_meta_socket uid helper, from Florian Westphal. 12) Add nft_meta_cgroup helper, from Florian. 13) Add nft_meta_ifkind helper, from Florian. 14) Group all interface related meta selector, from Florian. 15) Add nft_prandom_u32() helper, from Florian. 16) Add nft_meta_rtclassid helper, from Florian. 17) Add support for matching on the slave device index, from Florian. This batch, among other things, contains updates for the netfilter tunnel netlink interface: This extension is still incomplete and lacking proper userspace support which is actually my fault, I did not find the time to go back and finish this. This update is breaking tunnel UAPI in some aspects to fix it but do it better sooner than never. ====================

David S. Miller committed 6 years ago

Commit ba402812 parents 1a1fda5 c14ceb07 files · +357 −144Browse files

Unified · Split

7 files
  1. include/linux/netdevice.h +1 −0
  2. include/uapi/linux/netfilter/nf_tables.h +4 −0
  3. net/core/dev.c +0 −2
  4. net/netfilter/nf_conntrack_core.c +0 −1
  5. net/netfilter/nf_conntrack_extend.c +0 −1
  6. net/netfilter/nft_meta.c +313 −127
  7. net/netfilter/nft_tunnel.c +39 −13
include/linux/netdevice.h+1−0
@@ -1709,6 +1709,7 @@ enum netdev_priv_flags { · 1708 unmodified lines
17091709 * @miniq_ingress: ingress/clsact qdisc specific data for
17101710 * ingress processing
17111711 * @ingress_queue: XXX: need comments on this one
1712+ * @nf_hooks_ingress: netfilter hooks executed for ingress packets
17121713 * @broadcast: hw bcast address
17131714 *
17141715 * @rx_cpu_rmap: CPU reverse-mapping for RX completion interrupts,
include/uapi/linux/netfilter/nf_tables.h+4−0
@@ -805,6 +805,8 @@ enum nft_exthdr_attributes { · 804 unmodified lines
805805 * @NFT_META_TIME_NS: time since epoch (in nanoseconds)
806806 * @NFT_META_TIME_DAY: day of week (from 0 = Sunday to 6 = Saturday)
807807 * @NFT_META_TIME_HOUR: hour of day (in seconds)
808+ * @NFT_META_SDIF: slave device interface index
809+ * @NFT_META_SDIFNAME: slave device interface name
808810 */
809811 enum nft_meta_keys {
810812 NFT_META_LEN,
@@ -840,6 +842,8 @@ enum nft_meta_keys { · 29 unmodified lines
840842 NFT_META_TIME_NS,
841843 NFT_META_TIME_DAY,
842844 NFT_META_TIME_HOUR,
845+ NFT_META_SDIF,
846+ NFT_META_SDIFNAME,
843847 };
844848
845849 /**
net/core/dev.c+0−2
@@ -4932,7 +4932,6 @@ static bool skb_pfmemalloc_protocol(struct sk_buff *skb) · 4931 unmodified lines
49324932 static inline int nf_ingress(struct sk_buff *skb, struct packet_type **pt_prev,
49334933 int *ret, struct net_device *orig_dev)
49344934 {
4935−#ifdef CONFIG_NETFILTER_INGRESS
49364935 if (nf_hook_ingress_active(skb)) {
49374936 int ingress_retval;
49384937
@@ -4946,7 +4945,6 @@ static inline int nf_ingress(struct sk_buff *skb, struct packet_type **pt_prev, · 7 unmodified lines
49464945 rcu_read_unlock();
49474946 return ingress_retval;
49484947 }
4949−#endif /* CONFIG_NETFILTER_INGRESS */
49504948 return 0;
49514949 }
49524950
net/netfilter/nf_conntrack_core.c+0−1
@@ -2334,7 +2334,6 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp) · 2333 unmodified lines
23342334
23352335 return nf_conntrack_hash_resize(hashsize);
23362336 }
2337−EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
23382337
23392338 static __always_inline unsigned int total_extension_size(void)
23402339 {
net/netfilter/nf_conntrack_extend.c+0−1
@@ -37,7 +37,6 @@ void nf_ct_ext_destroy(struct nf_conn *ct) · 36 unmodified lines
3737
3838 kfree(ct->ext);
3939 }
40−EXPORT_SYMBOL(nf_ct_ext_destroy);
4140
4241 void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
4342 {
net/netfilter/nft_meta.c+313−127
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <linux/smp.h>
1818 #include <linux/static_key.h>
1919 #include <net/dst.h>
20+#include <net/ip.h>
2021 #include <net/sock.h>
2122 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
2223 #include <net/netfilter/nf_tables.h>
@@ -33,8 +34,9 @@ · 10 unmodified lines
3334
3435 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
3536
36−static u8 nft_meta_weekday(time64_t secs)
37+static u8 nft_meta_weekday(void)
3738 {
39+ time64_t secs = ktime_get_real_seconds();
3840 unsigned int dse;
3941 u8 wday;
4042
@@ -56,14 +58,264 @@ static u32 nft_meta_hour(time64_t secs) · 15 unmodified lines
5658 + tm.tm_sec;
5759 }
5860
61+static noinline_for_stack void
62+nft_meta_get_eval_time(enum nft_meta_keys key,
63+ u32 *dest)
64+{
65+ switch (key) {
66+ case NFT_META_TIME_NS:
67+ nft_reg_store64(dest, ktime_get_real_ns());
68+ break;
69+ case NFT_META_TIME_DAY:
70+ nft_reg_store8(dest, nft_meta_weekday());
71+ break;
72+ case NFT_META_TIME_HOUR:
73+ *dest = nft_meta_hour(ktime_get_real_seconds());
74+ break;
75+ default:
76+ break;
77+ }
78+}
79+
80+static noinline bool
81+nft_meta_get_eval_pkttype_lo(const struct nft_pktinfo *pkt,
82+ u32 *dest)
83+{
84+ const struct sk_buff *skb = pkt->skb;
85+
86+ switch (nft_pf(pkt)) {
87+ case NFPROTO_IPV4:
88+ if (ipv4_is_multicast(ip_hdr(skb)->daddr))
89+ nft_reg_store8(dest, PACKET_MULTICAST);
90+ else
91+ nft_reg_store8(dest, PACKET_BROADCAST);
92+ break;
93+ case NFPROTO_IPV6:
94+ nft_reg_store8(dest, PACKET_MULTICAST);
95+ break;
96+ case NFPROTO_NETDEV:
97+ switch (skb->protocol) {
98+ case htons(ETH_P_IP): {
99+ int noff = skb_network_offset(skb);
100+ struct iphdr *iph, _iph;
101+
102+ iph = skb_header_pointer(skb, noff,
103+ sizeof(_iph), &_iph);
104+ if (!iph)
105+ return false;
106+
107+ if (ipv4_is_multicast(iph->daddr))
108+ nft_reg_store8(dest, PACKET_MULTICAST);
109+ else
110+ nft_reg_store8(dest, PACKET_BROADCAST);
111+
112+ break;
113+ }
114+ case htons(ETH_P_IPV6):
115+ nft_reg_store8(dest, PACKET_MULTICAST);
116+ break;
117+ default:
118+ WARN_ON_ONCE(1);
119+ return false;
120+ }
121+ break;
122+ default:
123+ WARN_ON_ONCE(1);
124+ return false;
125+ }
126+
127+ return true;
128+}
129+
130+static noinline bool
131+nft_meta_get_eval_skugid(enum nft_meta_keys key,
132+ u32 *dest,
133+ const struct nft_pktinfo *pkt)
134+{
135+ struct sock *sk = skb_to_full_sk(pkt->skb);
136+ struct socket *sock;
137+
138+ if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
139+ return false;
140+
141+ read_lock_bh(&sk->sk_callback_lock);
142+ sock = sk->sk_socket;
143+ if (!sock || !sock->file) {
144+ read_unlock_bh(&sk->sk_callback_lock);
145+ return false;
146+ }
147+
148+ switch (key) {
149+ case NFT_META_SKUID:
150+ *dest = from_kuid_munged(&init_user_ns,
151+ sock->file->f_cred->fsuid);
152+ break;
153+ case NFT_META_SKGID:
154+ *dest = from_kgid_munged(&init_user_ns,
155+ sock->file->f_cred->fsgid);
156+ break;
157+ default:
158+ break;
159+ }
160+
161+ read_unlock_bh(&sk->sk_callback_lock);
162+ return true;
163+}
164+
165+#ifdef CONFIG_CGROUP_NET_CLASSID
166+static noinline bool
167+nft_meta_get_eval_cgroup(u32 *dest, const struct nft_pktinfo *pkt)
168+{
169+ struct sock *sk = skb_to_full_sk(pkt->skb);
170+
171+ if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
172+ return false;
173+
174+ *dest = sock_cgroup_classid(&sk->sk_cgrp_data);
175+ return true;
176+}
177+#endif
178+
179+static noinline bool nft_meta_get_eval_kind(enum nft_meta_keys key,
180+ u32 *dest,
181+ const struct nft_pktinfo *pkt)
182+{
183+ const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
184+
185+ switch (key) {
186+ case NFT_META_IIFKIND:
187+ if (!in || !in->rtnl_link_ops)
188+ return false;
189+ strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ);
190+ break;
191+ case NFT_META_OIFKIND:
192+ if (!out || !out->rtnl_link_ops)
193+ return false;
194+ strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
195+ break;
196+ default:
197+ return false;
198+ }
199+
200+ return true;
201+}
202+
203+static void nft_meta_store_ifindex(u32 *dest, const struct net_device *dev)
204+{
205+ *dest = dev ? dev->ifindex : 0;
206+}
207+
208+static void nft_meta_store_ifname(u32 *dest, const struct net_device *dev)
209+{
210+ strncpy((char *)dest, dev ? dev->name : "", IFNAMSIZ);
211+}
212+
213+static bool nft_meta_store_iftype(u32 *dest, const struct net_device *dev)
214+{
215+ if (!dev)
216+ return false;
217+
218+ nft_reg_store16(dest, dev->type);
219+ return true;
220+}
221+
222+static bool nft_meta_store_ifgroup(u32 *dest, const struct net_device *dev)
223+{
224+ if (!dev)
225+ return false;
226+
227+ *dest = dev->group;
228+ return true;
229+}
230+
231+static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
232+ const struct nft_pktinfo *pkt)
233+{
234+ switch (key) {
235+ case NFT_META_IIFNAME:
236+ nft_meta_store_ifname(dest, nft_in(pkt));
237+ break;
238+ case NFT_META_OIFNAME:
239+ nft_meta_store_ifname(dest, nft_out(pkt));
240+ break;
241+ case NFT_META_IIF:
242+ nft_meta_store_ifindex(dest, nft_in(pkt));
243+ break;
244+ case NFT_META_OIF:
245+ nft_meta_store_ifindex(dest, nft_out(pkt));
246+ break;
247+ case NFT_META_IIFTYPE:
248+ if (!nft_meta_store_iftype(dest, nft_in(pkt)))
249+ return false;
250+ break;
251+ case NFT_META_OIFTYPE:
252+ if (!nft_meta_store_iftype(dest, nft_out(pkt)))
253+ return false;
254+ break;
255+ case NFT_META_IIFGROUP:
256+ if (!nft_meta_store_ifgroup(dest, nft_out(pkt)))
257+ return false;
258+ break;
259+ case NFT_META_OIFGROUP:
260+ if (!nft_meta_store_ifgroup(dest, nft_out(pkt)))
261+ return false;
262+ break;
263+ default:
264+ return false;
265+ }
266+
267+ return true;
268+}
269+
270+static noinline u32 nft_prandom_u32(void)
271+{
272+ struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);
273+
274+ return prandom_u32_state(state);
275+}
276+
277+#ifdef CONFIG_IP_ROUTE_CLASSID
278+static noinline bool
279+nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
280+{
281+ const struct dst_entry *dst = skb_dst(skb);
282+
283+ if (!dst)
284+ return false;
285+
286+ *dest = dst->tclassid;
287+ return true;
288+}
289+#endif
290+
291+static noinline u32 nft_meta_get_eval_sdif(const struct nft_pktinfo *pkt)
292+{
293+ switch (nft_pf(pkt)) {
294+ case NFPROTO_IPV4:
295+ return inet_sdif(pkt->skb);
296+ case NFPROTO_IPV6:
297+ return inet6_sdif(pkt->skb);
298+ }
299+
300+ return 0;
301+}
302+
303+static noinline void
304+nft_meta_get_eval_sdifname(u32 *dest, const struct nft_pktinfo *pkt)
305+{
306+ u32 sdif = nft_meta_get_eval_sdif(pkt);
307+ const struct net_device *dev;
308+
309+ dev = sdif ? dev_get_by_index_rcu(nft_net(pkt), sdif) : NULL;
310+ nft_meta_store_ifname(dest, dev);
311+}
312+
59313 void nft_meta_get_eval(const struct nft_expr *expr,
60314 struct nft_regs *regs,
61315 const struct nft_pktinfo *pkt)
62316 {
63317 const struct nft_meta *priv = nft_expr_priv(expr);
64318 const struct sk_buff *skb = pkt->skb;
65− const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
66− struct sock *sk;
67319 u32 *dest = &regs->data[priv->dreg];
68320
69321 switch (priv->key) {
@@ -88,69 +340,26 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 18 unmodified lines
88340 *dest = skb->mark;
89341 break;
90342 case NFT_META_IIF:
91− *dest = in ? in->ifindex : 0;
92− break;
93343 case NFT_META_OIF:
94− *dest = out ? out->ifindex : 0;
95− break;
96344 case NFT_META_IIFNAME:
97− strncpy((char *)dest, in ? in->name : "", IFNAMSIZ);
98− break;
99345 case NFT_META_OIFNAME:
100− strncpy((char *)dest, out ? out->name : "", IFNAMSIZ);
101− break;
102346 case NFT_META_IIFTYPE:
103− if (in == NULL)
104− goto err;
105− nft_reg_store16(dest, in->type);
106− break;
107347 case NFT_META_OIFTYPE:
108− if (out == NULL)
348+ case NFT_META_IIFGROUP:
349+ case NFT_META_OIFGROUP:
350+ if (!nft_meta_get_eval_ifname(priv->key, dest, pkt))
109351 goto err;
110− nft_reg_store16(dest, out->type);
111352 break;
112353 case NFT_META_SKUID:
113− sk = skb_to_full_sk(skb);
114− if (!sk || !sk_fullsock(sk) ||
115− !net_eq(nft_net(pkt), sock_net(sk)))
116− goto err;
117−
118− read_lock_bh(&sk->sk_callback_lock);
119− if (sk->sk_socket == NULL ||
120− sk->sk_socket->file == NULL) {
121− read_unlock_bh(&sk->sk_callback_lock);
122− goto err;
123− }
124−
125− *dest = from_kuid_munged(&init_user_ns,
126− sk->sk_socket->file->f_cred->fsuid);
127− read_unlock_bh(&sk->sk_callback_lock);
128− break;
129354 case NFT_META_SKGID:
130− sk = skb_to_full_sk(skb);
131− if (!sk || !sk_fullsock(sk) ||
132− !net_eq(nft_net(pkt), sock_net(sk)))
355+ if (!nft_meta_get_eval_skugid(priv->key, dest, pkt))
133356 goto err;
134−
135− read_lock_bh(&sk->sk_callback_lock);
136− if (sk->sk_socket == NULL ||
137− sk->sk_socket->file == NULL) {
138− read_unlock_bh(&sk->sk_callback_lock);
139− goto err;
140− }
141− *dest = from_kgid_munged(&init_user_ns,
142− sk->sk_socket->file->f_cred->fsgid);
143− read_unlock_bh(&sk->sk_callback_lock);
144357 break;
145358 #ifdef CONFIG_IP_ROUTE_CLASSID
146− case NFT_META_RTCLASSID: {
147− const struct dst_entry *dst = skb_dst(skb);
148−
149− if (dst == NULL)
359+ case NFT_META_RTCLASSID:
360+ if (!nft_meta_get_eval_rtclassid(skb, dest))
150361 goto err;
151− *dest = dst->tclassid;
152362 break;
153− }
154363 #endif
155364 #ifdef CONFIG_NETWORK_SECMARK
156365 case NFT_META_SECMARK:
@@ -163,97 +372,41 @@ void nft_meta_get_eval(const struct nft_expr *expr, · 6 unmodified lines
163372 break;
164373 }
165374
166− switch (nft_pf(pkt)) {
167− case NFPROTO_IPV4:
168− if (ipv4_is_multicast(ip_hdr(skb)->daddr))
169− nft_reg_store8(dest, PACKET_MULTICAST);
170− else
171− nft_reg_store8(dest, PACKET_BROADCAST);
172− break;
173− case NFPROTO_IPV6:
174− nft_reg_store8(dest, PACKET_MULTICAST);
175− break;
176− case NFPROTO_NETDEV:
177− switch (skb->protocol) {
178− case htons(ETH_P_IP): {
179− int noff = skb_network_offset(skb);
180− struct iphdr *iph, _iph;
181−
182− iph = skb_header_pointer(skb, noff,
183− sizeof(_iph), &_iph);
184− if (!iph)
185− goto err;
186−
187− if (ipv4_is_multicast(iph->daddr))
188− nft_reg_store8(dest, PACKET_MULTICAST);
189− else
190− nft_reg_store8(dest, PACKET_BROADCAST);
191−
192− break;
193− }
194− case htons(ETH_P_IPV6):
195− nft_reg_store8(dest, PACKET_MULTICAST);
196− break;
197− default:
198− WARN_ON_ONCE(1);
199− goto err;
200− }
201− break;
202− default:
203− WARN_ON_ONCE(1);
375+ if (!nft_meta_get_eval_pkttype_lo(pkt, dest))
204376 goto err;
205− }
206377 break;
207378 case NFT_META_CPU:
208379 *dest = raw_smp_processor_id();
209380 break;
210− case NFT_META_IIFGROUP:
211− if (in == NULL)
212− goto err;
213− *dest = in->group;
214− break;
215− case NFT_META_OIFGROUP:
216− if (out == NULL)
217− goto err;
218− *dest = out->group;
219− break;
220381 #ifdef CONFIG_CGROUP_NET_CLASSID
221382 case NFT_META_CGROUP:
222− sk = skb_to_full_sk(skb);
223− if (!sk || !sk_fullsock(sk) ||
224− !net_eq(nft_net(pkt), sock_net(sk)))
383+ if (!nft_meta_get_eval_cgroup(dest, pkt))
225384 goto err;
226− *dest = sock_cgroup_classid(&sk->sk_cgrp_data);
227385 break;
228386 #endif
229− case NFT_META_PRANDOM: {
230− struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);
231− *dest = prandom_u32_state(state);
387+ case NFT_META_PRANDOM:
388+ *dest = nft_prandom_u32();
232389 break;
233− }
234390 #ifdef CONFIG_XFRM
235391 case NFT_META_SECPATH:
236392 nft_reg_store8(dest, secpath_exists(skb));
237393 break;
238394 #endif
239395 case NFT_META_IIFKIND:
240− if (in == NULL || in->rtnl_link_ops == NULL)
241− goto err;
242− strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ);
243− break;
244396 case NFT_META_OIFKIND:
245− if (out == NULL || out->rtnl_link_ops == NULL)
397+ if (!nft_meta_get_eval_kind(priv->key, dest, pkt))
246398 goto err;
247− strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
248399 break;
249400 case NFT_META_TIME_NS:
250− nft_reg_store64(dest, ktime_get_real_ns());
251− break;
252401 case NFT_META_TIME_DAY:
253− nft_reg_store8(dest, nft_meta_weekday(ktime_get_real_seconds()));
254− break;
255402 case NFT_META_TIME_HOUR:
256− *dest = nft_meta_hour(ktime_get_real_seconds());
403+ nft_meta_get_eval_time(priv->key, dest);
404+ break;
405+ case NFT_META_SDIF:
406+ *dest = nft_meta_get_eval_sdif(pkt);
407+ break;
408+ case NFT_META_SDIFNAME:
409+ nft_meta_get_eval_sdifname(dest, pkt);
257410 break;
258411 default:
259412 WARN_ON(1);
@@ -335,6 +488,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx, · 75 unmodified lines
335488 case NFT_META_MARK:
336489 case NFT_META_IIF:
337490 case NFT_META_OIF:
491+ case NFT_META_SDIF:
338492 case NFT_META_SKUID:
339493 case NFT_META_SKGID:
340494 #ifdef CONFIG_IP_ROUTE_CLASSID
@@ -356,6 +510,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx, · 15 unmodified lines
356510 case NFT_META_OIFNAME:
357511 case NFT_META_IIFKIND:
358512 case NFT_META_OIFKIND:
513+ case NFT_META_SDIFNAME:
359514 len = IFNAMSIZ;
360515 break;
361516 case NFT_META_PRANDOM:
@@ -386,16 +541,28 @@ int nft_meta_get_init(const struct nft_ctx *ctx, · 24 unmodified lines
386541 }
387542 EXPORT_SYMBOL_GPL(nft_meta_get_init);
388543
389−static int nft_meta_get_validate(const struct nft_ctx *ctx,
390− const struct nft_expr *expr,
391− const struct nft_data **data)
544+static int nft_meta_get_validate_sdif(const struct nft_ctx *ctx)
392545 {
393−#ifdef CONFIG_XFRM
394− const struct nft_meta *priv = nft_expr_priv(expr);
395546 unsigned int hooks;
396547
397− if (priv->key != NFT_META_SECPATH)
398− return 0;
548+ switch (ctx->family) {
549+ case NFPROTO_IPV4:
550+ case NFPROTO_IPV6:
551+ case NFPROTO_INET:
552+ hooks = (1 << NF_INET_LOCAL_IN) |
553+ (1 << NF_INET_FORWARD);
554+ break;
555+ default:
556+ return -EOPNOTSUPP;
557+ }
558+
559+ return nft_chain_validate_hooks(ctx->chain, hooks);
560+}
561+
562+static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx)
563+{
564+#ifdef CONFIG_XFRM
565+ unsigned int hooks;
399566
400567 switch (ctx->family) {
401568 case NFPROTO_NETDEV:
@@ -418,6 +585,25 @@ static int nft_meta_get_validate(const struct nft_ctx *ctx, · 16 unmodified lines
418585 #endif
419586 }
420587
588+static int nft_meta_get_validate(const struct nft_ctx *ctx,
589+ const struct nft_expr *expr,
590+ const struct nft_data **data)
591+{
592+ const struct nft_meta *priv = nft_expr_priv(expr);
593+
594+ switch (priv->key) {
595+ case NFT_META_SECPATH:
596+ return nft_meta_get_validate_xfrm(ctx);
597+ case NFT_META_SDIF:
598+ case NFT_META_SDIFNAME:
599+ return nft_meta_get_validate_sdif(ctx);
600+ default:
601+ break;
602+ }
603+
604+ return 0;
605+}
606+
421607 int nft_meta_set_validate(const struct nft_ctx *ctx,
422608 const struct nft_expr *expr,
423609 const struct nft_data **data)
net/netfilter/nft_tunnel.c+39−13
@@ -248,8 +248,9 @@ static int nft_tunnel_obj_vxlan_init(const struct nlattr *attr, · 247 unmodified lines
248248 }
249249
250250 static const struct nla_policy nft_tunnel_opts_erspan_policy[NFTA_TUNNEL_KEY_ERSPAN_MAX + 1] = {
251+ [NFTA_TUNNEL_KEY_ERSPAN_VERSION] = { .type = NLA_U32 },
251252 [NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX] = { .type = NLA_U32 },
252− [NFTA_TUNNEL_KEY_ERSPAN_V2_DIR] = { .type = NLA_U8 },
253+ [NFTA_TUNNEL_KEY_ERSPAN_V2_DIR] = { .type = NLA_U8 },
253254 [NFTA_TUNNEL_KEY_ERSPAN_V2_HWID] = { .type = NLA_U8 },
254255 };
255256
@@ -442,10 +443,15 @@ static int nft_tunnel_ip_dump(struct sk_buff *skb, struct ip_tunnel_info *info) · 186 unmodified lines
442443 if (!nest)
443444 return -1;
444445
445− if (nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_SRC, &info->key.u.ipv6.src) < 0 ||
446− nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_DST, &info->key.u.ipv6.dst) < 0 ||
447− nla_put_be32(skb, NFTA_TUNNEL_KEY_IP6_FLOWLABEL, info->key.label))
446+ if (nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_SRC,
447+ &info->key.u.ipv6.src) < 0 ||
448+ nla_put_in6_addr(skb, NFTA_TUNNEL_KEY_IP6_DST,
449+ &info->key.u.ipv6.dst) < 0 ||
450+ nla_put_be32(skb, NFTA_TUNNEL_KEY_IP6_FLOWLABEL,
451+ info->key.label)) {
452+ nla_nest_cancel(skb, nest);
448453 return -1;
454+ }
449455
450456 nla_nest_end(skb, nest);
451457 } else {
@@ -453,9 +459,13 @@ static int nft_tunnel_ip_dump(struct sk_buff *skb, struct ip_tunnel_info *info) · 1 unmodified line
453459 if (!nest)
454460 return -1;
455461
456− if (nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_SRC, info->key.u.ipv4.src) < 0 ||
457− nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_DST, info->key.u.ipv4.dst) < 0)
462+ if (nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_SRC,
463+ info->key.u.ipv4.src) < 0 ||
464+ nla_put_in_addr(skb, NFTA_TUNNEL_KEY_IP_DST,
465+ info->key.u.ipv4.dst) < 0) {
466+ nla_nest_cancel(skb, nest);
458467 return -1;
468+ }
459469
460470 nla_nest_end(skb, nest);
461471 }
@@ -467,42 +477,58 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb, · 5 unmodified lines
467477 struct nft_tunnel_obj *priv)
468478 {
469479 struct nft_tunnel_opts *opts = &priv->opts;
470− struct nlattr *nest;
480+ struct nlattr *nest, *inner;
471481
472482 nest = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS);
473483 if (!nest)
474484 return -1;
475485
476486 if (opts->flags & TUNNEL_VXLAN_OPT) {
487+ inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_VXLAN);
488+ if (!inner)
489+ goto failure;
477490 if (nla_put_be32(skb, NFTA_TUNNEL_KEY_VXLAN_GBP,
478491 htonl(opts->u.vxlan.gbp)))
479− return -1;
492+ goto inner_failure;
493+ nla_nest_end(skb, inner);
480494 } else if (opts->flags & TUNNEL_ERSPAN_OPT) {
495+ inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_ERSPAN);
496+ if (!inner)
497+ goto failure;
498+ if (nla_put_be32(skb, NFTA_TUNNEL_KEY_ERSPAN_VERSION,
499+ htonl(opts->u.erspan.version)))
500+ goto inner_failure;
481501 switch (opts->u.erspan.version) {
482502 case ERSPAN_VERSION:
483503 if (nla_put_be32(skb, NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX,
484504 opts->u.erspan.u.index))
485− return -1;
505+ goto inner_failure;
486506 break;
487507 case ERSPAN_VERSION2:
488508 if (nla_put_u8(skb, NFTA_TUNNEL_KEY_ERSPAN_V2_HWID,
489509 get_hwid(&opts->u.erspan.u.md2)) ||
490510 nla_put_u8(skb, NFTA_TUNNEL_KEY_ERSPAN_V2_DIR,
491511 opts->u.erspan.u.md2.dir))
492− return -1;
512+ goto inner_failure;
493513 break;
494514 }
515+ nla_nest_end(skb, inner);
495516 }
496517 nla_nest_end(skb, nest);
497−
498518 return 0;
519+
520+inner_failure:
521+ nla_nest_cancel(skb, inner);
522+failure:
523+ nla_nest_cancel(skb, nest);
524+ return -1;
499525 }
500526
501527 static int nft_tunnel_ports_dump(struct sk_buff *skb,
502528 struct ip_tunnel_info *info)
503529 {
504− if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, htons(info->key.tp_src)) < 0 ||
505− nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, htons(info->key.tp_dst)) < 0)
530+ if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, info->key.tp_src) < 0 ||
531+ nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, info->key.tp_dst) < 0)
506532 return -1;
507533
508534 return 0;