Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions net/ipv6/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
if (!skb2)
return 1;

/* Remove debris left by IPv4 stack. */
memset(IP6CB(skb2), 0, sizeof(*IP6CB(skb2)));

skb_dst_drop(skb2);
skb_pull(skb2, nhs);
skb_reset_network_header(skb2);
Expand Down
5 changes: 5 additions & 0 deletions net/ipv6/ip6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,16 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (!skb2)
return 0;

/* Remove debris left by IPv6 stack. */
memset(IPCB(skb2), 0, sizeof(*IPCB(skb2)));

skb_dst_drop(skb2);

skb_pull(skb2, offset);
skb_reset_network_header(skb2);
eiph = ip_hdr(skb2);
if (eiph->version != 4 || eiph->ihl < 5)
goto out;

/* Try to guess incoming interface */
rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL, eiph->saddr,
Expand Down
54 changes: 35 additions & 19 deletions net/sched/sch_cake.c
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
b->backlogs[idx] -= len;
b->tin_backlog -= len;
sch->qstats.backlog -= len;
qdisc_tree_reduce_backlog(sch, 1, len);

flow->dropped++;
b->tin_dropped++;
Expand Down Expand Up @@ -1694,14 +1693,14 @@ static void cake_reconfigure(struct Qdisc *sch);
static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
u32 idx, tin, prev_qlen, prev_backlog, drop_id;
struct cake_sched_data *q = qdisc_priv(sch);
int len = qdisc_pkt_len(skb);
int ret;
int len = qdisc_pkt_len(skb), ret;
struct sk_buff *ack = NULL;
ktime_t now = ktime_get();
struct cake_tin_data *b;
struct cake_flow *flow;
u32 idx;
bool same_flow = false;

/* choose flow to insert into */
idx = cake_classify(sch, &b, skb, q->flow_mode, &ret);
Expand All @@ -1711,6 +1710,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
__qdisc_drop(skb, to_free);
return ret;
}
tin = (u32)(b - q->tins);
idx--;
flow = &b->flows[idx];

Expand Down Expand Up @@ -1773,6 +1773,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
consume_skb(skb);
} else {
/* not splitting */
int ack_pkt_len = 0;

cobalt_set_enqueue_time(skb, now);
get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb);
flow_queue_add(flow, skb);
Expand All @@ -1783,13 +1785,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (ack) {
b->ack_drops++;
sch->qstats.drops++;
b->bytes += qdisc_pkt_len(ack);
len -= qdisc_pkt_len(ack);
ack_pkt_len = qdisc_pkt_len(ack);
b->bytes += ack_pkt_len;
q->buffer_used += skb->truesize - ack->truesize;
if (q->rate_flags & CAKE_FLAG_INGRESS)
cake_advance_shaper(q, b, ack, now, true);

qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack));
qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len);
consume_skb(ack);
} else {
sch->q.qlen++;
Expand All @@ -1798,11 +1800,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,

/* stats */
b->packets++;
b->bytes += len;
b->backlogs[idx] += len;
b->tin_backlog += len;
sch->qstats.backlog += len;
q->avg_window_bytes += len;
b->bytes += len - ack_pkt_len;
b->backlogs[idx] += len - ack_pkt_len;
b->tin_backlog += len - ack_pkt_len;
sch->qstats.backlog += len - ack_pkt_len;
q->avg_window_bytes += len - ack_pkt_len;
}

if (q->overflow_timeout)
Expand Down Expand Up @@ -1895,15 +1897,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (q->buffer_used > q->buffer_max_used)
q->buffer_max_used = q->buffer_used;

if (q->buffer_used > q->buffer_limit) {
u32 dropped = 0;
if (q->buffer_used <= q->buffer_limit)
return NET_XMIT_SUCCESS;

while (q->buffer_used > q->buffer_limit) {
dropped++;
cake_drop(sch, to_free);
}
b->drop_overlimit += dropped;
prev_qlen = sch->q.qlen;
prev_backlog = sch->qstats.backlog;

while (q->buffer_used > q->buffer_limit) {
drop_id = cake_drop(sch, to_free);
if ((drop_id >> 16) == tin &&
(drop_id & 0xFFFF) == idx)
same_flow = true;
}

prev_qlen -= sch->q.qlen;
prev_backlog -= sch->qstats.backlog;
b->drop_overlimit += prev_qlen;

if (same_flow) {
qdisc_tree_reduce_backlog(sch, prev_qlen - 1,
prev_backlog - len);
return NET_XMIT_CN;
}
qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog);
return NET_XMIT_SUCCESS;
}

Expand Down
2 changes: 1 addition & 1 deletion net/sched/sch_choke.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx,
if (idx == q->tail)
choke_zap_tail_holes(q);

--sch->q.qlen;
qdisc_qstats_backlog_dec(sch, skb);
qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb));
qdisc_drop(skb, sch, to_free);
--sch->q.qlen;
}

struct choke_skb_cb {
Expand Down
Loading