Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

The conflict was an interaction between a bug fix in the
netvsc driver in 'net' and an optimization of the RX path
in 'net-next'.

Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
David S. Miller 2017-02-07 16:29:30 -05:00
commit 3efa70d78f
176 changed files with 1221 additions and 1049 deletions

View file

@ -3393,9 +3393,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
}
if (idev) {
if (idev->if_flags & IF_READY)
/* device is already configured. */
if (idev->if_flags & IF_READY) {
/* device is already configured -
* but resend MLD reports, we might
* have roamed and need to update
* multicast snooping switches
*/
ipv6_mc_up(idev);
break;
}
idev->if_flags |= IF_READY;
}

View file

@ -327,7 +327,6 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
struct ipv6_sr_hdr *hdr;
struct inet6_dev *idev;
struct in6_addr *addr;
bool cleanup = false;
int accept_seg6;
hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
@ -351,11 +350,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
#endif
looped_back:
if (hdr->segments_left > 0) {
if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 &&
sr_has_cleanup(hdr))
cleanup = true;
} else {
if (hdr->segments_left == 0) {
if (hdr->nexthdr == NEXTHDR_IPV6) {
int offset = (hdr->hdrlen + 1) << 3;
@ -418,21 +413,6 @@ looped_back:
ipv6_hdr(skb)->daddr = *addr;
if (cleanup) {
int srhlen = (hdr->hdrlen + 1) << 3;
int nh = hdr->nexthdr;
skb_pull_rcsum(skb, sizeof(struct ipv6hdr) + srhlen);
memmove(skb_network_header(skb) + srhlen,
skb_network_header(skb),
(unsigned char *)hdr - skb_network_header(skb));
skb->network_header += srhlen;
ipv6_hdr(skb)->nexthdr = nh;
ipv6_hdr(skb)->payload_len = htons(skb->len -
sizeof(struct ipv6hdr));
skb_push_rcsum(skb, sizeof(struct ipv6hdr));
}
skb_dst_drop(skb);
ip6_route_input(skb);
@ -453,13 +433,8 @@ looped_back:
}
ipv6_hdr(skb)->hop_limit--;
/* be sure that srh is still present before reinjecting */
if (!cleanup) {
skb_pull(skb, sizeof(struct ipv6hdr));
goto looped_back;
}
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
skb_pull(skb, sizeof(struct ipv6hdr));
goto looped_back;
}
dst_input(skb);

View file

@ -367,35 +367,37 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
u8 type, u8 code, int offset, __be32 info)
{
const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
__be16 *p = (__be16 *)(skb->data + offset);
int grehlen = offset + 4;
const struct gre_base_hdr *greh;
const struct ipv6hdr *ipv6h;
int grehlen = sizeof(*greh);
struct ip6_tnl *t;
int key_off = 0;
__be16 flags;
__be32 key;
flags = p[0];
if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
if (flags&(GRE_VERSION|GRE_ROUTING))
return;
if (flags&GRE_KEY) {
grehlen += 4;
if (flags&GRE_CSUM)
grehlen += 4;
}
if (!pskb_may_pull(skb, offset + grehlen))
return;
greh = (const struct gre_base_hdr *)(skb->data + offset);
flags = greh->flags;
if (flags & (GRE_VERSION | GRE_ROUTING))
return;
if (flags & GRE_CSUM)
grehlen += 4;
if (flags & GRE_KEY) {
key_off = grehlen + offset;
grehlen += 4;
}
/* If only 8 bytes returned, keyed message will be dropped here */
if (!pskb_may_pull(skb, grehlen))
if (!pskb_may_pull(skb, offset + grehlen))
return;
ipv6h = (const struct ipv6hdr *)skb->data;
p = (__be16 *)(skb->data + offset);
greh = (const struct gre_base_hdr *)(skb->data + offset);
key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
flags & GRE_KEY ?
*(((__be32 *)p) + (grehlen / 4) - 1) : 0,
p[1]);
key, greh->protocol);
if (!t)
return;

View file

@ -174,7 +174,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
* hash function (RadioGatun) with up to 1216 bits
*/
/* saddr(16) + first_seg(1) + cleanup(1) + keyid(4) + seglist(16n) */
/* saddr(16) + first_seg(1) + flags(1) + keyid(4) + seglist(16n) */
plen = 16 + 1 + 1 + 4 + (hdr->first_segment + 1) * 16;
/* this limit allows for 14 segments */
@ -186,7 +186,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
*
* 1. Source IPv6 address (128 bits)
* 2. first_segment value (8 bits)
* 3. cleanup flag (8 bits: highest bit is cleanup value, others are 0)
* 3. Flags (8 bits)
* 4. HMAC Key ID (32 bits)
* 5. All segments in the segments list (n * 128 bits)
*/
@ -202,8 +202,8 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr,
/* first_segment value */
*off++ = hdr->first_segment;
/* cleanup flag */
*off++ = !!(sr_has_cleanup(hdr)) << 7;
/* flags */
*off++ = hdr->flags;
/* HMAC Key ID */
memcpy(off, &hmackeyid, 4);

View file

@ -996,6 +996,16 @@ drop:
return 0; /* don't send reset */
}
static void tcp_v6_restore_cb(struct sk_buff *skb)
{
/* We need to move header back to the beginning if xfrm6_policy_check()
* and tcp_v6_fill_cb() are going to be called again.
* ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
*/
memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
sizeof(struct inet6_skb_parm));
}
static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst,
@ -1184,8 +1194,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
sk_gfp_mask(sk, GFP_ATOMIC));
consume_skb(ireq->pktopts);
ireq->pktopts = NULL;
if (newnp->pktoptions)
if (newnp->pktoptions) {
tcp_v6_restore_cb(newnp->pktoptions);
skb_set_owner_r(newnp->pktoptions, newsk);
}
}
}
@ -1200,16 +1212,6 @@ out:
return NULL;
}
static void tcp_v6_restore_cb(struct sk_buff *skb)
{
/* We need to move header back to the beginning if xfrm6_policy_check()
* and tcp_v6_fill_cb() are going to be called again.
* ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
*/
memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
sizeof(struct inet6_skb_parm));
}
/* The socket must have it's spinlock held when we get
* here, unless it is a TCP_LISTEN socket.
*

View file

@ -454,7 +454,7 @@ try_again:
return err;
csum_copy_err:
if (!__sk_queue_drop_skb(sk, skb, flags)) {
if (!__sk_queue_drop_skb(sk, skb, flags, udp_skb_destructor)) {
if (is_udp4) {
UDP_INC_STATS(sock_net(sk),
UDP_MIB_CSUMERRORS, is_udplite);