Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several cases of overlapping changes, except the packet scheduler conflicts which deal with the addition of the free list parameter to qdisc_enqueue(). Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -23,6 +23,11 @@ struct esp_skb_cb {
|
||||
void *tmp;
|
||||
};
|
||||
|
||||
struct esp_output_extra {
|
||||
__be32 seqhi;
|
||||
u32 esphoff;
|
||||
};
|
||||
|
||||
#define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
|
||||
|
||||
static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
|
||||
@@ -35,11 +40,11 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
|
||||
*
|
||||
* TODO: Use spare space in skb for this where possible.
|
||||
*/
|
||||
static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen)
|
||||
static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int extralen)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
len = seqhilen;
|
||||
len = extralen;
|
||||
|
||||
len += crypto_aead_ivsize(aead);
|
||||
|
||||
@@ -57,15 +62,16 @@ static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen)
|
||||
return kmalloc(len, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static inline __be32 *esp_tmp_seqhi(void *tmp)
|
||||
static inline void *esp_tmp_extra(void *tmp)
|
||||
{
|
||||
return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32));
|
||||
return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra));
|
||||
}
|
||||
static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen)
|
||||
|
||||
static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int extralen)
|
||||
{
|
||||
return crypto_aead_ivsize(aead) ?
|
||||
PTR_ALIGN((u8 *)tmp + seqhilen,
|
||||
crypto_aead_alignmask(aead) + 1) : tmp + seqhilen;
|
||||
PTR_ALIGN((u8 *)tmp + extralen,
|
||||
crypto_aead_alignmask(aead) + 1) : tmp + extralen;
|
||||
}
|
||||
|
||||
static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
|
||||
@@ -99,7 +105,7 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset)
|
||||
{
|
||||
struct ip_esp_hdr *esph = (void *)(skb->data + offset);
|
||||
void *tmp = ESP_SKB_CB(skb)->tmp;
|
||||
__be32 *seqhi = esp_tmp_seqhi(tmp);
|
||||
__be32 *seqhi = esp_tmp_extra(tmp);
|
||||
|
||||
esph->seq_no = esph->spi;
|
||||
esph->spi = *seqhi;
|
||||
@@ -107,7 +113,11 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset)
|
||||
|
||||
static void esp_output_restore_header(struct sk_buff *skb)
|
||||
{
|
||||
esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32));
|
||||
void *tmp = ESP_SKB_CB(skb)->tmp;
|
||||
struct esp_output_extra *extra = esp_tmp_extra(tmp);
|
||||
|
||||
esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff -
|
||||
sizeof(__be32));
|
||||
}
|
||||
|
||||
static void esp_output_done_esn(struct crypto_async_request *base, int err)
|
||||
@@ -121,6 +131,7 @@ static void esp_output_done_esn(struct crypto_async_request *base, int err)
|
||||
static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
int err;
|
||||
struct esp_output_extra *extra;
|
||||
struct ip_esp_hdr *esph;
|
||||
struct crypto_aead *aead;
|
||||
struct aead_request *req;
|
||||
@@ -137,8 +148,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
int tfclen;
|
||||
int nfrags;
|
||||
int assoclen;
|
||||
int seqhilen;
|
||||
__be32 *seqhi;
|
||||
int extralen;
|
||||
__be64 seqno;
|
||||
|
||||
/* skb is pure payload to encrypt */
|
||||
@@ -166,21 +176,21 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
nfrags = err;
|
||||
|
||||
assoclen = sizeof(*esph);
|
||||
seqhilen = 0;
|
||||
extralen = 0;
|
||||
|
||||
if (x->props.flags & XFRM_STATE_ESN) {
|
||||
seqhilen += sizeof(__be32);
|
||||
assoclen += seqhilen;
|
||||
extralen += sizeof(*extra);
|
||||
assoclen += sizeof(__be32);
|
||||
}
|
||||
|
||||
tmp = esp_alloc_tmp(aead, nfrags, seqhilen);
|
||||
tmp = esp_alloc_tmp(aead, nfrags, extralen);
|
||||
if (!tmp) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
seqhi = esp_tmp_seqhi(tmp);
|
||||
iv = esp_tmp_iv(aead, tmp, seqhilen);
|
||||
extra = esp_tmp_extra(tmp);
|
||||
iv = esp_tmp_iv(aead, tmp, extralen);
|
||||
req = esp_tmp_req(aead, iv);
|
||||
sg = esp_req_sg(aead, req);
|
||||
|
||||
@@ -247,8 +257,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
* encryption.
|
||||
*/
|
||||
if ((x->props.flags & XFRM_STATE_ESN)) {
|
||||
esph = (void *)(skb_transport_header(skb) - sizeof(__be32));
|
||||
*seqhi = esph->spi;
|
||||
extra->esphoff = (unsigned char *)esph -
|
||||
skb_transport_header(skb);
|
||||
esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4);
|
||||
extra->seqhi = esph->spi;
|
||||
esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi);
|
||||
aead_request_set_callback(req, 0, esp_output_done_esn, skb);
|
||||
}
|
||||
@@ -445,7 +457,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
goto out;
|
||||
|
||||
ESP_SKB_CB(skb)->tmp = tmp;
|
||||
seqhi = esp_tmp_seqhi(tmp);
|
||||
seqhi = esp_tmp_extra(tmp);
|
||||
iv = esp_tmp_iv(aead, tmp, seqhilen);
|
||||
req = esp_tmp_req(aead, iv);
|
||||
sg = esp_req_sg(aead, req);
|
||||
|
@@ -62,26 +62,26 @@ EXPORT_SYMBOL_GPL(gre_del_protocol);
|
||||
|
||||
/* Fills in tpi and returns header length to be pulled. */
|
||||
int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
||||
bool *csum_err, __be16 proto)
|
||||
bool *csum_err, __be16 proto, int nhs)
|
||||
{
|
||||
const struct gre_base_hdr *greh;
|
||||
__be32 *options;
|
||||
int hdr_len;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
|
||||
if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr))))
|
||||
return -EINVAL;
|
||||
|
||||
greh = (struct gre_base_hdr *)skb_transport_header(skb);
|
||||
greh = (struct gre_base_hdr *)(skb->data + nhs);
|
||||
if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
|
||||
return -EINVAL;
|
||||
|
||||
tpi->flags = gre_flags_to_tnl_flags(greh->flags);
|
||||
hdr_len = gre_calc_hlen(tpi->flags);
|
||||
|
||||
if (!pskb_may_pull(skb, hdr_len))
|
||||
if (!pskb_may_pull(skb, nhs + hdr_len))
|
||||
return -EINVAL;
|
||||
|
||||
greh = (struct gre_base_hdr *)skb_transport_header(skb);
|
||||
greh = (struct gre_base_hdr *)(skb->data + nhs);
|
||||
tpi->proto = greh->protocol;
|
||||
|
||||
options = (__be32 *)(greh + 1);
|
||||
|
@@ -49,12 +49,6 @@
|
||||
#include <net/gre.h>
|
||||
#include <net/dst_metadata.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/ipv6.h>
|
||||
#include <net/ip6_fib.h>
|
||||
#include <net/ip6_route.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Problems & solutions
|
||||
--------------------
|
||||
@@ -226,12 +220,14 @@ static void gre_err(struct sk_buff *skb, u32 info)
|
||||
* by themselves???
|
||||
*/
|
||||
|
||||
const struct iphdr *iph = (struct iphdr *)skb->data;
|
||||
const int type = icmp_hdr(skb)->type;
|
||||
const int code = icmp_hdr(skb)->code;
|
||||
struct tnl_ptk_info tpi;
|
||||
bool csum_err = false;
|
||||
|
||||
if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP)) < 0) {
|
||||
if (gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP),
|
||||
iph->ihl * 4) < 0) {
|
||||
if (!csum_err) /* ignore csum errors. */
|
||||
return;
|
||||
}
|
||||
@@ -347,7 +343,7 @@ static int gre_rcv(struct sk_buff *skb)
|
||||
}
|
||||
#endif
|
||||
|
||||
hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP));
|
||||
hdr_len = gre_parse_header(skb, &tpi, &csum_err, htons(ETH_P_IP), 0);
|
||||
if (hdr_len < 0)
|
||||
goto drop;
|
||||
|
||||
@@ -1154,6 +1150,7 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
|
||||
{
|
||||
struct nlattr *tb[IFLA_MAX + 1];
|
||||
struct net_device *dev;
|
||||
LIST_HEAD(list_kill);
|
||||
struct ip_tunnel *t;
|
||||
int err;
|
||||
|
||||
@@ -1169,8 +1166,10 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
|
||||
t->collect_md = true;
|
||||
|
||||
err = ipgre_newlink(net, dev, tb, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
if (err < 0) {
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* openvswitch users expect packet sizes to be unrestricted,
|
||||
* so set the largest MTU we can.
|
||||
@@ -1179,9 +1178,14 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = rtnl_configure_link(dev, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
return dev;
|
||||
out:
|
||||
free_netdev(dev);
|
||||
ip_tunnel_dellink(dev, &list_kill);
|
||||
unregister_netdevice_many(&list_kill);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
|
||||
|
@@ -127,7 +127,9 @@ __be32 ic_myaddr = NONE; /* My IP address */
|
||||
static __be32 ic_netmask = NONE; /* Netmask for local subnet */
|
||||
__be32 ic_gateway = NONE; /* Gateway IP address */
|
||||
|
||||
__be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */
|
||||
#ifdef IPCONFIG_DYNAMIC
|
||||
static __be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */
|
||||
#endif
|
||||
|
||||
__be32 ic_servaddr = NONE; /* Boot server IP address */
|
||||
|
||||
|
@@ -891,8 +891,10 @@ static struct mfc_cache *ipmr_cache_alloc(void)
|
||||
{
|
||||
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
|
||||
|
||||
if (c)
|
||||
if (c) {
|
||||
c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
|
||||
c->mfc_un.res.minvif = MAXVIFS;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@@ -2753,7 +2753,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *hole = NULL;
|
||||
u32 last_lost;
|
||||
u32 max_segs, last_lost;
|
||||
int mib_idx;
|
||||
int fwd_rexmitting = 0;
|
||||
|
||||
@@ -2773,6 +2773,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
|
||||
last_lost = tp->snd_una;
|
||||
}
|
||||
|
||||
max_segs = tcp_tso_autosize(sk, tcp_current_mss(sk));
|
||||
tcp_for_write_queue_from(skb, sk) {
|
||||
__u8 sacked = TCP_SKB_CB(skb)->sacked;
|
||||
int segs;
|
||||
@@ -2786,6 +2787,10 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
|
||||
segs = tp->snd_cwnd - tcp_packets_in_flight(tp);
|
||||
if (segs <= 0)
|
||||
return;
|
||||
/* In case tcp_shift_skb_data() have aggregated large skbs,
|
||||
* we need to make sure not sending too bigs TSO packets
|
||||
*/
|
||||
segs = min_t(int, segs, max_segs);
|
||||
|
||||
if (fwd_rexmitting) {
|
||||
begin_fwd:
|
||||
|
@@ -391,9 +391,9 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum)
|
||||
return udp_lib_get_port(sk, snum, ipv4_rcv_saddr_equal, hash2_nulladdr);
|
||||
}
|
||||
|
||||
static inline int compute_score(struct sock *sk, struct net *net,
|
||||
__be32 saddr, unsigned short hnum, __be16 sport,
|
||||
__be32 daddr, __be16 dport, int dif)
|
||||
static int compute_score(struct sock *sk, struct net *net,
|
||||
__be32 saddr, __be16 sport,
|
||||
__be32 daddr, unsigned short hnum, int dif)
|
||||
{
|
||||
int score;
|
||||
struct inet_sock *inet;
|
||||
@@ -434,52 +434,6 @@ static inline int compute_score(struct sock *sk, struct net *net,
|
||||
return score;
|
||||
}
|
||||
|
||||
/*
|
||||
* In this second variant, we check (daddr, dport) matches (inet_rcv_sadd, inet_num)
|
||||
*/
|
||||
static inline int compute_score2(struct sock *sk, struct net *net,
|
||||
__be32 saddr, __be16 sport,
|
||||
__be32 daddr, unsigned int hnum, int dif)
|
||||
{
|
||||
int score;
|
||||
struct inet_sock *inet;
|
||||
|
||||
if (!net_eq(sock_net(sk), net) ||
|
||||
ipv6_only_sock(sk))
|
||||
return -1;
|
||||
|
||||
inet = inet_sk(sk);
|
||||
|
||||
if (inet->inet_rcv_saddr != daddr ||
|
||||
inet->inet_num != hnum)
|
||||
return -1;
|
||||
|
||||
score = (sk->sk_family == PF_INET) ? 2 : 1;
|
||||
|
||||
if (inet->inet_daddr) {
|
||||
if (inet->inet_daddr != saddr)
|
||||
return -1;
|
||||
score += 4;
|
||||
}
|
||||
|
||||
if (inet->inet_dport) {
|
||||
if (inet->inet_dport != sport)
|
||||
return -1;
|
||||
score += 4;
|
||||
}
|
||||
|
||||
if (sk->sk_bound_dev_if) {
|
||||
if (sk->sk_bound_dev_if != dif)
|
||||
return -1;
|
||||
score += 4;
|
||||
}
|
||||
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
score++;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
|
||||
const __u16 lport, const __be32 faddr,
|
||||
const __be16 fport)
|
||||
@@ -492,11 +446,11 @@ static u32 udp_ehashfn(const struct net *net, const __be32 laddr,
|
||||
udp_ehash_secret + net_hash_mix(net));
|
||||
}
|
||||
|
||||
/* called with read_rcu_lock() */
|
||||
/* called with rcu_read_lock() */
|
||||
static struct sock *udp4_lib_lookup2(struct net *net,
|
||||
__be32 saddr, __be16 sport,
|
||||
__be32 daddr, unsigned int hnum, int dif,
|
||||
struct udp_hslot *hslot2, unsigned int slot2,
|
||||
struct udp_hslot *hslot2,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct sock *sk, *result;
|
||||
@@ -506,7 +460,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
|
||||
result = NULL;
|
||||
badness = 0;
|
||||
udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
|
||||
score = compute_score2(sk, net, saddr, sport,
|
||||
score = compute_score(sk, net, saddr, sport,
|
||||
daddr, hnum, dif);
|
||||
if (score > badness) {
|
||||
reuseport = sk->sk_reuseport;
|
||||
@@ -554,17 +508,22 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
|
||||
|
||||
result = udp4_lib_lookup2(net, saddr, sport,
|
||||
daddr, hnum, dif,
|
||||
hslot2, slot2, skb);
|
||||
hslot2, skb);
|
||||
if (!result) {
|
||||
unsigned int old_slot2 = slot2;
|
||||
hash2 = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum);
|
||||
slot2 = hash2 & udptable->mask;
|
||||
/* avoid searching the same slot again. */
|
||||
if (unlikely(slot2 == old_slot2))
|
||||
return result;
|
||||
|
||||
hslot2 = &udptable->hash2[slot2];
|
||||
if (hslot->count < hslot2->count)
|
||||
goto begin;
|
||||
|
||||
result = udp4_lib_lookup2(net, saddr, sport,
|
||||
htonl(INADDR_ANY), hnum, dif,
|
||||
hslot2, slot2, skb);
|
||||
daddr, hnum, dif,
|
||||
hslot2, skb);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -572,8 +531,8 @@ begin:
|
||||
result = NULL;
|
||||
badness = 0;
|
||||
sk_for_each_rcu(sk, &hslot->head) {
|
||||
score = compute_score(sk, net, saddr, hnum, sport,
|
||||
daddr, dport, dif);
|
||||
score = compute_score(sk, net, saddr, sport,
|
||||
daddr, hnum, dif);
|
||||
if (score > badness) {
|
||||
reuseport = sk->sk_reuseport;
|
||||
if (reuseport) {
|
||||
@@ -1755,8 +1714,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
|
||||
return err;
|
||||
}
|
||||
|
||||
return skb_checksum_init_zero_check(skb, proto, uh->check,
|
||||
inet_compute_pseudo);
|
||||
/* Note, we are only interested in != 0 or == 0, thus the
|
||||
* force to int.
|
||||
*/
|
||||
return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
|
||||
inet_compute_pseudo);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user