Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

1) UAF in chain binding support from previous batch, from Dan Carpenter.

2) Queue up delayed work to expire connections with no destination,
   from Andrew Sy Kim.

3) Use fallthrough pseudo-keyword, from Gustavo A. R. Silva.

4) Replace HTTP links with HTTPS, from Alexander A. Klimov.

5) Remove superfluous null header checks in ip6tables, from
   Gaurav Singh.

6) Add extended netlink error reporting for expression.

7) Report EEXIST on overlapping chain, set elements and flowtable
   devices.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Aug 3, 2020
2 parents c23cf40 + 77a9218 commit f2e0b29
Show file tree
Hide file tree
Showing 35 changed files with 173 additions and 93 deletions.
29 changes: 29 additions & 0 deletions include/net/ip_vs.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/spinlock.h> /* for struct rwlock_t */
#include <linux/atomic.h> /* for struct atomic_t */
#include <linux/refcount.h> /* for struct refcount_t */
#include <linux/workqueue.h>

#include <linux/compiler.h>
#include <linux/timer.h>
Expand Down Expand Up @@ -886,6 +887,8 @@ struct netns_ipvs {
atomic_t conn_out_counter;

#ifdef CONFIG_SYSCTL
/* delayed work for expiring no dest connections */
struct delayed_work expire_nodest_conn_work;
/* 1/rate drop and drop-entry variables */
struct delayed_work defense_work; /* Work handler */
int drop_rate;
Expand Down Expand Up @@ -1051,6 +1054,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
return ipvs->sysctl_conn_reuse_mode;
}

static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_expire_nodest_conn;
}

static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_schedule_icmp;
Expand Down Expand Up @@ -1138,6 +1146,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
return 1;
}

static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
{
return 0;
}

static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{
return 0;
Expand Down Expand Up @@ -1507,6 +1520,22 @@ static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
#endif

#ifdef CONFIG_SYSCTL
/* Enqueue delayed work for expiring no dest connections
* Only run when sysctl_expire_nodest=1
*/
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs)
{
if (sysctl_expire_nodest_conn(ipvs))
queue_delayed_work(system_long_wq,
&ipvs->expire_nodest_conn_work, 1);
}

void ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs);
#else
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) {}
#endif

#define IP_VS_DFWD_METHOD(dest) (atomic_read(&(dest)->conn_flags) & \
IP_VS_CONN_F_FWD_MASK)

Expand Down
2 changes: 1 addition & 1 deletion include/uapi/linux/netfilter/xt_connmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <linux/types.h>

/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
/* Copyright (C) 2002,2004 MARA Systems AB <https://www.marasystems.com>
* by Henrik Nordstrom <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
Expand Down
2 changes: 1 addition & 1 deletion net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,7 @@ static int compat_mtw_from_user(const struct compat_ebt_entry_mwt *mwt,
size_kern = match_size;
module_put(match->me);
break;
case EBT_COMPAT_WATCHER: /* fallthrough */
case EBT_COMPAT_WATCHER:
case EBT_COMPAT_TARGET:
wt = xt_request_find_target(NFPROTO_BRIDGE, name,
mwt->u.revision);
Expand Down
2 changes: 1 addition & 1 deletion net/decnet/netfilter/dn_rtmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*
* DECnet Routing Message Grabulator
*
* (C) 2000 ChyGwyn Limited - http://www.chygwyn.com/
* (C) 2000 ChyGwyn Limited - https://www.chygwyn.com/
*
* Author: Steven Whitehouse <[email protected]>
*/
Expand Down
3 changes: 1 addition & 2 deletions net/ipv6/netfilter/ip6t_ah.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ static bool ah_mt6(const struct sk_buff *skb, struct xt_action_param *par)
ahinfo->hdrres, ah->reserved,
!(ahinfo->hdrres && ah->reserved));

return (ah != NULL) &&
spi_match(ahinfo->spis[0], ahinfo->spis[1],
return spi_match(ahinfo->spis[0], ahinfo->spis[1],
ntohl(ah->spi),
!!(ahinfo->invflags & IP6T_AH_INV_SPI)) &&
(!ahinfo->hdrlen ||
Expand Down
3 changes: 1 addition & 2 deletions net/ipv6/netfilter/ip6t_frag.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ frag_mt6(const struct sk_buff *skb, struct xt_action_param *par)
!((fraginfo->flags & IP6T_FRAG_NMF) &&
(ntohs(fh->frag_off) & IP6_MF)));

return (fh != NULL) &&
id_match(fraginfo->ids[0], fraginfo->ids[1],
return id_match(fraginfo->ids[0], fraginfo->ids[1],
ntohl(fh->identification),
!!(fraginfo->invflags & IP6T_FRAG_INV_IDS)) &&
!((fraginfo->flags & IP6T_FRAG_RES) &&
Expand Down
3 changes: 1 addition & 2 deletions net/ipv6/netfilter/ip6t_hbh.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ hbh_mt6(const struct sk_buff *skb, struct xt_action_param *par)
((optinfo->hdrlen == hdrlen) ^
!!(optinfo->invflags & IP6T_OPTS_INV_LEN))));

ret = (oh != NULL) &&
(!(optinfo->flags & IP6T_OPTS_LEN) ||
ret = (!(optinfo->flags & IP6T_OPTS_LEN) ||
((optinfo->hdrlen == hdrlen) ^
!!(optinfo->invflags & IP6T_OPTS_INV_LEN)));

Expand Down
3 changes: 1 addition & 2 deletions net/ipv6/netfilter/ip6t_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
!((rtinfo->flags & IP6T_RT_RES) &&
(((const struct rt0_hdr *)rh)->reserved)));

ret = (rh != NULL) &&
(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
ret = (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
rh->segments_left,
!!(rtinfo->invflags & IP6T_RT_INV_SGS))) &&
(!(rtinfo->flags & IP6T_RT_LEN) ||
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ config NF_TABLES
replace the existing {ip,ip6,arp,eb}_tables infrastructure. It
provides a pseudo-state machine with an extensible instruction-set
(also known as expressions) that the userspace 'nft' utility
(http://www.netfilter.org/projects/nftables) uses to build the
(https://www.netfilter.org/projects/nftables) uses to build the
rule-set. It also comes with the generic set infrastructure that
allows you to construct mappings between matchings and actions
for performance lookups.
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/ipset/ip_set_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,7 @@ ip_set_dump_do(struct sk_buff *skb, struct netlink_callback *cb)
goto next_set;
if (set->variant->uref)
set->variant->uref(set, cb, true);
/* fall through */
fallthrough;
default:
ret = set->variant->list(set, skb, cb);
if (!cb->args[IPSET_CB_ARG0])
Expand Down
39 changes: 39 additions & 0 deletions net/netfilter/ipvs/ip_vs_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,45 @@ static void ip_vs_conn_flush(struct netns_ipvs *ipvs)
goto flush_again;
}
}

#ifdef CONFIG_SYSCTL
void ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs)
{
int idx;
struct ip_vs_conn *cp, *cp_c;
struct ip_vs_dest *dest;

rcu_read_lock();
for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[idx], c_list) {
if (cp->ipvs != ipvs)
continue;

dest = cp->dest;
if (!dest || (dest->flags & IP_VS_DEST_F_AVAILABLE))
continue;

if (atomic_read(&cp->n_control))
continue;

cp_c = cp->control;
IP_VS_DBG(4, "del connection\n");
ip_vs_conn_del(cp);
if (cp_c && !atomic_read(&cp_c->n_control)) {
IP_VS_DBG(4, "del controlling connection\n");
ip_vs_conn_del(cp_c);
}
}
cond_resched_rcu();

/* netns clean up started, abort delayed work */
if (!ipvs->enable)
break;
}
rcu_read_unlock();
}
#endif

/*
* per netns init and exit
*/
Expand Down
47 changes: 20 additions & 27 deletions net/netfilter/ipvs/ip_vs_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,16 +694,10 @@ static int sysctl_nat_icmp_send(struct netns_ipvs *ipvs)
return ipvs->sysctl_nat_icmp_send;
}

static int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_expire_nodest_conn;
}

#else

static int sysctl_snat_reroute(struct netns_ipvs *ipvs) { return 0; }
static int sysctl_nat_icmp_send(struct netns_ipvs *ipvs) { return 0; }
static int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs) { return 0; }

#endif

Expand Down Expand Up @@ -2097,36 +2091,35 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
}
}

if (unlikely(!cp)) {
int v;

if (!ip_vs_try_to_schedule(ipvs, af, skb, pd, &v, &cp, &iph))
return v;
}

IP_VS_DBG_PKT(11, af, pp, skb, iph.off, "Incoming packet");

/* Check the server status */
if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
if (cp && cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
/* the destination server is not available */
if (sysctl_expire_nodest_conn(ipvs)) {
bool old_ct = ip_vs_conn_uses_old_conntrack(cp, skb);

__u32 flags = cp->flags;

/* when timer already started, silently drop the packet.*/
if (timer_pending(&cp->timer))
__ip_vs_conn_put(cp);
else
ip_vs_conn_put(cp);
if (!old_ct)
cp->flags &= ~IP_VS_CONN_F_NFCT;

if (sysctl_expire_nodest_conn(ipvs) &&
!(flags & IP_VS_CONN_F_ONE_PACKET)) {
/* try to expire the connection immediately */
ip_vs_conn_expire_now(cp);
__ip_vs_conn_put(cp);
if (old_ct)
return NF_DROP;
cp = NULL;
} else {
__ip_vs_conn_put(cp);
return NF_DROP;
}
}

return NF_DROP;
if (unlikely(!cp)) {
int v;

if (!ip_vs_try_to_schedule(ipvs, af, skb, pd, &v, &cp, &iph))
return v;
}

IP_VS_DBG_PKT(11, af, pp, skb, iph.off, "Incoming packet");

ip_vs_in_stats(cp, skb);
ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pd);
if (cp->packet_xmit)
Expand Down
22 changes: 22 additions & 0 deletions net/netfilter/ipvs/ip_vs_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@ static void update_defense_level(struct netns_ipvs *ipvs)
local_bh_enable();
}

/* Handler for delayed work for expiring no
* destination connections
*/
static void expire_nodest_conn_handler(struct work_struct *work)
{
struct netns_ipvs *ipvs;

ipvs = container_of(work, struct netns_ipvs,
expire_nodest_conn_work.work);
ip_vs_expire_nodest_conn_flush(ipvs);
}

/*
* Timer for checking the defense
Expand Down Expand Up @@ -1164,6 +1175,12 @@ static void __ip_vs_del_dest(struct netns_ipvs *ipvs, struct ip_vs_dest *dest,
list_add(&dest->t_list, &ipvs->dest_trash);
dest->idle_start = 0;
spin_unlock_bh(&ipvs->dest_trash_lock);

/* Queue up delayed work to expire all no destination connections.
* No-op when CONFIG_SYSCTL is disabled.
*/
if (!cleanup)
ip_vs_enqueue_expire_nodest_conns(ipvs);
}


Expand Down Expand Up @@ -4086,13 +4103,18 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
queue_delayed_work(system_long_wq, &ipvs->defense_work,
DEFENSE_TIMER_PERIOD);

/* Init delayed work for expiring no dest conn */
INIT_DELAYED_WORK(&ipvs->expire_nodest_conn_work,
expire_nodest_conn_handler);

return 0;
}

static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs)
{
struct net *net = ipvs->net;

cancel_delayed_work_sync(&ipvs->expire_nodest_conn_work);
cancel_delayed_work_sync(&ipvs->defense_work);
cancel_work_sync(&ipvs->defense_work.work);
unregister_net_sysctl_table(ipvs->sysctl_hdr);
Expand Down
6 changes: 3 additions & 3 deletions net/netfilter/nf_conntrack_h323_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,15 @@ static unsigned int get_uint(struct bitstr *bs, int b)
case 4:
v |= *bs->cur++;
v <<= 8;
/* fall through */
fallthrough;
case 3:
v |= *bs->cur++;
v <<= 8;
/* fall through */
fallthrough;
case 2:
v |= *bs->cur++;
v <<= 8;
/* fall through */
fallthrough;
case 1:
v |= *bs->cur++;
break;
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ void nf_ct_netns_put(struct net *net, uint8_t nfproto)
switch (nfproto) {
case NFPROTO_BRIDGE:
nf_ct_netns_do_put(net, NFPROTO_BRIDGE);
/* fall through */
fallthrough;
case NFPROTO_INET:
nf_ct_netns_do_put(net, NFPROTO_IPV4);
nf_ct_netns_do_put(net, NFPROTO_IPV6);
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_proto_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
return -NF_REPEAT;
return NF_DROP;
}
/* Fall through */
fallthrough;
case TCP_CONNTRACK_IGNORE:
/* Ignored packets:
*
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
ntohs(tuple->src.u.tcp.port),
ntohs(tuple->dst.u.tcp.port));
break;
case IPPROTO_UDPLITE: /* fallthrough */
case IPPROTO_UDPLITE:
case IPPROTO_UDP:
seq_printf(s, "sport=%hu dport=%hu ",
ntohs(tuple->src.u.udp.port),
Expand Down
12 changes: 6 additions & 6 deletions net/netfilter/nf_nat_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
static const unsigned int max_attempts = 128;

switch (tuple->dst.protonum) {
case IPPROTO_ICMP: /* fallthrough */
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
/* id is same for either direction... */
keyptr = &tuple->src.u.icmp.id;
Expand Down Expand Up @@ -442,11 +442,11 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
}
goto find_free_id;
#endif
case IPPROTO_UDP: /* fallthrough */
case IPPROTO_UDPLITE: /* fallthrough */
case IPPROTO_TCP: /* fallthrough */
case IPPROTO_SCTP: /* fallthrough */
case IPPROTO_DCCP: /* fallthrough */
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
if (maniptype == NF_NAT_MANIP_SRC)
keyptr = &tuple->src.u.all;
else
Expand Down
Loading

0 comments on commit f2e0b29

Please sign in to comment.