aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 16:38:27 -0400
commitaecdc33e111b2c447b622e287c6003726daa1426 (patch)
tree3e7657eae4b785e1a1fb5dfb225dbae0b2f0cfc6 /net/ipv6/addrconf.c
parenta20acf99f75e49271381d65db097c9763060a1e8 (diff)
parenta3a6cab5ea10cca64d036851fe0d932448f2fe4f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) GRE now works over ipv6, from Dmitry Kozlov. 2) Make SCTP more network namespace aware, from Eric Biederman. 3) TEAM driver now works with non-ethernet devices, from Jiri Pirko. 4) Make openvswitch network namespace aware, from Pravin B Shelar. 5) IPV6 NAT implementation, from Patrick McHardy. 6) Server side support for TCP Fast Open, from Jerry Chu and others. 7) Packet BPF filter supports MOD and XOR, from Eric Dumazet and Daniel Borkmann. 8) Increate the loopback default MTU to 64K, from Eric Dumazet. 9) Use a per-task rather than per-socket page fragment allocator for outgoing networking traffic. This benefits processes that have very many mostly idle sockets, which is quite common. From Eric Dumazet. 10) Use up to 32K for page fragment allocations, with fallbacks to smaller sizes when higher order page allocations fail. Benefits are a) less segments for driver to process b) less calls to page allocator c) less waste of space. From Eric Dumazet. 11) Allow GRO to be used on GRE tunnels, from Eric Dumazet. 12) VXLAN device driver, one way to handle VLAN issues such as the limitation of 4096 VLAN IDs yet still have some level of isolation. From Stephen Hemminger. 13) As usual there is a large boatload of driver changes, with the scale perhaps tilted towards the wireless side this time around. Fix up various fairly trivial conflicts, mostly caused by the user namespace changes. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1012 commits) hyperv: Add buffer for extended info after the RNDIS response message. hyperv: Report actual status in receive completion packet hyperv: Remove extra allocated space for recv_pkt_list elements hyperv: Fix page buffer handling in rndis_filter_send_request() hyperv: Fix the missing return value in rndis_filter_set_packet_filter() hyperv: Fix the max_xfer_size in RNDIS initialization vxlan: put UDP socket in correct namespace vxlan: Depend on CONFIG_INET sfc: Fix the reported priorities of different filter types sfc: Remove EFX_FILTER_FLAG_RX_OVERRIDE_IP sfc: Fix loopback self-test with separate_tx_channels=1 sfc: Fix MCDI structure field lookup sfc: Add parentheses around use of bitfield macro arguments sfc: Fix null function pointer in efx_sriov_channel_type vxlan: virtual extensible lan igmp: export symbol ip_mc_leave_group netlink: add attributes to fdb interface tg3: unconditionally select HWMON support when tg3 is enabled. Revert "net: ti cpsw ethernet: allow reading phy interface mode from DT" gre: fix sparse warning ...
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c83
1 files changed, 38 insertions, 45 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6bc85f7c31e3..480e68422efb 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -127,8 +127,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
127#endif 127#endif
128 128
129#ifdef CONFIG_IPV6_PRIVACY 129#ifdef CONFIG_IPV6_PRIVACY
130static int __ipv6_regen_rndid(struct inet6_dev *idev); 130static void __ipv6_regen_rndid(struct inet6_dev *idev);
131static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 131static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
132static void ipv6_regen_rndid(unsigned long data); 132static void ipv6_regen_rndid(unsigned long data);
133#endif 133#endif
134 134
@@ -788,10 +788,16 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
788 struct in6_addr prefix; 788 struct in6_addr prefix;
789 struct rt6_info *rt; 789 struct rt6_info *rt;
790 struct net *net = dev_net(ifp->idev->dev); 790 struct net *net = dev_net(ifp->idev->dev);
791 struct flowi6 fl6 = {};
792
791 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 793 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
792 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 794 fl6.flowi6_oif = ifp->idev->dev->ifindex;
795 fl6.daddr = prefix;
796 rt = (struct rt6_info *)ip6_route_lookup(net, &fl6,
797 RT6_LOOKUP_F_IFACE);
793 798
794 if (rt && addrconf_is_prefix_route(rt)) { 799 if (rt != net->ipv6.ip6_null_entry &&
800 addrconf_is_prefix_route(rt)) {
795 if (onlink == 0) { 801 if (onlink == 0) {
796 ip6_del_rt(rt); 802 ip6_del_rt(rt);
797 rt = NULL; 803 rt = NULL;
@@ -852,16 +858,7 @@ retry:
852 } 858 }
853 in6_ifa_hold(ifp); 859 in6_ifa_hold(ifp);
854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); 860 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
855 if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { 861 __ipv6_try_regen_rndid(idev, tmpaddr);
856 spin_unlock_bh(&ifp->lock);
857 write_unlock(&idev->lock);
858 pr_warn("%s: regeneration of randomized interface id failed\n",
859 __func__);
860 in6_ifa_put(ifp);
861 in6_dev_put(idev);
862 ret = -1;
863 goto out;
864 }
865 memcpy(&addr.s6_addr[8], idev->rndid, 8); 862 memcpy(&addr.s6_addr[8], idev->rndid, 8);
866 age = (now - ifp->tstamp) / HZ; 863 age = (now - ifp->tstamp) / HZ;
867 tmp_valid_lft = min_t(__u32, 864 tmp_valid_lft = min_t(__u32,
@@ -1079,8 +1076,10 @@ static int ipv6_get_saddr_eval(struct net *net,
1079 break; 1076 break;
1080 case IPV6_SADDR_RULE_PREFIX: 1077 case IPV6_SADDR_RULE_PREFIX:
1081 /* Rule 8: Use longest matching prefix */ 1078 /* Rule 8: Use longest matching prefix */
1082 score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, 1079 ret = ipv6_addr_diff(&score->ifa->addr, dst->addr);
1083 dst->addr); 1080 if (ret > score->ifa->prefix_len)
1081 ret = score->ifa->prefix_len;
1082 score->matchlen = ret;
1084 break; 1083 break;
1085 default: 1084 default:
1086 ret = 0; 1085 ret = 0;
@@ -1093,7 +1092,7 @@ out:
1093 return ret; 1092 return ret;
1094} 1093}
1095 1094
1096int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, 1095int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
1097 const struct in6_addr *daddr, unsigned int prefs, 1096 const struct in6_addr *daddr, unsigned int prefs,
1098 struct in6_addr *saddr) 1097 struct in6_addr *saddr)
1099{ 1098{
@@ -1600,7 +1599,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1600 1599
1601#ifdef CONFIG_IPV6_PRIVACY 1600#ifdef CONFIG_IPV6_PRIVACY
1602/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */ 1601/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
1603static int __ipv6_regen_rndid(struct inet6_dev *idev) 1602static void __ipv6_regen_rndid(struct inet6_dev *idev)
1604{ 1603{
1605regen: 1604regen:
1606 get_random_bytes(idev->rndid, sizeof(idev->rndid)); 1605 get_random_bytes(idev->rndid, sizeof(idev->rndid));
@@ -1627,8 +1626,6 @@ regen:
1627 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00) 1626 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
1628 goto regen; 1627 goto regen;
1629 } 1628 }
1630
1631 return 0;
1632} 1629}
1633 1630
1634static void ipv6_regen_rndid(unsigned long data) 1631static void ipv6_regen_rndid(unsigned long data)
@@ -1642,8 +1639,7 @@ static void ipv6_regen_rndid(unsigned long data)
1642 if (idev->dead) 1639 if (idev->dead)
1643 goto out; 1640 goto out;
1644 1641
1645 if (__ipv6_regen_rndid(idev) < 0) 1642 __ipv6_regen_rndid(idev);
1646 goto out;
1647 1643
1648 expires = jiffies + 1644 expires = jiffies +
1649 idev->cnf.temp_prefered_lft * HZ - 1645 idev->cnf.temp_prefered_lft * HZ -
@@ -1664,13 +1660,10 @@ out:
1664 in6_dev_put(idev); 1660 in6_dev_put(idev);
1665} 1661}
1666 1662
1667static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) 1663static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
1668{ 1664{
1669 int ret = 0;
1670
1671 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0) 1665 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
1672 ret = __ipv6_regen_rndid(idev); 1666 __ipv6_regen_rndid(idev);
1673 return ret;
1674} 1667}
1675#endif 1668#endif
1676 1669
@@ -1721,7 +1714,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1721 if (table == NULL) 1714 if (table == NULL)
1722 return NULL; 1715 return NULL;
1723 1716
1724 write_lock_bh(&table->tb6_lock); 1717 read_lock_bh(&table->tb6_lock);
1725 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0); 1718 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
1726 if (!fn) 1719 if (!fn)
1727 goto out; 1720 goto out;
@@ -1736,7 +1729,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1736 break; 1729 break;
1737 } 1730 }
1738out: 1731out:
1739 write_unlock_bh(&table->tb6_lock); 1732 read_unlock_bh(&table->tb6_lock);
1740 return rt; 1733 return rt;
1741} 1734}
1742 1735
@@ -3549,12 +3542,12 @@ static inline int inet6_ifaddr_msgsize(void)
3549} 3542}
3550 3543
3551static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3544static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3552 u32 pid, u32 seq, int event, unsigned int flags) 3545 u32 portid, u32 seq, int event, unsigned int flags)
3553{ 3546{
3554 struct nlmsghdr *nlh; 3547 struct nlmsghdr *nlh;
3555 u32 preferred, valid; 3548 u32 preferred, valid;
3556 3549
3557 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3550 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3558 if (nlh == NULL) 3551 if (nlh == NULL)
3559 return -EMSGSIZE; 3552 return -EMSGSIZE;
3560 3553
@@ -3592,7 +3585,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3592} 3585}
3593 3586
3594static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3587static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3595 u32 pid, u32 seq, int event, u16 flags) 3588 u32 portid, u32 seq, int event, u16 flags)
3596{ 3589{
3597 struct nlmsghdr *nlh; 3590 struct nlmsghdr *nlh;
3598 u8 scope = RT_SCOPE_UNIVERSE; 3591 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3601,7 +3594,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3601 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE) 3594 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
3602 scope = RT_SCOPE_SITE; 3595 scope = RT_SCOPE_SITE;
3603 3596
3604 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3597 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3605 if (nlh == NULL) 3598 if (nlh == NULL)
3606 return -EMSGSIZE; 3599 return -EMSGSIZE;
3607 3600
@@ -3617,7 +3610,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3617} 3610}
3618 3611
3619static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3612static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3620 u32 pid, u32 seq, int event, unsigned int flags) 3613 u32 portid, u32 seq, int event, unsigned int flags)
3621{ 3614{
3622 struct nlmsghdr *nlh; 3615 struct nlmsghdr *nlh;
3623 u8 scope = RT_SCOPE_UNIVERSE; 3616 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3626,7 +3619,7 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3626 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE) 3619 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
3627 scope = RT_SCOPE_SITE; 3620 scope = RT_SCOPE_SITE;
3628 3621
3629 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3622 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3630 if (nlh == NULL) 3623 if (nlh == NULL)
3631 return -EMSGSIZE; 3624 return -EMSGSIZE;
3632 3625
@@ -3667,7 +3660,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3667 if (++ip_idx < s_ip_idx) 3660 if (++ip_idx < s_ip_idx)
3668 continue; 3661 continue;
3669 err = inet6_fill_ifaddr(skb, ifa, 3662 err = inet6_fill_ifaddr(skb, ifa,
3670 NETLINK_CB(cb->skb).pid, 3663 NETLINK_CB(cb->skb).portid,
3671 cb->nlh->nlmsg_seq, 3664 cb->nlh->nlmsg_seq,
3672 RTM_NEWADDR, 3665 RTM_NEWADDR,
3673 NLM_F_MULTI); 3666 NLM_F_MULTI);
@@ -3683,7 +3676,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3683 if (ip_idx < s_ip_idx) 3676 if (ip_idx < s_ip_idx)
3684 continue; 3677 continue;
3685 err = inet6_fill_ifmcaddr(skb, ifmca, 3678 err = inet6_fill_ifmcaddr(skb, ifmca,
3686 NETLINK_CB(cb->skb).pid, 3679 NETLINK_CB(cb->skb).portid,
3687 cb->nlh->nlmsg_seq, 3680 cb->nlh->nlmsg_seq,
3688 RTM_GETMULTICAST, 3681 RTM_GETMULTICAST,
3689 NLM_F_MULTI); 3682 NLM_F_MULTI);
@@ -3698,7 +3691,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3698 if (ip_idx < s_ip_idx) 3691 if (ip_idx < s_ip_idx)
3699 continue; 3692 continue;
3700 err = inet6_fill_ifacaddr(skb, ifaca, 3693 err = inet6_fill_ifacaddr(skb, ifaca,
3701 NETLINK_CB(cb->skb).pid, 3694 NETLINK_CB(cb->skb).portid,
3702 cb->nlh->nlmsg_seq, 3695 cb->nlh->nlmsg_seq,
3703 RTM_GETANYCAST, 3696 RTM_GETANYCAST,
3704 NLM_F_MULTI); 3697 NLM_F_MULTI);
@@ -3820,7 +3813,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3820 goto errout_ifa; 3813 goto errout_ifa;
3821 } 3814 }
3822 3815
3823 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3816 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
3824 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3817 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3825 if (err < 0) { 3818 if (err < 0) {
3826 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ 3819 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
@@ -3828,7 +3821,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3828 kfree_skb(skb); 3821 kfree_skb(skb);
3829 goto errout_ifa; 3822 goto errout_ifa;
3830 } 3823 }
3831 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 3824 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
3832errout_ifa: 3825errout_ifa:
3833 in6_ifa_put(ifa); 3826 in6_ifa_put(ifa);
3834errout: 3827errout:
@@ -4030,14 +4023,14 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4030} 4023}
4031 4024
4032static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 4025static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
4033 u32 pid, u32 seq, int event, unsigned int flags) 4026 u32 portid, u32 seq, int event, unsigned int flags)
4034{ 4027{
4035 struct net_device *dev = idev->dev; 4028 struct net_device *dev = idev->dev;
4036 struct ifinfomsg *hdr; 4029 struct ifinfomsg *hdr;
4037 struct nlmsghdr *nlh; 4030 struct nlmsghdr *nlh;
4038 void *protoinfo; 4031 void *protoinfo;
4039 4032
4040 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 4033 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*hdr), flags);
4041 if (nlh == NULL) 4034 if (nlh == NULL)
4042 return -EMSGSIZE; 4035 return -EMSGSIZE;
4043 4036
@@ -4095,7 +4088,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
4095 if (!idev) 4088 if (!idev)
4096 goto cont; 4089 goto cont;
4097 if (inet6_fill_ifinfo(skb, idev, 4090 if (inet6_fill_ifinfo(skb, idev,
4098 NETLINK_CB(cb->skb).pid, 4091 NETLINK_CB(cb->skb).portid,
4099 cb->nlh->nlmsg_seq, 4092 cb->nlh->nlmsg_seq,
4100 RTM_NEWLINK, NLM_F_MULTI) <= 0) 4093 RTM_NEWLINK, NLM_F_MULTI) <= 0)
4101 goto out; 4094 goto out;
@@ -4143,14 +4136,14 @@ static inline size_t inet6_prefix_nlmsg_size(void)
4143} 4136}
4144 4137
4145static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 4138static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
4146 struct prefix_info *pinfo, u32 pid, u32 seq, 4139 struct prefix_info *pinfo, u32 portid, u32 seq,
4147 int event, unsigned int flags) 4140 int event, unsigned int flags)
4148{ 4141{
4149 struct prefixmsg *pmsg; 4142 struct prefixmsg *pmsg;
4150 struct nlmsghdr *nlh; 4143 struct nlmsghdr *nlh;
4151 struct prefix_cacheinfo ci; 4144 struct prefix_cacheinfo ci;
4152 4145
4153 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); 4146 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*pmsg), flags);
4154 if (nlh == NULL) 4147 if (nlh == NULL)
4155 return -EMSGSIZE; 4148 return -EMSGSIZE;
4156 4149