aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-09 14:46:04 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-09 14:46:04 -0400
commitca69d7102fde3e22b09536867ba14ace84ea80e1 (patch)
tree6cfba19b3885c0ce11df838cdda53cb556e2c46f /net
parent3ab1a30fbded99936956442d8cf8f379064e4a26 (diff)
parentaadd51aa71f8d013c818a312bb2a0c5714830dbc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for your net-next tree. They are: * nf_tables set timeout infrastructure from Patrick Mchardy. 1) Add support for set timeout support. 2) Add support for set element timeouts using the new set extension infrastructure. 4) Add garbage collection helper functions to get rid of stale elements. Elements are accumulated in a batch that are asynchronously released via RCU when the batch is full. 5) Add garbage collection synchronization helpers. This introduces a new element busy bit to address concurrent access from the netlink API and the garbage collector. 5) Add timeout support for the nft_hash set implementation. The garbage collector peridically checks for stale elements from the workqueue. * iptables/nftables cgroup fixes: 6) Ignore non full-socket objects from the input path, otherwise cgroup match may crash, from Daniel Borkmann. 7) Fix cgroup in nf_tables. 8) Save some cycles from xt_socket by skipping packet header parsing when skb->sk is already set because of early demux. Also from Daniel. * br_netfilter updates from Florian Westphal. 9) Save frag_max_size and restore it from the forward path too. 10) Use a per-cpu area to restore the original source MAC address when traffic is DNAT'ed. 11) Add helper functions to access physical devices. 12) Use these new physdev helper function from xt_physdev. 13) Add another nf_bridge_info_get() helper function to fetch the br_netfilter state information. 14) Annotate original layer 2 protocol number in nf_bridge info, instead of using kludgy flags. 15) Also annotate the pkttype mangling when the packet travels back and forth from the IP to the bridge layer, instead of using a flag. * More nf_tables set enhancement from Patrick: 16) Fix possible usage of set variant that doesn't support timeouts. 17) Avoid spurious "set is full" errors from Netlink API when there are pending stale elements scheduled to be released. 18) Restrict loop checks to set maps. 19) Add support for dynamic set updates from the packet path. 20) Add support to store optional user data (eg. comments) per set element. BTW, I have also pulled net-next into nf-next to anticipate the conflict resolution between your okfn() signature changes and Florian's br_netfilter updates. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c144
-rw-r--r--net/ipv4/netfilter/nf_reject_ipv4.c4
-rw-r--r--net/ipv6/netfilter/nf_reject_ipv6.c4
-rw-r--r--net/netfilter/Makefile2
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c32
-rw-r--r--net/netfilter/nf_log_common.c5
-rw-r--r--net/netfilter/nf_queue.c18
-rw-r--r--net/netfilter/nf_tables_api.c186
-rw-r--r--net/netfilter/nf_tables_core.c7
-rw-r--r--net/netfilter/nfnetlink_log.c17
-rw-r--r--net/netfilter/nfnetlink_queue_core.c28
-rw-r--r--net/netfilter/nft_dynset.c218
-rw-r--r--net/netfilter/nft_hash.c117
-rw-r--r--net/netfilter/nft_lookup.c2
-rw-r--r--net/netfilter/nft_meta.c5
-rw-r--r--net/netfilter/xt_cgroup.c2
-rw-r--r--net/netfilter/xt_physdev.c34
-rw-r--r--net/netfilter/xt_socket.c95
18 files changed, 747 insertions, 173 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index acd31c9f2116..ab55e2472beb 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -111,6 +111,24 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
111 pppoe_proto(skb) == htons(PPP_IPV6) && \ 111 pppoe_proto(skb) == htons(PPP_IPV6) && \
112 brnf_filter_pppoe_tagged) 112 brnf_filter_pppoe_tagged)
113 113
114/* largest possible L2 header, see br_nf_dev_queue_xmit() */
115#define NF_BRIDGE_MAX_MAC_HEADER_LENGTH (PPPOE_SES_HLEN + ETH_HLEN)
116
117#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
118struct brnf_frag_data {
119 char mac[NF_BRIDGE_MAX_MAC_HEADER_LENGTH];
120 u8 encap_size;
121 u8 size;
122};
123
124static DEFINE_PER_CPU(struct brnf_frag_data, brnf_frag_data_storage);
125#endif
126
127static struct nf_bridge_info *nf_bridge_info_get(const struct sk_buff *skb)
128{
129 return skb->nf_bridge;
130}
131
114static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) 132static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
115{ 133{
116 struct net_bridge_port *port; 134 struct net_bridge_port *port;
@@ -189,14 +207,6 @@ static inline void nf_bridge_pull_encap_header_rcsum(struct sk_buff *skb)
189 skb->network_header += len; 207 skb->network_header += len;
190} 208}
191 209
192static inline void nf_bridge_save_header(struct sk_buff *skb)
193{
194 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
195
196 skb_copy_from_linear_data_offset(skb, -header_size,
197 skb->nf_bridge->data, header_size);
198}
199
200/* When handing a packet over to the IP layer 210/* When handing a packet over to the IP layer
201 * check whether we have a skb that is in the 211 * check whether we have a skb that is in the
202 * expected format 212 * expected format
@@ -252,10 +262,16 @@ drop:
252 262
253static void nf_bridge_update_protocol(struct sk_buff *skb) 263static void nf_bridge_update_protocol(struct sk_buff *skb)
254{ 264{
255 if (skb->nf_bridge->mask & BRNF_8021Q) 265 switch (skb->nf_bridge->orig_proto) {
266 case BRNF_PROTO_8021Q:
256 skb->protocol = htons(ETH_P_8021Q); 267 skb->protocol = htons(ETH_P_8021Q);
257 else if (skb->nf_bridge->mask & BRNF_PPPoE) 268 break;
269 case BRNF_PROTO_PPPOE:
258 skb->protocol = htons(ETH_P_PPP_SES); 270 skb->protocol = htons(ETH_P_PPP_SES);
271 break;
272 case BRNF_PROTO_UNCHANGED:
273 break;
274 }
259} 275}
260 276
261/* PF_BRIDGE/PRE_ROUTING *********************************************/ 277/* PF_BRIDGE/PRE_ROUTING *********************************************/
@@ -263,12 +279,12 @@ static void nf_bridge_update_protocol(struct sk_buff *skb)
263 * bridge PRE_ROUTING hook. */ 279 * bridge PRE_ROUTING hook. */
264static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb) 280static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
265{ 281{
266 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 282 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
267 struct rtable *rt; 283 struct rtable *rt;
268 284
269 if (nf_bridge->mask & BRNF_PKT_TYPE) { 285 if (nf_bridge->pkt_otherhost) {
270 skb->pkt_type = PACKET_OTHERHOST; 286 skb->pkt_type = PACKET_OTHERHOST;
271 nf_bridge->mask ^= BRNF_PKT_TYPE; 287 nf_bridge->pkt_otherhost = false;
272 } 288 }
273 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; 289 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
274 290
@@ -296,7 +312,6 @@ static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
296 */ 312 */
297static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb) 313static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
298{ 314{
299 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
300 struct neighbour *neigh; 315 struct neighbour *neigh;
301 struct dst_entry *dst; 316 struct dst_entry *dst;
302 317
@@ -306,6 +321,7 @@ static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
306 dst = skb_dst(skb); 321 dst = skb_dst(skb);
307 neigh = dst_neigh_lookup_skb(dst, skb); 322 neigh = dst_neigh_lookup_skb(dst, skb);
308 if (neigh) { 323 if (neigh) {
324 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
309 int ret; 325 int ret;
310 326
311 if (neigh->hh.hh_len) { 327 if (neigh->hh.hh_len) {
@@ -319,7 +335,7 @@ static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
319 */ 335 */
320 skb_copy_from_linear_data_offset(skb, 336 skb_copy_from_linear_data_offset(skb,
321 -(ETH_HLEN-ETH_ALEN), 337 -(ETH_HLEN-ETH_ALEN),
322 skb->nf_bridge->data, 338 nf_bridge->neigh_header,
323 ETH_HLEN-ETH_ALEN); 339 ETH_HLEN-ETH_ALEN);
324 /* tell br_dev_xmit to continue with forwarding */ 340 /* tell br_dev_xmit to continue with forwarding */
325 nf_bridge->mask |= BRNF_BRIDGED_DNAT; 341 nf_bridge->mask |= BRNF_BRIDGED_DNAT;
@@ -392,7 +408,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
392{ 408{
393 struct net_device *dev = skb->dev; 409 struct net_device *dev = skb->dev;
394 struct iphdr *iph = ip_hdr(skb); 410 struct iphdr *iph = ip_hdr(skb);
395 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 411 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
396 struct rtable *rt; 412 struct rtable *rt;
397 int err; 413 int err;
398 int frag_max_size; 414 int frag_max_size;
@@ -400,9 +416,9 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
400 frag_max_size = IPCB(skb)->frag_max_size; 416 frag_max_size = IPCB(skb)->frag_max_size;
401 BR_INPUT_SKB_CB(skb)->frag_max_size = frag_max_size; 417 BR_INPUT_SKB_CB(skb)->frag_max_size = frag_max_size;
402 418
403 if (nf_bridge->mask & BRNF_PKT_TYPE) { 419 if (nf_bridge->pkt_otherhost) {
404 skb->pkt_type = PACKET_OTHERHOST; 420 skb->pkt_type = PACKET_OTHERHOST;
405 nf_bridge->mask ^= BRNF_PKT_TYPE; 421 nf_bridge->pkt_otherhost = false;
406 } 422 }
407 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; 423 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
408 if (dnat_took_place(skb)) { 424 if (dnat_took_place(skb)) {
@@ -485,20 +501,21 @@ static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct
485/* Some common code for IPv4/IPv6 */ 501/* Some common code for IPv4/IPv6 */
486static struct net_device *setup_pre_routing(struct sk_buff *skb) 502static struct net_device *setup_pre_routing(struct sk_buff *skb)
487{ 503{
488 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 504 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
489 505
490 if (skb->pkt_type == PACKET_OTHERHOST) { 506 if (skb->pkt_type == PACKET_OTHERHOST) {
491 skb->pkt_type = PACKET_HOST; 507 skb->pkt_type = PACKET_HOST;
492 nf_bridge->mask |= BRNF_PKT_TYPE; 508 nf_bridge->pkt_otherhost = true;
493 } 509 }
494 510
495 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; 511 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
496 nf_bridge->physindev = skb->dev; 512 nf_bridge->physindev = skb->dev;
497 skb->dev = brnf_get_logical_dev(skb, skb->dev); 513 skb->dev = brnf_get_logical_dev(skb, skb->dev);
514
498 if (skb->protocol == htons(ETH_P_8021Q)) 515 if (skb->protocol == htons(ETH_P_8021Q))
499 nf_bridge->mask |= BRNF_8021Q; 516 nf_bridge->orig_proto = BRNF_PROTO_8021Q;
500 else if (skb->protocol == htons(ETH_P_PPP_SES)) 517 else if (skb->protocol == htons(ETH_P_PPP_SES))
501 nf_bridge->mask |= BRNF_PPPoE; 518 nf_bridge->orig_proto = BRNF_PROTO_PPPOE;
502 519
503 /* Must drop socket now because of tproxy. */ 520 /* Must drop socket now because of tproxy. */
504 skb_orphan(skb); 521 skb_orphan(skb);
@@ -680,14 +697,21 @@ static unsigned int br_nf_local_in(const struct nf_hook_ops *ops,
680/* PF_BRIDGE/FORWARD *************************************************/ 697/* PF_BRIDGE/FORWARD *************************************************/
681static int br_nf_forward_finish(struct sock *sk, struct sk_buff *skb) 698static int br_nf_forward_finish(struct sock *sk, struct sk_buff *skb)
682{ 699{
683 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 700 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
684 struct net_device *in; 701 struct net_device *in;
685 702
686 if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) { 703 if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {
704 int frag_max_size;
705
706 if (skb->protocol == htons(ETH_P_IP)) {
707 frag_max_size = IPCB(skb)->frag_max_size;
708 BR_INPUT_SKB_CB(skb)->frag_max_size = frag_max_size;
709 }
710
687 in = nf_bridge->physindev; 711 in = nf_bridge->physindev;
688 if (nf_bridge->mask & BRNF_PKT_TYPE) { 712 if (nf_bridge->pkt_otherhost) {
689 skb->pkt_type = PACKET_OTHERHOST; 713 skb->pkt_type = PACKET_OTHERHOST;
690 nf_bridge->mask ^= BRNF_PKT_TYPE; 714 nf_bridge->pkt_otherhost = false;
691 } 715 }
692 nf_bridge_update_protocol(skb); 716 nf_bridge_update_protocol(skb);
693 } else { 717 } else {
@@ -722,6 +746,10 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
722 if (!nf_bridge_unshare(skb)) 746 if (!nf_bridge_unshare(skb))
723 return NF_DROP; 747 return NF_DROP;
724 748
749 nf_bridge = nf_bridge_info_get(skb);
750 if (!nf_bridge)
751 return NF_DROP;
752
725 parent = bridge_parent(state->out); 753 parent = bridge_parent(state->out);
726 if (!parent) 754 if (!parent)
727 return NF_DROP; 755 return NF_DROP;
@@ -735,14 +763,19 @@ static unsigned int br_nf_forward_ip(const struct nf_hook_ops *ops,
735 763
736 nf_bridge_pull_encap_header(skb); 764 nf_bridge_pull_encap_header(skb);
737 765
738 nf_bridge = skb->nf_bridge;
739 if (skb->pkt_type == PACKET_OTHERHOST) { 766 if (skb->pkt_type == PACKET_OTHERHOST) {
740 skb->pkt_type = PACKET_HOST; 767 skb->pkt_type = PACKET_HOST;
741 nf_bridge->mask |= BRNF_PKT_TYPE; 768 nf_bridge->pkt_otherhost = true;
742 } 769 }
743 770
744 if (pf == NFPROTO_IPV4 && br_parse_ip_options(skb)) 771 if (pf == NFPROTO_IPV4) {
745 return NF_DROP; 772 int frag_max = BR_INPUT_SKB_CB(skb)->frag_max_size;
773
774 if (br_parse_ip_options(skb))
775 return NF_DROP;
776
777 IPCB(skb)->frag_max_size = frag_max;
778 }
746 779
747 nf_bridge->physoutdev = skb->dev; 780 nf_bridge->physoutdev = skb->dev;
748 if (pf == NFPROTO_IPV4) 781 if (pf == NFPROTO_IPV4)
@@ -792,30 +825,22 @@ static unsigned int br_nf_forward_arp(const struct nf_hook_ops *ops,
792} 825}
793 826
794#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) 827#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
795static bool nf_bridge_copy_header(struct sk_buff *skb) 828static int br_nf_push_frag_xmit(struct sock *sk, struct sk_buff *skb)
796{ 829{
830 struct brnf_frag_data *data;
797 int err; 831 int err;
798 unsigned int header_size;
799 832
800 nf_bridge_update_protocol(skb); 833 data = this_cpu_ptr(&brnf_frag_data_storage);
801 header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); 834 err = skb_cow_head(skb, data->size);
802 err = skb_cow_head(skb, header_size);
803 if (err)
804 return false;
805
806 skb_copy_to_linear_data_offset(skb, -header_size,
807 skb->nf_bridge->data, header_size);
808 __skb_push(skb, nf_bridge_encap_header_len(skb));
809 return true;
810}
811 835
812static int br_nf_push_frag_xmit(struct sock *sk, struct sk_buff *skb) 836 if (err) {
813{
814 if (!nf_bridge_copy_header(skb)) {
815 kfree_skb(skb); 837 kfree_skb(skb);
816 return 0; 838 return 0;
817 } 839 }
818 840
841 skb_copy_to_linear_data_offset(skb, -data->size, data->mac, data->size);
842 __skb_push(skb, data->encap_size);
843
819 return br_dev_queue_push_xmit(sk, skb); 844 return br_dev_queue_push_xmit(sk, skb);
820} 845}
821 846
@@ -833,14 +858,27 @@ static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb)
833 * boundaries by preserving frag_list rather than refragmenting. 858 * boundaries by preserving frag_list rather than refragmenting.
834 */ 859 */
835 if (skb->len + mtu_reserved > skb->dev->mtu) { 860 if (skb->len + mtu_reserved > skb->dev->mtu) {
861 struct brnf_frag_data *data;
862
836 frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; 863 frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
837 if (br_parse_ip_options(skb)) 864 if (br_parse_ip_options(skb))
838 /* Drop invalid packet */ 865 /* Drop invalid packet */
839 return NF_DROP; 866 return NF_DROP;
840 IPCB(skb)->frag_max_size = frag_max_size; 867 IPCB(skb)->frag_max_size = frag_max_size;
868
869 nf_bridge_update_protocol(skb);
870
871 data = this_cpu_ptr(&brnf_frag_data_storage);
872 data->encap_size = nf_bridge_encap_header_len(skb);
873 data->size = ETH_HLEN + data->encap_size;
874
875 skb_copy_from_linear_data_offset(skb, -data->size, data->mac,
876 data->size);
877
841 ret = ip_fragment(sk, skb, br_nf_push_frag_xmit); 878 ret = ip_fragment(sk, skb, br_nf_push_frag_xmit);
842 } else 879 } else {
843 ret = br_dev_queue_push_xmit(sk, skb); 880 ret = br_dev_queue_push_xmit(sk, skb);
881 }
844 882
845 return ret; 883 return ret;
846} 884}
@@ -856,7 +894,7 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
856 struct sk_buff *skb, 894 struct sk_buff *skb,
857 const struct nf_hook_state *state) 895 const struct nf_hook_state *state)
858{ 896{
859 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 897 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
860 struct net_device *realoutdev = bridge_parent(skb->dev); 898 struct net_device *realoutdev = bridge_parent(skb->dev);
861 u_int8_t pf; 899 u_int8_t pf;
862 900
@@ -882,11 +920,10 @@ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops,
882 * about the value of skb->pkt_type. */ 920 * about the value of skb->pkt_type. */
883 if (skb->pkt_type == PACKET_OTHERHOST) { 921 if (skb->pkt_type == PACKET_OTHERHOST) {
884 skb->pkt_type = PACKET_HOST; 922 skb->pkt_type = PACKET_HOST;
885 nf_bridge->mask |= BRNF_PKT_TYPE; 923 nf_bridge->pkt_otherhost = true;
886 } 924 }
887 925
888 nf_bridge_pull_encap_header(skb); 926 nf_bridge_pull_encap_header(skb);
889 nf_bridge_save_header(skb);
890 if (pf == NFPROTO_IPV4) 927 if (pf == NFPROTO_IPV4)
891 skb->protocol = htons(ETH_P_IP); 928 skb->protocol = htons(ETH_P_IP);
892 else 929 else
@@ -925,13 +962,16 @@ static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops,
925 */ 962 */
926static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) 963static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
927{ 964{
928 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 965 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
929 966
930 skb_pull(skb, ETH_HLEN); 967 skb_pull(skb, ETH_HLEN);
931 nf_bridge->mask &= ~BRNF_BRIDGED_DNAT; 968 nf_bridge->mask &= ~BRNF_BRIDGED_DNAT;
932 969
933 skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), 970 BUILD_BUG_ON(sizeof(nf_bridge->neigh_header) != (ETH_HLEN - ETH_ALEN));
934 skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); 971
972 skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN),
973 nf_bridge->neigh_header,
974 ETH_HLEN - ETH_ALEN);
935 skb->dev = nf_bridge->physindev; 975 skb->dev = nf_bridge->physindev;
936 br_handle_frame_finish(NULL, skb); 976 br_handle_frame_finish(NULL, skb);
937} 977}
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
index c5b794da51a9..3262e41ff76f 100644
--- a/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -13,6 +13,7 @@
13#include <net/dst.h> 13#include <net/dst.h>
14#include <net/netfilter/ipv4/nf_reject.h> 14#include <net/netfilter/ipv4/nf_reject.h>
15#include <linux/netfilter_ipv4.h> 15#include <linux/netfilter_ipv4.h>
16#include <linux/netfilter_bridge.h>
16#include <net/netfilter/ipv4/nf_reject.h> 17#include <net/netfilter/ipv4/nf_reject.h>
17 18
18const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb, 19const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
@@ -146,7 +147,8 @@ void nf_send_reset(struct sk_buff *oldskb, int hook)
146 */ 147 */
147 if (oldskb->nf_bridge) { 148 if (oldskb->nf_bridge) {
148 struct ethhdr *oeth = eth_hdr(oldskb); 149 struct ethhdr *oeth = eth_hdr(oldskb);
149 nskb->dev = oldskb->nf_bridge->physindev; 150
151 nskb->dev = nf_bridge_get_physindev(oldskb);
150 niph->tot_len = htons(nskb->len); 152 niph->tot_len = htons(nskb->len);
151 ip_send_check(niph); 153 ip_send_check(niph);
152 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol), 154 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
index 3afdce03d94e..94b4c6dfb400 100644
--- a/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -13,6 +13,7 @@
13#include <net/ip6_checksum.h> 13#include <net/ip6_checksum.h>
14#include <net/netfilter/ipv6/nf_reject.h> 14#include <net/netfilter/ipv6/nf_reject.h>
15#include <linux/netfilter_ipv6.h> 15#include <linux/netfilter_ipv6.h>
16#include <linux/netfilter_bridge.h>
16#include <net/netfilter/ipv6/nf_reject.h> 17#include <net/netfilter/ipv6/nf_reject.h>
17 18
18const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb, 19const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
@@ -195,7 +196,8 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
195 */ 196 */
196 if (oldskb->nf_bridge) { 197 if (oldskb->nf_bridge) {
197 struct ethhdr *oeth = eth_hdr(oldskb); 198 struct ethhdr *oeth = eth_hdr(oldskb);
198 nskb->dev = oldskb->nf_bridge->physindev; 199
200 nskb->dev = nf_bridge_get_physindev(oldskb);
199 nskb->protocol = htons(ETH_P_IPV6); 201 nskb->protocol = htons(ETH_P_IPV6);
200 ip6h->payload_len = htons(sizeof(struct tcphdr)); 202 ip6h->payload_len = htons(sizeof(struct tcphdr));
201 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol), 203 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 89f73a9e9874..a87d8b8ec730 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -70,7 +70,7 @@ obj-$(CONFIG_NETFILTER_SYNPROXY) += nf_synproxy_core.o
70 70
71# nf_tables 71# nf_tables
72nf_tables-objs += nf_tables_core.o nf_tables_api.o 72nf_tables-objs += nf_tables_core.o nf_tables_api.o
73nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o 73nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o nft_dynset.o
74nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o 74nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o
75 75
76obj-$(CONFIG_NF_TABLES) += nf_tables.o 76obj-$(CONFIG_NF_TABLES) += nf_tables.o
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index 758b002130d9..380ef5148ea1 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -19,6 +19,7 @@
19#include <net/netlink.h> 19#include <net/netlink.h>
20 20
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter_bridge.h>
22#include <linux/netfilter/ipset/pfxlen.h> 23#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 24#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
@@ -211,6 +212,22 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next,
211#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) 212#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
212#include "ip_set_hash_gen.h" 213#include "ip_set_hash_gen.h"
213 214
215#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
216static const char *get_physindev_name(const struct sk_buff *skb)
217{
218 struct net_device *dev = nf_bridge_get_physindev(skb);
219
220 return dev ? dev->name : NULL;
221}
222
223static const char *get_phyoutdev_name(const struct sk_buff *skb)
224{
225 struct net_device *dev = nf_bridge_get_physoutdev(skb);
226
227 return dev ? dev->name : NULL;
228}
229#endif
230
214static int 231static int
215hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, 232hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
216 const struct xt_action_param *par, 233 const struct xt_action_param *par,
@@ -234,16 +251,15 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
234 e.ip &= ip_set_netmask(e.cidr); 251 e.ip &= ip_set_netmask(e.cidr);
235 252
236#define IFACE(dir) (par->dir ? par->dir->name : NULL) 253#define IFACE(dir) (par->dir ? par->dir->name : NULL)
237#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL)
238#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) 254#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
239 255
240 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 256 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
241#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 257#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
242 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 258 e.iface = SRCDIR ? get_physindev_name(skb) :
259 get_phyoutdev_name(skb);
243 260
244 if (!nf_bridge) 261 if (!e.iface)
245 return -EINVAL; 262 return -EINVAL;
246 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
247 e.physdev = 1; 263 e.physdev = 1;
248#else 264#else
249 e.iface = NULL; 265 e.iface = NULL;
@@ -476,11 +492,11 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
476 492
477 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 493 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
478#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 494#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
479 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 495 e.iface = SRCDIR ? get_physindev_name(skb) :
480 496 get_phyoutdev_name(skb);
481 if (!nf_bridge) 497 if (!e.iface)
482 return -EINVAL; 498 return -EINVAL;
483 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 499
484 e.physdev = 1; 500 e.physdev = 1;
485#else 501#else
486 e.iface = NULL; 502 e.iface = NULL;
diff --git a/net/netfilter/nf_log_common.c b/net/netfilter/nf_log_common.c
index 2631876ac55b..a5aa5967b8e1 100644
--- a/net/netfilter/nf_log_common.c
+++ b/net/netfilter/nf_log_common.c
@@ -17,6 +17,7 @@
17#include <net/route.h> 17#include <net/route.h>
18 18
19#include <linux/netfilter.h> 19#include <linux/netfilter.h>
20#include <linux/netfilter_bridge.h>
20#include <linux/netfilter/xt_LOG.h> 21#include <linux/netfilter/xt_LOG.h>
21#include <net/netfilter/nf_log.h> 22#include <net/netfilter/nf_log.h>
22 23
@@ -163,10 +164,10 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
163 const struct net_device *physindev; 164 const struct net_device *physindev;
164 const struct net_device *physoutdev; 165 const struct net_device *physoutdev;
165 166
166 physindev = skb->nf_bridge->physindev; 167 physindev = nf_bridge_get_physindev(skb);
167 if (physindev && in != physindev) 168 if (physindev && in != physindev)
168 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name); 169 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
169 physoutdev = skb->nf_bridge->physoutdev; 170 physoutdev = nf_bridge_get_physoutdev(skb);
170 if (physoutdev && out != physoutdev) 171 if (physoutdev && out != physoutdev)
171 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name); 172 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
172 } 173 }
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 3f3ac57b2998..2e88032cd5ad 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -10,6 +10,7 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/skbuff.h> 11#include <linux/skbuff.h>
12#include <linux/netfilter.h> 12#include <linux/netfilter.h>
13#include <linux/netfilter_bridge.h>
13#include <linux/seq_file.h> 14#include <linux/seq_file.h>
14#include <linux/rcupdate.h> 15#include <linux/rcupdate.h>
15#include <net/protocol.h> 16#include <net/protocol.h>
@@ -58,12 +59,14 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
58 sock_put(state->sk); 59 sock_put(state->sk);
59#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 60#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
60 if (entry->skb->nf_bridge) { 61 if (entry->skb->nf_bridge) {
61 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 62 struct net_device *physdev;
62 63
63 if (nf_bridge->physindev) 64 physdev = nf_bridge_get_physindev(entry->skb);
64 dev_put(nf_bridge->physindev); 65 if (physdev)
65 if (nf_bridge->physoutdev) 66 dev_put(physdev);
66 dev_put(nf_bridge->physoutdev); 67 physdev = nf_bridge_get_physoutdev(entry->skb);
68 if (physdev)
69 dev_put(physdev);
67 } 70 }
68#endif 71#endif
69 /* Drop reference to owner of hook which queued us. */ 72 /* Drop reference to owner of hook which queued us. */
@@ -87,13 +90,12 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
87 sock_hold(state->sk); 90 sock_hold(state->sk);
88#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 91#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
89 if (entry->skb->nf_bridge) { 92 if (entry->skb->nf_bridge) {
90 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
91 struct net_device *physdev; 93 struct net_device *physdev;
92 94
93 physdev = nf_bridge->physindev; 95 physdev = nf_bridge_get_physindev(entry->skb);
94 if (physdev) 96 if (physdev)
95 dev_hold(physdev); 97 dev_hold(physdev);
96 physdev = nf_bridge->physoutdev; 98 physdev = nf_bridge_get_physoutdev(entry->skb);
97 if (physdev) 99 if (physdev)
98 dev_hold(physdev); 100 dev_hold(physdev);
99 } 101 }
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 5604c2df05d1..0b96fa0d64b2 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2159,7 +2159,7 @@ nft_select_set_ops(const struct nlattr * const nla[],
2159 features = 0; 2159 features = 0;
2160 if (nla[NFTA_SET_FLAGS] != NULL) { 2160 if (nla[NFTA_SET_FLAGS] != NULL) {
2161 features = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS])); 2161 features = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2162 features &= NFT_SET_INTERVAL | NFT_SET_MAP; 2162 features &= NFT_SET_INTERVAL | NFT_SET_MAP | NFT_SET_TIMEOUT;
2163 } 2163 }
2164 2164
2165 bops = NULL; 2165 bops = NULL;
@@ -2216,6 +2216,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
2216 [NFTA_SET_POLICY] = { .type = NLA_U32 }, 2216 [NFTA_SET_POLICY] = { .type = NLA_U32 },
2217 [NFTA_SET_DESC] = { .type = NLA_NESTED }, 2217 [NFTA_SET_DESC] = { .type = NLA_NESTED },
2218 [NFTA_SET_ID] = { .type = NLA_U32 }, 2218 [NFTA_SET_ID] = { .type = NLA_U32 },
2219 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2220 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
2219}; 2221};
2220 2222
2221static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { 2223static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2366,6 +2368,13 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2366 goto nla_put_failure; 2368 goto nla_put_failure;
2367 } 2369 }
2368 2370
2371 if (set->timeout &&
2372 nla_put_be64(skb, NFTA_SET_TIMEOUT, cpu_to_be64(set->timeout)))
2373 goto nla_put_failure;
2374 if (set->gc_int &&
2375 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
2376 goto nla_put_failure;
2377
2369 if (set->policy != NFT_SET_POL_PERFORMANCE) { 2378 if (set->policy != NFT_SET_POL_PERFORMANCE) {
2370 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy))) 2379 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
2371 goto nla_put_failure; 2380 goto nla_put_failure;
@@ -2578,7 +2587,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2578 char name[IFNAMSIZ]; 2587 char name[IFNAMSIZ];
2579 unsigned int size; 2588 unsigned int size;
2580 bool create; 2589 bool create;
2581 u32 ktype, dtype, flags, policy; 2590 u64 timeout;
2591 u32 ktype, dtype, flags, policy, gc_int;
2582 struct nft_set_desc desc; 2592 struct nft_set_desc desc;
2583 int err; 2593 int err;
2584 2594
@@ -2605,7 +2615,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2605 if (nla[NFTA_SET_FLAGS] != NULL) { 2615 if (nla[NFTA_SET_FLAGS] != NULL) {
2606 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS])); 2616 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2607 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT | 2617 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2608 NFT_SET_INTERVAL | NFT_SET_MAP)) 2618 NFT_SET_INTERVAL | NFT_SET_MAP |
2619 NFT_SET_TIMEOUT))
2609 return -EINVAL; 2620 return -EINVAL;
2610 } 2621 }
2611 2622
@@ -2631,6 +2642,19 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2631 } else if (flags & NFT_SET_MAP) 2642 } else if (flags & NFT_SET_MAP)
2632 return -EINVAL; 2643 return -EINVAL;
2633 2644
2645 timeout = 0;
2646 if (nla[NFTA_SET_TIMEOUT] != NULL) {
2647 if (!(flags & NFT_SET_TIMEOUT))
2648 return -EINVAL;
2649 timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_TIMEOUT]));
2650 }
2651 gc_int = 0;
2652 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
2653 if (!(flags & NFT_SET_TIMEOUT))
2654 return -EINVAL;
2655 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
2656 }
2657
2634 policy = NFT_SET_POL_PERFORMANCE; 2658 policy = NFT_SET_POL_PERFORMANCE;
2635 if (nla[NFTA_SET_POLICY] != NULL) 2659 if (nla[NFTA_SET_POLICY] != NULL)
2636 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY])); 2660 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
@@ -2699,6 +2723,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2699 set->flags = flags; 2723 set->flags = flags;
2700 set->size = desc.size; 2724 set->size = desc.size;
2701 set->policy = policy; 2725 set->policy = policy;
2726 set->timeout = timeout;
2727 set->gc_int = gc_int;
2702 2728
2703 err = ops->init(set, &desc, nla); 2729 err = ops->init(set, &desc, nla);
2704 if (err < 0) 2730 if (err < 0)
@@ -2785,12 +2811,13 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
2785 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS) 2811 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
2786 return -EBUSY; 2812 return -EBUSY;
2787 2813
2788 if (set->flags & NFT_SET_MAP) { 2814 if (binding->flags & NFT_SET_MAP) {
2789 /* If the set is already bound to the same chain all 2815 /* If the set is already bound to the same chain all
2790 * jumps are already validated for that chain. 2816 * jumps are already validated for that chain.
2791 */ 2817 */
2792 list_for_each_entry(i, &set->bindings, list) { 2818 list_for_each_entry(i, &set->bindings, list) {
2793 if (i->chain == binding->chain) 2819 if (binding->flags & NFT_SET_MAP &&
2820 i->chain == binding->chain)
2794 goto bind; 2821 goto bind;
2795 } 2822 }
2796 2823
@@ -2837,6 +2864,18 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
2837 .len = sizeof(u8), 2864 .len = sizeof(u8),
2838 .align = __alignof__(u8), 2865 .align = __alignof__(u8),
2839 }, 2866 },
2867 [NFT_SET_EXT_TIMEOUT] = {
2868 .len = sizeof(u64),
2869 .align = __alignof__(u64),
2870 },
2871 [NFT_SET_EXT_EXPIRATION] = {
2872 .len = sizeof(unsigned long),
2873 .align = __alignof__(unsigned long),
2874 },
2875 [NFT_SET_EXT_USERDATA] = {
2876 .len = sizeof(struct nft_userdata),
2877 .align = __alignof__(struct nft_userdata),
2878 },
2840}; 2879};
2841EXPORT_SYMBOL_GPL(nft_set_ext_types); 2880EXPORT_SYMBOL_GPL(nft_set_ext_types);
2842 2881
@@ -2848,6 +2887,9 @@ static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
2848 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED }, 2887 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
2849 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED }, 2888 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
2850 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 }, 2889 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
2890 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
2891 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
2892 .len = NFT_USERDATA_MAXLEN },
2851}; 2893};
2852 2894
2853static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = { 2895static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
@@ -2909,6 +2951,34 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
2909 htonl(*nft_set_ext_flags(ext)))) 2951 htonl(*nft_set_ext_flags(ext))))
2910 goto nla_put_failure; 2952 goto nla_put_failure;
2911 2953
2954 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
2955 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
2956 cpu_to_be64(*nft_set_ext_timeout(ext))))
2957 goto nla_put_failure;
2958
2959 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
2960 unsigned long expires, now = jiffies;
2961
2962 expires = *nft_set_ext_expiration(ext);
2963 if (time_before(now, expires))
2964 expires -= now;
2965 else
2966 expires = 0;
2967
2968 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
2969 cpu_to_be64(jiffies_to_msecs(expires))))
2970 goto nla_put_failure;
2971 }
2972
2973 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
2974 struct nft_userdata *udata;
2975
2976 udata = nft_set_ext_userdata(ext);
2977 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
2978 udata->len + 1, udata->data))
2979 goto nla_put_failure;
2980 }
2981
2912 nla_nest_end(skb, nest); 2982 nla_nest_end(skb, nest);
2913 return 0; 2983 return 0;
2914 2984
@@ -3128,11 +3198,11 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3128 return trans; 3198 return trans;
3129} 3199}
3130 3200
3131static void *nft_set_elem_init(const struct nft_set *set, 3201void *nft_set_elem_init(const struct nft_set *set,
3132 const struct nft_set_ext_tmpl *tmpl, 3202 const struct nft_set_ext_tmpl *tmpl,
3133 const struct nft_data *key, 3203 const struct nft_data *key,
3134 const struct nft_data *data, 3204 const struct nft_data *data,
3135 gfp_t gfp) 3205 u64 timeout, gfp_t gfp)
3136{ 3206{
3137 struct nft_set_ext *ext; 3207 struct nft_set_ext *ext;
3138 void *elem; 3208 void *elem;
@@ -3147,6 +3217,11 @@ static void *nft_set_elem_init(const struct nft_set *set,
3147 memcpy(nft_set_ext_key(ext), key, set->klen); 3217 memcpy(nft_set_ext_key(ext), key, set->klen);
3148 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) 3218 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3149 memcpy(nft_set_ext_data(ext), data, set->dlen); 3219 memcpy(nft_set_ext_data(ext), data, set->dlen);
3220 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
3221 *nft_set_ext_expiration(ext) =
3222 jiffies + msecs_to_jiffies(timeout);
3223 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
3224 *nft_set_ext_timeout(ext) = timeout;
3150 3225
3151 return elem; 3226 return elem;
3152} 3227}
@@ -3172,15 +3247,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3172 struct nft_set_ext *ext; 3247 struct nft_set_ext *ext;
3173 struct nft_set_elem elem; 3248 struct nft_set_elem elem;
3174 struct nft_set_binding *binding; 3249 struct nft_set_binding *binding;
3250 struct nft_userdata *udata;
3175 struct nft_data data; 3251 struct nft_data data;
3176 enum nft_registers dreg; 3252 enum nft_registers dreg;
3177 struct nft_trans *trans; 3253 struct nft_trans *trans;
3254 u64 timeout;
3178 u32 flags; 3255 u32 flags;
3256 u8 ulen;
3179 int err; 3257 int err;
3180 3258
3181 if (set->size && set->nelems == set->size)
3182 return -ENFILE;
3183
3184 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr, 3259 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3185 nft_set_elem_policy); 3260 nft_set_elem_policy);
3186 if (err < 0) 3261 if (err < 0)
@@ -3215,6 +3290,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3215 return -EINVAL; 3290 return -EINVAL;
3216 } 3291 }
3217 3292
3293 timeout = 0;
3294 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
3295 if (!(set->flags & NFT_SET_TIMEOUT))
3296 return -EINVAL;
3297 timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_ELEM_TIMEOUT]));
3298 } else if (set->flags & NFT_SET_TIMEOUT) {
3299 timeout = set->timeout;
3300 }
3301
3218 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]); 3302 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]);
3219 if (err < 0) 3303 if (err < 0)
3220 goto err1; 3304 goto err1;
@@ -3223,6 +3307,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3223 goto err2; 3307 goto err2;
3224 3308
3225 nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY); 3309 nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY);
3310 if (timeout > 0) {
3311 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3312 if (timeout != set->timeout)
3313 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
3314 }
3226 3315
3227 if (nla[NFTA_SET_ELEM_DATA] != NULL) { 3316 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
3228 err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]); 3317 err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]);
@@ -3241,6 +3330,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3241 .chain = (struct nft_chain *)binding->chain, 3330 .chain = (struct nft_chain *)binding->chain,
3242 }; 3331 };
3243 3332
3333 if (!(binding->flags & NFT_SET_MAP))
3334 continue;
3335
3244 err = nft_validate_data_load(&bind_ctx, dreg, 3336 err = nft_validate_data_load(&bind_ctx, dreg,
3245 &data, d2.type); 3337 &data, d2.type);
3246 if (err < 0) 3338 if (err < 0)
@@ -3250,20 +3342,38 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3250 nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA); 3342 nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA);
3251 } 3343 }
3252 3344
3345 /* The full maximum length of userdata can exceed the maximum
3346 * offset value (U8_MAX) for following extensions, therefor it
3347 * must be the last extension added.
3348 */
3349 ulen = 0;
3350 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
3351 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
3352 if (ulen > 0)
3353 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
3354 ulen);
3355 }
3356
3253 err = -ENOMEM; 3357 err = -ENOMEM;
3254 elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data, GFP_KERNEL); 3358 elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data,
3359 timeout, GFP_KERNEL);
3255 if (elem.priv == NULL) 3360 if (elem.priv == NULL)
3256 goto err3; 3361 goto err3;
3257 3362
3258 ext = nft_set_elem_ext(set, elem.priv); 3363 ext = nft_set_elem_ext(set, elem.priv);
3259 if (flags) 3364 if (flags)
3260 *nft_set_ext_flags(ext) = flags; 3365 *nft_set_ext_flags(ext) = flags;
3366 if (ulen > 0) {
3367 udata = nft_set_ext_userdata(ext);
3368 udata->len = ulen - 1;
3369 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
3370 }
3261 3371
3262 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); 3372 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
3263 if (trans == NULL) 3373 if (trans == NULL)
3264 goto err4; 3374 goto err4;
3265 3375
3266 ext->genmask = nft_genmask_cur(ctx->net); 3376 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
3267 err = set->ops->insert(set, &elem); 3377 err = set->ops->insert(set, &elem);
3268 if (err < 0) 3378 if (err < 0)
3269 goto err5; 3379 goto err5;
@@ -3316,11 +3426,15 @@ static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
3316 return -EBUSY; 3426 return -EBUSY;
3317 3427
3318 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { 3428 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3429 if (set->size &&
3430 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact))
3431 return -ENFILE;
3432
3319 err = nft_add_set_elem(&ctx, set, attr); 3433 err = nft_add_set_elem(&ctx, set, attr);
3320 if (err < 0) 3434 if (err < 0) {
3435 atomic_dec(&set->nelems);
3321 break; 3436 break;
3322 3437 }
3323 set->nelems++;
3324 } 3438 }
3325 return err; 3439 return err;
3326} 3440}
@@ -3402,11 +3516,36 @@ static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
3402 if (err < 0) 3516 if (err < 0)
3403 break; 3517 break;
3404 3518
3405 set->nelems--; 3519 set->ndeact++;
3406 } 3520 }
3407 return err; 3521 return err;
3408} 3522}
3409 3523
3524void nft_set_gc_batch_release(struct rcu_head *rcu)
3525{
3526 struct nft_set_gc_batch *gcb;
3527 unsigned int i;
3528
3529 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
3530 for (i = 0; i < gcb->head.cnt; i++)
3531 nft_set_elem_destroy(gcb->head.set, gcb->elems[i]);
3532 kfree(gcb);
3533}
3534EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
3535
3536struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
3537 gfp_t gfp)
3538{
3539 struct nft_set_gc_batch *gcb;
3540
3541 gcb = kzalloc(sizeof(*gcb), gfp);
3542 if (gcb == NULL)
3543 return gcb;
3544 gcb->head.set = set;
3545 return gcb;
3546}
3547EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
3548
3410static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, 3549static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
3411 u32 portid, u32 seq) 3550 u32 portid, u32 seq)
3412{ 3551{
@@ -3710,6 +3849,8 @@ static int nf_tables_commit(struct sk_buff *skb)
3710 &te->elem, 3849 &te->elem,
3711 NFT_MSG_DELSETELEM, 0); 3850 NFT_MSG_DELSETELEM, 0);
3712 te->set->ops->remove(te->set, &te->elem); 3851 te->set->ops->remove(te->set, &te->elem);
3852 atomic_dec(&te->set->nelems);
3853 te->set->ndeact--;
3713 break; 3854 break;
3714 } 3855 }
3715 } 3856 }
@@ -3813,16 +3954,16 @@ static int nf_tables_abort(struct sk_buff *skb)
3813 nft_trans_destroy(trans); 3954 nft_trans_destroy(trans);
3814 break; 3955 break;
3815 case NFT_MSG_NEWSETELEM: 3956 case NFT_MSG_NEWSETELEM:
3816 nft_trans_elem_set(trans)->nelems--;
3817 te = (struct nft_trans_elem *)trans->data; 3957 te = (struct nft_trans_elem *)trans->data;
3818 3958
3819 te->set->ops->remove(te->set, &te->elem); 3959 te->set->ops->remove(te->set, &te->elem);
3960 atomic_dec(&te->set->nelems);
3820 break; 3961 break;
3821 case NFT_MSG_DELSETELEM: 3962 case NFT_MSG_DELSETELEM:
3822 te = (struct nft_trans_elem *)trans->data; 3963 te = (struct nft_trans_elem *)trans->data;
3823 3964
3824 nft_trans_elem_set(trans)->nelems++;
3825 te->set->ops->activate(te->set, &te->elem); 3965 te->set->ops->activate(te->set, &te->elem);
3966 te->set->ndeact--;
3826 3967
3827 nft_trans_destroy(trans); 3968 nft_trans_destroy(trans);
3828 break; 3969 break;
@@ -3960,7 +4101,8 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
3960 continue; 4101 continue;
3961 4102
3962 list_for_each_entry(binding, &set->bindings, list) { 4103 list_for_each_entry(binding, &set->bindings, list) {
3963 if (binding->chain != chain) 4104 if (!(binding->flags & NFT_SET_MAP) ||
4105 binding->chain != chain)
3964 continue; 4106 continue;
3965 4107
3966 iter.skip = 0; 4108 iter.skip = 0;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index ef4dfcbaf149..7caf08a9225d 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -239,8 +239,14 @@ int __init nf_tables_core_module_init(void)
239 if (err < 0) 239 if (err < 0)
240 goto err6; 240 goto err6;
241 241
242 err = nft_dynset_module_init();
243 if (err < 0)
244 goto err7;
245
242 return 0; 246 return 0;
243 247
248err7:
249 nft_payload_module_exit();
244err6: 250err6:
245 nft_byteorder_module_exit(); 251 nft_byteorder_module_exit();
246err5: 252err5:
@@ -257,6 +263,7 @@ err1:
257 263
258void nf_tables_core_module_exit(void) 264void nf_tables_core_module_exit(void)
259{ 265{
266 nft_dynset_module_exit();
260 nft_payload_module_exit(); 267 nft_payload_module_exit();
261 nft_byteorder_module_exit(); 268 nft_byteorder_module_exit();
262 nft_bitwise_module_exit(); 269 nft_bitwise_module_exit();
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 957b83a0223b..51afea4b0af7 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -23,6 +23,7 @@
23#include <linux/ipv6.h> 23#include <linux/ipv6.h>
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/netfilter.h> 25#include <linux/netfilter.h>
26#include <linux/netfilter_bridge.h>
26#include <net/netlink.h> 27#include <net/netlink.h>
27#include <linux/netfilter/nfnetlink.h> 28#include <linux/netfilter/nfnetlink.h>
28#include <linux/netfilter/nfnetlink_log.h> 29#include <linux/netfilter/nfnetlink_log.h>
@@ -448,14 +449,18 @@ __build_packet_message(struct nfnl_log_net *log,
448 htonl(br_port_get_rcu(indev)->br->dev->ifindex))) 449 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
449 goto nla_put_failure; 450 goto nla_put_failure;
450 } else { 451 } else {
452 struct net_device *physindev;
453
451 /* Case 2: indev is bridge group, we need to look for 454 /* Case 2: indev is bridge group, we need to look for
452 * physical device (when called from ipv4) */ 455 * physical device (when called from ipv4) */
453 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, 456 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
454 htonl(indev->ifindex))) 457 htonl(indev->ifindex)))
455 goto nla_put_failure; 458 goto nla_put_failure;
456 if (skb->nf_bridge && skb->nf_bridge->physindev && 459
460 physindev = nf_bridge_get_physindev(skb);
461 if (physindev &&
457 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, 462 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
458 htonl(skb->nf_bridge->physindev->ifindex))) 463 htonl(physindev->ifindex)))
459 goto nla_put_failure; 464 goto nla_put_failure;
460 } 465 }
461#endif 466#endif
@@ -479,14 +484,18 @@ __build_packet_message(struct nfnl_log_net *log,
479 htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) 484 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
480 goto nla_put_failure; 485 goto nla_put_failure;
481 } else { 486 } else {
487 struct net_device *physoutdev;
488
482 /* Case 2: indev is a bridge group, we need to look 489 /* Case 2: indev is a bridge group, we need to look
483 * for physical device (when called from ipv4) */ 490 * for physical device (when called from ipv4) */
484 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, 491 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
485 htonl(outdev->ifindex))) 492 htonl(outdev->ifindex)))
486 goto nla_put_failure; 493 goto nla_put_failure;
487 if (skb->nf_bridge && skb->nf_bridge->physoutdev && 494
495 physoutdev = nf_bridge_get_physoutdev(skb);
496 if (physoutdev &&
488 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, 497 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
489 htonl(skb->nf_bridge->physoutdev->ifindex))) 498 htonl(physoutdev->ifindex)))
490 goto nla_put_failure; 499 goto nla_put_failure;
491 } 500 }
492#endif 501#endif
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 6e74655a8d4f..628afc350c02 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -25,6 +25,7 @@
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/netfilter_ipv4.h> 26#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h> 27#include <linux/netfilter_ipv6.h>
28#include <linux/netfilter_bridge.h>
28#include <linux/netfilter/nfnetlink.h> 29#include <linux/netfilter/nfnetlink.h>
29#include <linux/netfilter/nfnetlink_queue.h> 30#include <linux/netfilter/nfnetlink_queue.h>
30#include <linux/list.h> 31#include <linux/list.h>
@@ -396,14 +397,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
396 htonl(br_port_get_rcu(indev)->br->dev->ifindex))) 397 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
397 goto nla_put_failure; 398 goto nla_put_failure;
398 } else { 399 } else {
400 int physinif;
401
399 /* Case 2: indev is bridge group, we need to look for 402 /* Case 2: indev is bridge group, we need to look for
400 * physical device (when called from ipv4) */ 403 * physical device (when called from ipv4) */
401 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, 404 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV,
402 htonl(indev->ifindex))) 405 htonl(indev->ifindex)))
403 goto nla_put_failure; 406 goto nla_put_failure;
404 if (entskb->nf_bridge && entskb->nf_bridge->physindev && 407
408 physinif = nf_bridge_get_physinif(entskb);
409 if (physinif &&
405 nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV, 410 nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
406 htonl(entskb->nf_bridge->physindev->ifindex))) 411 htonl(physinif)))
407 goto nla_put_failure; 412 goto nla_put_failure;
408 } 413 }
409#endif 414#endif
@@ -426,14 +431,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
426 htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) 431 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
427 goto nla_put_failure; 432 goto nla_put_failure;
428 } else { 433 } else {
434 int physoutif;
435
429 /* Case 2: outdev is bridge group, we need to look for 436 /* Case 2: outdev is bridge group, we need to look for
430 * physical output device (when called from ipv4) */ 437 * physical output device (when called from ipv4) */
431 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, 438 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
432 htonl(outdev->ifindex))) 439 htonl(outdev->ifindex)))
433 goto nla_put_failure; 440 goto nla_put_failure;
434 if (entskb->nf_bridge && entskb->nf_bridge->physoutdev && 441
442 physoutif = nf_bridge_get_physoutif(entskb);
443 if (physoutif &&
435 nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV, 444 nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
436 htonl(entskb->nf_bridge->physoutdev->ifindex))) 445 htonl(physoutif)))
437 goto nla_put_failure; 446 goto nla_put_failure;
438 } 447 }
439#endif 448#endif
@@ -765,11 +774,12 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
765 return 1; 774 return 1;
766#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 775#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
767 if (entry->skb->nf_bridge) { 776 if (entry->skb->nf_bridge) {
768 if (entry->skb->nf_bridge->physindev && 777 int physinif, physoutif;
769 entry->skb->nf_bridge->physindev->ifindex == ifindex) 778
770 return 1; 779 physinif = nf_bridge_get_physinif(entry->skb);
771 if (entry->skb->nf_bridge->physoutdev && 780 physoutif = nf_bridge_get_physoutif(entry->skb);
772 entry->skb->nf_bridge->physoutdev->ifindex == ifindex) 781
782 if (physinif == ifindex || physoutif == ifindex)
773 return 1; 783 return 1;
774 } 784 }
775#endif 785#endif
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
new file mode 100644
index 000000000000..eeb72dee78ef
--- /dev/null
+++ b/net/netfilter/nft_dynset.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2015 Patrick McHardy <kaber@trash.net>
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
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/netlink.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter/nf_tables.h>
16#include <net/netfilter/nf_tables.h>
17#include <net/netfilter/nf_tables_core.h>
18
19struct nft_dynset {
20 struct nft_set *set;
21 struct nft_set_ext_tmpl tmpl;
22 enum nft_dynset_ops op:8;
23 enum nft_registers sreg_key:8;
24 enum nft_registers sreg_data:8;
25 u64 timeout;
26 struct nft_set_binding binding;
27};
28
29static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1])
31{
32 const struct nft_dynset *priv = nft_expr_priv(expr);
33 u64 timeout;
34 void *elem;
35
36 if (set->size && !atomic_add_unless(&set->nelems, 1, set->size))
37 return NULL;
38
39 timeout = priv->timeout ? : set->timeout;
40 elem = nft_set_elem_init(set, &priv->tmpl,
41 &data[priv->sreg_key], &data[priv->sreg_data],
42 timeout, GFP_ATOMIC);
43 if (elem == NULL) {
44 if (set->size)
45 atomic_dec(&set->nelems);
46 }
47 return elem;
48}
49
50static void nft_dynset_eval(const struct nft_expr *expr,
51 struct nft_data data[NFT_REG_MAX + 1],
52 const struct nft_pktinfo *pkt)
53{
54 const struct nft_dynset *priv = nft_expr_priv(expr);
55 struct nft_set *set = priv->set;
56 const struct nft_set_ext *ext;
57 u64 timeout;
58
59 if (set->ops->update(set, &data[priv->sreg_key], nft_dynset_new,
60 expr, data, &ext)) {
61 if (priv->op == NFT_DYNSET_OP_UPDATE &&
62 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
63 timeout = priv->timeout ? : set->timeout;
64 *nft_set_ext_expiration(ext) = jiffies + timeout;
65 return;
66 }
67 }
68
69 data[NFT_REG_VERDICT].verdict = NFT_BREAK;
70}
71
72static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
73 [NFTA_DYNSET_SET_NAME] = { .type = NLA_STRING },
74 [NFTA_DYNSET_SET_ID] = { .type = NLA_U32 },
75 [NFTA_DYNSET_OP] = { .type = NLA_U32 },
76 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
77 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
78 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
79};
80
81static int nft_dynset_init(const struct nft_ctx *ctx,
82 const struct nft_expr *expr,
83 const struct nlattr * const tb[])
84{
85 struct nft_dynset *priv = nft_expr_priv(expr);
86 struct nft_set *set;
87 u64 timeout;
88 int err;
89
90 if (tb[NFTA_DYNSET_SET_NAME] == NULL ||
91 tb[NFTA_DYNSET_OP] == NULL ||
92 tb[NFTA_DYNSET_SREG_KEY] == NULL)
93 return -EINVAL;
94
95 set = nf_tables_set_lookup(ctx->table, tb[NFTA_DYNSET_SET_NAME]);
96 if (IS_ERR(set)) {
97 if (tb[NFTA_DYNSET_SET_ID])
98 set = nf_tables_set_lookup_byid(ctx->net,
99 tb[NFTA_DYNSET_SET_ID]);
100 if (IS_ERR(set))
101 return PTR_ERR(set);
102 }
103
104 if (set->flags & NFT_SET_CONSTANT)
105 return -EBUSY;
106
107 priv->op = ntohl(nla_get_be32(tb[NFTA_DYNSET_OP]));
108 switch (priv->op) {
109 case NFT_DYNSET_OP_ADD:
110 break;
111 case NFT_DYNSET_OP_UPDATE:
112 if (!(set->flags & NFT_SET_TIMEOUT))
113 return -EOPNOTSUPP;
114 break;
115 default:
116 return -EOPNOTSUPP;
117 }
118
119 timeout = 0;
120 if (tb[NFTA_DYNSET_TIMEOUT] != NULL) {
121 if (!(set->flags & NFT_SET_TIMEOUT))
122 return -EINVAL;
123 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
124 }
125
126 priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY]));
127 err = nft_validate_input_register(priv->sreg_key);
128 if (err < 0)
129 return err;
130
131 if (tb[NFTA_DYNSET_SREG_DATA] != NULL) {
132 if (!(set->flags & NFT_SET_MAP))
133 return -EINVAL;
134 if (set->dtype == NFT_DATA_VERDICT)
135 return -EOPNOTSUPP;
136
137 priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA]));
138 err = nft_validate_input_register(priv->sreg_data);
139 if (err < 0)
140 return err;
141 } else if (set->flags & NFT_SET_MAP)
142 return -EINVAL;
143
144 nft_set_ext_prepare(&priv->tmpl);
145 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
146 if (set->flags & NFT_SET_MAP)
147 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen);
148 if (set->flags & NFT_SET_TIMEOUT) {
149 if (timeout || set->timeout)
150 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
151 }
152
153 priv->timeout = timeout;
154
155 err = nf_tables_bind_set(ctx, set, &priv->binding);
156 if (err < 0)
157 return err;
158
159 priv->set = set;
160 return 0;
161}
162
163static void nft_dynset_destroy(const struct nft_ctx *ctx,
164 const struct nft_expr *expr)
165{
166 struct nft_dynset *priv = nft_expr_priv(expr);
167
168 nf_tables_unbind_set(ctx, priv->set, &priv->binding);
169}
170
171static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
172{
173 const struct nft_dynset *priv = nft_expr_priv(expr);
174
175 if (nla_put_be32(skb, NFTA_DYNSET_SREG_KEY, htonl(priv->sreg_key)))
176 goto nla_put_failure;
177 if (priv->set->flags & NFT_SET_MAP &&
178 nla_put_be32(skb, NFTA_DYNSET_SREG_DATA, htonl(priv->sreg_data)))
179 goto nla_put_failure;
180 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op)))
181 goto nla_put_failure;
182 if (nla_put_string(skb, NFTA_DYNSET_SET_NAME, priv->set->name))
183 goto nla_put_failure;
184 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout)))
185 goto nla_put_failure;
186 return 0;
187
188nla_put_failure:
189 return -1;
190}
191
192static struct nft_expr_type nft_dynset_type;
193static const struct nft_expr_ops nft_dynset_ops = {
194 .type = &nft_dynset_type,
195 .size = NFT_EXPR_SIZE(sizeof(struct nft_dynset)),
196 .eval = nft_dynset_eval,
197 .init = nft_dynset_init,
198 .destroy = nft_dynset_destroy,
199 .dump = nft_dynset_dump,
200};
201
202static struct nft_expr_type nft_dynset_type __read_mostly = {
203 .name = "dynset",
204 .ops = &nft_dynset_ops,
205 .policy = nft_dynset_policy,
206 .maxattr = NFTA_DYNSET_MAX,
207 .owner = THIS_MODULE,
208};
209
210int __init nft_dynset_module_init(void)
211{
212 return nft_register_expr(&nft_dynset_type);
213}
214
215void nft_dynset_module_exit(void)
216{
217 nft_unregister_expr(&nft_dynset_type);
218}
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index c7e1a9d7d46f..bc23806b7fbe 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -15,6 +15,7 @@
15#include <linux/log2.h> 15#include <linux/log2.h>
16#include <linux/jhash.h> 16#include <linux/jhash.h>
17#include <linux/netlink.h> 17#include <linux/netlink.h>
18#include <linux/workqueue.h>
18#include <linux/rhashtable.h> 19#include <linux/rhashtable.h>
19#include <linux/netfilter.h> 20#include <linux/netfilter.h>
20#include <linux/netfilter/nf_tables.h> 21#include <linux/netfilter/nf_tables.h>
@@ -25,6 +26,7 @@
25 26
26struct nft_hash { 27struct nft_hash {
27 struct rhashtable ht; 28 struct rhashtable ht;
29 struct delayed_work gc_work;
28}; 30};
29 31
30struct nft_hash_elem { 32struct nft_hash_elem {
@@ -62,6 +64,8 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
62 64
63 if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen)) 65 if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
64 return 1; 66 return 1;
67 if (nft_set_elem_expired(&he->ext))
68 return 1;
65 if (!nft_set_elem_active(&he->ext, x->genmask)) 69 if (!nft_set_elem_active(&he->ext, x->genmask))
66 return 1; 70 return 1;
67 return 0; 71 return 0;
@@ -86,6 +90,42 @@ static bool nft_hash_lookup(const struct nft_set *set,
86 return !!he; 90 return !!he;
87} 91}
88 92
93static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
94 void *(*new)(struct nft_set *,
95 const struct nft_expr *,
96 struct nft_data []),
97 const struct nft_expr *expr,
98 struct nft_data data[],
99 const struct nft_set_ext **ext)
100{
101 struct nft_hash *priv = nft_set_priv(set);
102 struct nft_hash_elem *he;
103 struct nft_hash_cmp_arg arg = {
104 .genmask = NFT_GENMASK_ANY,
105 .set = set,
106 .key = key,
107 };
108
109 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
110 if (he != NULL)
111 goto out;
112
113 he = new(set, expr, data);
114 if (he == NULL)
115 goto err1;
116 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
117 nft_hash_params))
118 goto err2;
119out:
120 *ext = &he->ext;
121 return true;
122
123err2:
124 nft_set_elem_destroy(set, he);
125err1:
126 return false;
127}
128
89static int nft_hash_insert(const struct nft_set *set, 129static int nft_hash_insert(const struct nft_set *set,
90 const struct nft_set_elem *elem) 130 const struct nft_set_elem *elem)
91{ 131{
@@ -107,6 +147,7 @@ static void nft_hash_activate(const struct nft_set *set,
107 struct nft_hash_elem *he = elem->priv; 147 struct nft_hash_elem *he = elem->priv;
108 148
109 nft_set_elem_change_active(set, &he->ext); 149 nft_set_elem_change_active(set, &he->ext);
150 nft_set_elem_clear_busy(&he->ext);
110} 151}
111 152
112static void *nft_hash_deactivate(const struct nft_set *set, 153static void *nft_hash_deactivate(const struct nft_set *set,
@@ -120,9 +161,15 @@ static void *nft_hash_deactivate(const struct nft_set *set,
120 .key = &elem->key, 161 .key = &elem->key,
121 }; 162 };
122 163
164 rcu_read_lock();
123 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params); 165 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
124 if (he != NULL) 166 if (he != NULL) {
125 nft_set_elem_change_active(set, &he->ext); 167 if (!nft_set_elem_mark_busy(&he->ext))
168 nft_set_elem_change_active(set, &he->ext);
169 else
170 he = NULL;
171 }
172 rcu_read_unlock();
126 173
127 return he; 174 return he;
128} 175}
@@ -170,6 +217,8 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
170 217
171 if (iter->count < iter->skip) 218 if (iter->count < iter->skip)
172 goto cont; 219 goto cont;
220 if (nft_set_elem_expired(&he->ext))
221 goto cont;
173 if (!nft_set_elem_active(&he->ext, genmask)) 222 if (!nft_set_elem_active(&he->ext, genmask))
174 goto cont; 223 goto cont;
175 224
@@ -188,6 +237,55 @@ out:
188 rhashtable_walk_exit(&hti); 237 rhashtable_walk_exit(&hti);
189} 238}
190 239
240static void nft_hash_gc(struct work_struct *work)
241{
242 struct nft_set *set;
243 struct nft_hash_elem *he;
244 struct nft_hash *priv;
245 struct nft_set_gc_batch *gcb = NULL;
246 struct rhashtable_iter hti;
247 int err;
248
249 priv = container_of(work, struct nft_hash, gc_work.work);
250 set = nft_set_container_of(priv);
251
252 err = rhashtable_walk_init(&priv->ht, &hti);
253 if (err)
254 goto schedule;
255
256 err = rhashtable_walk_start(&hti);
257 if (err && err != -EAGAIN)
258 goto out;
259
260 while ((he = rhashtable_walk_next(&hti))) {
261 if (IS_ERR(he)) {
262 if (PTR_ERR(he) != -EAGAIN)
263 goto out;
264 continue;
265 }
266
267 if (!nft_set_elem_expired(&he->ext))
268 continue;
269 if (nft_set_elem_mark_busy(&he->ext))
270 continue;
271
272 gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
273 if (gcb == NULL)
274 goto out;
275 rhashtable_remove_fast(&priv->ht, &he->node, nft_hash_params);
276 atomic_dec(&set->nelems);
277 nft_set_gc_batch_add(gcb, he);
278 }
279out:
280 rhashtable_walk_stop(&hti);
281 rhashtable_walk_exit(&hti);
282
283 nft_set_gc_batch_complete(gcb);
284schedule:
285 queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
286 nft_set_gc_interval(set));
287}
288
191static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) 289static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
192{ 290{
193 return sizeof(struct nft_hash); 291 return sizeof(struct nft_hash);
@@ -207,11 +305,20 @@ static int nft_hash_init(const struct nft_set *set,
207{ 305{
208 struct nft_hash *priv = nft_set_priv(set); 306 struct nft_hash *priv = nft_set_priv(set);
209 struct rhashtable_params params = nft_hash_params; 307 struct rhashtable_params params = nft_hash_params;
308 int err;
210 309
211 params.nelem_hint = desc->size ?: NFT_HASH_ELEMENT_HINT; 310 params.nelem_hint = desc->size ?: NFT_HASH_ELEMENT_HINT;
212 params.key_len = set->klen; 311 params.key_len = set->klen;
213 312
214 return rhashtable_init(&priv->ht, &params); 313 err = rhashtable_init(&priv->ht, &params);
314 if (err < 0)
315 return err;
316
317 INIT_DEFERRABLE_WORK(&priv->gc_work, nft_hash_gc);
318 if (set->flags & NFT_SET_TIMEOUT)
319 queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
320 nft_set_gc_interval(set));
321 return 0;
215} 322}
216 323
217static void nft_hash_elem_destroy(void *ptr, void *arg) 324static void nft_hash_elem_destroy(void *ptr, void *arg)
@@ -223,6 +330,7 @@ static void nft_hash_destroy(const struct nft_set *set)
223{ 330{
224 struct nft_hash *priv = nft_set_priv(set); 331 struct nft_hash *priv = nft_set_priv(set);
225 332
333 cancel_delayed_work_sync(&priv->gc_work);
226 rhashtable_free_and_destroy(&priv->ht, nft_hash_elem_destroy, 334 rhashtable_free_and_destroy(&priv->ht, nft_hash_elem_destroy,
227 (void *)set); 335 (void *)set);
228} 336}
@@ -263,8 +371,9 @@ static struct nft_set_ops nft_hash_ops __read_mostly = {
263 .deactivate = nft_hash_deactivate, 371 .deactivate = nft_hash_deactivate,
264 .remove = nft_hash_remove, 372 .remove = nft_hash_remove,
265 .lookup = nft_hash_lookup, 373 .lookup = nft_hash_lookup,
374 .update = nft_hash_update,
266 .walk = nft_hash_walk, 375 .walk = nft_hash_walk,
267 .features = NFT_SET_MAP, 376 .features = NFT_SET_MAP | NFT_SET_TIMEOUT,
268 .owner = THIS_MODULE, 377 .owner = THIS_MODULE,
269}; 378};
270 379
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index a5f30b8760ea..d8cf86fb30fc 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -92,6 +92,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
92 } else if (set->flags & NFT_SET_MAP) 92 } else if (set->flags & NFT_SET_MAP)
93 return -EINVAL; 93 return -EINVAL;
94 94
95 priv->binding.flags = set->flags & NFT_SET_MAP;
96
95 err = nf_tables_bind_set(ctx, set, &priv->binding); 97 err = nf_tables_bind_set(ctx, set, &priv->binding);
96 if (err < 0) 98 if (err < 0)
97 return err; 99 return err;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 5197874372ec..d79ce88be77f 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -166,9 +166,8 @@ void nft_meta_get_eval(const struct nft_expr *expr,
166 dest->data[0] = out->group; 166 dest->data[0] = out->group;
167 break; 167 break;
168 case NFT_META_CGROUP: 168 case NFT_META_CGROUP:
169 if (skb->sk == NULL) 169 if (skb->sk == NULL || !sk_fullsock(skb->sk))
170 break; 170 goto err;
171
172 dest->data[0] = skb->sk->sk_classid; 171 dest->data[0] = skb->sk->sk_classid;
173 break; 172 break;
174 default: 173 default:
diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c
index 7198d660b4de..a1d126f29463 100644
--- a/net/netfilter/xt_cgroup.c
+++ b/net/netfilter/xt_cgroup.c
@@ -39,7 +39,7 @@ cgroup_mt(const struct sk_buff *skb, struct xt_action_param *par)
39{ 39{
40 const struct xt_cgroup_info *info = par->matchinfo; 40 const struct xt_cgroup_info *info = par->matchinfo;
41 41
42 if (skb->sk == NULL) 42 if (skb->sk == NULL || !sk_fullsock(skb->sk))
43 return false; 43 return false;
44 44
45 return (info->id == skb->sk->sk_classid) ^ info->invert; 45 return (info->id == skb->sk->sk_classid) ^ info->invert;
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 50a52043650f..1caaccbc306c 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -25,16 +25,15 @@ MODULE_ALIAS("ip6t_physdev");
25static bool 25static bool
26physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) 26physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
27{ 27{
28 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
29 const struct xt_physdev_info *info = par->matchinfo; 28 const struct xt_physdev_info *info = par->matchinfo;
29 const struct net_device *physdev;
30 unsigned long ret; 30 unsigned long ret;
31 const char *indev, *outdev; 31 const char *indev, *outdev;
32 const struct nf_bridge_info *nf_bridge;
33 32
34 /* Not a bridged IP packet or no info available yet: 33 /* Not a bridged IP packet or no info available yet:
35 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 34 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
36 * the destination device will be a bridge. */ 35 * the destination device will be a bridge. */
37 if (!(nf_bridge = skb->nf_bridge)) { 36 if (!skb->nf_bridge) {
38 /* Return MATCH if the invert flags of the used options are on */ 37 /* Return MATCH if the invert flags of the used options are on */
39 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 38 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
40 !(info->invert & XT_PHYSDEV_OP_BRIDGED)) 39 !(info->invert & XT_PHYSDEV_OP_BRIDGED))
@@ -54,30 +53,41 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
54 return true; 53 return true;
55 } 54 }
56 55
56 physdev = nf_bridge_get_physoutdev(skb);
57 outdev = physdev ? physdev->name : NULL;
58
57 /* This only makes sense in the FORWARD and POSTROUTING chains */ 59 /* This only makes sense in the FORWARD and POSTROUTING chains */
58 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 60 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
59 (!!nf_bridge->physoutdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED))) 61 (!!outdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
60 return false; 62 return false;
61 63
64 physdev = nf_bridge_get_physindev(skb);
65 indev = physdev ? physdev->name : NULL;
66
62 if ((info->bitmask & XT_PHYSDEV_OP_ISIN && 67 if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
63 (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || 68 (!indev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) ||
64 (info->bitmask & XT_PHYSDEV_OP_ISOUT && 69 (info->bitmask & XT_PHYSDEV_OP_ISOUT &&
65 (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) 70 (!outdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT))))
66 return false; 71 return false;
67 72
68 if (!(info->bitmask & XT_PHYSDEV_OP_IN)) 73 if (!(info->bitmask & XT_PHYSDEV_OP_IN))
69 goto match_outdev; 74 goto match_outdev;
70 indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
71 ret = ifname_compare_aligned(indev, info->physindev, info->in_mask);
72 75
73 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN)) 76 if (indev) {
74 return false; 77 ret = ifname_compare_aligned(indev, info->physindev,
78 info->in_mask);
79
80 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
81 return false;
82 }
75 83
76match_outdev: 84match_outdev:
77 if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) 85 if (!(info->bitmask & XT_PHYSDEV_OP_OUT))
78 return true; 86 return true;
79 outdev = nf_bridge->physoutdev ? 87
80 nf_bridge->physoutdev->name : nulldevname; 88 if (!outdev)
89 return false;
90
81 ret = ifname_compare_aligned(outdev, info->physoutdev, info->out_mask); 91 ret = ifname_compare_aligned(outdev, info->physoutdev, info->out_mask);
82 92
83 return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT)); 93 return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index 895534e87a47..e092cb046326 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -143,13 +143,10 @@ static bool xt_socket_sk_is_transparent(struct sock *sk)
143 } 143 }
144} 144}
145 145
146static bool 146static struct sock *xt_socket_lookup_slow_v4(const struct sk_buff *skb,
147socket_match(const struct sk_buff *skb, struct xt_action_param *par, 147 const struct net_device *indev)
148 const struct xt_socket_mtinfo1 *info)
149{ 148{
150 const struct iphdr *iph = ip_hdr(skb); 149 const struct iphdr *iph = ip_hdr(skb);
151 struct udphdr _hdr, *hp = NULL;
152 struct sock *sk = skb->sk;
153 __be32 uninitialized_var(daddr), uninitialized_var(saddr); 150 __be32 uninitialized_var(daddr), uninitialized_var(saddr);
154 __be16 uninitialized_var(dport), uninitialized_var(sport); 151 __be16 uninitialized_var(dport), uninitialized_var(sport);
155 u8 uninitialized_var(protocol); 152 u8 uninitialized_var(protocol);
@@ -159,10 +156,12 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
159#endif 156#endif
160 157
161 if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) { 158 if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
159 struct udphdr _hdr, *hp;
160
162 hp = skb_header_pointer(skb, ip_hdrlen(skb), 161 hp = skb_header_pointer(skb, ip_hdrlen(skb),
163 sizeof(_hdr), &_hdr); 162 sizeof(_hdr), &_hdr);
164 if (hp == NULL) 163 if (hp == NULL)
165 return false; 164 return NULL;
166 165
167 protocol = iph->protocol; 166 protocol = iph->protocol;
168 saddr = iph->saddr; 167 saddr = iph->saddr;
@@ -172,16 +171,17 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
172 171
173 } else if (iph->protocol == IPPROTO_ICMP) { 172 } else if (iph->protocol == IPPROTO_ICMP) {
174 if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr, 173 if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr,
175 &sport, &dport)) 174 &sport, &dport))
176 return false; 175 return NULL;
177 } else { 176 } else {
178 return false; 177 return NULL;
179 } 178 }
180 179
181#ifdef XT_SOCKET_HAVE_CONNTRACK 180#ifdef XT_SOCKET_HAVE_CONNTRACK
182 /* Do the lookup with the original socket address in case this is a 181 /* Do the lookup with the original socket address in
183 * reply packet of an established SNAT-ted connection. */ 182 * case this is a reply packet of an established
184 183 * SNAT-ted connection.
184 */
185 ct = nf_ct_get(skb, &ctinfo); 185 ct = nf_ct_get(skb, &ctinfo);
186 if (ct && !nf_ct_is_untracked(ct) && 186 if (ct && !nf_ct_is_untracked(ct) &&
187 ((iph->protocol != IPPROTO_ICMP && 187 ((iph->protocol != IPPROTO_ICMP &&
@@ -197,10 +197,18 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
197 } 197 }
198#endif 198#endif
199 199
200 return xt_socket_get_sock_v4(dev_net(skb->dev), protocol, saddr, daddr,
201 sport, dport, indev);
202}
203
204static bool
205socket_match(const struct sk_buff *skb, struct xt_action_param *par,
206 const struct xt_socket_mtinfo1 *info)
207{
208 struct sock *sk = skb->sk;
209
200 if (!sk) 210 if (!sk)
201 sk = xt_socket_get_sock_v4(dev_net(skb->dev), protocol, 211 sk = xt_socket_lookup_slow_v4(skb, par->in);
202 saddr, daddr, sport, dport,
203 par->in);
204 if (sk) { 212 if (sk) {
205 bool wildcard; 213 bool wildcard;
206 bool transparent = true; 214 bool transparent = true;
@@ -225,12 +233,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
225 sk = NULL; 233 sk = NULL;
226 } 234 }
227 235
228 pr_debug("proto %hhu %pI4:%hu -> %pI4:%hu (orig %pI4:%hu) sock %p\n", 236 return sk != NULL;
229 protocol, &saddr, ntohs(sport),
230 &daddr, ntohs(dport),
231 &iph->daddr, hp ? ntohs(hp->dest) : 0, sk);
232
233 return (sk != NULL);
234} 237}
235 238
236static bool 239static bool
@@ -327,28 +330,26 @@ xt_socket_get_sock_v6(struct net *net, const u8 protocol,
327 return NULL; 330 return NULL;
328} 331}
329 332
330static bool 333static struct sock *xt_socket_lookup_slow_v6(const struct sk_buff *skb,
331socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par) 334 const struct net_device *indev)
332{ 335{
333 struct ipv6hdr ipv6_var, *iph = ipv6_hdr(skb);
334 struct udphdr _hdr, *hp = NULL;
335 struct sock *sk = skb->sk;
336 const struct in6_addr *daddr = NULL, *saddr = NULL;
337 __be16 uninitialized_var(dport), uninitialized_var(sport); 336 __be16 uninitialized_var(dport), uninitialized_var(sport);
338 int thoff = 0, uninitialized_var(tproto); 337 const struct in6_addr *daddr = NULL, *saddr = NULL;
339 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; 338 struct ipv6hdr *iph = ipv6_hdr(skb);
339 int thoff = 0, tproto;
340 340
341 tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); 341 tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
342 if (tproto < 0) { 342 if (tproto < 0) {
343 pr_debug("unable to find transport header in IPv6 packet, dropping\n"); 343 pr_debug("unable to find transport header in IPv6 packet, dropping\n");
344 return NF_DROP; 344 return NULL;
345 } 345 }
346 346
347 if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) { 347 if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
348 hp = skb_header_pointer(skb, thoff, 348 struct udphdr _hdr, *hp;
349 sizeof(_hdr), &_hdr); 349
350 hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
350 if (hp == NULL) 351 if (hp == NULL)
351 return false; 352 return NULL;
352 353
353 saddr = &iph->saddr; 354 saddr = &iph->saddr;
354 sport = hp->source; 355 sport = hp->source;
@@ -356,17 +357,27 @@ socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
356 dport = hp->dest; 357 dport = hp->dest;
357 358
358 } else if (tproto == IPPROTO_ICMPV6) { 359 } else if (tproto == IPPROTO_ICMPV6) {
360 struct ipv6hdr ipv6_var;
361
359 if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr, 362 if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr,
360 &sport, &dport, &ipv6_var)) 363 &sport, &dport, &ipv6_var))
361 return false; 364 return NULL;
362 } else { 365 } else {
363 return false; 366 return NULL;
364 } 367 }
365 368
369 return xt_socket_get_sock_v6(dev_net(skb->dev), tproto, saddr, daddr,
370 sport, dport, indev);
371}
372
373static bool
374socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
375{
376 const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
377 struct sock *sk = skb->sk;
378
366 if (!sk) 379 if (!sk)
367 sk = xt_socket_get_sock_v6(dev_net(skb->dev), tproto, 380 sk = xt_socket_lookup_slow_v6(skb, par->in);
368 saddr, daddr, sport, dport,
369 par->in);
370 if (sk) { 381 if (sk) {
371 bool wildcard; 382 bool wildcard;
372 bool transparent = true; 383 bool transparent = true;
@@ -391,13 +402,7 @@ socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par)
391 sk = NULL; 402 sk = NULL;
392 } 403 }
393 404
394 pr_debug("proto %hhd %pI6:%hu -> %pI6:%hu " 405 return sk != NULL;
395 "(orig %pI6:%hu) sock %p\n",
396 tproto, saddr, ntohs(sport),
397 daddr, ntohs(dport),
398 &iph->daddr, hp ? ntohs(hp->dest) : 0, sk);
399
400 return (sk != NULL);
401} 406}
402#endif 407#endif
403 408