Commit 545b29019c8959c805abfe8194d47e989f1a6e5f
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Merge branch 'master' of git://1984.lsi.us.es/nf-next
Conflicts: net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c Minor conflict due to some IS_ENABLED conversions done in net-next. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 7 changed files Side-by-side Diff
include/uapi/linux/in6.h
include/uapi/linux/netfilter_ipv6/ip6_tables.h
... | ... | @@ -178,6 +178,9 @@ |
178 | 178 | #define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5) |
179 | 179 | #define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET |
180 | 180 | |
181 | +/* obtain original address if REDIRECT'd connection */ | |
182 | +#define IP6T_SO_ORIGINAL_DST 80 | |
183 | + | |
181 | 184 | /* ICMP matching stuff */ |
182 | 185 | struct ip6t_icmp { |
183 | 186 | __u8 type; /* type to match */ |
net/ipv4/netfilter/iptable_nat.c
... | ... | @@ -276,9 +276,7 @@ |
276 | 276 | return -ENOMEM; |
277 | 277 | net->ipv4.nat_table = ipt_register_table(net, &nf_nat_ipv4_table, repl); |
278 | 278 | kfree(repl); |
279 | - if (IS_ERR(net->ipv4.nat_table)) | |
280 | - return PTR_ERR(net->ipv4.nat_table); | |
281 | - return 0; | |
279 | + return PTR_RET(net->ipv4.nat_table); | |
282 | 280 | } |
283 | 281 | |
284 | 282 | static void __net_exit iptable_nat_net_exit(struct net *net) |
net/ipv6/netfilter/ip6table_nat.c
... | ... | @@ -277,9 +277,7 @@ |
277 | 277 | return -ENOMEM; |
278 | 278 | net->ipv6.ip6table_nat = ip6t_register_table(net, &nf_nat_ipv6_table, repl); |
279 | 279 | kfree(repl); |
280 | - if (IS_ERR(net->ipv6.ip6table_nat)) | |
281 | - return PTR_ERR(net->ipv6.ip6table_nat); | |
282 | - return 0; | |
280 | + return PTR_RET(net->ipv6.ip6table_nat); | |
283 | 281 | } |
284 | 282 | |
285 | 283 | static void __net_exit ip6table_nat_net_exit(struct net *net) |
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | |
22 | 22 | #include <linux/netfilter_bridge.h> |
23 | 23 | #include <linux/netfilter_ipv6.h> |
24 | +#include <linux/netfilter_ipv6/ip6_tables.h> | |
24 | 25 | #include <net/netfilter/nf_conntrack.h> |
25 | 26 | #include <net/netfilter/nf_conntrack_helper.h> |
26 | 27 | #include <net/netfilter/nf_conntrack_l4proto.h> |
... | ... | @@ -295,6 +296,55 @@ |
295 | 296 | }, |
296 | 297 | }; |
297 | 298 | |
299 | +static int | |
300 | +ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len) | |
301 | +{ | |
302 | + const struct inet_sock *inet = inet_sk(sk); | |
303 | + const struct ipv6_pinfo *inet6 = inet6_sk(sk); | |
304 | + const struct nf_conntrack_tuple_hash *h; | |
305 | + struct sockaddr_in6 sin6; | |
306 | + struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 }; | |
307 | + struct nf_conn *ct; | |
308 | + | |
309 | + tuple.src.u3.in6 = inet6->rcv_saddr; | |
310 | + tuple.src.u.tcp.port = inet->inet_sport; | |
311 | + tuple.dst.u3.in6 = inet6->daddr; | |
312 | + tuple.dst.u.tcp.port = inet->inet_dport; | |
313 | + tuple.dst.protonum = sk->sk_protocol; | |
314 | + | |
315 | + if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) | |
316 | + return -ENOPROTOOPT; | |
317 | + | |
318 | + if (*len < 0 || (unsigned int) *len < sizeof(sin6)) | |
319 | + return -EINVAL; | |
320 | + | |
321 | + h = nf_conntrack_find_get(sock_net(sk), NF_CT_DEFAULT_ZONE, &tuple); | |
322 | + if (!h) { | |
323 | + pr_debug("IP6T_SO_ORIGINAL_DST: Can't find %pI6c/%u-%pI6c/%u.\n", | |
324 | + &tuple.src.u3.ip6, ntohs(tuple.src.u.tcp.port), | |
325 | + &tuple.dst.u3.ip6, ntohs(tuple.dst.u.tcp.port)); | |
326 | + return -ENOENT; | |
327 | + } | |
328 | + | |
329 | + ct = nf_ct_tuplehash_to_ctrack(h); | |
330 | + | |
331 | + sin6.sin6_family = AF_INET6; | |
332 | + sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port; | |
333 | + sin6.sin6_flowinfo = inet6->flow_label & IPV6_FLOWINFO_MASK; | |
334 | + memcpy(&sin6.sin6_addr, | |
335 | + &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6, | |
336 | + sizeof(sin6.sin6_addr)); | |
337 | + | |
338 | + nf_ct_put(ct); | |
339 | + | |
340 | + if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL) | |
341 | + sin6.sin6_scope_id = sk->sk_bound_dev_if; | |
342 | + else | |
343 | + sin6.sin6_scope_id = 0; | |
344 | + | |
345 | + return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0; | |
346 | +} | |
347 | + | |
298 | 348 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
299 | 349 | |
300 | 350 | #include <linux/netfilter/nfnetlink.h> |
... | ... | @@ -359,6 +409,14 @@ |
359 | 409 | MODULE_LICENSE("GPL"); |
360 | 410 | MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); |
361 | 411 | |
412 | +static struct nf_sockopt_ops so_getorigdst6 = { | |
413 | + .pf = NFPROTO_IPV6, | |
414 | + .get_optmin = IP6T_SO_ORIGINAL_DST, | |
415 | + .get_optmax = IP6T_SO_ORIGINAL_DST + 1, | |
416 | + .get = ipv6_getorigdst, | |
417 | + .owner = THIS_MODULE, | |
418 | +}; | |
419 | + | |
362 | 420 | static int ipv6_net_init(struct net *net) |
363 | 421 | { |
364 | 422 | int ret = 0; |
... | ... | @@ -425,6 +483,12 @@ |
425 | 483 | need_conntrack(); |
426 | 484 | nf_defrag_ipv6_enable(); |
427 | 485 | |
486 | + ret = nf_register_sockopt(&so_getorigdst6); | |
487 | + if (ret < 0) { | |
488 | + pr_err("Unable to register netfilter socket option\n"); | |
489 | + return ret; | |
490 | + } | |
491 | + | |
428 | 492 | ret = register_pernet_subsys(&ipv6_net_ops); |
429 | 493 | if (ret < 0) |
430 | 494 | goto cleanup_pernet; |
... | ... | @@ -440,6 +504,7 @@ |
440 | 504 | cleanup_ipv6: |
441 | 505 | unregister_pernet_subsys(&ipv6_net_ops); |
442 | 506 | cleanup_pernet: |
507 | + nf_unregister_sockopt(&so_getorigdst6); | |
443 | 508 | return ret; |
444 | 509 | } |
445 | 510 | |
... | ... | @@ -448,6 +513,7 @@ |
448 | 513 | synchronize_net(); |
449 | 514 | nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); |
450 | 515 | unregister_pernet_subsys(&ipv6_net_ops); |
516 | + nf_unregister_sockopt(&so_getorigdst6); | |
451 | 517 | } |
452 | 518 | |
453 | 519 | module_init(nf_conntrack_l3proto_ipv6_init); |
net/netfilter/ipvs/ip_vs_nfct.c
... | ... | @@ -82,7 +82,7 @@ |
82 | 82 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) |
83 | 83 | { |
84 | 84 | enum ip_conntrack_info ctinfo; |
85 | - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | |
85 | + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | |
86 | 86 | struct nf_conntrack_tuple new_tuple; |
87 | 87 | |
88 | 88 | if (ct == NULL || nf_ct_is_confirmed(ct) || nf_ct_is_untracked(ct) || |
net/netfilter/ipvs/ip_vs_xmit.c
... | ... | @@ -594,7 +594,7 @@ |
594 | 594 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
595 | 595 | if (cp->flags & IP_VS_CONN_F_SYNC && local) { |
596 | 596 | enum ip_conntrack_info ctinfo; |
597 | - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | |
597 | + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | |
598 | 598 | |
599 | 599 | if (ct && !nf_ct_is_untracked(ct)) { |
600 | 600 | IP_VS_DBG_RL_PKT(10, AF_INET, pp, skb, 0, |
... | ... | @@ -710,7 +710,7 @@ |
710 | 710 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
711 | 711 | if (cp->flags & IP_VS_CONN_F_SYNC && local) { |
712 | 712 | enum ip_conntrack_info ctinfo; |
713 | - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | |
713 | + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | |
714 | 714 | |
715 | 715 | if (ct && !nf_ct_is_untracked(ct)) { |
716 | 716 | IP_VS_DBG_RL_PKT(10, AF_INET6, pp, skb, 0, |
... | ... | @@ -1235,7 +1235,7 @@ |
1235 | 1235 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
1236 | 1236 | if (cp->flags & IP_VS_CONN_F_SYNC && local) { |
1237 | 1237 | enum ip_conntrack_info ctinfo; |
1238 | - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | |
1238 | + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | |
1239 | 1239 | |
1240 | 1240 | if (ct && !nf_ct_is_untracked(ct)) { |
1241 | 1241 | IP_VS_DBG(10, "%s(): " |
... | ... | @@ -1356,7 +1356,7 @@ |
1356 | 1356 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
1357 | 1357 | if (cp->flags & IP_VS_CONN_F_SYNC && local) { |
1358 | 1358 | enum ip_conntrack_info ctinfo; |
1359 | - struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | |
1359 | + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | |
1360 | 1360 | |
1361 | 1361 | if (ct && !nf_ct_is_untracked(ct)) { |
1362 | 1362 | IP_VS_DBG(10, "%s(): " |