aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_vs.h214
-rw-r--r--include/net/netfilter/br_netfilter.h6
-rw-r--r--include/net/netfilter/ipv4/nf_reject.h119
-rw-r--r--include/net/netfilter/nft_reject.h9
-rw-r--r--include/uapi/linux/netfilter/nf_tables.h21
-rw-r--r--net/bridge/br_netfilter.c5
-rw-r--r--net/bridge/netfilter/nf_tables_bridge.c2
-rw-r--r--net/bridge/netfilter/nft_reject_bridge.c95
-rw-r--r--net/core/skbuff.c2
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv4/netfilter/Kconfig6
-rw-r--r--net/ipv4/netfilter/Makefile3
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c2
-rw-r--r--net/ipv4/netfilter/nf_reject_ipv4.c127
-rw-r--r--net/ipv4/netfilter/nft_masq_ipv4.c34
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c1
-rw-r--r--net/ipv6/netfilter/Kconfig6
-rw-r--r--net/ipv6/netfilter/Makefile3
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c2
-rw-r--r--net/ipv6/netfilter/nf_reject_ipv6.c163
-rw-r--r--net/ipv6/netfilter/nft_masq_ipv6.c34
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c4
-rw-r--r--net/netfilter/nf_log_common.c2
-rw-r--r--net/netfilter/nf_queue.c4
-rw-r--r--net/netfilter/nf_tables_api.c1
-rw-r--r--net/netfilter/nfnetlink_log.c8
-rw-r--r--net/netfilter/nfnetlink_queue_core.c12
-rw-r--r--net/netfilter/nft_compat.c116
-rw-r--r--net/netfilter/nft_reject.c37
-rw-r--r--net/netfilter/nft_reject_inet.c94
-rw-r--r--net/netfilter/xt_physdev.c3
32 files changed, 699 insertions, 440 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 576d7f0bed5d..615b20b58545 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1,6 +1,5 @@
1/* 1/* IP Virtual Server
2 * IP Virtual Server 2 * data structure and functionality definitions
3 * data structure and functionality definitions
4 */ 3 */
5 4
6#ifndef _NET_IP_VS_H 5#ifndef _NET_IP_VS_H
@@ -12,7 +11,7 @@
12 11
13#include <linux/list.h> /* for struct list_head */ 12#include <linux/list.h> /* for struct list_head */
14#include <linux/spinlock.h> /* for struct rwlock_t */ 13#include <linux/spinlock.h> /* for struct rwlock_t */
15#include <linux/atomic.h> /* for struct atomic_t */ 14#include <linux/atomic.h> /* for struct atomic_t */
16#include <linux/compiler.h> 15#include <linux/compiler.h>
17#include <linux/timer.h> 16#include <linux/timer.h>
18#include <linux/bug.h> 17#include <linux/bug.h>
@@ -30,15 +29,13 @@
30#endif 29#endif
31#include <net/net_namespace.h> /* Netw namespace */ 30#include <net/net_namespace.h> /* Netw namespace */
32 31
33/* 32/* Generic access of ipvs struct */
34 * Generic access of ipvs struct
35 */
36static inline struct netns_ipvs *net_ipvs(struct net* net) 33static inline struct netns_ipvs *net_ipvs(struct net* net)
37{ 34{
38 return net->ipvs; 35 return net->ipvs;
39} 36}
40/* 37
41 * Get net ptr from skb in traffic cases 38/* Get net ptr from skb in traffic cases
42 * use skb_sknet when call is from userland (ioctl or netlink) 39 * use skb_sknet when call is from userland (ioctl or netlink)
43 */ 40 */
44static inline struct net *skb_net(const struct sk_buff *skb) 41static inline struct net *skb_net(const struct sk_buff *skb)
@@ -90,8 +87,8 @@ static inline struct net *skb_sknet(const struct sk_buff *skb)
90 return &init_net; 87 return &init_net;
91#endif 88#endif
92} 89}
93/* 90
94 * This one needed for single_open_net since net is stored directly in 91/* This one needed for single_open_net since net is stored directly in
95 * private not as a struct i.e. seq_file_net can't be used. 92 * private not as a struct i.e. seq_file_net can't be used.
96 */ 93 */
97static inline struct net *seq_file_single_net(struct seq_file *seq) 94static inline struct net *seq_file_single_net(struct seq_file *seq)
@@ -108,7 +105,7 @@ extern int ip_vs_conn_tab_size;
108 105
109struct ip_vs_iphdr { 106struct ip_vs_iphdr {
110 __u32 len; /* IPv4 simply where L4 starts 107 __u32 len; /* IPv4 simply where L4 starts
111 IPv6 where L4 Transport Header starts */ 108 * IPv6 where L4 Transport Header starts */
112 __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/ 109 __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
113 __s16 protocol; 110 __s16 protocol;
114 __s32 flags; 111 __s32 flags;
@@ -304,16 +301,11 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
304#define LeaveFunction(level) do {} while (0) 301#define LeaveFunction(level) do {} while (0)
305#endif 302#endif
306 303
307 304/* The port number of FTP service (in network order). */
308/*
309 * The port number of FTP service (in network order).
310 */
311#define FTPPORT cpu_to_be16(21) 305#define FTPPORT cpu_to_be16(21)
312#define FTPDATA cpu_to_be16(20) 306#define FTPDATA cpu_to_be16(20)
313 307
314/* 308/* TCP State Values */
315 * TCP State Values
316 */
317enum { 309enum {
318 IP_VS_TCP_S_NONE = 0, 310 IP_VS_TCP_S_NONE = 0,
319 IP_VS_TCP_S_ESTABLISHED, 311 IP_VS_TCP_S_ESTABLISHED,
@@ -329,25 +321,19 @@ enum {
329 IP_VS_TCP_S_LAST 321 IP_VS_TCP_S_LAST
330}; 322};
331 323
332/* 324/* UDP State Values */
333 * UDP State Values
334 */
335enum { 325enum {
336 IP_VS_UDP_S_NORMAL, 326 IP_VS_UDP_S_NORMAL,
337 IP_VS_UDP_S_LAST, 327 IP_VS_UDP_S_LAST,
338}; 328};
339 329
340/* 330/* ICMP State Values */
341 * ICMP State Values
342 */
343enum { 331enum {
344 IP_VS_ICMP_S_NORMAL, 332 IP_VS_ICMP_S_NORMAL,
345 IP_VS_ICMP_S_LAST, 333 IP_VS_ICMP_S_LAST,
346}; 334};
347 335
348/* 336/* SCTP State Values */
349 * SCTP State Values
350 */
351enum ip_vs_sctp_states { 337enum ip_vs_sctp_states {
352 IP_VS_SCTP_S_NONE, 338 IP_VS_SCTP_S_NONE,
353 IP_VS_SCTP_S_INIT1, 339 IP_VS_SCTP_S_INIT1,
@@ -366,21 +352,18 @@ enum ip_vs_sctp_states {
366 IP_VS_SCTP_S_LAST 352 IP_VS_SCTP_S_LAST
367}; 353};
368 354
369/* 355/* Delta sequence info structure
370 * Delta sequence info structure 356 * Each ip_vs_conn has 2 (output AND input seq. changes).
371 * Each ip_vs_conn has 2 (output AND input seq. changes). 357 * Only used in the VS/NAT.
372 * Only used in the VS/NAT.
373 */ 358 */
374struct ip_vs_seq { 359struct ip_vs_seq {
375 __u32 init_seq; /* Add delta from this seq */ 360 __u32 init_seq; /* Add delta from this seq */
376 __u32 delta; /* Delta in sequence numbers */ 361 __u32 delta; /* Delta in sequence numbers */
377 __u32 previous_delta; /* Delta in sequence numbers 362 __u32 previous_delta; /* Delta in sequence numbers
378 before last resized pkt */ 363 * before last resized pkt */
379}; 364};
380 365
381/* 366/* counters per cpu */
382 * counters per cpu
383 */
384struct ip_vs_counters { 367struct ip_vs_counters {
385 __u32 conns; /* connections scheduled */ 368 __u32 conns; /* connections scheduled */
386 __u32 inpkts; /* incoming packets */ 369 __u32 inpkts; /* incoming packets */
@@ -388,17 +371,13 @@ struct ip_vs_counters {
388 __u64 inbytes; /* incoming bytes */ 371 __u64 inbytes; /* incoming bytes */
389 __u64 outbytes; /* outgoing bytes */ 372 __u64 outbytes; /* outgoing bytes */
390}; 373};
391/* 374/* Stats per cpu */
392 * Stats per cpu
393 */
394struct ip_vs_cpu_stats { 375struct ip_vs_cpu_stats {
395 struct ip_vs_counters ustats; 376 struct ip_vs_counters ustats;
396 struct u64_stats_sync syncp; 377 struct u64_stats_sync syncp;
397}; 378};
398 379
399/* 380/* IPVS statistics objects */
400 * IPVS statistics objects
401 */
402struct ip_vs_estimator { 381struct ip_vs_estimator {
403 struct list_head list; 382 struct list_head list;
404 383
@@ -491,9 +470,7 @@ struct ip_vs_protocol {
491 void (*timeout_change)(struct ip_vs_proto_data *pd, int flags); 470 void (*timeout_change)(struct ip_vs_proto_data *pd, int flags);
492}; 471};
493 472
494/* 473/* protocol data per netns */
495 * protocol data per netns
496 */
497struct ip_vs_proto_data { 474struct ip_vs_proto_data {
498 struct ip_vs_proto_data *next; 475 struct ip_vs_proto_data *next;
499 struct ip_vs_protocol *pp; 476 struct ip_vs_protocol *pp;
@@ -520,9 +497,7 @@ struct ip_vs_conn_param {
520 __u8 pe_data_len; 497 __u8 pe_data_len;
521}; 498};
522 499
523/* 500/* IP_VS structure allocated for each dynamically scheduled connection */
524 * IP_VS structure allocated for each dynamically scheduled connection
525 */
526struct ip_vs_conn { 501struct ip_vs_conn {
527 struct hlist_node c_list; /* hashed list heads */ 502 struct hlist_node c_list; /* hashed list heads */
528 /* Protocol, addresses and port numbers */ 503 /* Protocol, addresses and port numbers */
@@ -561,17 +536,18 @@ struct ip_vs_conn {
561 struct ip_vs_dest *dest; /* real server */ 536 struct ip_vs_dest *dest; /* real server */
562 atomic_t in_pkts; /* incoming packet counter */ 537 atomic_t in_pkts; /* incoming packet counter */
563 538
564 /* packet transmitter for different forwarding methods. If it 539 /* Packet transmitter for different forwarding methods. If it
565 mangles the packet, it must return NF_DROP or better NF_STOLEN, 540 * mangles the packet, it must return NF_DROP or better NF_STOLEN,
566 otherwise this must be changed to a sk_buff **. 541 * otherwise this must be changed to a sk_buff **.
567 NF_ACCEPT can be returned when destination is local. 542 * NF_ACCEPT can be returned when destination is local.
568 */ 543 */
569 int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, 544 int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
570 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 545 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
571 546
572 /* Note: we can group the following members into a structure, 547 /* Note: we can group the following members into a structure,
573 in order to save more space, and the following members are 548 * in order to save more space, and the following members are
574 only used in VS/NAT anyway */ 549 * only used in VS/NAT anyway
550 */
575 struct ip_vs_app *app; /* bound ip_vs_app object */ 551 struct ip_vs_app *app; /* bound ip_vs_app object */
576 void *app_data; /* Application private data */ 552 void *app_data; /* Application private data */
577 struct ip_vs_seq in_seq; /* incoming seq. struct */ 553 struct ip_vs_seq in_seq; /* incoming seq. struct */
@@ -584,9 +560,7 @@ struct ip_vs_conn {
584 struct rcu_head rcu_head; 560 struct rcu_head rcu_head;
585}; 561};
586 562
587/* 563/* To save some memory in conn table when name space is disabled. */
588 * To save some memory in conn table when name space is disabled.
589 */
590static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp) 564static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp)
591{ 565{
592#ifdef CONFIG_NET_NS 566#ifdef CONFIG_NET_NS
@@ -595,6 +569,7 @@ static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp)
595 return &init_net; 569 return &init_net;
596#endif 570#endif
597} 571}
572
598static inline void ip_vs_conn_net_set(struct ip_vs_conn *cp, struct net *net) 573static inline void ip_vs_conn_net_set(struct ip_vs_conn *cp, struct net *net)
599{ 574{
600#ifdef CONFIG_NET_NS 575#ifdef CONFIG_NET_NS
@@ -612,13 +587,12 @@ static inline int ip_vs_conn_net_eq(const struct ip_vs_conn *cp,
612#endif 587#endif
613} 588}
614 589
615/* 590/* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user
616 * Extended internal versions of struct ip_vs_service_user and 591 * for IPv6 support.
617 * ip_vs_dest_user for IPv6 support.
618 * 592 *
619 * We need these to conveniently pass around service and destination 593 * We need these to conveniently pass around service and destination
620 * options, but unfortunately, we also need to keep the old definitions to 594 * options, but unfortunately, we also need to keep the old definitions to
621 * maintain userspace backwards compatibility for the setsockopt interface. 595 * maintain userspace backwards compatibility for the setsockopt interface.
622 */ 596 */
623struct ip_vs_service_user_kern { 597struct ip_vs_service_user_kern {
624 /* virtual service addresses */ 598 /* virtual service addresses */
@@ -656,8 +630,8 @@ struct ip_vs_dest_user_kern {
656 630
657 631
658/* 632/*
659 * The information about the virtual service offered to the net 633 * The information about the virtual service offered to the net and the
660 * and the forwarding entries 634 * forwarding entries.
661 */ 635 */
662struct ip_vs_service { 636struct ip_vs_service {
663 struct hlist_node s_list; /* for normal service table */ 637 struct hlist_node s_list; /* for normal service table */
@@ -697,9 +671,8 @@ struct ip_vs_dest_dst {
697 struct rcu_head rcu_head; 671 struct rcu_head rcu_head;
698}; 672};
699 673
700/* 674/* The real server destination forwarding entry with ip address, port number,
701 * The real server destination forwarding entry 675 * and so on.
702 * with ip address, port number, and so on.
703 */ 676 */
704struct ip_vs_dest { 677struct ip_vs_dest {
705 struct list_head n_list; /* for the dests in the service */ 678 struct list_head n_list; /* for the dests in the service */
@@ -738,10 +711,7 @@ struct ip_vs_dest {
738 unsigned int in_rs_table:1; /* we are in rs_table */ 711 unsigned int in_rs_table:1; /* we are in rs_table */
739}; 712};
740 713
741 714/* The scheduler object */
742/*
743 * The scheduler object
744 */
745struct ip_vs_scheduler { 715struct ip_vs_scheduler {
746 struct list_head n_list; /* d-linked list head */ 716 struct list_head n_list; /* d-linked list head */
747 char *name; /* scheduler name */ 717 char *name; /* scheduler name */
@@ -781,9 +751,7 @@ struct ip_vs_pe {
781 int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf); 751 int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf);
782}; 752};
783 753
784/* 754/* The application module object (a.k.a. app incarnation) */
785 * The application module object (a.k.a. app incarnation)
786 */
787struct ip_vs_app { 755struct ip_vs_app {
788 struct list_head a_list; /* member in app list */ 756 struct list_head a_list; /* member in app list */
789 int type; /* IP_VS_APP_TYPE_xxx */ 757 int type; /* IP_VS_APP_TYPE_xxx */
@@ -799,16 +767,14 @@ struct ip_vs_app {
799 atomic_t usecnt; /* usage counter */ 767 atomic_t usecnt; /* usage counter */
800 struct rcu_head rcu_head; 768 struct rcu_head rcu_head;
801 769
802 /* 770 /* output hook: Process packet in inout direction, diff set for TCP.
803 * output hook: Process packet in inout direction, diff set for TCP.
804 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, 771 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
805 * 2=Mangled but checksum was not updated 772 * 2=Mangled but checksum was not updated
806 */ 773 */
807 int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, 774 int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
808 struct sk_buff *, int *diff); 775 struct sk_buff *, int *diff);
809 776
810 /* 777 /* input hook: Process packet in outin direction, diff set for TCP.
811 * input hook: Process packet in outin direction, diff set for TCP.
812 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, 778 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
813 * 2=Mangled but checksum was not updated 779 * 2=Mangled but checksum was not updated
814 */ 780 */
@@ -867,9 +833,7 @@ struct ipvs_master_sync_state {
867struct netns_ipvs { 833struct netns_ipvs {
868 int gen; /* Generation */ 834 int gen; /* Generation */
869 int enable; /* enable like nf_hooks do */ 835 int enable; /* enable like nf_hooks do */
870 /* 836 /* Hash table: for real service lookups */
871 * Hash table: for real service lookups
872 */
873 #define IP_VS_RTAB_BITS 4 837 #define IP_VS_RTAB_BITS 4
874 #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) 838 #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS)
875 #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) 839 #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)
@@ -903,7 +867,7 @@ struct netns_ipvs {
903 struct list_head sctp_apps[SCTP_APP_TAB_SIZE]; 867 struct list_head sctp_apps[SCTP_APP_TAB_SIZE];
904#endif 868#endif
905 /* ip_vs_conn */ 869 /* ip_vs_conn */
906 atomic_t conn_count; /* connection counter */ 870 atomic_t conn_count; /* connection counter */
907 871
908 /* ip_vs_ctl */ 872 /* ip_vs_ctl */
909 struct ip_vs_stats tot_stats; /* Statistics & est. */ 873 struct ip_vs_stats tot_stats; /* Statistics & est. */
@@ -990,9 +954,9 @@ struct netns_ipvs {
990 char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; 954 char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
991 /* net name space ptr */ 955 /* net name space ptr */
992 struct net *net; /* Needed by timer routines */ 956 struct net *net; /* Needed by timer routines */
993 /* Number of heterogeneous destinations, needed because 957 /* Number of heterogeneous destinations, needed becaus heterogeneous
994 * heterogeneous are not supported when synchronization is 958 * are not supported when synchronization is enabled.
995 * enabled */ 959 */
996 unsigned int mixed_address_family_dests; 960 unsigned int mixed_address_family_dests;
997}; 961};
998 962
@@ -1147,9 +1111,8 @@ static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
1147 1111
1148#endif 1112#endif
1149 1113
1150/* 1114/* IPVS core functions
1151 * IPVS core functions 1115 * (from ip_vs_core.c)
1152 * (from ip_vs_core.c)
1153 */ 1116 */
1154const char *ip_vs_proto_name(unsigned int proto); 1117const char *ip_vs_proto_name(unsigned int proto);
1155void ip_vs_init_hash_table(struct list_head *table, int rows); 1118void ip_vs_init_hash_table(struct list_head *table, int rows);
@@ -1157,11 +1120,9 @@ void ip_vs_init_hash_table(struct list_head *table, int rows);
1157 1120
1158#define IP_VS_APP_TYPE_FTP 1 1121#define IP_VS_APP_TYPE_FTP 1
1159 1122
1160/* 1123/* ip_vs_conn handling functions
1161 * ip_vs_conn handling functions 1124 * (from ip_vs_conn.c)
1162 * (from ip_vs_conn.c)
1163 */ 1125 */
1164
1165enum { 1126enum {
1166 IP_VS_DIR_INPUT = 0, 1127 IP_VS_DIR_INPUT = 0,
1167 IP_VS_DIR_OUTPUT, 1128 IP_VS_DIR_OUTPUT,
@@ -1292,9 +1253,7 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
1292 atomic_inc(&ctl_cp->n_control); 1253 atomic_inc(&ctl_cp->n_control);
1293} 1254}
1294 1255
1295/* 1256/* IPVS netns init & cleanup functions */
1296 * IPVS netns init & cleanup functions
1297 */
1298int ip_vs_estimator_net_init(struct net *net); 1257int ip_vs_estimator_net_init(struct net *net);
1299int ip_vs_control_net_init(struct net *net); 1258int ip_vs_control_net_init(struct net *net);
1300int ip_vs_protocol_net_init(struct net *net); 1259int ip_vs_protocol_net_init(struct net *net);
@@ -1309,9 +1268,8 @@ void ip_vs_estimator_net_cleanup(struct net *net);
1309void ip_vs_sync_net_cleanup(struct net *net); 1268void ip_vs_sync_net_cleanup(struct net *net);
1310void ip_vs_service_net_cleanup(struct net *net); 1269void ip_vs_service_net_cleanup(struct net *net);
1311 1270
1312/* 1271/* IPVS application functions
1313 * IPVS application functions 1272 * (from ip_vs_app.c)
1314 * (from ip_vs_app.c)
1315 */ 1273 */
1316#define IP_VS_APP_MAX_PORTS 8 1274#define IP_VS_APP_MAX_PORTS 8
1317struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app); 1275struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app);
@@ -1331,9 +1289,7 @@ int unregister_ip_vs_pe(struct ip_vs_pe *pe);
1331struct ip_vs_pe *ip_vs_pe_getbyname(const char *name); 1289struct ip_vs_pe *ip_vs_pe_getbyname(const char *name);
1332struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name); 1290struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
1333 1291
1334/* 1292/* Use a #define to avoid all of module.h just for these trivial ops */
1335 * Use a #define to avoid all of module.h just for these trivial ops
1336 */
1337#define ip_vs_pe_get(pe) \ 1293#define ip_vs_pe_get(pe) \
1338 if (pe && pe->module) \ 1294 if (pe && pe->module) \
1339 __module_get(pe->module); 1295 __module_get(pe->module);
@@ -1342,9 +1298,7 @@ struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
1342 if (pe && pe->module) \ 1298 if (pe && pe->module) \
1343 module_put(pe->module); 1299 module_put(pe->module);
1344 1300
1345/* 1301/* IPVS protocol functions (from ip_vs_proto.c) */
1346 * IPVS protocol functions (from ip_vs_proto.c)
1347 */
1348int ip_vs_protocol_init(void); 1302int ip_vs_protocol_init(void);
1349void ip_vs_protocol_cleanup(void); 1303void ip_vs_protocol_cleanup(void);
1350void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags); 1304void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags);
@@ -1362,9 +1316,8 @@ extern struct ip_vs_protocol ip_vs_protocol_esp;
1362extern struct ip_vs_protocol ip_vs_protocol_ah; 1316extern struct ip_vs_protocol ip_vs_protocol_ah;
1363extern struct ip_vs_protocol ip_vs_protocol_sctp; 1317extern struct ip_vs_protocol ip_vs_protocol_sctp;
1364 1318
1365/* 1319/* Registering/unregistering scheduler functions
1366 * Registering/unregistering scheduler functions 1320 * (from ip_vs_sched.c)
1367 * (from ip_vs_sched.c)
1368 */ 1321 */
1369int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); 1322int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
1370int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); 1323int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler);
@@ -1383,10 +1336,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
1383 1336
1384void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); 1337void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);
1385 1338
1386 1339/* IPVS control data and functions (from ip_vs_ctl.c) */
1387/*
1388 * IPVS control data and functions (from ip_vs_ctl.c)
1389 */
1390extern struct ip_vs_stats ip_vs_stats; 1340extern struct ip_vs_stats ip_vs_stats;
1391extern int sysctl_ip_vs_sync_ver; 1341extern int sysctl_ip_vs_sync_ver;
1392 1342
@@ -1427,26 +1377,21 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
1427 kfree(dest); 1377 kfree(dest);
1428} 1378}
1429 1379
1430/* 1380/* IPVS sync daemon data and function prototypes
1431 * IPVS sync daemon data and function prototypes 1381 * (from ip_vs_sync.c)
1432 * (from ip_vs_sync.c)
1433 */ 1382 */
1434int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid); 1383int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid);
1435int stop_sync_thread(struct net *net, int state); 1384int stop_sync_thread(struct net *net, int state);
1436void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts); 1385void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts);
1437 1386
1438/* 1387/* IPVS rate estimator prototypes (from ip_vs_est.c) */
1439 * IPVS rate estimator prototypes (from ip_vs_est.c)
1440 */
1441void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats); 1388void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats);
1442void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats); 1389void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats);
1443void ip_vs_zero_estimator(struct ip_vs_stats *stats); 1390void ip_vs_zero_estimator(struct ip_vs_stats *stats);
1444void ip_vs_read_estimator(struct ip_vs_stats_user *dst, 1391void ip_vs_read_estimator(struct ip_vs_stats_user *dst,
1445 struct ip_vs_stats *stats); 1392 struct ip_vs_stats *stats);
1446 1393
1447/* 1394/* Various IPVS packet transmitters (from ip_vs_xmit.c) */
1448 * Various IPVS packet transmitters (from ip_vs_xmit.c)
1449 */
1450int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 1395int ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
1451 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); 1396 struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
1452int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, 1397int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
@@ -1477,12 +1422,10 @@ int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
1477#endif 1422#endif
1478 1423
1479#ifdef CONFIG_SYSCTL 1424#ifdef CONFIG_SYSCTL
1480/* 1425/* This is a simple mechanism to ignore packets when
1481 * This is a simple mechanism to ignore packets when 1426 * we are loaded. Just set ip_vs_drop_rate to 'n' and
1482 * we are loaded. Just set ip_vs_drop_rate to 'n' and 1427 * we start to drop 1/rate of the packets
1483 * we start to drop 1/rate of the packets
1484 */ 1428 */
1485
1486static inline int ip_vs_todrop(struct netns_ipvs *ipvs) 1429static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
1487{ 1430{
1488 if (!ipvs->drop_rate) 1431 if (!ipvs->drop_rate)
@@ -1496,9 +1439,7 @@ static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
1496static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; } 1439static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
1497#endif 1440#endif
1498 1441
1499/* 1442/* ip_vs_fwd_tag returns the forwarding tag of the connection */
1500 * ip_vs_fwd_tag returns the forwarding tag of the connection
1501 */
1502#define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK) 1443#define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK)
1503 1444
1504static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp) 1445static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
@@ -1557,9 +1498,7 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
1557 return csum_partial(diff, sizeof(diff), oldsum); 1498 return csum_partial(diff, sizeof(diff), oldsum);
1558} 1499}
1559 1500
1560/* 1501/* Forget current conntrack (unconfirmed) and attach notrack entry */
1561 * Forget current conntrack (unconfirmed) and attach notrack entry
1562 */
1563static inline void ip_vs_notrack(struct sk_buff *skb) 1502static inline void ip_vs_notrack(struct sk_buff *skb)
1564{ 1503{
1565#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 1504#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -1576,9 +1515,8 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
1576} 1515}
1577 1516
1578#ifdef CONFIG_IP_VS_NFCT 1517#ifdef CONFIG_IP_VS_NFCT
1579/* 1518/* Netfilter connection tracking
1580 * Netfilter connection tracking 1519 * (from ip_vs_nfct.c)
1581 * (from ip_vs_nfct.c)
1582 */ 1520 */
1583static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs) 1521static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
1584{ 1522{
@@ -1617,14 +1555,12 @@ static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
1617static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) 1555static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
1618{ 1556{
1619} 1557}
1620/* CONFIG_IP_VS_NFCT */ 1558#endif /* CONFIG_IP_VS_NFCT */
1621#endif
1622 1559
1623static inline int 1560static inline int
1624ip_vs_dest_conn_overhead(struct ip_vs_dest *dest) 1561ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
1625{ 1562{
1626 /* 1563 /* We think the overhead of processing active connections is 256
1627 * We think the overhead of processing active connections is 256
1628 * times higher than that of inactive connections in average. (This 1564 * times higher than that of inactive connections in average. (This
1629 * 256 times might not be accurate, we will change it later) We 1565 * 256 times might not be accurate, we will change it later) We
1630 * use the following formula to estimate the overhead now: 1566 * use the following formula to estimate the overhead now:
diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h
new file mode 100644
index 000000000000..2aa6048a55c1
--- /dev/null
+++ b/include/net/netfilter/br_netfilter.h
@@ -0,0 +1,6 @@
1#ifndef _BR_NETFILTER_H_
2#define _BR_NETFILTER_H_
3
4void br_netfilter_enable(void);
5
6#endif /* _BR_NETFILTER_H_ */
diff --git a/include/net/netfilter/ipv4/nf_reject.h b/include/net/netfilter/ipv4/nf_reject.h
index f713b5a31d62..e8427193c777 100644
--- a/include/net/netfilter/ipv4/nf_reject.h
+++ b/include/net/netfilter/ipv4/nf_reject.h
@@ -1,128 +1,13 @@
1#ifndef _IPV4_NF_REJECT_H 1#ifndef _IPV4_NF_REJECT_H
2#define _IPV4_NF_REJECT_H 2#define _IPV4_NF_REJECT_H
3 3
4#include <net/ip.h> 4#include <net/icmp.h>
5#include <net/tcp.h>
6#include <net/route.h>
7#include <net/dst.h>
8 5
9static inline void nf_send_unreach(struct sk_buff *skb_in, int code) 6static inline void nf_send_unreach(struct sk_buff *skb_in, int code)
10{ 7{
11 icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); 8 icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
12} 9}
13 10
14/* Send RST reply */ 11void nf_send_reset(struct sk_buff *oldskb, int hook);
15static void nf_send_reset(struct sk_buff *oldskb, int hook)
16{
17 struct sk_buff *nskb;
18 const struct iphdr *oiph;
19 struct iphdr *niph;
20 const struct tcphdr *oth;
21 struct tcphdr _otcph, *tcph;
22
23 /* IP header checks: fragment. */
24 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
25 return;
26
27 oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
28 sizeof(_otcph), &_otcph);
29 if (oth == NULL)
30 return;
31
32 /* No RST for RST. */
33 if (oth->rst)
34 return;
35
36 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
37 return;
38
39 /* Check checksum */
40 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
41 return;
42 oiph = ip_hdr(oldskb);
43
44 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
45 LL_MAX_HEADER, GFP_ATOMIC);
46 if (!nskb)
47 return;
48
49 skb_reserve(nskb, LL_MAX_HEADER);
50
51 skb_reset_network_header(nskb);
52 niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
53 niph->version = 4;
54 niph->ihl = sizeof(struct iphdr) / 4;
55 niph->tos = 0;
56 niph->id = 0;
57 niph->frag_off = htons(IP_DF);
58 niph->protocol = IPPROTO_TCP;
59 niph->check = 0;
60 niph->saddr = oiph->daddr;
61 niph->daddr = oiph->saddr;
62
63 skb_reset_transport_header(nskb);
64 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
65 memset(tcph, 0, sizeof(*tcph));
66 tcph->source = oth->dest;
67 tcph->dest = oth->source;
68 tcph->doff = sizeof(struct tcphdr) / 4;
69
70 if (oth->ack)
71 tcph->seq = oth->ack_seq;
72 else {
73 tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
74 oldskb->len - ip_hdrlen(oldskb) -
75 (oth->doff << 2));
76 tcph->ack = 1;
77 }
78
79 tcph->rst = 1;
80 tcph->check = ~tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
81 niph->daddr, 0);
82 nskb->ip_summed = CHECKSUM_PARTIAL;
83 nskb->csum_start = (unsigned char *)tcph - nskb->head;
84 nskb->csum_offset = offsetof(struct tcphdr, check);
85
86 /* ip_route_me_harder expects skb->dst to be set */
87 skb_dst_set_noref(nskb, skb_dst(oldskb));
88
89 nskb->protocol = htons(ETH_P_IP);
90 if (ip_route_me_harder(nskb, RTN_UNSPEC))
91 goto free_nskb;
92
93 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
94
95 /* "Never happens" */
96 if (nskb->len > dst_mtu(skb_dst(nskb)))
97 goto free_nskb;
98
99 nf_ct_attach(nskb, oldskb);
100
101#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
102 /* If we use ip_local_out for bridged traffic, the MAC source on
103 * the RST will be ours, instead of the destination's. This confuses
104 * some routers/firewalls, and they drop the packet. So we need to
105 * build the eth header using the original destination's MAC as the
106 * source, and send the RST packet directly.
107 */
108 if (oldskb->nf_bridge) {
109 struct ethhdr *oeth = eth_hdr(oldskb);
110 nskb->dev = oldskb->nf_bridge->physindev;
111 niph->tot_len = htons(nskb->len);
112 ip_send_check(niph);
113 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
114 oeth->h_source, oeth->h_dest, nskb->len) < 0)
115 goto free_nskb;
116 dev_queue_xmit(nskb);
117 } else
118#endif
119 ip_local_out(nskb);
120
121 return;
122
123 free_nskb:
124 kfree_skb(nskb);
125}
126
127 12
128#endif /* _IPV4_NF_REJECT_H */ 13#endif /* _IPV4_NF_REJECT_H */
diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h
index 36b0da2d55bb..60fa1530006b 100644
--- a/include/net/netfilter/nft_reject.h
+++ b/include/net/netfilter/nft_reject.h
@@ -14,12 +14,7 @@ int nft_reject_init(const struct nft_ctx *ctx,
14 14
15int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr); 15int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr);
16 16
17void nft_reject_ipv4_eval(const struct nft_expr *expr, 17int nft_reject_icmp_code(u8 code);
18 struct nft_data data[NFT_REG_MAX + 1], 18int nft_reject_icmpv6_code(u8 code);
19 const struct nft_pktinfo *pkt);
20
21void nft_reject_ipv6_eval(const struct nft_expr *expr,
22 struct nft_data data[NFT_REG_MAX + 1],
23 const struct nft_pktinfo *pkt);
24 19
25#endif 20#endif
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index b72ccfeaf865..c26df6787fb0 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -749,13 +749,34 @@ enum nft_queue_attributes {
749 * 749 *
750 * @NFT_REJECT_ICMP_UNREACH: reject using ICMP unreachable 750 * @NFT_REJECT_ICMP_UNREACH: reject using ICMP unreachable
751 * @NFT_REJECT_TCP_RST: reject using TCP RST 751 * @NFT_REJECT_TCP_RST: reject using TCP RST
752 * @NFT_REJECT_ICMPX_UNREACH: abstracted ICMP unreachable for bridge and inet
752 */ 753 */
753enum nft_reject_types { 754enum nft_reject_types {
754 NFT_REJECT_ICMP_UNREACH, 755 NFT_REJECT_ICMP_UNREACH,
755 NFT_REJECT_TCP_RST, 756 NFT_REJECT_TCP_RST,
757 NFT_REJECT_ICMPX_UNREACH,
756}; 758};
757 759
758/** 760/**
761 * enum nft_reject_code - Generic reject codes for IPv4/IPv6
762 *
763 * @NFT_REJECT_ICMPX_NO_ROUTE: no route to host / network unreachable
764 * @NFT_REJECT_ICMPX_PORT_UNREACH: port unreachable
765 * @NFT_REJECT_ICMPX_HOST_UNREACH: host unreachable
766 * @NFT_REJECT_ICMPX_ADMIN_PROHIBITED: administratively prohibited
767 *
768 * These codes are mapped to real ICMP and ICMPv6 codes.
769 */
770enum nft_reject_inet_code {
771 NFT_REJECT_ICMPX_NO_ROUTE = 0,
772 NFT_REJECT_ICMPX_PORT_UNREACH,
773 NFT_REJECT_ICMPX_HOST_UNREACH,
774 NFT_REJECT_ICMPX_ADMIN_PROHIBITED,
775 __NFT_REJECT_ICMPX_MAX
776};
777#define NFT_REJECT_ICMPX_MAX (__NFT_REJECT_ICMPX_MAX + 1)
778
779/**
759 * enum nft_reject_attributes - nf_tables reject expression netlink attributes 780 * enum nft_reject_attributes - nf_tables reject expression netlink attributes
760 * 781 *
761 * @NFTA_REJECT_TYPE: packet type to use (NLA_U32: nft_reject_types) 782 * @NFTA_REJECT_TYPE: packet type to use (NLA_U32: nft_reject_types)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 97e43937aaca..fa1270cc5086 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -856,6 +856,11 @@ static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops,
856 return NF_ACCEPT; 856 return NF_ACCEPT;
857} 857}
858 858
859void br_netfilter_enable(void)
860{
861}
862EXPORT_SYMBOL_GPL(br_netfilter_enable);
863
859/* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because 864/* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
860 * br_dev_queue_push_xmit is called afterwards */ 865 * br_dev_queue_push_xmit is called afterwards */
861static struct nf_hook_ops br_nf_ops[] __read_mostly = { 866static struct nf_hook_ops br_nf_ops[] __read_mostly = {
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 5bcc0d8b31f2..da17a5eab8b4 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -34,9 +34,11 @@ static struct nft_af_info nft_af_bridge __read_mostly = {
34 .owner = THIS_MODULE, 34 .owner = THIS_MODULE,
35 .nops = 1, 35 .nops = 1,
36 .hooks = { 36 .hooks = {
37 [NF_BR_PRE_ROUTING] = nft_do_chain_bridge,
37 [NF_BR_LOCAL_IN] = nft_do_chain_bridge, 38 [NF_BR_LOCAL_IN] = nft_do_chain_bridge,
38 [NF_BR_FORWARD] = nft_do_chain_bridge, 39 [NF_BR_FORWARD] = nft_do_chain_bridge,
39 [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, 40 [NF_BR_LOCAL_OUT] = nft_do_chain_bridge,
41 [NF_BR_POST_ROUTING] = nft_do_chain_bridge,
40 }, 42 },
41}; 43};
42 44
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index ee3ffe93e14e..a76479535df2 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -14,21 +14,106 @@
14#include <linux/netfilter/nf_tables.h> 14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h> 15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nft_reject.h> 16#include <net/netfilter/nft_reject.h>
17#include <net/netfilter/ipv4/nf_reject.h>
18#include <net/netfilter/ipv6/nf_reject.h>
17 19
18static void nft_reject_bridge_eval(const struct nft_expr *expr, 20static void nft_reject_bridge_eval(const struct nft_expr *expr,
19 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_data data[NFT_REG_MAX + 1],
20 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
21{ 23{
24 struct nft_reject *priv = nft_expr_priv(expr);
25 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
26
22 switch (eth_hdr(pkt->skb)->h_proto) { 27 switch (eth_hdr(pkt->skb)->h_proto) {
23 case htons(ETH_P_IP): 28 case htons(ETH_P_IP):
24 return nft_reject_ipv4_eval(expr, data, pkt); 29 switch (priv->type) {
30 case NFT_REJECT_ICMP_UNREACH:
31 nf_send_unreach(pkt->skb, priv->icmp_code);
32 break;
33 case NFT_REJECT_TCP_RST:
34 nf_send_reset(pkt->skb, pkt->ops->hooknum);
35 break;
36 case NFT_REJECT_ICMPX_UNREACH:
37 nf_send_unreach(pkt->skb,
38 nft_reject_icmp_code(priv->icmp_code));
39 break;
40 }
41 break;
25 case htons(ETH_P_IPV6): 42 case htons(ETH_P_IPV6):
26 return nft_reject_ipv6_eval(expr, data, pkt); 43 switch (priv->type) {
44 case NFT_REJECT_ICMP_UNREACH:
45 nf_send_unreach6(net, pkt->skb, priv->icmp_code,
46 pkt->ops->hooknum);
47 break;
48 case NFT_REJECT_TCP_RST:
49 nf_send_reset6(net, pkt->skb, pkt->ops->hooknum);
50 break;
51 case NFT_REJECT_ICMPX_UNREACH:
52 nf_send_unreach6(net, pkt->skb,
53 nft_reject_icmpv6_code(priv->icmp_code),
54 pkt->ops->hooknum);
55 break;
56 }
57 break;
27 default: 58 default:
28 /* No explicit way to reject this protocol, drop it. */ 59 /* No explicit way to reject this protocol, drop it. */
29 data[NFT_REG_VERDICT].verdict = NF_DROP;
30 break; 60 break;
31 } 61 }
62 data[NFT_REG_VERDICT].verdict = NF_DROP;
63}
64
65static int nft_reject_bridge_init(const struct nft_ctx *ctx,
66 const struct nft_expr *expr,
67 const struct nlattr * const tb[])
68{
69 struct nft_reject *priv = nft_expr_priv(expr);
70 int icmp_code;
71
72 if (tb[NFTA_REJECT_TYPE] == NULL)
73 return -EINVAL;
74
75 priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
76 switch (priv->type) {
77 case NFT_REJECT_ICMP_UNREACH:
78 case NFT_REJECT_ICMPX_UNREACH:
79 if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
80 return -EINVAL;
81
82 icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
83 if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
84 icmp_code > NFT_REJECT_ICMPX_MAX)
85 return -EINVAL;
86
87 priv->icmp_code = icmp_code;
88 break;
89 case NFT_REJECT_TCP_RST:
90 break;
91 default:
92 return -EINVAL;
93 }
94 return 0;
95}
96
97static int nft_reject_bridge_dump(struct sk_buff *skb,
98 const struct nft_expr *expr)
99{
100 const struct nft_reject *priv = nft_expr_priv(expr);
101
102 if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
103 goto nla_put_failure;
104
105 switch (priv->type) {
106 case NFT_REJECT_ICMP_UNREACH:
107 case NFT_REJECT_ICMPX_UNREACH:
108 if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
109 goto nla_put_failure;
110 break;
111 }
112
113 return 0;
114
115nla_put_failure:
116 return -1;
32} 117}
33 118
34static struct nft_expr_type nft_reject_bridge_type; 119static struct nft_expr_type nft_reject_bridge_type;
@@ -36,8 +121,8 @@ static const struct nft_expr_ops nft_reject_bridge_ops = {
36 .type = &nft_reject_bridge_type, 121 .type = &nft_reject_bridge_type,
37 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), 122 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
38 .eval = nft_reject_bridge_eval, 123 .eval = nft_reject_bridge_eval,
39 .init = nft_reject_init, 124 .init = nft_reject_bridge_init,
40 .dump = nft_reject_dump, 125 .dump = nft_reject_bridge_dump,
41}; 126};
42 127
43static struct nft_expr_type nft_reject_bridge_type __read_mostly = { 128static struct nft_expr_type nft_reject_bridge_type __read_mostly = {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 28916e47f959..9a423e2c5766 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -572,7 +572,7 @@ static void skb_release_head_state(struct sk_buff *skb)
572#if IS_ENABLED(CONFIG_NF_CONNTRACK) 572#if IS_ENABLED(CONFIG_NF_CONNTRACK)
573 nf_conntrack_put(skb->nfct); 573 nf_conntrack_put(skb->nfct);
574#endif 574#endif
575#ifdef CONFIG_BRIDGE_NETFILTER 575#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
576 nf_bridge_put(skb->nf_bridge); 576 nf_bridge_put(skb->nf_bridge);
577#endif 577#endif
578/* XXX: IS this still necessary? - JHS */ 578/* XXX: IS this still necessary? - JHS */
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index c8fa62476461..e35b71289156 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -516,7 +516,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
516 516
517 hlen = iph->ihl * 4; 517 hlen = iph->ihl * 4;
518 mtu = mtu - hlen; /* Size of data space */ 518 mtu = mtu - hlen; /* Size of data space */
519#ifdef CONFIG_BRIDGE_NETFILTER 519#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
520 if (skb->nf_bridge) 520 if (skb->nf_bridge)
521 mtu -= nf_bridge_mtu_reduction(skb); 521 mtu -= nf_bridge_mtu_reduction(skb);
522#endif 522#endif
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 345242a79db6..4c019d5c3f57 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -61,8 +61,13 @@ config NFT_CHAIN_ROUTE_IPV4
61 fields such as the source, destination, type of service and 61 fields such as the source, destination, type of service and
62 the packet mark. 62 the packet mark.
63 63
64config NF_REJECT_IPV4
65 tristate "IPv4 packet rejection"
66 default m if NETFILTER_ADVANCED=n
67
64config NFT_REJECT_IPV4 68config NFT_REJECT_IPV4
65 depends on NF_TABLES_IPV4 69 depends on NF_TABLES_IPV4
70 select NF_REJECT_IPV4
66 default NFT_REJECT 71 default NFT_REJECT
67 tristate 72 tristate
68 73
@@ -208,6 +213,7 @@ config IP_NF_FILTER
208config IP_NF_TARGET_REJECT 213config IP_NF_TARGET_REJECT
209 tristate "REJECT target support" 214 tristate "REJECT target support"
210 depends on IP_NF_FILTER 215 depends on IP_NF_FILTER
216 select NF_REJECT_IPV4
211 default m if NETFILTER_ADVANCED=n 217 default m if NETFILTER_ADVANCED=n
212 help 218 help
213 The REJECT target allows a filtering rule to specify that an ICMP 219 The REJECT target allows a filtering rule to specify that an ICMP
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 14488cc5fd2c..f4cef5af0969 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -23,6 +23,9 @@ obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
23obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o 23obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o
24obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o 24obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o
25 25
26# reject
27obj-$(CONFIG_NF_REJECT_IPV4) += nf_reject_ipv4.o
28
26# NAT helpers (nf_conntrack) 29# NAT helpers (nf_conntrack)
27obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o 30obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
28obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o 31obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 5b6e0df4ccff..8f48f5517e33 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -20,7 +20,7 @@
20#include <linux/netfilter/x_tables.h> 20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter_ipv4/ipt_REJECT.h> 22#include <linux/netfilter_ipv4/ipt_REJECT.h>
23#ifdef CONFIG_BRIDGE_NETFILTER 23#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
24#include <linux/netfilter_bridge.h> 24#include <linux/netfilter_bridge.h>
25#endif 25#endif
26 26
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index 76bd1aef257f..7e5ca6f2d0cd 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -50,7 +50,7 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
50 zone = nf_ct_zone((struct nf_conn *)skb->nfct); 50 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
51#endif 51#endif
52 52
53#ifdef CONFIG_BRIDGE_NETFILTER 53#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
54 if (skb->nf_bridge && 54 if (skb->nf_bridge &&
55 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 55 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
56 return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone; 56 return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
new file mode 100644
index 000000000000..b023b4eb1a96
--- /dev/null
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -0,0 +1,127 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <net/ip.h>
10#include <net/tcp.h>
11#include <net/route.h>
12#include <net/dst.h>
13#include <linux/netfilter_ipv4.h>
14
15/* Send RST reply */
16void nf_send_reset(struct sk_buff *oldskb, int hook)
17{
18 struct sk_buff *nskb;
19 const struct iphdr *oiph;
20 struct iphdr *niph;
21 const struct tcphdr *oth;
22 struct tcphdr _otcph, *tcph;
23
24 /* IP header checks: fragment. */
25 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
26 return;
27
28 oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
29 sizeof(_otcph), &_otcph);
30 if (oth == NULL)
31 return;
32
33 /* No RST for RST. */
34 if (oth->rst)
35 return;
36
37 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
38 return;
39
40 /* Check checksum */
41 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
42 return;
43 oiph = ip_hdr(oldskb);
44
45 nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
46 LL_MAX_HEADER, GFP_ATOMIC);
47 if (!nskb)
48 return;
49
50 skb_reserve(nskb, LL_MAX_HEADER);
51
52 skb_reset_network_header(nskb);
53 niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
54 niph->version = 4;
55 niph->ihl = sizeof(struct iphdr) / 4;
56 niph->tos = 0;
57 niph->id = 0;
58 niph->frag_off = htons(IP_DF);
59 niph->protocol = IPPROTO_TCP;
60 niph->check = 0;
61 niph->saddr = oiph->daddr;
62 niph->daddr = oiph->saddr;
63
64 skb_reset_transport_header(nskb);
65 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
66 memset(tcph, 0, sizeof(*tcph));
67 tcph->source = oth->dest;
68 tcph->dest = oth->source;
69 tcph->doff = sizeof(struct tcphdr) / 4;
70
71 if (oth->ack)
72 tcph->seq = oth->ack_seq;
73 else {
74 tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
75 oldskb->len - ip_hdrlen(oldskb) -
76 (oth->doff << 2));
77 tcph->ack = 1;
78 }
79
80 tcph->rst = 1;
81 tcph->check = ~tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
82 niph->daddr, 0);
83 nskb->ip_summed = CHECKSUM_PARTIAL;
84 nskb->csum_start = (unsigned char *)tcph - nskb->head;
85 nskb->csum_offset = offsetof(struct tcphdr, check);
86
87 /* ip_route_me_harder expects skb->dst to be set */
88 skb_dst_set_noref(nskb, skb_dst(oldskb));
89
90 nskb->protocol = htons(ETH_P_IP);
91 if (ip_route_me_harder(nskb, RTN_UNSPEC))
92 goto free_nskb;
93
94 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
95
96 /* "Never happens" */
97 if (nskb->len > dst_mtu(skb_dst(nskb)))
98 goto free_nskb;
99
100 nf_ct_attach(nskb, oldskb);
101
102#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
103 /* If we use ip_local_out for bridged traffic, the MAC source on
104 * the RST will be ours, instead of the destination's. This confuses
105 * some routers/firewalls, and they drop the packet. So we need to
106 * build the eth header using the original destination's MAC as the
107 * source, and send the RST packet directly.
108 */
109 if (oldskb->nf_bridge) {
110 struct ethhdr *oeth = eth_hdr(oldskb);
111 nskb->dev = oldskb->nf_bridge->physindev;
112 niph->tot_len = htons(nskb->len);
113 ip_send_check(niph);
114 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
115 oeth->h_source, oeth->h_dest, nskb->len) < 0)
116 goto free_nskb;
117 dev_queue_xmit(nskb);
118 } else
119#endif
120 ip_local_out(nskb);
121
122 return;
123
124 free_nskb:
125 kfree_skb(nskb);
126}
127EXPORT_SYMBOL_GPL(nf_send_reset);
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c
index 6ea1d207b6a5..1c636d6b5b50 100644
--- a/net/ipv4/netfilter/nft_masq_ipv4.c
+++ b/net/ipv4/netfilter/nft_masq_ipv4.c
@@ -32,33 +32,12 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr,
32 data[NFT_REG_VERDICT].verdict = verdict; 32 data[NFT_REG_VERDICT].verdict = verdict;
33} 33}
34 34
35static int nft_masq_ipv4_init(const struct nft_ctx *ctx,
36 const struct nft_expr *expr,
37 const struct nlattr * const tb[])
38{
39 int err;
40
41 err = nft_masq_init(ctx, expr, tb);
42 if (err < 0)
43 return err;
44
45 nf_nat_masquerade_ipv4_register_notifier();
46 return 0;
47}
48
49static void nft_masq_ipv4_destroy(const struct nft_ctx *ctx,
50 const struct nft_expr *expr)
51{
52 nf_nat_masquerade_ipv4_unregister_notifier();
53}
54
55static struct nft_expr_type nft_masq_ipv4_type; 35static struct nft_expr_type nft_masq_ipv4_type;
56static const struct nft_expr_ops nft_masq_ipv4_ops = { 36static const struct nft_expr_ops nft_masq_ipv4_ops = {
57 .type = &nft_masq_ipv4_type, 37 .type = &nft_masq_ipv4_type,
58 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)), 38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
59 .eval = nft_masq_ipv4_eval, 39 .eval = nft_masq_ipv4_eval,
60 .init = nft_masq_ipv4_init, 40 .init = nft_masq_init,
61 .destroy = nft_masq_ipv4_destroy,
62 .dump = nft_masq_dump, 41 .dump = nft_masq_dump,
63}; 42};
64 43
@@ -73,12 +52,21 @@ static struct nft_expr_type nft_masq_ipv4_type __read_mostly = {
73 52
74static int __init nft_masq_ipv4_module_init(void) 53static int __init nft_masq_ipv4_module_init(void)
75{ 54{
76 return nft_register_expr(&nft_masq_ipv4_type); 55 int ret;
56
57 ret = nft_register_expr(&nft_masq_ipv4_type);
58 if (ret < 0)
59 return ret;
60
61 nf_nat_masquerade_ipv4_register_notifier();
62
63 return ret;
77} 64}
78 65
79static void __exit nft_masq_ipv4_module_exit(void) 66static void __exit nft_masq_ipv4_module_exit(void)
80{ 67{
81 nft_unregister_expr(&nft_masq_ipv4_type); 68 nft_unregister_expr(&nft_masq_ipv4_type);
69 nf_nat_masquerade_ipv4_unregister_notifier();
82} 70}
83 71
84module_init(nft_masq_ipv4_module_init); 72module_init(nft_masq_ipv4_module_init);
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index e79718a382f2..ed33299c56d1 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -16,7 +16,6 @@
16#include <linux/netfilter.h> 16#include <linux/netfilter.h>
17#include <linux/netfilter/nf_tables.h> 17#include <linux/netfilter/nf_tables.h>
18#include <net/netfilter/nf_tables.h> 18#include <net/netfilter/nf_tables.h>
19#include <net/icmp.h>
20#include <net/netfilter/ipv4/nf_reject.h> 19#include <net/netfilter/ipv4/nf_reject.h>
21#include <net/netfilter/nft_reject.h> 20#include <net/netfilter/nft_reject.h>
22 21
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index bb1a40db7be1..6af874fc187f 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -40,8 +40,13 @@ config NFT_CHAIN_ROUTE_IPV6
40 fields such as the source, destination, flowlabel, hop-limit and 40 fields such as the source, destination, flowlabel, hop-limit and
41 the packet mark. 41 the packet mark.
42 42
43config NF_REJECT_IPV6
44 tristate "IPv6 packet rejection"
45 default m if NETFILTER_ADVANCED=n
46
43config NFT_REJECT_IPV6 47config NFT_REJECT_IPV6
44 depends on NF_TABLES_IPV6 48 depends on NF_TABLES_IPV6
49 select NF_REJECT_IPV6
45 default NFT_REJECT 50 default NFT_REJECT
46 tristate 51 tristate
47 52
@@ -208,6 +213,7 @@ config IP6_NF_FILTER
208config IP6_NF_TARGET_REJECT 213config IP6_NF_TARGET_REJECT
209 tristate "REJECT target support" 214 tristate "REJECT target support"
210 depends on IP6_NF_FILTER 215 depends on IP6_NF_FILTER
216 select NF_REJECT_IPV6
211 default m if NETFILTER_ADVANCED=n 217 default m if NETFILTER_ADVANCED=n
212 help 218 help
213 The REJECT target allows a filtering rule to specify that an ICMPv6 219 The REJECT target allows a filtering rule to specify that an ICMPv6
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 0f7e5b3f328d..fbb25f01143c 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -27,6 +27,9 @@ obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
27# logging 27# logging
28obj-$(CONFIG_NF_LOG_IPV6) += nf_log_ipv6.o 28obj-$(CONFIG_NF_LOG_IPV6) += nf_log_ipv6.o
29 29
30# reject
31obj-$(CONFIG_NF_REJECT_IPV6) += nf_reject_ipv6.o
32
30# nf_tables 33# nf_tables
31obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o 34obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o
32obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o 35obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index 7b9a748c6bac..e70382e4dfb5 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -40,7 +40,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
40 zone = nf_ct_zone((struct nf_conn *)skb->nfct); 40 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
41#endif 41#endif
42 42
43#ifdef CONFIG_BRIDGE_NETFILTER 43#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
44 if (skb->nf_bridge && 44 if (skb->nf_bridge &&
45 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) 45 skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
46 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; 46 return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
new file mode 100644
index 000000000000..5f5f0438d74d
--- /dev/null
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -0,0 +1,163 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <net/ipv6.h>
9#include <net/ip6_route.h>
10#include <net/ip6_fib.h>
11#include <net/ip6_checksum.h>
12#include <linux/netfilter_ipv6.h>
13
14void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
15{
16 struct sk_buff *nskb;
17 struct tcphdr otcph, *tcph;
18 unsigned int otcplen, hh_len;
19 int tcphoff, needs_ack;
20 const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
21 struct ipv6hdr *ip6h;
22#define DEFAULT_TOS_VALUE 0x0U
23 const __u8 tclass = DEFAULT_TOS_VALUE;
24 struct dst_entry *dst = NULL;
25 u8 proto;
26 __be16 frag_off;
27 struct flowi6 fl6;
28
29 if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
30 (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
31 pr_debug("addr is not unicast.\n");
32 return;
33 }
34
35 proto = oip6h->nexthdr;
36 tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto, &frag_off);
37
38 if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
39 pr_debug("Cannot get TCP header.\n");
40 return;
41 }
42
43 otcplen = oldskb->len - tcphoff;
44
45 /* IP header checks: fragment, too short. */
46 if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
47 pr_debug("proto(%d) != IPPROTO_TCP, "
48 "or too short. otcplen = %d\n",
49 proto, otcplen);
50 return;
51 }
52
53 if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr)))
54 BUG();
55
56 /* No RST for RST. */
57 if (otcph.rst) {
58 pr_debug("RST is set\n");
59 return;
60 }
61
62 /* Check checksum. */
63 if (nf_ip6_checksum(oldskb, hook, tcphoff, IPPROTO_TCP)) {
64 pr_debug("TCP checksum is invalid\n");
65 return;
66 }
67
68 memset(&fl6, 0, sizeof(fl6));
69 fl6.flowi6_proto = IPPROTO_TCP;
70 fl6.saddr = oip6h->daddr;
71 fl6.daddr = oip6h->saddr;
72 fl6.fl6_sport = otcph.dest;
73 fl6.fl6_dport = otcph.source;
74 security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
75 dst = ip6_route_output(net, NULL, &fl6);
76 if (dst == NULL || dst->error) {
77 dst_release(dst);
78 return;
79 }
80 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
81 if (IS_ERR(dst))
82 return;
83
84 hh_len = (dst->dev->hard_header_len + 15)&~15;
85 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
86 + sizeof(struct tcphdr) + dst->trailer_len,
87 GFP_ATOMIC);
88
89 if (!nskb) {
90 net_dbg_ratelimited("cannot alloc skb\n");
91 dst_release(dst);
92 return;
93 }
94
95 skb_dst_set(nskb, dst);
96
97 skb_reserve(nskb, hh_len + dst->header_len);
98
99 skb_put(nskb, sizeof(struct ipv6hdr));
100 skb_reset_network_header(nskb);
101 ip6h = ipv6_hdr(nskb);
102 ip6_flow_hdr(ip6h, tclass, 0);
103 ip6h->hop_limit = ip6_dst_hoplimit(dst);
104 ip6h->nexthdr = IPPROTO_TCP;
105 ip6h->saddr = oip6h->daddr;
106 ip6h->daddr = oip6h->saddr;
107
108 skb_reset_transport_header(nskb);
109 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
110 /* Truncate to length (no data) */
111 tcph->doff = sizeof(struct tcphdr)/4;
112 tcph->source = otcph.dest;
113 tcph->dest = otcph.source;
114
115 if (otcph.ack) {
116 needs_ack = 0;
117 tcph->seq = otcph.ack_seq;
118 tcph->ack_seq = 0;
119 } else {
120 needs_ack = 1;
121 tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
122 + otcplen - (otcph.doff<<2));
123 tcph->seq = 0;
124 }
125
126 /* Reset flags */
127 ((u_int8_t *)tcph)[13] = 0;
128 tcph->rst = 1;
129 tcph->ack = needs_ack;
130 tcph->window = 0;
131 tcph->urg_ptr = 0;
132 tcph->check = 0;
133
134 /* Adjust TCP checksum */
135 tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
136 &ipv6_hdr(nskb)->daddr,
137 sizeof(struct tcphdr), IPPROTO_TCP,
138 csum_partial(tcph,
139 sizeof(struct tcphdr), 0));
140
141 nf_ct_attach(nskb, oldskb);
142
143#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
144 /* If we use ip6_local_out for bridged traffic, the MAC source on
145 * the RST will be ours, instead of the destination's. This confuses
146 * some routers/firewalls, and they drop the packet. So we need to
147 * build the eth header using the original destination's MAC as the
148 * source, and send the RST packet directly.
149 */
150 if (oldskb->nf_bridge) {
151 struct ethhdr *oeth = eth_hdr(oldskb);
152 nskb->dev = oldskb->nf_bridge->physindev;
153 nskb->protocol = htons(ETH_P_IPV6);
154 ip6h->payload_len = htons(sizeof(struct tcphdr));
155 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
156 oeth->h_source, oeth->h_dest, nskb->len) < 0)
157 return;
158 dev_queue_xmit(nskb);
159 } else
160#endif
161 ip6_local_out(nskb);
162}
163EXPORT_SYMBOL_GPL(nf_send_reset6);
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c
index 4e51334ef6b7..556262f40761 100644
--- a/net/ipv6/netfilter/nft_masq_ipv6.c
+++ b/net/ipv6/netfilter/nft_masq_ipv6.c
@@ -32,33 +32,12 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr,
32 data[NFT_REG_VERDICT].verdict = verdict; 32 data[NFT_REG_VERDICT].verdict = verdict;
33} 33}
34 34
35static int nft_masq_ipv6_init(const struct nft_ctx *ctx,
36 const struct nft_expr *expr,
37 const struct nlattr * const tb[])
38{
39 int err;
40
41 err = nft_masq_init(ctx, expr, tb);
42 if (err < 0)
43 return err;
44
45 nf_nat_masquerade_ipv6_register_notifier();
46 return 0;
47}
48
49static void nft_masq_ipv6_destroy(const struct nft_ctx *ctx,
50 const struct nft_expr *expr)
51{
52 nf_nat_masquerade_ipv6_unregister_notifier();
53}
54
55static struct nft_expr_type nft_masq_ipv6_type; 35static struct nft_expr_type nft_masq_ipv6_type;
56static const struct nft_expr_ops nft_masq_ipv6_ops = { 36static const struct nft_expr_ops nft_masq_ipv6_ops = {
57 .type = &nft_masq_ipv6_type, 37 .type = &nft_masq_ipv6_type,
58 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)), 38 .size = NFT_EXPR_SIZE(sizeof(struct nft_masq)),
59 .eval = nft_masq_ipv6_eval, 39 .eval = nft_masq_ipv6_eval,
60 .init = nft_masq_ipv6_init, 40 .init = nft_masq_init,
61 .destroy = nft_masq_ipv6_destroy,
62 .dump = nft_masq_dump, 41 .dump = nft_masq_dump,
63}; 42};
64 43
@@ -73,12 +52,21 @@ static struct nft_expr_type nft_masq_ipv6_type __read_mostly = {
73 52
74static int __init nft_masq_ipv6_module_init(void) 53static int __init nft_masq_ipv6_module_init(void)
75{ 54{
76 return nft_register_expr(&nft_masq_ipv6_type); 55 int ret;
56
57 ret = nft_register_expr(&nft_masq_ipv6_type);
58 if (ret < 0)
59 return ret;
60
61 nf_nat_masquerade_ipv6_register_notifier();
62
63 return ret;
77} 64}
78 65
79static void __exit nft_masq_ipv6_module_exit(void) 66static void __exit nft_masq_ipv6_module_exit(void)
80{ 67{
81 nft_unregister_expr(&nft_masq_ipv6_type); 68 nft_unregister_expr(&nft_masq_ipv6_type);
69 nf_nat_masquerade_ipv6_unregister_notifier();
82} 70}
83 71
84module_init(nft_masq_ipv6_module_init); 72module_init(nft_masq_ipv6_module_init);
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index 03cdb69ac9bf..35dd35873442 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -237,7 +237,7 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
237#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) 237#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
238 238
239 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 239 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
240#ifdef CONFIG_BRIDGE_NETFILTER 240#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
241 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 241 const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
242 242
243 if (!nf_bridge) 243 if (!nf_bridge)
@@ -474,7 +474,7 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
474 ip6_netmask(&e.ip, e.cidr); 474 ip6_netmask(&e.ip, e.cidr);
475 475
476 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 476 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
477#ifdef CONFIG_BRIDGE_NETFILTER 477#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
478 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 478 const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
479 479
480 if (!nf_bridge) 480 if (!nf_bridge)
diff --git a/net/netfilter/nf_log_common.c b/net/netfilter/nf_log_common.c
index eeb8ef4ff1a3..a2233e77cf39 100644
--- a/net/netfilter/nf_log_common.c
+++ b/net/netfilter/nf_log_common.c
@@ -158,7 +158,7 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
158 '0' + loginfo->u.log.level, prefix, 158 '0' + loginfo->u.log.level, prefix,
159 in ? in->name : "", 159 in ? in->name : "",
160 out ? out->name : ""); 160 out ? out->name : "");
161#ifdef CONFIG_BRIDGE_NETFILTER 161#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
162 if (skb->nf_bridge) { 162 if (skb->nf_bridge) {
163 const struct net_device *physindev; 163 const struct net_device *physindev;
164 const struct net_device *physoutdev; 164 const struct net_device *physoutdev;
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 5d24b1fdb593..4c8b68e5fa16 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -52,7 +52,7 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
52 dev_put(entry->indev); 52 dev_put(entry->indev);
53 if (entry->outdev) 53 if (entry->outdev)
54 dev_put(entry->outdev); 54 dev_put(entry->outdev);
55#ifdef CONFIG_BRIDGE_NETFILTER 55#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
56 if (entry->skb->nf_bridge) { 56 if (entry->skb->nf_bridge) {
57 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 57 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
58 58
@@ -77,7 +77,7 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
77 dev_hold(entry->indev); 77 dev_hold(entry->indev);
78 if (entry->outdev) 78 if (entry->outdev)
79 dev_hold(entry->outdev); 79 dev_hold(entry->outdev);
80#ifdef CONFIG_BRIDGE_NETFILTER 80#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
81 if (entry->skb->nf_bridge) { 81 if (entry->skb->nf_bridge) {
82 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 82 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
83 struct net_device *physdev; 83 struct net_device *physdev;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 19e79f0d9ad2..556a0dfa4abc 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4163,6 +4163,7 @@ static void __exit nf_tables_module_exit(void)
4163{ 4163{
4164 unregister_pernet_subsys(&nf_tables_net_ops); 4164 unregister_pernet_subsys(&nf_tables_net_ops);
4165 nfnetlink_subsys_unregister(&nf_tables_subsys); 4165 nfnetlink_subsys_unregister(&nf_tables_subsys);
4166 rcu_barrier();
4166 nf_tables_core_module_exit(); 4167 nf_tables_core_module_exit();
4167 kfree(info); 4168 kfree(info);
4168} 4169}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index a11c5ff2f720..b1e3a0579416 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -36,7 +36,7 @@
36 36
37#include <linux/atomic.h> 37#include <linux/atomic.h>
38 38
39#ifdef CONFIG_BRIDGE_NETFILTER 39#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
40#include "../bridge/br_private.h" 40#include "../bridge/br_private.h"
41#endif 41#endif
42 42
@@ -429,7 +429,7 @@ __build_packet_message(struct nfnl_log_net *log,
429 goto nla_put_failure; 429 goto nla_put_failure;
430 430
431 if (indev) { 431 if (indev) {
432#ifndef CONFIG_BRIDGE_NETFILTER 432#if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
433 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, 433 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
434 htonl(indev->ifindex))) 434 htonl(indev->ifindex)))
435 goto nla_put_failure; 435 goto nla_put_failure;
@@ -460,7 +460,7 @@ __build_packet_message(struct nfnl_log_net *log,
460 } 460 }
461 461
462 if (outdev) { 462 if (outdev) {
463#ifndef CONFIG_BRIDGE_NETFILTER 463#if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
464 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, 464 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
465 htonl(outdev->ifindex))) 465 htonl(outdev->ifindex)))
466 goto nla_put_failure; 466 goto nla_put_failure;
@@ -640,7 +640,7 @@ nfulnl_log_packet(struct net *net,
640 + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) 640 + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
641 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 641 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
642 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 642 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
643#ifdef CONFIG_BRIDGE_NETFILTER 643#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
644 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 644 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
645 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 645 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
646#endif 646#endif
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 108120f216b1..a82077d9f59b 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -36,7 +36,7 @@
36 36
37#include <linux/atomic.h> 37#include <linux/atomic.h>
38 38
39#ifdef CONFIG_BRIDGE_NETFILTER 39#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
40#include "../bridge/br_private.h" 40#include "../bridge/br_private.h"
41#endif 41#endif
42 42
@@ -302,7 +302,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
302 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) 302 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
303 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 303 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
304 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 304 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
305#ifdef CONFIG_BRIDGE_NETFILTER 305#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
306 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 306 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
307 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 307 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
308#endif 308#endif
@@ -380,7 +380,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
380 380
381 indev = entry->indev; 381 indev = entry->indev;
382 if (indev) { 382 if (indev) {
383#ifndef CONFIG_BRIDGE_NETFILTER 383#if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
384 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex))) 384 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex)))
385 goto nla_put_failure; 385 goto nla_put_failure;
386#else 386#else
@@ -410,7 +410,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
410 } 410 }
411 411
412 if (outdev) { 412 if (outdev) {
413#ifndef CONFIG_BRIDGE_NETFILTER 413#if !IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
414 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex))) 414 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex)))
415 goto nla_put_failure; 415 goto nla_put_failure;
416#else 416#else
@@ -569,7 +569,7 @@ nf_queue_entry_dup(struct nf_queue_entry *e)
569 return NULL; 569 return NULL;
570} 570}
571 571
572#ifdef CONFIG_BRIDGE_NETFILTER 572#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
573/* When called from bridge netfilter, skb->data must point to MAC header 573/* When called from bridge netfilter, skb->data must point to MAC header
574 * before calling skb_gso_segment(). Else, original MAC header is lost 574 * before calling skb_gso_segment(). Else, original MAC header is lost
575 * and segmented skbs will be sent to wrong destination. 575 * and segmented skbs will be sent to wrong destination.
@@ -763,7 +763,7 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
763 if (entry->outdev) 763 if (entry->outdev)
764 if (entry->outdev->ifindex == ifindex) 764 if (entry->outdev->ifindex == ifindex)
765 return 1; 765 return 1;
766#ifdef CONFIG_BRIDGE_NETFILTER 766#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
767 if (entry->skb->nf_bridge) { 767 if (entry->skb->nf_bridge) {
768 if (entry->skb->nf_bridge->physindev && 768 if (entry->skb->nf_bridge->physindev &&
769 entry->skb->nf_bridge->physindev->ifindex == ifindex) 769 entry->skb->nf_bridge->physindev->ifindex == ifindex)
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 1840989092ed..7e2683c8a44a 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -101,26 +101,12 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
101 101
102static void target_compat_from_user(struct xt_target *t, void *in, void *out) 102static void target_compat_from_user(struct xt_target *t, void *in, void *out)
103{ 103{
104#ifdef CONFIG_COMPAT 104 int pad;
105 if (t->compat_from_user) {
106 int pad;
107
108 t->compat_from_user(out, in);
109 pad = XT_ALIGN(t->targetsize) - t->targetsize;
110 if (pad > 0)
111 memset(out + t->targetsize, 0, pad);
112 } else
113#endif
114 memcpy(out, in, XT_ALIGN(t->targetsize));
115}
116 105
117static inline int nft_compat_target_offset(struct xt_target *target) 106 memcpy(out, in, t->targetsize);
118{ 107 pad = XT_ALIGN(t->targetsize) - t->targetsize;
119#ifdef CONFIG_COMPAT 108 if (pad > 0)
120 return xt_compat_target_offset(target); 109 memset(out + t->targetsize, 0, pad);
121#else
122 return 0;
123#endif
124} 110}
125 111
126static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = { 112static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = {
@@ -208,34 +194,6 @@ nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
208 module_put(target->me); 194 module_put(target->me);
209} 195}
210 196
211static int
212target_dump_info(struct sk_buff *skb, const struct xt_target *t, const void *in)
213{
214 int ret;
215
216#ifdef CONFIG_COMPAT
217 if (t->compat_to_user) {
218 mm_segment_t old_fs;
219 void *out;
220
221 out = kmalloc(XT_ALIGN(t->targetsize), GFP_ATOMIC);
222 if (out == NULL)
223 return -ENOMEM;
224
225 /* We want to reuse existing compat_to_user */
226 old_fs = get_fs();
227 set_fs(KERNEL_DS);
228 t->compat_to_user(out, in);
229 set_fs(old_fs);
230 ret = nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(t->targetsize), out);
231 kfree(out);
232 } else
233#endif
234 ret = nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(t->targetsize), in);
235
236 return ret;
237}
238
239static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr) 197static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
240{ 198{
241 const struct xt_target *target = expr->ops->data; 199 const struct xt_target *target = expr->ops->data;
@@ -243,7 +201,7 @@ static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
243 201
244 if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) || 202 if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) ||
245 nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) || 203 nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) ||
246 target_dump_info(skb, target, info)) 204 nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(target->targetsize), info))
247 goto nla_put_failure; 205 goto nla_put_failure;
248 206
249 return 0; 207 return 0;
@@ -341,17 +299,12 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
341 299
342static void match_compat_from_user(struct xt_match *m, void *in, void *out) 300static void match_compat_from_user(struct xt_match *m, void *in, void *out)
343{ 301{
344#ifdef CONFIG_COMPAT 302 int pad;
345 if (m->compat_from_user) { 303
346 int pad; 304 memcpy(out, in, m->matchsize);
347 305 pad = XT_ALIGN(m->matchsize) - m->matchsize;
348 m->compat_from_user(out, in); 306 if (pad > 0)
349 pad = XT_ALIGN(m->matchsize) - m->matchsize; 307 memset(out + m->matchsize, 0, pad);
350 if (pad > 0)
351 memset(out + m->matchsize, 0, pad);
352 } else
353#endif
354 memcpy(out, in, XT_ALIGN(m->matchsize));
355} 308}
356 309
357static int 310static int
@@ -404,43 +357,6 @@ nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
404 module_put(match->me); 357 module_put(match->me);
405} 358}
406 359
407static int
408match_dump_info(struct sk_buff *skb, const struct xt_match *m, const void *in)
409{
410 int ret;
411
412#ifdef CONFIG_COMPAT
413 if (m->compat_to_user) {
414 mm_segment_t old_fs;
415 void *out;
416
417 out = kmalloc(XT_ALIGN(m->matchsize), GFP_ATOMIC);
418 if (out == NULL)
419 return -ENOMEM;
420
421 /* We want to reuse existing compat_to_user */
422 old_fs = get_fs();
423 set_fs(KERNEL_DS);
424 m->compat_to_user(out, in);
425 set_fs(old_fs);
426 ret = nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(m->matchsize), out);
427 kfree(out);
428 } else
429#endif
430 ret = nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(m->matchsize), in);
431
432 return ret;
433}
434
435static inline int nft_compat_match_offset(struct xt_match *match)
436{
437#ifdef CONFIG_COMPAT
438 return xt_compat_match_offset(match);
439#else
440 return 0;
441#endif
442}
443
444static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr) 360static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
445{ 361{
446 void *info = nft_expr_priv(expr); 362 void *info = nft_expr_priv(expr);
@@ -448,7 +364,7 @@ static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
448 364
449 if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) || 365 if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
450 nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) || 366 nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) ||
451 match_dump_info(skb, match, info)) 367 nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(match->matchsize), info))
452 goto nla_put_failure; 368 goto nla_put_failure;
453 369
454 return 0; 370 return 0;
@@ -643,8 +559,7 @@ nft_match_select_ops(const struct nft_ctx *ctx,
643 return ERR_PTR(-ENOMEM); 559 return ERR_PTR(-ENOMEM);
644 560
645 nft_match->ops.type = &nft_match_type; 561 nft_match->ops.type = &nft_match_type;
646 nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize) + 562 nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
647 nft_compat_match_offset(match));
648 nft_match->ops.eval = nft_match_eval; 563 nft_match->ops.eval = nft_match_eval;
649 nft_match->ops.init = nft_match_init; 564 nft_match->ops.init = nft_match_init;
650 nft_match->ops.destroy = nft_match_destroy; 565 nft_match->ops.destroy = nft_match_destroy;
@@ -714,8 +629,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
714 return ERR_PTR(-ENOMEM); 629 return ERR_PTR(-ENOMEM);
715 630
716 nft_target->ops.type = &nft_target_type; 631 nft_target->ops.type = &nft_target_type;
717 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize) + 632 nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
718 nft_compat_target_offset(target));
719 nft_target->ops.eval = nft_target_eval; 633 nft_target->ops.eval = nft_target_eval;
720 nft_target->ops.init = nft_target_init; 634 nft_target->ops.init = nft_target_init;
721 nft_target->ops.destroy = nft_target_destroy; 635 nft_target->ops.destroy = nft_target_destroy;
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index f3448c296446..ec8a456092a7 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -17,6 +17,8 @@
17#include <linux/netfilter/nf_tables.h> 17#include <linux/netfilter/nf_tables.h>
18#include <net/netfilter/nf_tables.h> 18#include <net/netfilter/nf_tables.h>
19#include <net/netfilter/nft_reject.h> 19#include <net/netfilter/nft_reject.h>
20#include <linux/icmp.h>
21#include <linux/icmpv6.h>
20 22
21const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { 23const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
22 [NFTA_REJECT_TYPE] = { .type = NLA_U32 }, 24 [NFTA_REJECT_TYPE] = { .type = NLA_U32 },
@@ -70,5 +72,40 @@ nla_put_failure:
70} 72}
71EXPORT_SYMBOL_GPL(nft_reject_dump); 73EXPORT_SYMBOL_GPL(nft_reject_dump);
72 74
75static u8 icmp_code_v4[NFT_REJECT_ICMPX_MAX] = {
76 [NFT_REJECT_ICMPX_NO_ROUTE] = ICMP_NET_UNREACH,
77 [NFT_REJECT_ICMPX_PORT_UNREACH] = ICMP_PORT_UNREACH,
78 [NFT_REJECT_ICMPX_HOST_UNREACH] = ICMP_HOST_UNREACH,
79 [NFT_REJECT_ICMPX_ADMIN_PROHIBITED] = ICMP_PKT_FILTERED,
80};
81
82int nft_reject_icmp_code(u8 code)
83{
84 if (code > NFT_REJECT_ICMPX_MAX)
85 return -EINVAL;
86
87 return icmp_code_v4[code];
88}
89
90EXPORT_SYMBOL_GPL(nft_reject_icmp_code);
91
92
93static u8 icmp_code_v6[NFT_REJECT_ICMPX_MAX] = {
94 [NFT_REJECT_ICMPX_NO_ROUTE] = ICMPV6_NOROUTE,
95 [NFT_REJECT_ICMPX_PORT_UNREACH] = ICMPV6_PORT_UNREACH,
96 [NFT_REJECT_ICMPX_HOST_UNREACH] = ICMPV6_ADDR_UNREACH,
97 [NFT_REJECT_ICMPX_ADMIN_PROHIBITED] = ICMPV6_ADM_PROHIBITED,
98};
99
100int nft_reject_icmpv6_code(u8 code)
101{
102 if (code > NFT_REJECT_ICMPX_MAX)
103 return -EINVAL;
104
105 return icmp_code_v6[code];
106}
107
108EXPORT_SYMBOL_GPL(nft_reject_icmpv6_code);
109
73MODULE_LICENSE("GPL"); 110MODULE_LICENSE("GPL");
74MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 111MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index b718a52a4654..7b5f9d58680a 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -14,17 +14,103 @@
14#include <linux/netfilter/nf_tables.h> 14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h> 15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nft_reject.h> 16#include <net/netfilter/nft_reject.h>
17#include <net/netfilter/ipv4/nf_reject.h>
18#include <net/netfilter/ipv6/nf_reject.h>
17 19
18static void nft_reject_inet_eval(const struct nft_expr *expr, 20static void nft_reject_inet_eval(const struct nft_expr *expr,
19 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_data data[NFT_REG_MAX + 1],
20 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
21{ 23{
24 struct nft_reject *priv = nft_expr_priv(expr);
25 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
26
22 switch (pkt->ops->pf) { 27 switch (pkt->ops->pf) {
23 case NFPROTO_IPV4: 28 case NFPROTO_IPV4:
24 return nft_reject_ipv4_eval(expr, data, pkt); 29 switch (priv->type) {
30 case NFT_REJECT_ICMP_UNREACH:
31 nf_send_unreach(pkt->skb, priv->icmp_code);
32 break;
33 case NFT_REJECT_TCP_RST:
34 nf_send_reset(pkt->skb, pkt->ops->hooknum);
35 break;
36 case NFT_REJECT_ICMPX_UNREACH:
37 nf_send_unreach(pkt->skb,
38 nft_reject_icmp_code(priv->icmp_code));
39 break;
40 }
41 break;
25 case NFPROTO_IPV6: 42 case NFPROTO_IPV6:
26 return nft_reject_ipv6_eval(expr, data, pkt); 43 switch (priv->type) {
44 case NFT_REJECT_ICMP_UNREACH:
45 nf_send_unreach6(net, pkt->skb, priv->icmp_code,
46 pkt->ops->hooknum);
47 break;
48 case NFT_REJECT_TCP_RST:
49 nf_send_reset6(net, pkt->skb, pkt->ops->hooknum);
50 break;
51 case NFT_REJECT_ICMPX_UNREACH:
52 nf_send_unreach6(net, pkt->skb,
53 nft_reject_icmpv6_code(priv->icmp_code),
54 pkt->ops->hooknum);
55 break;
56 }
57 break;
58 }
59 data[NFT_REG_VERDICT].verdict = NF_DROP;
60}
61
62static int nft_reject_inet_init(const struct nft_ctx *ctx,
63 const struct nft_expr *expr,
64 const struct nlattr * const tb[])
65{
66 struct nft_reject *priv = nft_expr_priv(expr);
67 int icmp_code;
68
69 if (tb[NFTA_REJECT_TYPE] == NULL)
70 return -EINVAL;
71
72 priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
73 switch (priv->type) {
74 case NFT_REJECT_ICMP_UNREACH:
75 case NFT_REJECT_ICMPX_UNREACH:
76 if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
77 return -EINVAL;
78
79 icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
80 if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
81 icmp_code > NFT_REJECT_ICMPX_MAX)
82 return -EINVAL;
83
84 priv->icmp_code = icmp_code;
85 break;
86 case NFT_REJECT_TCP_RST:
87 break;
88 default:
89 return -EINVAL;
27 } 90 }
91 return 0;
92}
93
94static int nft_reject_inet_dump(struct sk_buff *skb,
95 const struct nft_expr *expr)
96{
97 const struct nft_reject *priv = nft_expr_priv(expr);
98
99 if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
100 goto nla_put_failure;
101
102 switch (priv->type) {
103 case NFT_REJECT_ICMP_UNREACH:
104 case NFT_REJECT_ICMPX_UNREACH:
105 if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
106 goto nla_put_failure;
107 break;
108 }
109
110 return 0;
111
112nla_put_failure:
113 return -1;
28} 114}
29 115
30static struct nft_expr_type nft_reject_inet_type; 116static struct nft_expr_type nft_reject_inet_type;
@@ -32,8 +118,8 @@ static const struct nft_expr_ops nft_reject_inet_ops = {
32 .type = &nft_reject_inet_type, 118 .type = &nft_reject_inet_type,
33 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), 119 .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
34 .eval = nft_reject_inet_eval, 120 .eval = nft_reject_inet_eval,
35 .init = nft_reject_init, 121 .init = nft_reject_inet_init,
36 .dump = nft_reject_dump, 122 .dump = nft_reject_inet_dump,
37}; 123};
38 124
39static struct nft_expr_type nft_reject_inet_type __read_mostly = { 125static struct nft_expr_type nft_reject_inet_type __read_mostly = {
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index d7ca16b8b8df..f440f57a452f 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -13,6 +13,7 @@
13#include <linux/netfilter_bridge.h> 13#include <linux/netfilter_bridge.h>
14#include <linux/netfilter/xt_physdev.h> 14#include <linux/netfilter/xt_physdev.h>
15#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/x_tables.h>
16#include <net/netfilter/br_netfilter.h>
16 17
17MODULE_LICENSE("GPL"); 18MODULE_LICENSE("GPL");
18MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 19MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
@@ -87,6 +88,8 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
87{ 88{
88 const struct xt_physdev_info *info = par->matchinfo; 89 const struct xt_physdev_info *info = par->matchinfo;
89 90
91 br_netfilter_enable();
92
90 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 93 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
91 info->bitmask & ~XT_PHYSDEV_OP_MASK) 94 info->bitmask & ~XT_PHYSDEV_OP_MASK)
92 return -EINVAL; 95 return -EINVAL;