diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 15:34:42 -0500 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 15:34:42 -0500 |
| commit | 8e22e1b3499a446df48c2b26667ca36c55bf864c (patch) | |
| tree | 5329f98b3eb3c95a9dcbab0fa4f9b6e62f0e788d /net/ipv6 | |
| parent | 00d3c14f14d51babd8aeafd5fa734ccf04f5ca3d (diff) | |
| parent | 64a577196d66b44e37384bc5c4d78c61f59d5b2a (diff) | |
Merge airlied/drm-next into drm-misc-next
Backmerge the main pull request to sync up with all the newly landed
drivers. Otherwise we'll have chaos even before 4.12 started in
earnest.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 20 | ||||
| -rw-r--r-- | net/ipv6/exthdrs.c | 31 | ||||
| -rw-r--r-- | net/ipv6/ila/ila_lwt.c | 1 | ||||
| -rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6_gre.c | 43 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 6 | ||||
| -rw-r--r-- | net/ipv6/ip6_tunnel.c | 36 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_rpfilter.c | 8 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_reject_ipv6.c | 3 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nft_fib_ipv6.c | 13 | ||||
| -rw-r--r-- | net/ipv6/route.c | 12 | ||||
| -rw-r--r-- | net/ipv6/seg6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/seg6_hmac.c | 8 | ||||
| -rw-r--r-- | net/ipv6/seg6_iptunnel.c | 1 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 1 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 28 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 2 |
18 files changed, 118 insertions, 100 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c1e124bc8e1e..a7bcc0ab5e99 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -3386,9 +3386,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
| 3386 | } | 3386 | } |
| 3387 | 3387 | ||
| 3388 | if (idev) { | 3388 | if (idev) { |
| 3389 | if (idev->if_flags & IF_READY) | 3389 | if (idev->if_flags & IF_READY) { |
| 3390 | /* device is already configured. */ | 3390 | /* device is already configured - |
| 3391 | * but resend MLD reports, we might | ||
| 3392 | * have roamed and need to update | ||
| 3393 | * multicast snooping switches | ||
| 3394 | */ | ||
| 3395 | ipv6_mc_up(idev); | ||
| 3391 | break; | 3396 | break; |
| 3397 | } | ||
| 3392 | idev->if_flags |= IF_READY; | 3398 | idev->if_flags |= IF_READY; |
| 3393 | } | 3399 | } |
| 3394 | 3400 | ||
| @@ -4009,6 +4015,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id) | |||
| 4009 | 4015 | ||
| 4010 | if (bump_id) | 4016 | if (bump_id) |
| 4011 | rt_genid_bump_ipv6(dev_net(dev)); | 4017 | rt_genid_bump_ipv6(dev_net(dev)); |
| 4018 | |||
| 4019 | /* Make sure that a new temporary address will be created | ||
| 4020 | * before this temporary address becomes deprecated. | ||
| 4021 | */ | ||
| 4022 | if (ifp->flags & IFA_F_TEMPORARY) | ||
| 4023 | addrconf_verify_rtnl(); | ||
| 4012 | } | 4024 | } |
| 4013 | 4025 | ||
| 4014 | static void addrconf_dad_run(struct inet6_dev *idev) | 4026 | static void addrconf_dad_run(struct inet6_dev *idev) |
| @@ -5540,8 +5552,7 @@ static void addrconf_disable_change(struct net *net, __s32 newf) | |||
| 5540 | struct net_device *dev; | 5552 | struct net_device *dev; |
| 5541 | struct inet6_dev *idev; | 5553 | struct inet6_dev *idev; |
| 5542 | 5554 | ||
| 5543 | rcu_read_lock(); | 5555 | for_each_netdev(net, dev) { |
| 5544 | for_each_netdev_rcu(net, dev) { | ||
| 5545 | idev = __in6_dev_get(dev); | 5556 | idev = __in6_dev_get(dev); |
| 5546 | if (idev) { | 5557 | if (idev) { |
| 5547 | int changed = (!idev->cnf.disable_ipv6) ^ (!newf); | 5558 | int changed = (!idev->cnf.disable_ipv6) ^ (!newf); |
| @@ -5550,7 +5561,6 @@ static void addrconf_disable_change(struct net *net, __s32 newf) | |||
| 5550 | dev_disable_change(idev); | 5561 | dev_disable_change(idev); |
| 5551 | } | 5562 | } |
| 5552 | } | 5563 | } |
| 5553 | rcu_read_unlock(); | ||
| 5554 | } | 5564 | } |
| 5555 | 5565 | ||
| 5556 | static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf) | 5566 | static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int newf) |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index e4198502fd98..275cac628a95 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -327,7 +327,6 @@ static int ipv6_srh_rcv(struct sk_buff *skb) | |||
| 327 | struct ipv6_sr_hdr *hdr; | 327 | struct ipv6_sr_hdr *hdr; |
| 328 | struct inet6_dev *idev; | 328 | struct inet6_dev *idev; |
| 329 | struct in6_addr *addr; | 329 | struct in6_addr *addr; |
| 330 | bool cleanup = false; | ||
| 331 | int accept_seg6; | 330 | int accept_seg6; |
| 332 | 331 | ||
| 333 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); | 332 | hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb); |
| @@ -351,11 +350,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb) | |||
| 351 | #endif | 350 | #endif |
| 352 | 351 | ||
| 353 | looped_back: | 352 | looped_back: |
| 354 | if (hdr->segments_left > 0) { | 353 | if (hdr->segments_left == 0) { |
| 355 | if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 && | ||
| 356 | sr_has_cleanup(hdr)) | ||
| 357 | cleanup = true; | ||
| 358 | } else { | ||
| 359 | if (hdr->nexthdr == NEXTHDR_IPV6) { | 354 | if (hdr->nexthdr == NEXTHDR_IPV6) { |
| 360 | int offset = (hdr->hdrlen + 1) << 3; | 355 | int offset = (hdr->hdrlen + 1) << 3; |
| 361 | 356 | ||
| @@ -418,21 +413,6 @@ looped_back: | |||
| 418 | 413 | ||
| 419 | ipv6_hdr(skb)->daddr = *addr; | 414 | ipv6_hdr(skb)->daddr = *addr; |
| 420 | 415 | ||
| 421 | if (cleanup) { | ||
| 422 | int srhlen = (hdr->hdrlen + 1) << 3; | ||
| 423 | int nh = hdr->nexthdr; | ||
| 424 | |||
| 425 | skb_pull_rcsum(skb, sizeof(struct ipv6hdr) + srhlen); | ||
| 426 | memmove(skb_network_header(skb) + srhlen, | ||
| 427 | skb_network_header(skb), | ||
| 428 | (unsigned char *)hdr - skb_network_header(skb)); | ||
| 429 | skb->network_header += srhlen; | ||
| 430 | ipv6_hdr(skb)->nexthdr = nh; | ||
| 431 | ipv6_hdr(skb)->payload_len = htons(skb->len - | ||
| 432 | sizeof(struct ipv6hdr)); | ||
| 433 | skb_push_rcsum(skb, sizeof(struct ipv6hdr)); | ||
| 434 | } | ||
| 435 | |||
| 436 | skb_dst_drop(skb); | 416 | skb_dst_drop(skb); |
| 437 | 417 | ||
| 438 | ip6_route_input(skb); | 418 | ip6_route_input(skb); |
| @@ -453,13 +433,8 @@ looped_back: | |||
| 453 | } | 433 | } |
| 454 | ipv6_hdr(skb)->hop_limit--; | 434 | ipv6_hdr(skb)->hop_limit--; |
| 455 | 435 | ||
| 456 | /* be sure that srh is still present before reinjecting */ | 436 | skb_pull(skb, sizeof(struct ipv6hdr)); |
| 457 | if (!cleanup) { | 437 | goto looped_back; |
| 458 | skb_pull(skb, sizeof(struct ipv6hdr)); | ||
| 459 | goto looped_back; | ||
| 460 | } | ||
| 461 | skb_set_transport_header(skb, sizeof(struct ipv6hdr)); | ||
| 462 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); | ||
| 463 | } | 438 | } |
| 464 | 439 | ||
| 465 | dst_input(skb); | 440 | dst_input(skb); |
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c index a7bc54ab46e2..13b5e85fe0d5 100644 --- a/net/ipv6/ila/ila_lwt.c +++ b/net/ipv6/ila/ila_lwt.c | |||
| @@ -238,6 +238,7 @@ static const struct lwtunnel_encap_ops ila_encap_ops = { | |||
| 238 | .fill_encap = ila_fill_encap_info, | 238 | .fill_encap = ila_fill_encap_info, |
| 239 | .get_encap_size = ila_encap_nlsize, | 239 | .get_encap_size = ila_encap_nlsize, |
| 240 | .cmp_encap = ila_encap_cmp, | 240 | .cmp_encap = ila_encap_cmp, |
| 241 | .owner = THIS_MODULE, | ||
| 241 | }; | 242 | }; |
| 242 | 243 | ||
| 243 | int ila_lwt_init(void) | 244 | int ila_lwt_init(void) |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 7396e75e161b..75c308239243 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
| @@ -176,7 +176,7 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused | |||
| 176 | /* Restore final destination back after routing done */ | 176 | /* Restore final destination back after routing done */ |
| 177 | fl6.daddr = sk->sk_v6_daddr; | 177 | fl6.daddr = sk->sk_v6_daddr; |
| 178 | 178 | ||
| 179 | res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), | 179 | res = ip6_xmit(sk, skb, &fl6, sk->sk_mark, rcu_dereference(np->opt), |
| 180 | np->tclass); | 180 | np->tclass); |
| 181 | rcu_read_unlock(); | 181 | rcu_read_unlock(); |
| 182 | return res; | 182 | return res; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 75b6108234dd..630b73be5999 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -367,35 +367,37 @@ static void ip6gre_tunnel_uninit(struct net_device *dev) | |||
| 367 | 367 | ||
| 368 | 368 | ||
| 369 | static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 369 | static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
| 370 | u8 type, u8 code, int offset, __be32 info) | 370 | u8 type, u8 code, int offset, __be32 info) |
| 371 | { | 371 | { |
| 372 | const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data; | 372 | const struct gre_base_hdr *greh; |
| 373 | __be16 *p = (__be16 *)(skb->data + offset); | 373 | const struct ipv6hdr *ipv6h; |
| 374 | int grehlen = offset + 4; | 374 | int grehlen = sizeof(*greh); |
| 375 | struct ip6_tnl *t; | 375 | struct ip6_tnl *t; |
| 376 | int key_off = 0; | ||
| 376 | __be16 flags; | 377 | __be16 flags; |
| 378 | __be32 key; | ||
| 377 | 379 | ||
| 378 | flags = p[0]; | 380 | if (!pskb_may_pull(skb, offset + grehlen)) |
| 379 | if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { | 381 | return; |
| 380 | if (flags&(GRE_VERSION|GRE_ROUTING)) | 382 | greh = (const struct gre_base_hdr *)(skb->data + offset); |
| 381 | return; | 383 | flags = greh->flags; |
| 382 | if (flags&GRE_KEY) { | 384 | if (flags & (GRE_VERSION | GRE_ROUTING)) |
| 383 | grehlen += 4; | 385 | return; |
| 384 | if (flags&GRE_CSUM) | 386 | if (flags & GRE_CSUM) |
| 385 | grehlen += 4; | 387 | grehlen += 4; |
| 386 | } | 388 | if (flags & GRE_KEY) { |
| 389 | key_off = grehlen + offset; | ||
| 390 | grehlen += 4; | ||
| 387 | } | 391 | } |
| 388 | 392 | ||
| 389 | /* If only 8 bytes returned, keyed message will be dropped here */ | 393 | if (!pskb_may_pull(skb, offset + grehlen)) |
| 390 | if (!pskb_may_pull(skb, grehlen)) | ||
| 391 | return; | 394 | return; |
| 392 | ipv6h = (const struct ipv6hdr *)skb->data; | 395 | ipv6h = (const struct ipv6hdr *)skb->data; |
| 393 | p = (__be16 *)(skb->data + offset); | 396 | greh = (const struct gre_base_hdr *)(skb->data + offset); |
| 397 | key = key_off ? *(__be32 *)(skb->data + key_off) : 0; | ||
| 394 | 398 | ||
| 395 | t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, | 399 | t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, |
| 396 | flags & GRE_KEY ? | 400 | key, greh->protocol); |
| 397 | *(((__be32 *)p) + (grehlen / 4) - 1) : 0, | ||
| 398 | p[1]); | ||
| 399 | if (!t) | 401 | if (!t) |
| 400 | return; | 402 | return; |
| 401 | 403 | ||
| @@ -582,6 +584,9 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) | |||
| 582 | return -1; | 584 | return -1; |
| 583 | 585 | ||
| 584 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); | 586 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); |
| 587 | /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ | ||
| 588 | ipv6h = ipv6_hdr(skb); | ||
| 589 | |||
| 585 | if (offset > 0) { | 590 | if (offset > 0) { |
| 586 | struct ipv6_tlv_tnl_enc_lim *tel; | 591 | struct ipv6_tlv_tnl_enc_lim *tel; |
| 587 | tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; | 592 | tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 38122d04fadc..b6a94ff0bbd0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -172,7 +172,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 172 | * which are using proper atomic operations or spinlocks. | 172 | * which are using proper atomic operations or spinlocks. |
| 173 | */ | 173 | */ |
| 174 | int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | 174 | int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, |
| 175 | struct ipv6_txoptions *opt, int tclass) | 175 | __u32 mark, struct ipv6_txoptions *opt, int tclass) |
| 176 | { | 176 | { |
| 177 | struct net *net = sock_net(sk); | 177 | struct net *net = sock_net(sk); |
| 178 | const struct ipv6_pinfo *np = inet6_sk(sk); | 178 | const struct ipv6_pinfo *np = inet6_sk(sk); |
| @@ -240,7 +240,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | |||
| 240 | 240 | ||
| 241 | skb->protocol = htons(ETH_P_IPV6); | 241 | skb->protocol = htons(ETH_P_IPV6); |
| 242 | skb->priority = sk->sk_priority; | 242 | skb->priority = sk->sk_priority; |
| 243 | skb->mark = sk->sk_mark; | 243 | skb->mark = mark; |
| 244 | 244 | ||
| 245 | mtu = dst_mtu(dst); | 245 | mtu = dst_mtu(dst); |
| 246 | if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) { | 246 | if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) { |
| @@ -1344,7 +1344,7 @@ emsgsize: | |||
| 1344 | */ | 1344 | */ |
| 1345 | if (transhdrlen && sk->sk_protocol == IPPROTO_UDP && | 1345 | if (transhdrlen && sk->sk_protocol == IPPROTO_UDP && |
| 1346 | headersize == sizeof(struct ipv6hdr) && | 1346 | headersize == sizeof(struct ipv6hdr) && |
| 1347 | length < mtu - headersize && | 1347 | length <= mtu - headersize && |
| 1348 | !(flags & MSG_MORE) && | 1348 | !(flags & MSG_MORE) && |
| 1349 | rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) | 1349 | rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) |
| 1350 | csummode = CHECKSUM_PARTIAL; | 1350 | csummode = CHECKSUM_PARTIAL; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 753d6d0860fb..75fac933c209 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -400,18 +400,19 @@ ip6_tnl_dev_uninit(struct net_device *dev) | |||
| 400 | 400 | ||
| 401 | __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) | 401 | __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) |
| 402 | { | 402 | { |
| 403 | const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw; | 403 | const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)raw; |
| 404 | __u8 nexthdr = ipv6h->nexthdr; | 404 | unsigned int nhoff = raw - skb->data; |
| 405 | __u16 off = sizeof(*ipv6h); | 405 | unsigned int off = nhoff + sizeof(*ipv6h); |
| 406 | u8 next, nexthdr = ipv6h->nexthdr; | ||
| 406 | 407 | ||
| 407 | while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) { | 408 | while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) { |
| 408 | __u16 optlen = 0; | ||
| 409 | struct ipv6_opt_hdr *hdr; | 409 | struct ipv6_opt_hdr *hdr; |
| 410 | if (raw + off + sizeof(*hdr) > skb->data && | 410 | u16 optlen; |
| 411 | !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr))) | 411 | |
| 412 | if (!pskb_may_pull(skb, off + sizeof(*hdr))) | ||
| 412 | break; | 413 | break; |
| 413 | 414 | ||
| 414 | hdr = (struct ipv6_opt_hdr *) (raw + off); | 415 | hdr = (struct ipv6_opt_hdr *)(skb->data + off); |
| 415 | if (nexthdr == NEXTHDR_FRAGMENT) { | 416 | if (nexthdr == NEXTHDR_FRAGMENT) { |
| 416 | struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr; | 417 | struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr; |
| 417 | if (frag_hdr->frag_off) | 418 | if (frag_hdr->frag_off) |
| @@ -422,20 +423,29 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) | |||
| 422 | } else { | 423 | } else { |
| 423 | optlen = ipv6_optlen(hdr); | 424 | optlen = ipv6_optlen(hdr); |
| 424 | } | 425 | } |
| 426 | /* cache hdr->nexthdr, since pskb_may_pull() might | ||
| 427 | * invalidate hdr | ||
| 428 | */ | ||
| 429 | next = hdr->nexthdr; | ||
| 425 | if (nexthdr == NEXTHDR_DEST) { | 430 | if (nexthdr == NEXTHDR_DEST) { |
| 426 | __u16 i = off + 2; | 431 | u16 i = 2; |
| 432 | |||
| 433 | /* Remember : hdr is no longer valid at this point. */ | ||
| 434 | if (!pskb_may_pull(skb, off + optlen)) | ||
| 435 | break; | ||
| 436 | |||
| 427 | while (1) { | 437 | while (1) { |
| 428 | struct ipv6_tlv_tnl_enc_lim *tel; | 438 | struct ipv6_tlv_tnl_enc_lim *tel; |
| 429 | 439 | ||
| 430 | /* No more room for encapsulation limit */ | 440 | /* No more room for encapsulation limit */ |
| 431 | if (i + sizeof (*tel) > off + optlen) | 441 | if (i + sizeof(*tel) > optlen) |
| 432 | break; | 442 | break; |
| 433 | 443 | ||
| 434 | tel = (struct ipv6_tlv_tnl_enc_lim *) &raw[i]; | 444 | tel = (struct ipv6_tlv_tnl_enc_lim *)(skb->data + off + i); |
| 435 | /* return index of option if found and valid */ | 445 | /* return index of option if found and valid */ |
| 436 | if (tel->type == IPV6_TLV_TNL_ENCAP_LIMIT && | 446 | if (tel->type == IPV6_TLV_TNL_ENCAP_LIMIT && |
| 437 | tel->length == 1) | 447 | tel->length == 1) |
| 438 | return i; | 448 | return i + off - nhoff; |
| 439 | /* else jump to next option */ | 449 | /* else jump to next option */ |
| 440 | if (tel->type) | 450 | if (tel->type) |
| 441 | i += tel->length + 2; | 451 | i += tel->length + 2; |
| @@ -443,7 +453,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw) | |||
| 443 | i++; | 453 | i++; |
| 444 | } | 454 | } |
| 445 | } | 455 | } |
| 446 | nexthdr = hdr->nexthdr; | 456 | nexthdr = next; |
| 447 | off += optlen; | 457 | off += optlen; |
| 448 | } | 458 | } |
| 449 | return 0; | 459 | return 0; |
| @@ -1303,6 +1313,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1303 | fl6.flowlabel = key->label; | 1313 | fl6.flowlabel = key->label; |
| 1304 | } else { | 1314 | } else { |
| 1305 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); | 1315 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); |
| 1316 | /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ | ||
| 1317 | ipv6h = ipv6_hdr(skb); | ||
| 1306 | if (offset > 0) { | 1318 | if (offset > 0) { |
| 1307 | struct ipv6_tlv_tnl_enc_lim *tel; | 1319 | struct ipv6_tlv_tnl_enc_lim *tel; |
| 1308 | 1320 | ||
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 7139fffd61b6..1bdc703cb966 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -779,6 +779,7 @@ static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im) | |||
| 779 | psf->sf_crcount = im->mca_crcount; | 779 | psf->sf_crcount = im->mca_crcount; |
| 780 | } | 780 | } |
| 781 | in6_dev_put(pmc->idev); | 781 | in6_dev_put(pmc->idev); |
| 782 | kfree(pmc); | ||
| 782 | } | 783 | } |
| 783 | spin_unlock_bh(&im->mca_lock); | 784 | spin_unlock_bh(&im->mca_lock); |
| 784 | } | 785 | } |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index d5263dc364a9..b12e61b7b16c 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
| @@ -72,10 +72,10 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb, | |||
| 72 | return ret; | 72 | return ret; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static bool rpfilter_is_local(const struct sk_buff *skb) | 75 | static bool |
| 76 | rpfilter_is_loopback(const struct sk_buff *skb, const struct net_device *in) | ||
| 76 | { | 77 | { |
| 77 | const struct rt6_info *rt = (const void *) skb_dst(skb); | 78 | return skb->pkt_type == PACKET_LOOPBACK || in->flags & IFF_LOOPBACK; |
| 78 | return rt && (rt->rt6i_flags & RTF_LOCAL); | ||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | 81 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) |
| @@ -85,7 +85,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 85 | struct ipv6hdr *iph; | 85 | struct ipv6hdr *iph; |
| 86 | bool invert = info->flags & XT_RPFILTER_INVERT; | 86 | bool invert = info->flags & XT_RPFILTER_INVERT; |
| 87 | 87 | ||
| 88 | if (rpfilter_is_local(skb)) | 88 | if (rpfilter_is_loopback(skb, xt_in(par))) |
| 89 | return true ^ invert; | 89 | return true ^ invert; |
| 90 | 90 | ||
| 91 | iph = ipv6_hdr(skb); | 91 | iph = ipv6_hdr(skb); |
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c index 10090400c72f..eedee5d108d9 100644 --- a/net/ipv6/netfilter/nf_reject_ipv6.c +++ b/net/ipv6/netfilter/nf_reject_ipv6.c | |||
| @@ -157,6 +157,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook) | |||
| 157 | fl6.fl6_sport = otcph->dest; | 157 | fl6.fl6_sport = otcph->dest; |
| 158 | fl6.fl6_dport = otcph->source; | 158 | fl6.fl6_dport = otcph->source; |
| 159 | fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev); | 159 | fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev); |
| 160 | fl6.flowi6_mark = IP6_REPLY_MARK(net, oldskb->mark); | ||
| 160 | security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); | 161 | security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); |
| 161 | dst = ip6_route_output(net, NULL, &fl6); | 162 | dst = ip6_route_output(net, NULL, &fl6); |
| 162 | if (dst->error) { | 163 | if (dst->error) { |
| @@ -180,6 +181,8 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook) | |||
| 180 | 181 | ||
| 181 | skb_dst_set(nskb, dst); | 182 | skb_dst_set(nskb, dst); |
| 182 | 183 | ||
| 184 | nskb->mark = fl6.flowi6_mark; | ||
| 185 | |||
| 183 | skb_reserve(nskb, hh_len + dst->header_len); | 186 | skb_reserve(nskb, hh_len + dst->header_len); |
| 184 | ip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, | 187 | ip6h = nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, |
| 185 | ip6_dst_hoplimit(dst)); | 188 | ip6_dst_hoplimit(dst)); |
diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c index c947aad8bcc6..765facf03d45 100644 --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c | |||
| @@ -18,13 +18,6 @@ | |||
| 18 | #include <net/ip6_fib.h> | 18 | #include <net/ip6_fib.h> |
| 19 | #include <net/ip6_route.h> | 19 | #include <net/ip6_route.h> |
| 20 | 20 | ||
| 21 | static bool fib6_is_local(const struct sk_buff *skb) | ||
| 22 | { | ||
| 23 | const struct rt6_info *rt = (const void *)skb_dst(skb); | ||
| 24 | |||
| 25 | return rt && (rt->rt6i_flags & RTF_LOCAL); | ||
| 26 | } | ||
| 27 | |||
| 28 | static int get_ifindex(const struct net_device *dev) | 21 | static int get_ifindex(const struct net_device *dev) |
| 29 | { | 22 | { |
| 30 | return dev ? dev->ifindex : 0; | 23 | return dev ? dev->ifindex : 0; |
| @@ -164,8 +157,10 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, | |||
| 164 | 157 | ||
| 165 | lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif); | 158 | lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif); |
| 166 | 159 | ||
| 167 | if (nft_hook(pkt) == NF_INET_PRE_ROUTING && fib6_is_local(pkt->skb)) { | 160 | if (nft_hook(pkt) == NF_INET_PRE_ROUTING && |
| 168 | nft_fib_store_result(dest, priv->result, pkt, LOOPBACK_IFINDEX); | 161 | nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { |
| 162 | nft_fib_store_result(dest, priv->result, pkt, | ||
| 163 | nft_in(pkt)->ifindex); | ||
| 169 | return; | 164 | return; |
| 170 | } | 165 | } |
| 171 | 166 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4f6b067c8753..7ea85370c11c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2896,6 +2896,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 2896 | if (tb[RTA_MULTIPATH]) { | 2896 | if (tb[RTA_MULTIPATH]) { |
| 2897 | cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]); | 2897 | cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]); |
| 2898 | cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); | 2898 | cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); |
| 2899 | |||
| 2900 | err = lwtunnel_valid_encap_type_attr(cfg->fc_mp, | ||
| 2901 | cfg->fc_mp_len); | ||
| 2902 | if (err < 0) | ||
| 2903 | goto errout; | ||
| 2899 | } | 2904 | } |
| 2900 | 2905 | ||
| 2901 | if (tb[RTA_PREF]) { | 2906 | if (tb[RTA_PREF]) { |
| @@ -2909,9 +2914,14 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 2909 | if (tb[RTA_ENCAP]) | 2914 | if (tb[RTA_ENCAP]) |
| 2910 | cfg->fc_encap = tb[RTA_ENCAP]; | 2915 | cfg->fc_encap = tb[RTA_ENCAP]; |
| 2911 | 2916 | ||
| 2912 | if (tb[RTA_ENCAP_TYPE]) | 2917 | if (tb[RTA_ENCAP_TYPE]) { |
| 2913 | cfg->fc_encap_type = nla_get_u16(tb[RTA_ENCAP_TYPE]); | 2918 | cfg->fc_encap_type = nla_get_u16(tb[RTA_ENCAP_TYPE]); |
| 2914 | 2919 | ||
| 2920 | err = lwtunnel_valid_encap_type(cfg->fc_encap_type); | ||
| 2921 | if (err < 0) | ||
| 2922 | goto errout; | ||
| 2923 | } | ||
| 2924 | |||
| 2915 | if (tb[RTA_EXPIRES]) { | 2925 | if (tb[RTA_EXPIRES]) { |
| 2916 | unsigned long timeout = addrconf_timeout_fixup(nla_get_u32(tb[RTA_EXPIRES]), HZ); | 2926 | unsigned long timeout = addrconf_timeout_fixup(nla_get_u32(tb[RTA_EXPIRES]), HZ); |
| 2917 | 2927 | ||
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c index b172d85c650a..a855eb325b03 100644 --- a/net/ipv6/seg6.c +++ b/net/ipv6/seg6.c | |||
| @@ -176,6 +176,8 @@ static int seg6_genl_set_tunsrc(struct sk_buff *skb, struct genl_info *info) | |||
| 176 | 176 | ||
| 177 | val = nla_data(info->attrs[SEG6_ATTR_DST]); | 177 | val = nla_data(info->attrs[SEG6_ATTR_DST]); |
| 178 | t_new = kmemdup(val, sizeof(*val), GFP_KERNEL); | 178 | t_new = kmemdup(val, sizeof(*val), GFP_KERNEL); |
| 179 | if (!t_new) | ||
| 180 | return -ENOMEM; | ||
| 179 | 181 | ||
| 180 | mutex_lock(&sdata->lock); | 182 | mutex_lock(&sdata->lock); |
| 181 | 183 | ||
diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c index 03a064803626..6ef3dfb6e811 100644 --- a/net/ipv6/seg6_hmac.c +++ b/net/ipv6/seg6_hmac.c | |||
| @@ -174,7 +174,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr, | |||
| 174 | * hash function (RadioGatun) with up to 1216 bits | 174 | * hash function (RadioGatun) with up to 1216 bits |
| 175 | */ | 175 | */ |
| 176 | 176 | ||
| 177 | /* saddr(16) + first_seg(1) + cleanup(1) + keyid(4) + seglist(16n) */ | 177 | /* saddr(16) + first_seg(1) + flags(1) + keyid(4) + seglist(16n) */ |
| 178 | plen = 16 + 1 + 1 + 4 + (hdr->first_segment + 1) * 16; | 178 | plen = 16 + 1 + 1 + 4 + (hdr->first_segment + 1) * 16; |
| 179 | 179 | ||
| 180 | /* this limit allows for 14 segments */ | 180 | /* this limit allows for 14 segments */ |
| @@ -186,7 +186,7 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr, | |||
| 186 | * | 186 | * |
| 187 | * 1. Source IPv6 address (128 bits) | 187 | * 1. Source IPv6 address (128 bits) |
| 188 | * 2. first_segment value (8 bits) | 188 | * 2. first_segment value (8 bits) |
| 189 | * 3. cleanup flag (8 bits: highest bit is cleanup value, others are 0) | 189 | * 3. Flags (8 bits) |
| 190 | * 4. HMAC Key ID (32 bits) | 190 | * 4. HMAC Key ID (32 bits) |
| 191 | * 5. All segments in the segments list (n * 128 bits) | 191 | * 5. All segments in the segments list (n * 128 bits) |
| 192 | */ | 192 | */ |
| @@ -202,8 +202,8 @@ int seg6_hmac_compute(struct seg6_hmac_info *hinfo, struct ipv6_sr_hdr *hdr, | |||
| 202 | /* first_segment value */ | 202 | /* first_segment value */ |
| 203 | *off++ = hdr->first_segment; | 203 | *off++ = hdr->first_segment; |
| 204 | 204 | ||
| 205 | /* cleanup flag */ | 205 | /* flags */ |
| 206 | *off++ = !!(sr_has_cleanup(hdr)) << 7; | 206 | *off++ = hdr->flags; |
| 207 | 207 | ||
| 208 | /* HMAC Key ID */ | 208 | /* HMAC Key ID */ |
| 209 | memcpy(off, &hmackeyid, 4); | 209 | memcpy(off, &hmackeyid, 4); |
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c index 1d60cb132835..c46f8cbf5ab5 100644 --- a/net/ipv6/seg6_iptunnel.c +++ b/net/ipv6/seg6_iptunnel.c | |||
| @@ -422,6 +422,7 @@ static const struct lwtunnel_encap_ops seg6_iptun_ops = { | |||
| 422 | .fill_encap = seg6_fill_encap_info, | 422 | .fill_encap = seg6_fill_encap_info, |
| 423 | .get_encap_size = seg6_encap_nlsize, | 423 | .get_encap_size = seg6_encap_nlsize, |
| 424 | .cmp_encap = seg6_encap_cmp, | 424 | .cmp_encap = seg6_encap_cmp, |
| 425 | .owner = THIS_MODULE, | ||
| 425 | }; | 426 | }; |
| 426 | 427 | ||
| 427 | int __init seg6_iptunnel_init(void) | 428 | int __init seg6_iptunnel_init(void) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index fad992ad4bc8..99853c6e33a8 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -1380,6 +1380,7 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
| 1380 | err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL); | 1380 | err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL); |
| 1381 | if (err) { | 1381 | if (err) { |
| 1382 | free_percpu(dev->tstats); | 1382 | free_percpu(dev->tstats); |
| 1383 | dev->tstats = NULL; | ||
| 1383 | return err; | 1384 | return err; |
| 1384 | } | 1385 | } |
| 1385 | 1386 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 73bc8fc68acd..eaad72c3d746 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -469,7 +469,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, | |||
| 469 | opt = ireq->ipv6_opt; | 469 | opt = ireq->ipv6_opt; |
| 470 | if (!opt) | 470 | if (!opt) |
| 471 | opt = rcu_dereference(np->opt); | 471 | opt = rcu_dereference(np->opt); |
| 472 | err = ip6_xmit(sk, skb, fl6, opt, np->tclass); | 472 | err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, np->tclass); |
| 473 | rcu_read_unlock(); | 473 | rcu_read_unlock(); |
| 474 | err = net_xmit_eval(err); | 474 | err = net_xmit_eval(err); |
| 475 | } | 475 | } |
| @@ -840,7 +840,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 | |||
| 840 | dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); | 840 | dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); |
| 841 | if (!IS_ERR(dst)) { | 841 | if (!IS_ERR(dst)) { |
| 842 | skb_dst_set(buff, dst); | 842 | skb_dst_set(buff, dst); |
| 843 | ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass); | 843 | ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass); |
| 844 | TCP_INC_STATS(net, TCP_MIB_OUTSEGS); | 844 | TCP_INC_STATS(net, TCP_MIB_OUTSEGS); |
| 845 | if (rst) | 845 | if (rst) |
| 846 | TCP_INC_STATS(net, TCP_MIB_OUTRSTS); | 846 | TCP_INC_STATS(net, TCP_MIB_OUTRSTS); |
| @@ -991,6 +991,16 @@ drop: | |||
| 991 | return 0; /* don't send reset */ | 991 | return 0; /* don't send reset */ |
| 992 | } | 992 | } |
| 993 | 993 | ||
| 994 | static void tcp_v6_restore_cb(struct sk_buff *skb) | ||
| 995 | { | ||
| 996 | /* We need to move header back to the beginning if xfrm6_policy_check() | ||
| 997 | * and tcp_v6_fill_cb() are going to be called again. | ||
| 998 | * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. | ||
| 999 | */ | ||
| 1000 | memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, | ||
| 1001 | sizeof(struct inet6_skb_parm)); | ||
| 1002 | } | ||
| 1003 | |||
| 994 | static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, | 1004 | static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, |
| 995 | struct request_sock *req, | 1005 | struct request_sock *req, |
| 996 | struct dst_entry *dst, | 1006 | struct dst_entry *dst, |
| @@ -1182,8 +1192,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * | |||
| 1182 | sk_gfp_mask(sk, GFP_ATOMIC)); | 1192 | sk_gfp_mask(sk, GFP_ATOMIC)); |
| 1183 | consume_skb(ireq->pktopts); | 1193 | consume_skb(ireq->pktopts); |
| 1184 | ireq->pktopts = NULL; | 1194 | ireq->pktopts = NULL; |
| 1185 | if (newnp->pktoptions) | 1195 | if (newnp->pktoptions) { |
| 1196 | tcp_v6_restore_cb(newnp->pktoptions); | ||
| 1186 | skb_set_owner_r(newnp->pktoptions, newsk); | 1197 | skb_set_owner_r(newnp->pktoptions, newsk); |
| 1198 | } | ||
| 1187 | } | 1199 | } |
| 1188 | } | 1200 | } |
| 1189 | 1201 | ||
| @@ -1198,16 +1210,6 @@ out: | |||
| 1198 | return NULL; | 1210 | return NULL; |
| 1199 | } | 1211 | } |
| 1200 | 1212 | ||
| 1201 | static void tcp_v6_restore_cb(struct sk_buff *skb) | ||
| 1202 | { | ||
| 1203 | /* We need to move header back to the beginning if xfrm6_policy_check() | ||
| 1204 | * and tcp_v6_fill_cb() are going to be called again. | ||
| 1205 | * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. | ||
| 1206 | */ | ||
| 1207 | memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, | ||
| 1208 | sizeof(struct inet6_skb_parm)); | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | /* The socket must have it's spinlock held when we get | 1213 | /* The socket must have it's spinlock held when we get |
| 1212 | * here, unless it is a TCP_LISTEN socket. | 1214 | * here, unless it is a TCP_LISTEN socket. |
| 1213 | * | 1215 | * |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 4d5c4eee4b3f..8990856f5101 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -441,7 +441,7 @@ try_again: | |||
| 441 | return err; | 441 | return err; |
| 442 | 442 | ||
| 443 | csum_copy_err: | 443 | csum_copy_err: |
| 444 | if (!__sk_queue_drop_skb(sk, skb, flags)) { | 444 | if (!__sk_queue_drop_skb(sk, skb, flags, udp_skb_destructor)) { |
| 445 | if (is_udp4) { | 445 | if (is_udp4) { |
| 446 | UDP_INC_STATS(sock_net(sk), | 446 | UDP_INC_STATS(sock_net(sk), |
| 447 | UDP_MIB_CSUMERRORS, is_udplite); | 447 | UDP_MIB_CSUMERRORS, is_udplite); |
