diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 177 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 10 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 2 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 2 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 18 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 57 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 62 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 2 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 4 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 6 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_rpfilter.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 6 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_nat_proto_icmpv6.c | 2 | ||||
-rw-r--r-- | net/ipv6/raw.c | 6 | ||||
-rw-r--r-- | net/ipv6/route.c | 174 | ||||
-rw-r--r-- | net/ipv6/sit.c | 57 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 15 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 4 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 4 |
27 files changed, 540 insertions, 104 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 0424e4e27414..fab23db8ee73 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <net/pkt_sched.h> | 81 | #include <net/pkt_sched.h> |
82 | #include <linux/if_tunnel.h> | 82 | #include <linux/if_tunnel.h> |
83 | #include <linux/rtnetlink.h> | 83 | #include <linux/rtnetlink.h> |
84 | #include <linux/netconf.h> | ||
84 | 85 | ||
85 | #ifdef CONFIG_IPV6_PRIVACY | 86 | #ifdef CONFIG_IPV6_PRIVACY |
86 | #include <linux/random.h> | 87 | #include <linux/random.h> |
@@ -401,7 +402,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) | |||
401 | if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) | 402 | if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) |
402 | ndev->cnf.accept_dad = -1; | 403 | ndev->cnf.accept_dad = -1; |
403 | 404 | ||
404 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 405 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
405 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { | 406 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { |
406 | pr_info("%s: Disabled Multicast RS\n", dev->name); | 407 | pr_info("%s: Disabled Multicast RS\n", dev->name); |
407 | ndev->cnf.rtr_solicits = 0; | 408 | ndev->cnf.rtr_solicits = 0; |
@@ -460,6 +461,141 @@ static struct inet6_dev *ipv6_find_idev(struct net_device *dev) | |||
460 | return idev; | 461 | return idev; |
461 | } | 462 | } |
462 | 463 | ||
464 | static int inet6_netconf_msgsize_devconf(int type) | ||
465 | { | ||
466 | int size = NLMSG_ALIGN(sizeof(struct netconfmsg)) | ||
467 | + nla_total_size(4); /* NETCONFA_IFINDEX */ | ||
468 | |||
469 | /* type -1 is used for ALL */ | ||
470 | if (type == -1 || type == NETCONFA_FORWARDING) | ||
471 | size += nla_total_size(4); | ||
472 | |||
473 | return size; | ||
474 | } | ||
475 | |||
476 | static int inet6_netconf_fill_devconf(struct sk_buff *skb, int ifindex, | ||
477 | struct ipv6_devconf *devconf, u32 portid, | ||
478 | u32 seq, int event, unsigned int flags, | ||
479 | int type) | ||
480 | { | ||
481 | struct nlmsghdr *nlh; | ||
482 | struct netconfmsg *ncm; | ||
483 | |||
484 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct netconfmsg), | ||
485 | flags); | ||
486 | if (nlh == NULL) | ||
487 | return -EMSGSIZE; | ||
488 | |||
489 | ncm = nlmsg_data(nlh); | ||
490 | ncm->ncm_family = AF_INET6; | ||
491 | |||
492 | if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0) | ||
493 | goto nla_put_failure; | ||
494 | |||
495 | /* type -1 is used for ALL */ | ||
496 | if ((type == -1 || type == NETCONFA_FORWARDING) && | ||
497 | nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0) | ||
498 | goto nla_put_failure; | ||
499 | |||
500 | return nlmsg_end(skb, nlh); | ||
501 | |||
502 | nla_put_failure: | ||
503 | nlmsg_cancel(skb, nlh); | ||
504 | return -EMSGSIZE; | ||
505 | } | ||
506 | |||
507 | static void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex, | ||
508 | struct ipv6_devconf *devconf) | ||
509 | { | ||
510 | struct sk_buff *skb; | ||
511 | int err = -ENOBUFS; | ||
512 | |||
513 | skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC); | ||
514 | if (skb == NULL) | ||
515 | goto errout; | ||
516 | |||
517 | err = inet6_netconf_fill_devconf(skb, ifindex, devconf, 0, 0, | ||
518 | RTM_NEWNETCONF, 0, type); | ||
519 | if (err < 0) { | ||
520 | /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ | ||
521 | WARN_ON(err == -EMSGSIZE); | ||
522 | kfree_skb(skb); | ||
523 | goto errout; | ||
524 | } | ||
525 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC); | ||
526 | return; | ||
527 | errout: | ||
528 | if (err < 0) | ||
529 | rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err); | ||
530 | } | ||
531 | |||
532 | static const struct nla_policy devconf_ipv6_policy[NETCONFA_MAX+1] = { | ||
533 | [NETCONFA_IFINDEX] = { .len = sizeof(int) }, | ||
534 | [NETCONFA_FORWARDING] = { .len = sizeof(int) }, | ||
535 | }; | ||
536 | |||
537 | static int inet6_netconf_get_devconf(struct sk_buff *in_skb, | ||
538 | struct nlmsghdr *nlh, | ||
539 | void *arg) | ||
540 | { | ||
541 | struct net *net = sock_net(in_skb->sk); | ||
542 | struct nlattr *tb[NETCONFA_MAX+1]; | ||
543 | struct netconfmsg *ncm; | ||
544 | struct sk_buff *skb; | ||
545 | struct ipv6_devconf *devconf; | ||
546 | struct inet6_dev *in6_dev; | ||
547 | struct net_device *dev; | ||
548 | int ifindex; | ||
549 | int err; | ||
550 | |||
551 | err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX, | ||
552 | devconf_ipv6_policy); | ||
553 | if (err < 0) | ||
554 | goto errout; | ||
555 | |||
556 | err = EINVAL; | ||
557 | if (!tb[NETCONFA_IFINDEX]) | ||
558 | goto errout; | ||
559 | |||
560 | ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]); | ||
561 | switch (ifindex) { | ||
562 | case NETCONFA_IFINDEX_ALL: | ||
563 | devconf = net->ipv6.devconf_all; | ||
564 | break; | ||
565 | case NETCONFA_IFINDEX_DEFAULT: | ||
566 | devconf = net->ipv6.devconf_dflt; | ||
567 | break; | ||
568 | default: | ||
569 | dev = __dev_get_by_index(net, ifindex); | ||
570 | if (dev == NULL) | ||
571 | goto errout; | ||
572 | in6_dev = __in6_dev_get(dev); | ||
573 | if (in6_dev == NULL) | ||
574 | goto errout; | ||
575 | devconf = &in6_dev->cnf; | ||
576 | break; | ||
577 | } | ||
578 | |||
579 | err = -ENOBUFS; | ||
580 | skb = nlmsg_new(inet6_netconf_msgsize_devconf(-1), GFP_ATOMIC); | ||
581 | if (skb == NULL) | ||
582 | goto errout; | ||
583 | |||
584 | err = inet6_netconf_fill_devconf(skb, ifindex, devconf, | ||
585 | NETLINK_CB(in_skb).portid, | ||
586 | nlh->nlmsg_seq, RTM_NEWNETCONF, 0, | ||
587 | -1); | ||
588 | if (err < 0) { | ||
589 | /* -EMSGSIZE implies BUG in inet6_netconf_msgsize_devconf() */ | ||
590 | WARN_ON(err == -EMSGSIZE); | ||
591 | kfree_skb(skb); | ||
592 | goto errout; | ||
593 | } | ||
594 | err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid); | ||
595 | errout: | ||
596 | return err; | ||
597 | } | ||
598 | |||
463 | #ifdef CONFIG_SYSCTL | 599 | #ifdef CONFIG_SYSCTL |
464 | static void dev_forward_change(struct inet6_dev *idev) | 600 | static void dev_forward_change(struct inet6_dev *idev) |
465 | { | 601 | { |
@@ -471,7 +607,7 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
471 | dev = idev->dev; | 607 | dev = idev->dev; |
472 | if (idev->cnf.forwarding) | 608 | if (idev->cnf.forwarding) |
473 | dev_disable_lro(dev); | 609 | dev_disable_lro(dev); |
474 | if (dev && (dev->flags & IFF_MULTICAST)) { | 610 | if (dev->flags & IFF_MULTICAST) { |
475 | if (idev->cnf.forwarding) | 611 | if (idev->cnf.forwarding) |
476 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); | 612 | ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); |
477 | else | 613 | else |
@@ -486,6 +622,8 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
486 | else | 622 | else |
487 | addrconf_leave_anycast(ifa); | 623 | addrconf_leave_anycast(ifa); |
488 | } | 624 | } |
625 | inet6_netconf_notify_devconf(dev_net(dev), NETCONFA_FORWARDING, | ||
626 | dev->ifindex, &idev->cnf); | ||
489 | } | 627 | } |
490 | 628 | ||
491 | 629 | ||
@@ -518,6 +656,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
518 | *p = newf; | 656 | *p = newf; |
519 | 657 | ||
520 | if (p == &net->ipv6.devconf_dflt->forwarding) { | 658 | if (p == &net->ipv6.devconf_dflt->forwarding) { |
659 | if ((!newf) ^ (!old)) | ||
660 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
661 | NETCONFA_IFINDEX_DEFAULT, | ||
662 | net->ipv6.devconf_dflt); | ||
521 | rtnl_unlock(); | 663 | rtnl_unlock(); |
522 | return 0; | 664 | return 0; |
523 | } | 665 | } |
@@ -525,6 +667,10 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | |||
525 | if (p == &net->ipv6.devconf_all->forwarding) { | 667 | if (p == &net->ipv6.devconf_all->forwarding) { |
526 | net->ipv6.devconf_dflt->forwarding = newf; | 668 | net->ipv6.devconf_dflt->forwarding = newf; |
527 | addrconf_forward_change(net, newf); | 669 | addrconf_forward_change(net, newf); |
670 | if ((!newf) ^ (!old)) | ||
671 | inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING, | ||
672 | NETCONFA_IFINDEX_ALL, | ||
673 | net->ipv6.devconf_all); | ||
528 | } else if ((!newf) ^ (!old)) | 674 | } else if ((!newf) ^ (!old)) |
529 | dev_forward_change((struct inet6_dev *)table->extra1); | 675 | dev_forward_change((struct inet6_dev *)table->extra1); |
530 | rtnl_unlock(); | 676 | rtnl_unlock(); |
@@ -553,7 +699,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
553 | pr_warn("Freeing alive inet6 address %p\n", ifp); | 699 | pr_warn("Freeing alive inet6 address %p\n", ifp); |
554 | return; | 700 | return; |
555 | } | 701 | } |
556 | dst_release(&ifp->rt->dst); | 702 | ip6_rt_put(ifp->rt); |
557 | 703 | ||
558 | kfree_rcu(ifp, rcu); | 704 | kfree_rcu(ifp, rcu); |
559 | } | 705 | } |
@@ -805,7 +951,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
805 | rt6_set_expires(rt, expires); | 951 | rt6_set_expires(rt, expires); |
806 | } | 952 | } |
807 | } | 953 | } |
808 | dst_release(&rt->dst); | 954 | ip6_rt_put(rt); |
809 | } | 955 | } |
810 | 956 | ||
811 | /* clean up prefsrc entries */ | 957 | /* clean up prefsrc entries */ |
@@ -1692,7 +1838,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1692 | This thing is done here expecting that the whole | 1838 | This thing is done here expecting that the whole |
1693 | class of non-broadcast devices need not cloning. | 1839 | class of non-broadcast devices need not cloning. |
1694 | */ | 1840 | */ |
1695 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 1841 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
1696 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) | 1842 | if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) |
1697 | cfg.fc_flags |= RTF_NONEXTHOP; | 1843 | cfg.fc_flags |= RTF_NONEXTHOP; |
1698 | #endif | 1844 | #endif |
@@ -1752,7 +1898,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1752 | ip6_route_add(&cfg); | 1898 | ip6_route_add(&cfg); |
1753 | } | 1899 | } |
1754 | 1900 | ||
1755 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 1901 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
1756 | static void sit_route_add(struct net_device *dev) | 1902 | static void sit_route_add(struct net_device *dev) |
1757 | { | 1903 | { |
1758 | struct fib6_config cfg = { | 1904 | struct fib6_config cfg = { |
@@ -1881,8 +2027,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) | |||
1881 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, | 2027 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, |
1882 | dev, expires, flags); | 2028 | dev, expires, flags); |
1883 | } | 2029 | } |
1884 | if (rt) | 2030 | ip6_rt_put(rt); |
1885 | dst_release(&rt->dst); | ||
1886 | } | 2031 | } |
1887 | 2032 | ||
1888 | /* Try to figure out our local address for this prefix */ | 2033 | /* Try to figure out our local address for this prefix */ |
@@ -2104,7 +2249,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) | |||
2104 | if (dev == NULL) | 2249 | if (dev == NULL) |
2105 | goto err_exit; | 2250 | goto err_exit; |
2106 | 2251 | ||
2107 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2252 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2108 | if (dev->type == ARPHRD_SIT) { | 2253 | if (dev->type == ARPHRD_SIT) { |
2109 | const struct net_device_ops *ops = dev->netdev_ops; | 2254 | const struct net_device_ops *ops = dev->netdev_ops; |
2110 | struct ifreq ifr; | 2255 | struct ifreq ifr; |
@@ -2315,7 +2460,7 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr, | |||
2315 | } | 2460 | } |
2316 | } | 2461 | } |
2317 | 2462 | ||
2318 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2463 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2319 | static void sit_add_v4_addrs(struct inet6_dev *idev) | 2464 | static void sit_add_v4_addrs(struct inet6_dev *idev) |
2320 | { | 2465 | { |
2321 | struct in6_addr addr; | 2466 | struct in6_addr addr; |
@@ -2434,7 +2579,7 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2434 | addrconf_add_linklocal(idev, &addr); | 2579 | addrconf_add_linklocal(idev, &addr); |
2435 | } | 2580 | } |
2436 | 2581 | ||
2437 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2582 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2438 | static void addrconf_sit_config(struct net_device *dev) | 2583 | static void addrconf_sit_config(struct net_device *dev) |
2439 | { | 2584 | { |
2440 | struct inet6_dev *idev; | 2585 | struct inet6_dev *idev; |
@@ -2471,7 +2616,7 @@ static void addrconf_sit_config(struct net_device *dev) | |||
2471 | } | 2616 | } |
2472 | #endif | 2617 | #endif |
2473 | 2618 | ||
2474 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | 2619 | #if IS_ENABLED(CONFIG_NET_IPGRE) |
2475 | static void addrconf_gre_config(struct net_device *dev) | 2620 | static void addrconf_gre_config(struct net_device *dev) |
2476 | { | 2621 | { |
2477 | struct inet6_dev *idev; | 2622 | struct inet6_dev *idev; |
@@ -2601,12 +2746,12 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2601 | } | 2746 | } |
2602 | 2747 | ||
2603 | switch (dev->type) { | 2748 | switch (dev->type) { |
2604 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2749 | #if IS_ENABLED(CONFIG_IPV6_SIT) |
2605 | case ARPHRD_SIT: | 2750 | case ARPHRD_SIT: |
2606 | addrconf_sit_config(dev); | 2751 | addrconf_sit_config(dev); |
2607 | break; | 2752 | break; |
2608 | #endif | 2753 | #endif |
2609 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | 2754 | #if IS_ENABLED(CONFIG_NET_IPGRE) |
2610 | case ARPHRD_IPGRE: | 2755 | case ARPHRD_IPGRE: |
2611 | addrconf_gre_config(dev); | 2756 | addrconf_gre_config(dev); |
2612 | break; | 2757 | break; |
@@ -3194,7 +3339,7 @@ void if6_proc_exit(void) | |||
3194 | } | 3339 | } |
3195 | #endif /* CONFIG_PROC_FS */ | 3340 | #endif /* CONFIG_PROC_FS */ |
3196 | 3341 | ||
3197 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 3342 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
3198 | /* Check if address is a home address configured on any interface. */ | 3343 | /* Check if address is a home address configured on any interface. */ |
3199 | int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) | 3344 | int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr) |
3200 | { | 3345 | { |
@@ -4784,6 +4929,8 @@ int __init addrconf_init(void) | |||
4784 | inet6_dump_ifmcaddr, NULL); | 4929 | inet6_dump_ifmcaddr, NULL); |
4785 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, | 4930 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, |
4786 | inet6_dump_ifacaddr, NULL); | 4931 | inet6_dump_ifacaddr, NULL); |
4932 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, | ||
4933 | NULL, NULL); | ||
4787 | 4934 | ||
4788 | ipv6_addr_label_rtnl_register(); | 4935 | ipv6_addr_label_rtnl_register(); |
4789 | 4936 | ||
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 7e6139508ee7..ecc35b93314b 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define IPV6HDR_BASELEN 8 | 44 | #define IPV6HDR_BASELEN 8 |
45 | 45 | ||
46 | struct tmp_ext { | 46 | struct tmp_ext { |
47 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 47 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
48 | struct in6_addr saddr; | 48 | struct in6_addr saddr; |
49 | #endif | 49 | #endif |
50 | struct in6_addr daddr; | 50 | struct in6_addr daddr; |
@@ -152,7 +152,7 @@ bad: | |||
152 | return false; | 152 | return false; |
153 | } | 153 | } |
154 | 154 | ||
155 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 155 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
156 | /** | 156 | /** |
157 | * ipv6_rearrange_destopt - rearrange IPv6 destination options header | 157 | * ipv6_rearrange_destopt - rearrange IPv6 destination options header |
158 | * @iph: IPv6 header | 158 | * @iph: IPv6 header |
@@ -320,7 +320,7 @@ static void ah6_output_done(struct crypto_async_request *base, int err) | |||
320 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); | 320 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); |
321 | 321 | ||
322 | if (extlen) { | 322 | if (extlen) { |
323 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 323 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
324 | memcpy(&top_iph->saddr, iph_ext, extlen); | 324 | memcpy(&top_iph->saddr, iph_ext, extlen); |
325 | #else | 325 | #else |
326 | memcpy(&top_iph->daddr, iph_ext, extlen); | 326 | memcpy(&top_iph->daddr, iph_ext, extlen); |
@@ -385,7 +385,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
385 | memcpy(iph_base, top_iph, IPV6HDR_BASELEN); | 385 | memcpy(iph_base, top_iph, IPV6HDR_BASELEN); |
386 | 386 | ||
387 | if (extlen) { | 387 | if (extlen) { |
388 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 388 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
389 | memcpy(iph_ext, &top_iph->saddr, extlen); | 389 | memcpy(iph_ext, &top_iph->saddr, extlen); |
390 | #else | 390 | #else |
391 | memcpy(iph_ext, &top_iph->daddr, extlen); | 391 | memcpy(iph_ext, &top_iph->daddr, extlen); |
@@ -434,7 +434,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
434 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); | 434 | memcpy(top_iph, iph_base, IPV6HDR_BASELEN); |
435 | 435 | ||
436 | if (extlen) { | 436 | if (extlen) { |
437 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 437 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
438 | memcpy(&top_iph->saddr, iph_ext, extlen); | 438 | memcpy(&top_iph->saddr, iph_ext, extlen); |
439 | #else | 439 | #else |
440 | memcpy(&top_iph->daddr, iph_ext, extlen); | 440 | memcpy(&top_iph->daddr, iph_ext, extlen); |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index cdf02be5f191..4963c769a13f 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -84,7 +84,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
84 | rt = rt6_lookup(net, addr, NULL, 0, 0); | 84 | rt = rt6_lookup(net, addr, NULL, 0, 0); |
85 | if (rt) { | 85 | if (rt) { |
86 | dev = rt->dst.dev; | 86 | dev = rt->dst.dev; |
87 | dst_release(&rt->dst); | 87 | ip6_rt_put(rt); |
88 | } else if (ishost) { | 88 | } else if (ishost) { |
89 | err = -EADDRNOTAVAIL; | 89 | err = -EADDRNOTAVAIL; |
90 | goto error; | 90 | goto error; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index be2b67d631e5..93cbad2c0aa7 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -769,7 +769,7 @@ int datagram_send_ctl(struct net *net, struct sock *sk, | |||
769 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); | 769 | rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); |
770 | 770 | ||
771 | switch (rthdr->type) { | 771 | switch (rthdr->type) { |
772 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 772 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
773 | case IPV6_SRCRT_TYPE_2: | 773 | case IPV6_SRCRT_TYPE_2: |
774 | if (rthdr->hdrlen != 2 || | 774 | if (rthdr->hdrlen != 2 || |
775 | rthdr->segments_left != 1) { | 775 | rthdr->segments_left != 1) { |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index fa3d9c328092..f005acc58b2a 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <net/ndisc.h> | 43 | #include <net/ndisc.h> |
44 | #include <net/ip6_route.h> | 44 | #include <net/ip6_route.h> |
45 | #include <net/addrconf.h> | 45 | #include <net/addrconf.h> |
46 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 46 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
47 | #include <net/xfrm.h> | 47 | #include <net/xfrm.h> |
48 | #endif | 48 | #endif |
49 | 49 | ||
@@ -224,7 +224,7 @@ bad: | |||
224 | Destination options header. | 224 | Destination options header. |
225 | *****************************/ | 225 | *****************************/ |
226 | 226 | ||
227 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 227 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
228 | static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) | 228 | static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) |
229 | { | 229 | { |
230 | struct ipv6_destopt_hao *hao; | 230 | struct ipv6_destopt_hao *hao; |
@@ -288,7 +288,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff) | |||
288 | #endif | 288 | #endif |
289 | 289 | ||
290 | static const struct tlvtype_proc tlvprocdestopt_lst[] = { | 290 | static const struct tlvtype_proc tlvprocdestopt_lst[] = { |
291 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 291 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
292 | { | 292 | { |
293 | .type = IPV6_TLV_HAO, | 293 | .type = IPV6_TLV_HAO, |
294 | .func = ipv6_dest_hao, | 294 | .func = ipv6_dest_hao, |
@@ -300,7 +300,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = { | |||
300 | static int ipv6_destopt_rcv(struct sk_buff *skb) | 300 | static int ipv6_destopt_rcv(struct sk_buff *skb) |
301 | { | 301 | { |
302 | struct inet6_skb_parm *opt = IP6CB(skb); | 302 | struct inet6_skb_parm *opt = IP6CB(skb); |
303 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 303 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
304 | __u16 dstbuf; | 304 | __u16 dstbuf; |
305 | #endif | 305 | #endif |
306 | struct dst_entry *dst = skb_dst(skb); | 306 | struct dst_entry *dst = skb_dst(skb); |
@@ -315,14 +315,14 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
315 | } | 315 | } |
316 | 316 | ||
317 | opt->lastopt = opt->dst1 = skb_network_header_len(skb); | 317 | opt->lastopt = opt->dst1 = skb_network_header_len(skb); |
318 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 318 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
319 | dstbuf = opt->dst1; | 319 | dstbuf = opt->dst1; |
320 | #endif | 320 | #endif |
321 | 321 | ||
322 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { | 322 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { |
323 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; | 323 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; |
324 | opt = IP6CB(skb); | 324 | opt = IP6CB(skb); |
325 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 325 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
326 | opt->nhoff = dstbuf; | 326 | opt->nhoff = dstbuf; |
327 | #else | 327 | #else |
328 | opt->nhoff = opt->dst1; | 328 | opt->nhoff = opt->dst1; |
@@ -378,7 +378,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) | |||
378 | looped_back: | 378 | looped_back: |
379 | if (hdr->segments_left == 0) { | 379 | if (hdr->segments_left == 0) { |
380 | switch (hdr->type) { | 380 | switch (hdr->type) { |
381 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 381 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
382 | case IPV6_SRCRT_TYPE_2: | 382 | case IPV6_SRCRT_TYPE_2: |
383 | /* Silently discard type 2 header unless it was | 383 | /* Silently discard type 2 header unless it was |
384 | * processed by own | 384 | * processed by own |
@@ -404,7 +404,7 @@ looped_back: | |||
404 | } | 404 | } |
405 | 405 | ||
406 | switch (hdr->type) { | 406 | switch (hdr->type) { |
407 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 407 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
408 | case IPV6_SRCRT_TYPE_2: | 408 | case IPV6_SRCRT_TYPE_2: |
409 | if (accept_source_route < 0) | 409 | if (accept_source_route < 0) |
410 | goto unknown_rh; | 410 | goto unknown_rh; |
@@ -461,7 +461,7 @@ looped_back: | |||
461 | addr += i - 1; | 461 | addr += i - 1; |
462 | 462 | ||
463 | switch (hdr->type) { | 463 | switch (hdr->type) { |
464 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 464 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
465 | case IPV6_SRCRT_TYPE_2: | 465 | case IPV6_SRCRT_TYPE_2: |
466 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, | 466 | if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, |
467 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, | 467 | (xfrm_address_t *)&ipv6_hdr(skb)->saddr, |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index d9fb9110f607..2e1a432867c0 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -100,7 +100,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
100 | goto out; | 100 | goto out; |
101 | } | 101 | } |
102 | again: | 102 | again: |
103 | dst_release(&rt->dst); | 103 | ip6_rt_put(rt); |
104 | rt = NULL; | 104 | rt = NULL; |
105 | goto out; | 105 | goto out; |
106 | 106 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 24d69dbca4d6..b4a9fd51dae7 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -280,7 +280,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 283 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
284 | static void mip6_addr_swap(struct sk_buff *skb) | 284 | static void mip6_addr_swap(struct sk_buff *skb) |
285 | { | 285 | { |
286 | struct ipv6hdr *iph = ipv6_hdr(skb); | 286 | struct ipv6hdr *iph = ipv6_hdr(skb); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 24995a93ef8c..710cafd2e1a9 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -672,6 +672,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
672 | iter->rt6i_idev == rt->rt6i_idev && | 672 | iter->rt6i_idev == rt->rt6i_idev && |
673 | ipv6_addr_equal(&iter->rt6i_gateway, | 673 | ipv6_addr_equal(&iter->rt6i_gateway, |
674 | &rt->rt6i_gateway)) { | 674 | &rt->rt6i_gateway)) { |
675 | if (rt->rt6i_nsiblings) | ||
676 | rt->rt6i_nsiblings = 0; | ||
675 | if (!(iter->rt6i_flags & RTF_EXPIRES)) | 677 | if (!(iter->rt6i_flags & RTF_EXPIRES)) |
676 | return -EEXIST; | 678 | return -EEXIST; |
677 | if (!(rt->rt6i_flags & RTF_EXPIRES)) | 679 | if (!(rt->rt6i_flags & RTF_EXPIRES)) |
@@ -680,6 +682,21 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
680 | rt6_set_expires(iter, rt->dst.expires); | 682 | rt6_set_expires(iter, rt->dst.expires); |
681 | return -EEXIST; | 683 | return -EEXIST; |
682 | } | 684 | } |
685 | /* If we have the same destination and the same metric, | ||
686 | * but not the same gateway, then the route we try to | ||
687 | * add is sibling to this route, increment our counter | ||
688 | * of siblings, and later we will add our route to the | ||
689 | * list. | ||
690 | * Only static routes (which don't have flag | ||
691 | * RTF_EXPIRES) are used for ECMPv6. | ||
692 | * | ||
693 | * To avoid long list, we only had siblings if the | ||
694 | * route have a gateway. | ||
695 | */ | ||
696 | if (rt->rt6i_flags & RTF_GATEWAY && | ||
697 | !(rt->rt6i_flags & RTF_EXPIRES) && | ||
698 | !(iter->rt6i_flags & RTF_EXPIRES)) | ||
699 | rt->rt6i_nsiblings++; | ||
683 | } | 700 | } |
684 | 701 | ||
685 | if (iter->rt6i_metric > rt->rt6i_metric) | 702 | if (iter->rt6i_metric > rt->rt6i_metric) |
@@ -692,6 +709,35 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
692 | if (ins == &fn->leaf) | 709 | if (ins == &fn->leaf) |
693 | fn->rr_ptr = NULL; | 710 | fn->rr_ptr = NULL; |
694 | 711 | ||
712 | /* Link this route to others same route. */ | ||
713 | if (rt->rt6i_nsiblings) { | ||
714 | unsigned int rt6i_nsiblings; | ||
715 | struct rt6_info *sibling, *temp_sibling; | ||
716 | |||
717 | /* Find the first route that have the same metric */ | ||
718 | sibling = fn->leaf; | ||
719 | while (sibling) { | ||
720 | if (sibling->rt6i_metric == rt->rt6i_metric) { | ||
721 | list_add_tail(&rt->rt6i_siblings, | ||
722 | &sibling->rt6i_siblings); | ||
723 | break; | ||
724 | } | ||
725 | sibling = sibling->dst.rt6_next; | ||
726 | } | ||
727 | /* For each sibling in the list, increment the counter of | ||
728 | * siblings. BUG() if counters does not match, list of siblings | ||
729 | * is broken! | ||
730 | */ | ||
731 | rt6i_nsiblings = 0; | ||
732 | list_for_each_entry_safe(sibling, temp_sibling, | ||
733 | &rt->rt6i_siblings, rt6i_siblings) { | ||
734 | sibling->rt6i_nsiblings++; | ||
735 | BUG_ON(sibling->rt6i_nsiblings != rt->rt6i_nsiblings); | ||
736 | rt6i_nsiblings++; | ||
737 | } | ||
738 | BUG_ON(rt6i_nsiblings != rt->rt6i_nsiblings); | ||
739 | } | ||
740 | |||
695 | /* | 741 | /* |
696 | * insert node | 742 | * insert node |
697 | */ | 743 | */ |
@@ -1193,6 +1239,17 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
1193 | if (fn->rr_ptr == rt) | 1239 | if (fn->rr_ptr == rt) |
1194 | fn->rr_ptr = NULL; | 1240 | fn->rr_ptr = NULL; |
1195 | 1241 | ||
1242 | /* Remove this entry from other siblings */ | ||
1243 | if (rt->rt6i_nsiblings) { | ||
1244 | struct rt6_info *sibling, *next_sibling; | ||
1245 | |||
1246 | list_for_each_entry_safe(sibling, next_sibling, | ||
1247 | &rt->rt6i_siblings, rt6i_siblings) | ||
1248 | sibling->rt6i_nsiblings--; | ||
1249 | rt->rt6i_nsiblings = 0; | ||
1250 | list_del_init(&rt->rt6i_siblings); | ||
1251 | } | ||
1252 | |||
1196 | /* Adjust walkers */ | 1253 | /* Adjust walkers */ |
1197 | read_lock(&fib6_walker_lock); | 1254 | read_lock(&fib6_walker_lock); |
1198 | FOR_WALKERS(w) { | 1255 | FOR_WALKERS(w) { |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index d5cb3c4e66f8..12aa473e9793 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -1069,7 +1069,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu) | |||
1069 | dev->mtu = IPV6_MIN_MTU; | 1069 | dev->mtu = IPV6_MIN_MTU; |
1070 | } | 1070 | } |
1071 | } | 1071 | } |
1072 | dst_release(&rt->dst); | 1072 | ip6_rt_put(rt); |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | t->hlen = addend; | 1075 | t->hlen = addend; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index aece3e792f84..3deaa4e2e8e2 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -538,8 +538,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
538 | to->tc_index = from->tc_index; | 538 | to->tc_index = from->tc_index; |
539 | #endif | 539 | #endif |
540 | nf_copy(to, from); | 540 | nf_copy(to, from); |
541 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 541 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
542 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
543 | to->nf_trace = from->nf_trace; | 542 | to->nf_trace = from->nf_trace; |
544 | #endif | 543 | #endif |
545 | skb_copy_secmark(to, from); | 544 | skb_copy_secmark(to, from); |
@@ -564,7 +563,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
564 | found_rhdr = 1; | 563 | found_rhdr = 1; |
565 | break; | 564 | break; |
566 | case NEXTHDR_DEST: | 565 | case NEXTHDR_DEST: |
567 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 566 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
568 | if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) | 567 | if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) |
569 | break; | 568 | break; |
570 | #endif | 569 | #endif |
@@ -756,7 +755,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | if (err == 0) { | 755 | if (err == 0) { |
757 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), | 756 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), |
758 | IPSTATS_MIB_FRAGOKS); | 757 | IPSTATS_MIB_FRAGOKS); |
759 | dst_release(&rt->dst); | 758 | ip6_rt_put(rt); |
760 | return 0; | 759 | return 0; |
761 | } | 760 | } |
762 | 761 | ||
@@ -768,7 +767,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
768 | 767 | ||
769 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), | 768 | IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), |
770 | IPSTATS_MIB_FRAGFAILS); | 769 | IPSTATS_MIB_FRAGFAILS); |
771 | dst_release(&rt->dst); | 770 | ip6_rt_put(rt); |
772 | return err; | 771 | return err; |
773 | 772 | ||
774 | slow_path_clean: | 773 | slow_path_clean: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index cb7e2ded6f08..424ed45ef122 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -83,6 +83,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) | |||
83 | 83 | ||
84 | static int ip6_tnl_dev_init(struct net_device *dev); | 84 | static int ip6_tnl_dev_init(struct net_device *dev); |
85 | static void ip6_tnl_dev_setup(struct net_device *dev); | 85 | static void ip6_tnl_dev_setup(struct net_device *dev); |
86 | static struct rtnl_link_ops ip6_link_ops __read_mostly; | ||
86 | 87 | ||
87 | static int ip6_tnl_net_id __read_mostly; | 88 | static int ip6_tnl_net_id __read_mostly; |
88 | struct ip6_tnl_net { | 89 | struct ip6_tnl_net { |
@@ -299,6 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | |||
299 | goto failed_free; | 300 | goto failed_free; |
300 | 301 | ||
301 | strcpy(t->parms.name, dev->name); | 302 | strcpy(t->parms.name, dev->name); |
303 | dev->rtnl_link_ops = &ip6_link_ops; | ||
302 | 304 | ||
303 | dev_hold(dev); | 305 | dev_hold(dev); |
304 | ip6_tnl_link(ip6n, t); | 306 | ip6_tnl_link(ip6n, t); |
@@ -663,8 +665,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
663 | 665 | ||
664 | icmpv6_send(skb2, rel_type, rel_code, rel_info); | 666 | icmpv6_send(skb2, rel_type, rel_code, rel_info); |
665 | 667 | ||
666 | if (rt) | 668 | ip6_rt_put(rt); |
667 | dst_release(&rt->dst); | ||
668 | 669 | ||
669 | kfree_skb(skb2); | 670 | kfree_skb(skb2); |
670 | } | 671 | } |
@@ -1208,7 +1209,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1208 | if (dev->mtu < IPV6_MIN_MTU) | 1209 | if (dev->mtu < IPV6_MIN_MTU) |
1209 | dev->mtu = IPV6_MIN_MTU; | 1210 | dev->mtu = IPV6_MIN_MTU; |
1210 | } | 1211 | } |
1211 | dst_release(&rt->dst); | 1212 | ip6_rt_put(rt); |
1212 | } | 1213 | } |
1213 | } | 1214 | } |
1214 | 1215 | ||
@@ -1505,6 +1506,55 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) | |||
1505 | return 0; | 1506 | return 0; |
1506 | } | 1507 | } |
1507 | 1508 | ||
1509 | static size_t ip6_get_size(const struct net_device *dev) | ||
1510 | { | ||
1511 | return | ||
1512 | /* IFLA_IPTUN_LINK */ | ||
1513 | nla_total_size(4) + | ||
1514 | /* IFLA_IPTUN_LOCAL */ | ||
1515 | nla_total_size(sizeof(struct in6_addr)) + | ||
1516 | /* IFLA_IPTUN_REMOTE */ | ||
1517 | nla_total_size(sizeof(struct in6_addr)) + | ||
1518 | /* IFLA_IPTUN_TTL */ | ||
1519 | nla_total_size(1) + | ||
1520 | /* IFLA_IPTUN_ENCAP_LIMIT */ | ||
1521 | nla_total_size(1) + | ||
1522 | /* IFLA_IPTUN_FLOWINFO */ | ||
1523 | nla_total_size(4) + | ||
1524 | /* IFLA_IPTUN_FLAGS */ | ||
1525 | nla_total_size(4) + | ||
1526 | 0; | ||
1527 | } | ||
1528 | |||
1529 | static int ip6_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1530 | { | ||
1531 | struct ip6_tnl *tunnel = netdev_priv(dev); | ||
1532 | struct __ip6_tnl_parm *parm = &tunnel->parms; | ||
1533 | |||
1534 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1535 | nla_put(skb, IFLA_IPTUN_LOCAL, sizeof(struct in6_addr), | ||
1536 | &parm->raddr) || | ||
1537 | nla_put(skb, IFLA_IPTUN_REMOTE, sizeof(struct in6_addr), | ||
1538 | &parm->laddr) || | ||
1539 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->hop_limit) || | ||
1540 | nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) || | ||
1541 | nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || | ||
1542 | nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags)) | ||
1543 | goto nla_put_failure; | ||
1544 | return 0; | ||
1545 | |||
1546 | nla_put_failure: | ||
1547 | return -EMSGSIZE; | ||
1548 | } | ||
1549 | |||
1550 | static struct rtnl_link_ops ip6_link_ops __read_mostly = { | ||
1551 | .kind = "ip6tnl", | ||
1552 | .maxtype = IFLA_IPTUN_MAX, | ||
1553 | .priv_size = sizeof(struct ip6_tnl), | ||
1554 | .get_size = ip6_get_size, | ||
1555 | .fill_info = ip6_fill_info, | ||
1556 | }; | ||
1557 | |||
1508 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { | 1558 | static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { |
1509 | .handler = ip4ip6_rcv, | 1559 | .handler = ip4ip6_rcv, |
1510 | .err_handler = ip4ip6_err, | 1560 | .err_handler = ip4ip6_err, |
@@ -1613,9 +1663,14 @@ static int __init ip6_tunnel_init(void) | |||
1613 | pr_err("%s: can't register ip6ip6\n", __func__); | 1663 | pr_err("%s: can't register ip6ip6\n", __func__); |
1614 | goto out_ip6ip6; | 1664 | goto out_ip6ip6; |
1615 | } | 1665 | } |
1666 | err = rtnl_link_register(&ip6_link_ops); | ||
1667 | if (err < 0) | ||
1668 | goto rtnl_link_failed; | ||
1616 | 1669 | ||
1617 | return 0; | 1670 | return 0; |
1618 | 1671 | ||
1672 | rtnl_link_failed: | ||
1673 | xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); | ||
1619 | out_ip6ip6: | 1674 | out_ip6ip6: |
1620 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); | 1675 | xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); |
1621 | out_ip4ip6: | 1676 | out_ip4ip6: |
@@ -1630,6 +1685,7 @@ out_pernet: | |||
1630 | 1685 | ||
1631 | static void __exit ip6_tunnel_cleanup(void) | 1686 | static void __exit ip6_tunnel_cleanup(void) |
1632 | { | 1687 | { |
1688 | rtnl_link_unregister(&ip6_link_ops); | ||
1633 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) | 1689 | if (xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET)) |
1634 | pr_info("%s: can't deregister ip4ip6\n", __func__); | 1690 | pr_info("%s: can't deregister ip4ip6\n", __func__); |
1635 | 1691 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e1..a7bee6a91335 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -397,7 +397,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
397 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { | 397 | if (optname == IPV6_RTHDR && opt && opt->srcrt) { |
398 | struct ipv6_rt_hdr *rthdr = opt->srcrt; | 398 | struct ipv6_rt_hdr *rthdr = opt->srcrt; |
399 | switch (rthdr->type) { | 399 | switch (rthdr->type) { |
400 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 400 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
401 | case IPV6_SRCRT_TYPE_2: | 401 | case IPV6_SRCRT_TYPE_2: |
402 | if (rthdr->hdrlen != 2 || | 402 | if (rthdr->hdrlen != 2 || |
403 | rthdr->segments_left != 1) | 403 | rthdr->segments_left != 1) |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 92f8e48e4ba4..b19ed51a45bb 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -163,7 +163,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
163 | rt = rt6_lookup(net, addr, NULL, 0, 0); | 163 | rt = rt6_lookup(net, addr, NULL, 0, 0); |
164 | if (rt) { | 164 | if (rt) { |
165 | dev = rt->dst.dev; | 165 | dev = rt->dst.dev; |
166 | dst_release(&rt->dst); | 166 | ip6_rt_put(rt); |
167 | } | 167 | } |
168 | } else | 168 | } else |
169 | dev = dev_get_by_index_rcu(net, ifindex); | 169 | dev = dev_get_by_index_rcu(net, ifindex); |
@@ -260,7 +260,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, | |||
260 | 260 | ||
261 | if (rt) { | 261 | if (rt) { |
262 | dev = rt->dst.dev; | 262 | dev = rt->dst.dev; |
263 | dst_release(&rt->dst); | 263 | ip6_rt_put(rt); |
264 | } | 264 | } |
265 | } else | 265 | } else |
266 | dev = dev_get_by_index_rcu(net, ifindex); | 266 | dev = dev_get_by_index_rcu(net, ifindex); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2edce30ef733..4f47aa5183ae 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -905,7 +905,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
905 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && | 905 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && |
906 | net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp && | 906 | net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp && |
907 | pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) { | 907 | pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) { |
908 | /* XXX: idev->cnf.prixy_ndp */ | 908 | /* XXX: idev->cnf.proxy_ndp */ |
909 | goto out; | 909 | goto out; |
910 | } | 910 | } |
911 | 911 | ||
@@ -1144,7 +1144,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1144 | ND_PRINTK(0, err, | 1144 | ND_PRINTK(0, err, |
1145 | "RA: %s got default router without neighbour\n", | 1145 | "RA: %s got default router without neighbour\n", |
1146 | __func__); | 1146 | __func__); |
1147 | dst_release(&rt->dst); | 1147 | ip6_rt_put(rt); |
1148 | return; | 1148 | return; |
1149 | } | 1149 | } |
1150 | } | 1150 | } |
@@ -1169,7 +1169,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1169 | ND_PRINTK(0, err, | 1169 | ND_PRINTK(0, err, |
1170 | "RA: %s got default router without neighbour\n", | 1170 | "RA: %s got default router without neighbour\n", |
1171 | __func__); | 1171 | __func__); |
1172 | dst_release(&rt->dst); | 1172 | ip6_rt_put(rt); |
1173 | return; | 1173 | return; |
1174 | } | 1174 | } |
1175 | neigh->flags |= NTF_ROUTER; | 1175 | neigh->flags |= NTF_ROUTER; |
@@ -1325,8 +1325,7 @@ skip_routeinfo: | |||
1325 | ND_PRINTK(2, warn, "RA: invalid RA options\n"); | 1325 | ND_PRINTK(2, warn, "RA: invalid RA options\n"); |
1326 | } | 1326 | } |
1327 | out: | 1327 | out: |
1328 | if (rt) | 1328 | ip6_rt_put(rt); |
1329 | dst_release(&rt->dst); | ||
1330 | if (neigh) | 1329 | if (neigh) |
1331 | neigh_release(neigh); | 1330 | neigh_release(neigh); |
1332 | } | 1331 | } |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index d7cb04506c3d..10ce76a2cb94 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -207,8 +207,7 @@ ip6t_get_target_c(const struct ip6t_entry *e) | |||
207 | return ip6t_get_target((struct ip6t_entry *)e); | 207 | return ip6t_get_target((struct ip6t_entry *)e); |
208 | } | 208 | } |
209 | 209 | ||
210 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 210 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
211 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
212 | /* This cries for unification! */ | 211 | /* This cries for unification! */ |
213 | static const char *const hooknames[] = { | 212 | static const char *const hooknames[] = { |
214 | [NF_INET_PRE_ROUTING] = "PREROUTING", | 213 | [NF_INET_PRE_ROUTING] = "PREROUTING", |
@@ -381,8 +380,7 @@ ip6t_do_table(struct sk_buff *skb, | |||
381 | t = ip6t_get_target_c(e); | 380 | t = ip6t_get_target_c(e); |
382 | IP_NF_ASSERT(t->u.kernel.target); | 381 | IP_NF_ASSERT(t->u.kernel.target); |
383 | 382 | ||
384 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 383 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) |
385 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | ||
386 | /* The packet is traced: log it */ | 384 | /* The packet is traced: log it */ |
387 | if (unlikely(skb->nf_trace)) | 385 | if (unlikely(skb->nf_trace)) |
388 | trace_packet(skb, hook, in, out, | 386 | trace_packet(skb, hook, in, out, |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index 5d1d8b04d694..5060d54199ab 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -67,7 +67,7 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
67 | if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE)) | 67 | if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE)) |
68 | ret = true; | 68 | ret = true; |
69 | out: | 69 | out: |
70 | dst_release(&rt->dst); | 70 | ip6_rt_put(rt); |
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 8860d23e61cf..ccb5cbe93549 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -295,7 +295,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | |||
295 | }, | 295 | }, |
296 | }; | 296 | }; |
297 | 297 | ||
298 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 298 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
299 | 299 | ||
300 | #include <linux/netfilter/nfnetlink.h> | 300 | #include <linux/netfilter/nfnetlink.h> |
301 | #include <linux/netfilter/nfnetlink_conntrack.h> | 301 | #include <linux/netfilter/nfnetlink_conntrack.h> |
@@ -346,7 +346,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { | |||
346 | .invert_tuple = ipv6_invert_tuple, | 346 | .invert_tuple = ipv6_invert_tuple, |
347 | .print_tuple = ipv6_print_tuple, | 347 | .print_tuple = ipv6_print_tuple, |
348 | .get_l4proto = ipv6_get_l4proto, | 348 | .get_l4proto = ipv6_get_l4proto, |
349 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 349 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
350 | .tuple_to_nlattr = ipv6_tuple_to_nlattr, | 350 | .tuple_to_nlattr = ipv6_tuple_to_nlattr, |
351 | .nlattr_tuple_size = ipv6_nlattr_tuple_size, | 351 | .nlattr_tuple_size = ipv6_nlattr_tuple_size, |
352 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, | 352 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 2d54b2061d68..24df3dde0076 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -232,7 +232,7 @@ icmpv6_error(struct net *net, struct nf_conn *tmpl, | |||
232 | return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); | 232 | return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); |
233 | } | 233 | } |
234 | 234 | ||
235 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 235 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
236 | 236 | ||
237 | #include <linux/netfilter/nfnetlink.h> | 237 | #include <linux/netfilter/nfnetlink.h> |
238 | #include <linux/netfilter/nfnetlink_conntrack.h> | 238 | #include <linux/netfilter/nfnetlink_conntrack.h> |
@@ -375,7 +375,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = | |||
375 | .get_timeouts = icmpv6_get_timeouts, | 375 | .get_timeouts = icmpv6_get_timeouts, |
376 | .new = icmpv6_new, | 376 | .new = icmpv6_new, |
377 | .error = icmpv6_error, | 377 | .error = icmpv6_error, |
378 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 378 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
379 | .tuple_to_nlattr = icmpv6_tuple_to_nlattr, | 379 | .tuple_to_nlattr = icmpv6_tuple_to_nlattr, |
380 | .nlattr_tuple_size = icmpv6_nlattr_tuple_size, | 380 | .nlattr_tuple_size = icmpv6_nlattr_tuple_size, |
381 | .nlattr_to_tuple = icmpv6_nlattr_to_tuple, | 381 | .nlattr_to_tuple = icmpv6_nlattr_to_tuple, |
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index cdd6d045e42e..aacd121fe8c5 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/netfilter_ipv6.h> | 20 | #include <linux/netfilter_ipv6.h> |
21 | #include <linux/netfilter_bridge.h> | 21 | #include <linux/netfilter_bridge.h> |
22 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 22 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
23 | #include <net/netfilter/nf_conntrack.h> | 23 | #include <net/netfilter/nf_conntrack.h> |
24 | #include <net/netfilter/nf_conntrack_helper.h> | 24 | #include <net/netfilter/nf_conntrack_helper.h> |
25 | #include <net/netfilter/nf_conntrack_l4proto.h> | 25 | #include <net/netfilter/nf_conntrack_l4proto.h> |
@@ -35,7 +35,7 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | |||
35 | { | 35 | { |
36 | u16 zone = NF_CT_DEFAULT_ZONE; | 36 | u16 zone = NF_CT_DEFAULT_ZONE; |
37 | 37 | ||
38 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 38 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
39 | if (skb->nfct) | 39 | if (skb->nfct) |
40 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | 40 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); |
41 | #endif | 41 | #endif |
@@ -60,7 +60,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum, | |||
60 | { | 60 | { |
61 | struct sk_buff *reasm; | 61 | struct sk_buff *reasm; |
62 | 62 | ||
63 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 63 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
64 | /* Previously seen (loopback)? */ | 64 | /* Previously seen (loopback)? */ |
65 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) | 65 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) |
66 | return NF_ACCEPT; | 66 | return NF_ACCEPT; |
diff --git a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c index 5d6da784305b..61aaf70f376e 100644 --- a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c | |||
@@ -84,7 +84,7 @@ const struct nf_nat_l4proto nf_nat_l4proto_icmpv6 = { | |||
84 | .manip_pkt = icmpv6_manip_pkt, | 84 | .manip_pkt = icmpv6_manip_pkt, |
85 | .in_range = icmpv6_in_range, | 85 | .in_range = icmpv6_in_range, |
86 | .unique_tuple = icmpv6_unique_tuple, | 86 | .unique_tuple = icmpv6_unique_tuple, |
87 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 87 | #if IS_ENABLED(CONFIG_NF_CT_NETLINK) |
88 | .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, | 88 | .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, |
89 | #endif | 89 | #endif |
90 | }; | 90 | }; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d8e95c77db99..6cd29b1e8b92 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <net/udp.h> | 50 | #include <net/udp.h> |
51 | #include <net/inet_common.h> | 51 | #include <net/inet_common.h> |
52 | #include <net/tcp_states.h> | 52 | #include <net/tcp_states.h> |
53 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 53 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
54 | #include <net/mip6.h> | 54 | #include <net/mip6.h> |
55 | #endif | 55 | #endif |
56 | #include <linux/mroute6.h> | 56 | #include <linux/mroute6.h> |
@@ -123,7 +123,7 @@ static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb) | |||
123 | return 1; | 123 | return 1; |
124 | } | 124 | } |
125 | 125 | ||
126 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 126 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
127 | typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb); | 127 | typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb); |
128 | 128 | ||
129 | static mh_filter_t __rcu *mh_filter __read_mostly; | 129 | static mh_filter_t __rcu *mh_filter __read_mostly; |
@@ -184,7 +184,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
184 | filtered = icmpv6_filter(sk, skb); | 184 | filtered = icmpv6_filter(sk, skb); |
185 | break; | 185 | break; |
186 | 186 | ||
187 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 187 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
188 | case IPPROTO_MH: | 188 | case IPPROTO_MH: |
189 | { | 189 | { |
190 | /* XXX: To validate MH only once for each packet, | 190 | /* XXX: To validate MH only once for each packet, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b1e6cf0b95fd..30458726accf 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <net/xfrm.h> | 57 | #include <net/xfrm.h> |
58 | #include <net/netevent.h> | 58 | #include <net/netevent.h> |
59 | #include <net/netlink.h> | 59 | #include <net/netlink.h> |
60 | #include <net/nexthop.h> | ||
60 | 61 | ||
61 | #include <asm/uaccess.h> | 62 | #include <asm/uaccess.h> |
62 | 63 | ||
@@ -289,6 +290,8 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net, | |||
289 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); | 290 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); |
290 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); | 291 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); |
291 | rt->rt6i_genid = rt_genid(net); | 292 | rt->rt6i_genid = rt_genid(net); |
293 | INIT_LIST_HEAD(&rt->rt6i_siblings); | ||
294 | rt->rt6i_nsiblings = 0; | ||
292 | } | 295 | } |
293 | return rt; | 296 | return rt; |
294 | } | 297 | } |
@@ -318,13 +321,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
318 | } | 321 | } |
319 | } | 322 | } |
320 | 323 | ||
321 | static atomic_t __rt6_peer_genid = ATOMIC_INIT(0); | ||
322 | |||
323 | static u32 rt6_peer_genid(void) | ||
324 | { | ||
325 | return atomic_read(&__rt6_peer_genid); | ||
326 | } | ||
327 | |||
328 | void rt6_bind_peer(struct rt6_info *rt, int create) | 324 | void rt6_bind_peer(struct rt6_info *rt, int create) |
329 | { | 325 | { |
330 | struct inet_peer_base *base; | 326 | struct inet_peer_base *base; |
@@ -338,8 +334,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create) | |||
338 | if (peer) { | 334 | if (peer) { |
339 | if (!rt6_set_peer(rt, peer)) | 335 | if (!rt6_set_peer(rt, peer)) |
340 | inet_putpeer(peer); | 336 | inet_putpeer(peer); |
341 | else | ||
342 | rt->rt6i_peer_genid = rt6_peer_genid(); | ||
343 | } | 337 | } |
344 | } | 338 | } |
345 | 339 | ||
@@ -385,6 +379,69 @@ static bool rt6_need_strict(const struct in6_addr *daddr) | |||
385 | (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); | 379 | (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); |
386 | } | 380 | } |
387 | 381 | ||
382 | /* Multipath route selection: | ||
383 | * Hash based function using packet header and flowlabel. | ||
384 | * Adapted from fib_info_hashfn() | ||
385 | */ | ||
386 | static int rt6_info_hash_nhsfn(unsigned int candidate_count, | ||
387 | const struct flowi6 *fl6) | ||
388 | { | ||
389 | unsigned int val = fl6->flowi6_proto; | ||
390 | |||
391 | val ^= (__force u32)fl6->daddr.s6_addr32[0]; | ||
392 | val ^= (__force u32)fl6->daddr.s6_addr32[1]; | ||
393 | val ^= (__force u32)fl6->daddr.s6_addr32[2]; | ||
394 | val ^= (__force u32)fl6->daddr.s6_addr32[3]; | ||
395 | |||
396 | val ^= (__force u32)fl6->saddr.s6_addr32[0]; | ||
397 | val ^= (__force u32)fl6->saddr.s6_addr32[1]; | ||
398 | val ^= (__force u32)fl6->saddr.s6_addr32[2]; | ||
399 | val ^= (__force u32)fl6->saddr.s6_addr32[3]; | ||
400 | |||
401 | /* Work only if this not encapsulated */ | ||
402 | switch (fl6->flowi6_proto) { | ||
403 | case IPPROTO_UDP: | ||
404 | case IPPROTO_TCP: | ||
405 | case IPPROTO_SCTP: | ||
406 | val ^= (__force u16)fl6->fl6_sport; | ||
407 | val ^= (__force u16)fl6->fl6_dport; | ||
408 | break; | ||
409 | |||
410 | case IPPROTO_ICMPV6: | ||
411 | val ^= (__force u16)fl6->fl6_icmp_type; | ||
412 | val ^= (__force u16)fl6->fl6_icmp_code; | ||
413 | break; | ||
414 | } | ||
415 | /* RFC6438 recommands to use flowlabel */ | ||
416 | val ^= (__force u32)fl6->flowlabel; | ||
417 | |||
418 | /* Perhaps, we need to tune, this function? */ | ||
419 | val = val ^ (val >> 7) ^ (val >> 12); | ||
420 | return val % candidate_count; | ||
421 | } | ||
422 | |||
423 | static struct rt6_info *rt6_multipath_select(struct rt6_info *match, | ||
424 | struct flowi6 *fl6) | ||
425 | { | ||
426 | struct rt6_info *sibling, *next_sibling; | ||
427 | int route_choosen; | ||
428 | |||
429 | route_choosen = rt6_info_hash_nhsfn(match->rt6i_nsiblings + 1, fl6); | ||
430 | /* Don't change the route, if route_choosen == 0 | ||
431 | * (siblings does not include ourself) | ||
432 | */ | ||
433 | if (route_choosen) | ||
434 | list_for_each_entry_safe(sibling, next_sibling, | ||
435 | &match->rt6i_siblings, rt6i_siblings) { | ||
436 | route_choosen--; | ||
437 | if (route_choosen == 0) { | ||
438 | match = sibling; | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | return match; | ||
443 | } | ||
444 | |||
388 | /* | 445 | /* |
389 | * Route lookup. Any table->tb6_lock is implied. | 446 | * Route lookup. Any table->tb6_lock is implied. |
390 | */ | 447 | */ |
@@ -666,7 +723,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, | |||
666 | else | 723 | else |
667 | rt6_set_expires(rt, jiffies + HZ * lifetime); | 724 | rt6_set_expires(rt, jiffies + HZ * lifetime); |
668 | 725 | ||
669 | dst_release(&rt->dst); | 726 | ip6_rt_put(rt); |
670 | } | 727 | } |
671 | return 0; | 728 | return 0; |
672 | } | 729 | } |
@@ -702,6 +759,8 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, | |||
702 | restart: | 759 | restart: |
703 | rt = fn->leaf; | 760 | rt = fn->leaf; |
704 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); | 761 | rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); |
762 | if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) | ||
763 | rt = rt6_multipath_select(rt, fl6); | ||
705 | BACKTRACK(net, &fl6->saddr); | 764 | BACKTRACK(net, &fl6->saddr); |
706 | out: | 765 | out: |
707 | dst_use(&rt->dst, jiffies); | 766 | dst_use(&rt->dst, jiffies); |
@@ -863,7 +922,8 @@ restart_2: | |||
863 | 922 | ||
864 | restart: | 923 | restart: |
865 | rt = rt6_select(fn, oif, strict | reachable); | 924 | rt = rt6_select(fn, oif, strict | reachable); |
866 | 925 | if (rt->rt6i_nsiblings && oif == 0) | |
926 | rt = rt6_multipath_select(rt, fl6); | ||
867 | BACKTRACK(net, &fl6->saddr); | 927 | BACKTRACK(net, &fl6->saddr); |
868 | if (rt == net->ipv6.ip6_null_entry || | 928 | if (rt == net->ipv6.ip6_null_entry || |
869 | rt->rt6i_flags & RTF_CACHE) | 929 | rt->rt6i_flags & RTF_CACHE) |
@@ -879,7 +939,7 @@ restart: | |||
879 | else | 939 | else |
880 | goto out2; | 940 | goto out2; |
881 | 941 | ||
882 | dst_release(&rt->dst); | 942 | ip6_rt_put(rt); |
883 | rt = nrt ? : net->ipv6.ip6_null_entry; | 943 | rt = nrt ? : net->ipv6.ip6_null_entry; |
884 | 944 | ||
885 | dst_hold(&rt->dst); | 945 | dst_hold(&rt->dst); |
@@ -896,7 +956,7 @@ restart: | |||
896 | * Race condition! In the gap, when table->tb6_lock was | 956 | * Race condition! In the gap, when table->tb6_lock was |
897 | * released someone could insert this route. Relookup. | 957 | * released someone could insert this route. Relookup. |
898 | */ | 958 | */ |
899 | dst_release(&rt->dst); | 959 | ip6_rt_put(rt); |
900 | goto relookup; | 960 | goto relookup; |
901 | 961 | ||
902 | out: | 962 | out: |
@@ -1030,14 +1090,9 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
1030 | if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) | 1090 | if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev))) |
1031 | return NULL; | 1091 | return NULL; |
1032 | 1092 | ||
1033 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { | 1093 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
1034 | if (rt->rt6i_peer_genid != rt6_peer_genid()) { | ||
1035 | if (!rt6_has_peer(rt)) | ||
1036 | rt6_bind_peer(rt, 0); | ||
1037 | rt->rt6i_peer_genid = rt6_peer_genid(); | ||
1038 | } | ||
1039 | return dst; | 1094 | return dst; |
1040 | } | 1095 | |
1041 | return NULL; | 1096 | return NULL; |
1042 | } | 1097 | } |
1043 | 1098 | ||
@@ -1507,7 +1562,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1507 | goto out; | 1562 | goto out; |
1508 | if (dev) { | 1563 | if (dev) { |
1509 | if (dev != grt->dst.dev) { | 1564 | if (dev != grt->dst.dev) { |
1510 | dst_release(&grt->dst); | 1565 | ip6_rt_put(grt); |
1511 | goto out; | 1566 | goto out; |
1512 | } | 1567 | } |
1513 | } else { | 1568 | } else { |
@@ -1518,7 +1573,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1518 | } | 1573 | } |
1519 | if (!(grt->rt6i_flags & RTF_GATEWAY)) | 1574 | if (!(grt->rt6i_flags & RTF_GATEWAY)) |
1520 | err = 0; | 1575 | err = 0; |
1521 | dst_release(&grt->dst); | 1576 | ip6_rt_put(grt); |
1522 | 1577 | ||
1523 | if (err) | 1578 | if (err) |
1524 | goto out; | 1579 | goto out; |
@@ -1604,7 +1659,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info) | |||
1604 | write_unlock_bh(&table->tb6_lock); | 1659 | write_unlock_bh(&table->tb6_lock); |
1605 | 1660 | ||
1606 | out: | 1661 | out: |
1607 | dst_release(&rt->dst); | 1662 | ip6_rt_put(rt); |
1608 | return err; | 1663 | return err; |
1609 | } | 1664 | } |
1610 | 1665 | ||
@@ -2249,6 +2304,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { | |||
2249 | [RTA_IIF] = { .type = NLA_U32 }, | 2304 | [RTA_IIF] = { .type = NLA_U32 }, |
2250 | [RTA_PRIORITY] = { .type = NLA_U32 }, | 2305 | [RTA_PRIORITY] = { .type = NLA_U32 }, |
2251 | [RTA_METRICS] = { .type = NLA_NESTED }, | 2306 | [RTA_METRICS] = { .type = NLA_NESTED }, |
2307 | [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, | ||
2252 | }; | 2308 | }; |
2253 | 2309 | ||
2254 | static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | 2310 | static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, |
@@ -2326,11 +2382,71 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2326 | if (tb[RTA_TABLE]) | 2382 | if (tb[RTA_TABLE]) |
2327 | cfg->fc_table = nla_get_u32(tb[RTA_TABLE]); | 2383 | cfg->fc_table = nla_get_u32(tb[RTA_TABLE]); |
2328 | 2384 | ||
2385 | if (tb[RTA_MULTIPATH]) { | ||
2386 | cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]); | ||
2387 | cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); | ||
2388 | } | ||
2389 | |||
2329 | err = 0; | 2390 | err = 0; |
2330 | errout: | 2391 | errout: |
2331 | return err; | 2392 | return err; |
2332 | } | 2393 | } |
2333 | 2394 | ||
2395 | static int ip6_route_multipath(struct fib6_config *cfg, int add) | ||
2396 | { | ||
2397 | struct fib6_config r_cfg; | ||
2398 | struct rtnexthop *rtnh; | ||
2399 | int remaining; | ||
2400 | int attrlen; | ||
2401 | int err = 0, last_err = 0; | ||
2402 | |||
2403 | beginning: | ||
2404 | rtnh = (struct rtnexthop *)cfg->fc_mp; | ||
2405 | remaining = cfg->fc_mp_len; | ||
2406 | |||
2407 | /* Parse a Multipath Entry */ | ||
2408 | while (rtnh_ok(rtnh, remaining)) { | ||
2409 | memcpy(&r_cfg, cfg, sizeof(*cfg)); | ||
2410 | if (rtnh->rtnh_ifindex) | ||
2411 | r_cfg.fc_ifindex = rtnh->rtnh_ifindex; | ||
2412 | |||
2413 | attrlen = rtnh_attrlen(rtnh); | ||
2414 | if (attrlen > 0) { | ||
2415 | struct nlattr *nla, *attrs = rtnh_attrs(rtnh); | ||
2416 | |||
2417 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); | ||
2418 | if (nla) { | ||
2419 | nla_memcpy(&r_cfg.fc_gateway, nla, 16); | ||
2420 | r_cfg.fc_flags |= RTF_GATEWAY; | ||
2421 | } | ||
2422 | } | ||
2423 | err = add ? ip6_route_add(&r_cfg) : ip6_route_del(&r_cfg); | ||
2424 | if (err) { | ||
2425 | last_err = err; | ||
2426 | /* If we are trying to remove a route, do not stop the | ||
2427 | * loop when ip6_route_del() fails (because next hop is | ||
2428 | * already gone), we should try to remove all next hops. | ||
2429 | */ | ||
2430 | if (add) { | ||
2431 | /* If add fails, we should try to delete all | ||
2432 | * next hops that have been already added. | ||
2433 | */ | ||
2434 | add = 0; | ||
2435 | goto beginning; | ||
2436 | } | ||
2437 | } | ||
2438 | /* Because each route is added like a single route we remove | ||
2439 | * this flag after the first nexthop (if there is a collision, | ||
2440 | * we have already fail to add the first nexthop: | ||
2441 | * fib6_add_rt2node() has reject it). | ||
2442 | */ | ||
2443 | cfg->fc_nlinfo.nlh->nlmsg_flags &= ~NLM_F_EXCL; | ||
2444 | rtnh = rtnh_next(rtnh, &remaining); | ||
2445 | } | ||
2446 | |||
2447 | return last_err; | ||
2448 | } | ||
2449 | |||
2334 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2450 | static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
2335 | { | 2451 | { |
2336 | struct fib6_config cfg; | 2452 | struct fib6_config cfg; |
@@ -2340,7 +2456,10 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2340 | if (err < 0) | 2456 | if (err < 0) |
2341 | return err; | 2457 | return err; |
2342 | 2458 | ||
2343 | return ip6_route_del(&cfg); | 2459 | if (cfg.fc_mp) |
2460 | return ip6_route_multipath(&cfg, 0); | ||
2461 | else | ||
2462 | return ip6_route_del(&cfg); | ||
2344 | } | 2463 | } |
2345 | 2464 | ||
2346 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 2465 | static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
@@ -2352,7 +2471,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a | |||
2352 | if (err < 0) | 2471 | if (err < 0) |
2353 | return err; | 2472 | return err; |
2354 | 2473 | ||
2355 | return ip6_route_add(&cfg); | 2474 | if (cfg.fc_mp) |
2475 | return ip6_route_multipath(&cfg, 1); | ||
2476 | else | ||
2477 | return ip6_route_add(&cfg); | ||
2356 | } | 2478 | } |
2357 | 2479 | ||
2358 | static inline size_t rt6_nlmsg_size(void) | 2480 | static inline size_t rt6_nlmsg_size(void) |
@@ -2596,7 +2718,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2596 | 2718 | ||
2597 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 2719 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
2598 | if (!skb) { | 2720 | if (!skb) { |
2599 | dst_release(&rt->dst); | 2721 | ip6_rt_put(rt); |
2600 | err = -ENOBUFS; | 2722 | err = -ENOBUFS; |
2601 | goto errout; | 2723 | goto errout; |
2602 | } | 2724 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3ed54ffd8d50..b543c56cad28 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -68,6 +68,7 @@ | |||
68 | static int ipip6_tunnel_init(struct net_device *dev); | 68 | static int ipip6_tunnel_init(struct net_device *dev); |
69 | static void ipip6_tunnel_setup(struct net_device *dev); | 69 | static void ipip6_tunnel_setup(struct net_device *dev); |
70 | static void ipip6_dev_free(struct net_device *dev); | 70 | static void ipip6_dev_free(struct net_device *dev); |
71 | static struct rtnl_link_ops sit_link_ops __read_mostly; | ||
71 | 72 | ||
72 | static int sit_net_id __read_mostly; | 73 | static int sit_net_id __read_mostly; |
73 | struct sit_net { | 74 | struct sit_net { |
@@ -282,6 +283,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, | |||
282 | goto failed_free; | 283 | goto failed_free; |
283 | 284 | ||
284 | strcpy(nt->parms.name, dev->name); | 285 | strcpy(nt->parms.name, dev->name); |
286 | dev->rtnl_link_ops = &sit_link_ops; | ||
285 | 287 | ||
286 | dev_hold(dev); | 288 | dev_hold(dev); |
287 | 289 | ||
@@ -1216,6 +1218,47 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
1216 | return 0; | 1218 | return 0; |
1217 | } | 1219 | } |
1218 | 1220 | ||
1221 | static size_t sit_get_size(const struct net_device *dev) | ||
1222 | { | ||
1223 | return | ||
1224 | /* IFLA_IPTUN_LINK */ | ||
1225 | nla_total_size(4) + | ||
1226 | /* IFLA_IPTUN_LOCAL */ | ||
1227 | nla_total_size(4) + | ||
1228 | /* IFLA_IPTUN_REMOTE */ | ||
1229 | nla_total_size(4) + | ||
1230 | /* IFLA_IPTUN_TTL */ | ||
1231 | nla_total_size(1) + | ||
1232 | /* IFLA_IPTUN_TOS */ | ||
1233 | nla_total_size(1) + | ||
1234 | 0; | ||
1235 | } | ||
1236 | |||
1237 | static int sit_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1238 | { | ||
1239 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
1240 | struct ip_tunnel_parm *parm = &tunnel->parms; | ||
1241 | |||
1242 | if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || | ||
1243 | nla_put_be32(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) || | ||
1244 | nla_put_be32(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || | ||
1245 | nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || | ||
1246 | nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos)) | ||
1247 | goto nla_put_failure; | ||
1248 | return 0; | ||
1249 | |||
1250 | nla_put_failure: | ||
1251 | return -EMSGSIZE; | ||
1252 | } | ||
1253 | |||
1254 | static struct rtnl_link_ops sit_link_ops __read_mostly = { | ||
1255 | .kind = "sit", | ||
1256 | .maxtype = IFLA_IPTUN_MAX, | ||
1257 | .priv_size = sizeof(struct ip_tunnel), | ||
1258 | .get_size = sit_get_size, | ||
1259 | .fill_info = sit_fill_info, | ||
1260 | }; | ||
1261 | |||
1219 | static struct xfrm_tunnel sit_handler __read_mostly = { | 1262 | static struct xfrm_tunnel sit_handler __read_mostly = { |
1220 | .handler = ipip6_rcv, | 1263 | .handler = ipip6_rcv, |
1221 | .err_handler = ipip6_err, | 1264 | .err_handler = ipip6_err, |
@@ -1302,6 +1345,7 @@ static struct pernet_operations sit_net_ops = { | |||
1302 | 1345 | ||
1303 | static void __exit sit_cleanup(void) | 1346 | static void __exit sit_cleanup(void) |
1304 | { | 1347 | { |
1348 | rtnl_link_unregister(&sit_link_ops); | ||
1305 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | 1349 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
1306 | 1350 | ||
1307 | unregister_pernet_device(&sit_net_ops); | 1351 | unregister_pernet_device(&sit_net_ops); |
@@ -1319,10 +1363,21 @@ static int __init sit_init(void) | |||
1319 | return err; | 1363 | return err; |
1320 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); | 1364 | err = xfrm4_tunnel_register(&sit_handler, AF_INET6); |
1321 | if (err < 0) { | 1365 | if (err < 0) { |
1322 | unregister_pernet_device(&sit_net_ops); | ||
1323 | pr_info("%s: can't add protocol\n", __func__); | 1366 | pr_info("%s: can't add protocol\n", __func__); |
1367 | goto xfrm_tunnel_failed; | ||
1324 | } | 1368 | } |
1369 | err = rtnl_link_register(&sit_link_ops); | ||
1370 | if (err < 0) | ||
1371 | goto rtnl_link_failed; | ||
1372 | |||
1373 | out: | ||
1325 | return err; | 1374 | return err; |
1375 | |||
1376 | rtnl_link_failed: | ||
1377 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); | ||
1378 | xfrm_tunnel_failed: | ||
1379 | unregister_pernet_device(&sit_net_ops); | ||
1380 | goto out; | ||
1326 | } | 1381 | } |
1327 | 1382 | ||
1328 | module_init(sit_init); | 1383 | module_init(sit_init); |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 182ab9a85d6c..40161977f7cf 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -214,7 +214,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
214 | ireq6->iif = inet6_iif(skb); | 214 | ireq6->iif = inet6_iif(skb); |
215 | 215 | ||
216 | req->expires = 0UL; | 216 | req->expires = 0UL; |
217 | req->retrans = 0; | 217 | req->num_retrans = 0; |
218 | ireq->ecn_ok = ecn_ok; | 218 | ireq->ecn_ok = ecn_ok; |
219 | ireq->snd_wscale = tcp_opt.snd_wscale; | 219 | ireq->snd_wscale = tcp_opt.snd_wscale; |
220 | ireq->sack_ok = tcp_opt.sack_ok; | 220 | ireq->sack_ok = tcp_opt.sack_ok; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 26175bffbaa0..c73d0ebde9c8 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -495,9 +495,12 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, | |||
495 | struct request_values *rvp) | 495 | struct request_values *rvp) |
496 | { | 496 | { |
497 | struct flowi6 fl6; | 497 | struct flowi6 fl6; |
498 | int res; | ||
498 | 499 | ||
499 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 500 | res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); |
500 | return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); | 501 | if (!res) |
502 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
503 | return res; | ||
501 | } | 504 | } |
502 | 505 | ||
503 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 506 | static void tcp_v6_reqsk_destructor(struct request_sock *req) |
@@ -1364,7 +1367,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1364 | 1367 | ||
1365 | tcp_initialize_rcv_mss(newsk); | 1368 | tcp_initialize_rcv_mss(newsk); |
1366 | tcp_synack_rtt_meas(newsk, req); | 1369 | tcp_synack_rtt_meas(newsk, req); |
1367 | newtp->total_retrans = req->retrans; | 1370 | newtp->total_retrans = req->num_retrans; |
1368 | 1371 | ||
1369 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; | 1372 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; |
1370 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; | 1373 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; |
@@ -1741,11 +1744,11 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1741 | skb->destructor = sock_edemux; | 1744 | skb->destructor = sock_edemux; |
1742 | if (sk->sk_state != TCP_TIME_WAIT) { | 1745 | if (sk->sk_state != TCP_TIME_WAIT) { |
1743 | struct dst_entry *dst = sk->sk_rx_dst; | 1746 | struct dst_entry *dst = sk->sk_rx_dst; |
1744 | struct inet_sock *icsk = inet_sk(sk); | 1747 | |
1745 | if (dst) | 1748 | if (dst) |
1746 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1749 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
1747 | if (dst && | 1750 | if (dst && |
1748 | icsk->rx_dst_ifindex == skb->skb_iif) | 1751 | inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) |
1749 | skb_dst_set_noref(skb, dst); | 1752 | skb_dst_set_noref(skb, dst); |
1750 | } | 1753 | } |
1751 | } | 1754 | } |
@@ -1866,7 +1869,7 @@ static void get_openreq6(struct seq_file *seq, | |||
1866 | 0,0, /* could print option size, but that is af dependent. */ | 1869 | 0,0, /* could print option size, but that is af dependent. */ |
1867 | 1, /* timers active (only the expire timer) */ | 1870 | 1, /* timers active (only the expire timer) */ |
1868 | jiffies_to_clock_t(ttd), | 1871 | jiffies_to_clock_t(ttd), |
1869 | req->retrans, | 1872 | req->num_timeout, |
1870 | from_kuid_munged(seq_user_ns(seq), uid), | 1873 | from_kuid_munged(seq_user_ns(seq), uid), |
1871 | 0, /* non standard timer */ | 1874 | 0, /* non standard timer */ |
1872 | 0, /* open_requests have no inode */ | 1875 | 0, /* open_requests have no inode */ |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index f8c4c08ffb60..f3ed8ca59b94 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
21 | #include <net/ipv6.h> | 21 | #include <net/ipv6.h> |
22 | #include <net/ip6_route.h> | 22 | #include <net/ip6_route.h> |
23 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 23 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
24 | #include <net/mip6.h> | 24 | #include <net/mip6.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
@@ -182,7 +182,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
182 | fl6->flowi6_proto = nexthdr; | 182 | fl6->flowi6_proto = nexthdr; |
183 | return; | 183 | return; |
184 | 184 | ||
185 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 185 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
186 | case IPPROTO_MH: | 186 | case IPPROTO_MH: |
187 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { | 187 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
188 | struct ip6_mh *mh; | 188 | struct ip6_mh *mh; |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 3f2f7c4ab721..d8c70b8efc24 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -101,7 +101,7 @@ static int __xfrm6_state_sort_cmp(void *p) | |||
101 | return 1; | 101 | return 1; |
102 | else | 102 | else |
103 | return 3; | 103 | return 3; |
104 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 104 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
105 | case XFRM_MODE_ROUTEOPTIMIZATION: | 105 | case XFRM_MODE_ROUTEOPTIMIZATION: |
106 | case XFRM_MODE_IN_TRIGGER: | 106 | case XFRM_MODE_IN_TRIGGER: |
107 | return 2; | 107 | return 2; |
@@ -134,7 +134,7 @@ static int __xfrm6_tmpl_sort_cmp(void *p) | |||
134 | switch (v->mode) { | 134 | switch (v->mode) { |
135 | case XFRM_MODE_TRANSPORT: | 135 | case XFRM_MODE_TRANSPORT: |
136 | return 1; | 136 | return 1; |
137 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 137 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
138 | case XFRM_MODE_ROUTEOPTIMIZATION: | 138 | case XFRM_MODE_ROUTEOPTIMIZATION: |
139 | case XFRM_MODE_IN_TRIGGER: | 139 | case XFRM_MODE_IN_TRIGGER: |
140 | return 2; | 140 | return 2; |