Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several cases of bug fixes in 'net' overlapping other changes in 'net-next-. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -533,9 +533,9 @@ EXPORT_SYMBOL(inet_dgram_connect);
|
||||
|
||||
static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
|
||||
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
sk->sk_write_pending += writebias;
|
||||
|
||||
/* Basic assumption: if someone sets sk->sk_err, he _must_
|
||||
@@ -545,13 +545,12 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias)
|
||||
*/
|
||||
while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
|
||||
lock_sock(sk);
|
||||
if (signal_pending(current) || !timeo)
|
||||
break;
|
||||
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
|
||||
}
|
||||
finish_wait(sk_sleep(sk), &wait);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
sk->sk_write_pending -= writebias;
|
||||
return timeo;
|
||||
}
|
||||
|
@@ -2413,22 +2413,19 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
|
||||
struct key_vector *l, **tp = &iter->tnode;
|
||||
t_key key;
|
||||
|
||||
/* use cache location of next-to-find key */
|
||||
/* use cached location of previously found key */
|
||||
if (iter->pos > 0 && pos >= iter->pos) {
|
||||
pos -= iter->pos;
|
||||
key = iter->key;
|
||||
} else {
|
||||
iter->pos = 0;
|
||||
iter->pos = 1;
|
||||
key = 0;
|
||||
}
|
||||
|
||||
while ((l = leaf_walk_rcu(tp, key)) != NULL) {
|
||||
pos -= iter->pos;
|
||||
|
||||
while ((l = leaf_walk_rcu(tp, key)) && (pos-- > 0)) {
|
||||
key = l->key + 1;
|
||||
iter->pos++;
|
||||
|
||||
if (--pos <= 0)
|
||||
break;
|
||||
|
||||
l = NULL;
|
||||
|
||||
/* handle unlikely case of a key wrap */
|
||||
@@ -2437,7 +2434,7 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
|
||||
}
|
||||
|
||||
if (l)
|
||||
iter->key = key; /* remember it */
|
||||
iter->key = l->key; /* remember it */
|
||||
else
|
||||
iter->pos = 0; /* forget it */
|
||||
|
||||
@@ -2465,7 +2462,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
return fib_route_get_idx(iter, *pos);
|
||||
|
||||
iter->pos = 0;
|
||||
iter->key = 0;
|
||||
iter->key = KEY_MAX;
|
||||
|
||||
return SEQ_START_TOKEN;
|
||||
}
|
||||
@@ -2474,7 +2471,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct fib_route_iter *iter = seq->private;
|
||||
struct key_vector *l = NULL;
|
||||
t_key key = iter->key;
|
||||
t_key key = iter->key + 1;
|
||||
|
||||
++*pos;
|
||||
|
||||
@@ -2483,7 +2480,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
l = leaf_walk_rcu(&iter->tnode, key);
|
||||
|
||||
if (l) {
|
||||
iter->key = l->key + 1;
|
||||
iter->key = l->key;
|
||||
iter->pos++;
|
||||
} else {
|
||||
iter->pos = 0;
|
||||
|
@@ -479,7 +479,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
|
||||
fl4->flowi4_proto = IPPROTO_ICMP;
|
||||
fl4->fl4_icmp_type = type;
|
||||
fl4->fl4_icmp_code = code;
|
||||
fl4->flowi4_oif = l3mdev_master_ifindex(skb_in->dev);
|
||||
fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev);
|
||||
|
||||
security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
|
||||
rt = __ip_route_output_key_hash(net, fl4,
|
||||
@@ -504,7 +504,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
|
||||
if (err)
|
||||
goto relookup_failed;
|
||||
|
||||
if (inet_addr_type_dev_table(net, skb_in->dev,
|
||||
if (inet_addr_type_dev_table(net, skb_dst(skb_in)->dev,
|
||||
fl4_dec.saddr) == RTN_LOCAL) {
|
||||
rt2 = __ip_route_output_key(net, &fl4_dec);
|
||||
if (IS_ERR(rt2))
|
||||
|
@@ -117,7 +117,7 @@ int ip_forward(struct sk_buff *skb)
|
||||
if (opt->is_strictroute && rt->rt_uses_gateway)
|
||||
goto sr_failed;
|
||||
|
||||
IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
|
||||
IPCB(skb)->flags |= IPSKB_FORWARDED;
|
||||
mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
|
||||
if (ip_exceeds_mtu(skb, mtu)) {
|
||||
IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
|
||||
|
@@ -239,19 +239,23 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
|
||||
struct sk_buff *segs;
|
||||
int ret = 0;
|
||||
|
||||
/* common case: fragmentation of segments is not allowed,
|
||||
* or seglen is <= mtu
|
||||
/* common case: seglen is <= mtu
|
||||
*/
|
||||
if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) ||
|
||||
skb_gso_validate_mtu(skb, mtu))
|
||||
if (skb_gso_validate_mtu(skb, mtu))
|
||||
return ip_finish_output2(net, sk, skb);
|
||||
|
||||
/* Slowpath - GSO segment length is exceeding the dst MTU.
|
||||
/* Slowpath - GSO segment length exceeds the egress MTU.
|
||||
*
|
||||
* This can happen in two cases:
|
||||
* 1) TCP GRO packet, DF bit not set
|
||||
* 2) skb arrived via virtio-net, we thus get TSO/GSO skbs directly
|
||||
* from host network stack.
|
||||
* This can happen in several cases:
|
||||
* - Forwarding of a TCP GRO skb, when DF flag is not set.
|
||||
* - Forwarding of an skb that arrived on a virtualization interface
|
||||
* (virtio-net/vhost/tap) with TSO/GSO size set by other network
|
||||
* stack.
|
||||
* - Local GSO skb transmitted on an NETIF_F_TSO tunnel stacked over an
|
||||
* interface with a smaller MTU.
|
||||
* - Arriving GRO skb (or GSO skb in a virtualized environment) that is
|
||||
* bridged to a NETIF_F_TSO tunnel stacked over an interface with an
|
||||
* insufficent MTU.
|
||||
*/
|
||||
features = netif_skb_features(skb);
|
||||
BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
|
||||
@@ -1579,7 +1583,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
oif = arg->bound_dev_if;
|
||||
oif = oif ? : skb->skb_iif;
|
||||
if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
|
||||
oif = skb->skb_iif;
|
||||
|
||||
flowi4_init_output(&fl4, oif,
|
||||
IP4_REPLY_MARK(net, skb->mark),
|
||||
|
@@ -63,7 +63,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
|
||||
int pkt_len = skb->len - skb_inner_network_offset(skb);
|
||||
struct net *net = dev_net(rt->dst.dev);
|
||||
struct net_device *dev = skb->dev;
|
||||
int skb_iif = skb->skb_iif;
|
||||
struct iphdr *iph;
|
||||
int err;
|
||||
|
||||
@@ -73,16 +72,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
|
||||
skb_dst_set(skb, &rt->dst);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
|
||||
if (skb_iif && !(df & htons(IP_DF))) {
|
||||
/* Arrived from an ingress interface, got encapsulated, with
|
||||
* fragmentation of encapulating frames allowed.
|
||||
* If skb is gso, the resulting encapsulated network segments
|
||||
* may exceed dst mtu.
|
||||
* Allow IP Fragmentation of segments.
|
||||
*/
|
||||
IPCB(skb)->flags |= IPSKB_FRAG_SEGS;
|
||||
}
|
||||
|
||||
/* Push down and install the IP header. */
|
||||
skb_push(skb, sizeof(struct iphdr));
|
||||
skb_reset_network_header(skb);
|
||||
|
@@ -1754,7 +1754,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
|
||||
vif->dev->stats.tx_bytes += skb->len;
|
||||
}
|
||||
|
||||
IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
|
||||
IPCB(skb)->flags |= IPSKB_FORWARDED;
|
||||
|
||||
/* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
|
||||
* not only before forwarding, but after forwarding on all output
|
||||
|
@@ -28,7 +28,7 @@ static void nft_dup_ipv4_eval(const struct nft_expr *expr,
|
||||
struct in_addr gw = {
|
||||
.s_addr = (__force __be32)regs->data[priv->sreg_addr],
|
||||
};
|
||||
int oif = regs->data[priv->sreg_dev];
|
||||
int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1;
|
||||
|
||||
nf_dup_ipv4(nft_net(pkt), pkt->skb, nft_hook(pkt), &gw, oif);
|
||||
}
|
||||
@@ -59,7 +59,9 @@ static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
{
|
||||
struct nft_dup_ipv4 *priv = nft_expr_priv(expr);
|
||||
|
||||
if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr) ||
|
||||
if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr))
|
||||
goto nla_put_failure;
|
||||
if (priv->sreg_dev &&
|
||||
nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
@@ -755,7 +755,9 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
|
||||
goto reject_redirect;
|
||||
}
|
||||
|
||||
n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw);
|
||||
n = __ipv4_neigh_lookup(rt->dst.dev, new_gw);
|
||||
if (!n)
|
||||
n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev);
|
||||
if (!IS_ERR(n)) {
|
||||
if (!(n->nud_state & NUD_VALID)) {
|
||||
neigh_event_send(n, NULL);
|
||||
|
@@ -1162,7 +1162,7 @@ restart:
|
||||
|
||||
err = -EPIPE;
|
||||
if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
|
||||
goto out_err;
|
||||
goto do_error;
|
||||
|
||||
sg = !!(sk->sk_route_caps & NETIF_F_SG);
|
||||
|
||||
@@ -1239,7 +1239,7 @@ new_segment:
|
||||
|
||||
if (!skb_can_coalesce(skb, i, pfrag->page,
|
||||
pfrag->offset)) {
|
||||
if (i == sysctl_max_skb_frags || !sg) {
|
||||
if (i >= sysctl_max_skb_frags || !sg) {
|
||||
tcp_mark_push(tp, skb);
|
||||
goto new_segment;
|
||||
}
|
||||
|
@@ -56,6 +56,7 @@ struct dctcp {
|
||||
u32 next_seq;
|
||||
u32 ce_state;
|
||||
u32 delayed_ack_reserved;
|
||||
u32 loss_cwnd;
|
||||
};
|
||||
|
||||
static unsigned int dctcp_shift_g __read_mostly = 4; /* g = 1/2^4 */
|
||||
@@ -96,6 +97,7 @@ static void dctcp_init(struct sock *sk)
|
||||
ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA);
|
||||
|
||||
ca->delayed_ack_reserved = 0;
|
||||
ca->loss_cwnd = 0;
|
||||
ca->ce_state = 0;
|
||||
|
||||
dctcp_reset(tp, ca);
|
||||
@@ -111,9 +113,10 @@ static void dctcp_init(struct sock *sk)
|
||||
|
||||
static u32 dctcp_ssthresh(struct sock *sk)
|
||||
{
|
||||
const struct dctcp *ca = inet_csk_ca(sk);
|
||||
struct dctcp *ca = inet_csk_ca(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
ca->loss_cwnd = tp->snd_cwnd;
|
||||
return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->dctcp_alpha) >> 11U), 2U);
|
||||
}
|
||||
|
||||
@@ -308,12 +311,20 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 dctcp_cwnd_undo(struct sock *sk)
|
||||
{
|
||||
const struct dctcp *ca = inet_csk_ca(sk);
|
||||
|
||||
return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
|
||||
}
|
||||
|
||||
static struct tcp_congestion_ops dctcp __read_mostly = {
|
||||
.init = dctcp_init,
|
||||
.in_ack_event = dctcp_update_alpha,
|
||||
.cwnd_event = dctcp_cwnd_event,
|
||||
.ssthresh = dctcp_ssthresh,
|
||||
.cong_avoid = tcp_reno_cong_avoid,
|
||||
.undo_cwnd = dctcp_cwnd_undo,
|
||||
.set_state = dctcp_state,
|
||||
.get_info = dctcp_get_info,
|
||||
.flags = TCP_CONG_NEEDS_ECN,
|
||||
|
@@ -1567,6 +1567,21 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
EXPORT_SYMBOL(tcp_add_backlog);
|
||||
|
||||
int tcp_filter(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct tcphdr *th = (struct tcphdr *)skb->data;
|
||||
unsigned int eaten = skb->len;
|
||||
int err;
|
||||
|
||||
err = sk_filter_trim_cap(sk, skb, th->doff * 4);
|
||||
if (!err) {
|
||||
eaten -= skb->len;
|
||||
TCP_SKB_CB(skb)->end_seq -= eaten;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(tcp_filter);
|
||||
|
||||
/*
|
||||
* From tcp_input.c
|
||||
*/
|
||||
@@ -1679,8 +1694,10 @@ process:
|
||||
|
||||
nf_reset(skb);
|
||||
|
||||
if (sk_filter(sk, skb))
|
||||
if (tcp_filter(sk, skb))
|
||||
goto discard_and_relse;
|
||||
th = (const struct tcphdr *)skb->data;
|
||||
iph = ip_hdr(skb);
|
||||
|
||||
skb->dev = NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user