aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r--net/ipv6/ndisc.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c45852798092..58841c4ae947 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -59,6 +59,7 @@
59#include <linux/route.h> 59#include <linux/route.h>
60#include <linux/init.h> 60#include <linux/init.h>
61#include <linux/rcupdate.h> 61#include <linux/rcupdate.h>
62#include <linux/slab.h>
62#ifdef CONFIG_SYSCTL 63#ifdef CONFIG_SYSCTL
63#include <linux/sysctl.h> 64#include <linux/sysctl.h>
64#endif 65#endif
@@ -535,7 +536,7 @@ void ndisc_send_skb(struct sk_buff *skb,
535 idev = in6_dev_get(dst->dev); 536 idev = in6_dev_get(dst->dev);
536 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); 537 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
537 538
538 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 539 err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
539 dst_output); 540 dst_output);
540 if (!err) { 541 if (!err) {
541 ICMP6MSGOUT_INC_STATS(net, idev, type); 542 ICMP6MSGOUT_INC_STATS(net, idev, type);
@@ -585,6 +586,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
585 src_addr = solicited_addr; 586 src_addr = solicited_addr;
586 if (ifp->flags & IFA_F_OPTIMISTIC) 587 if (ifp->flags & IFA_F_OPTIMISTIC)
587 override = 0; 588 override = 0;
589 inc_opt |= ifp->idev->cnf.force_tllao;
588 in6_ifa_put(ifp); 590 in6_ifa_put(ifp);
589 } else { 591 } else {
590 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, 592 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
@@ -598,7 +600,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
598 icmp6h.icmp6_solicited = solicited; 600 icmp6h.icmp6_solicited = solicited;
599 icmp6h.icmp6_override = override; 601 icmp6h.icmp6_override = override;
600 602
601 inc_opt |= ifp->idev->cnf.force_tllao;
602 __ndisc_send(dev, neigh, daddr, src_addr, 603 __ndisc_send(dev, neigh, daddr, src_addr,
603 &icmp6h, solicited_addr, 604 &icmp6h, solicited_addr,
604 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); 605 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
@@ -889,8 +890,6 @@ out:
889 in6_ifa_put(ifp); 890 in6_ifa_put(ifp);
890 else 891 else
891 in6_dev_put(idev); 892 in6_dev_put(idev);
892
893 return;
894} 893}
895 894
896static void ndisc_recv_na(struct sk_buff *skb) 895static void ndisc_recv_na(struct sk_buff *skb)
@@ -1230,7 +1229,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1230 ND_PRINTK0(KERN_ERR 1229 ND_PRINTK0(KERN_ERR
1231 "ICMPv6 RA: %s() got default router without neighbour.\n", 1230 "ICMPv6 RA: %s() got default router without neighbour.\n",
1232 __func__); 1231 __func__);
1233 dst_release(&rt->u.dst); 1232 dst_release(&rt->dst);
1234 in6_dev_put(in6_dev); 1233 in6_dev_put(in6_dev);
1235 return; 1234 return;
1236 } 1235 }
@@ -1245,7 +1244,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1245 if (ra_msg->icmph.icmp6_hop_limit) { 1244 if (ra_msg->icmph.icmp6_hop_limit) {
1246 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; 1245 in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1247 if (rt) 1246 if (rt)
1248 rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit; 1247 rt->dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;
1249 } 1248 }
1250 1249
1251skip_defrtr: 1250skip_defrtr:
@@ -1364,7 +1363,7 @@ skip_linkparms:
1364 in6_dev->cnf.mtu6 = mtu; 1363 in6_dev->cnf.mtu6 = mtu;
1365 1364
1366 if (rt) 1365 if (rt)
1367 rt->u.dst.metrics[RTAX_MTU-1] = mtu; 1366 rt->dst.metrics[RTAX_MTU-1] = mtu;
1368 1367
1369 rt6_mtu_change(skb->dev, mtu); 1368 rt6_mtu_change(skb->dev, mtu);
1370 } 1369 }
@@ -1385,7 +1384,7 @@ skip_linkparms:
1385 } 1384 }
1386out: 1385out:
1387 if (rt) 1386 if (rt)
1388 dst_release(&rt->u.dst); 1387 dst_release(&rt->dst);
1389 else if (neigh) 1388 else if (neigh)
1390 neigh_release(neigh); 1389 neigh_release(neigh);
1391 in6_dev_put(in6_dev); 1390 in6_dev_put(in6_dev);
@@ -1617,7 +1616,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1617 skb_dst_set(buff, dst); 1616 skb_dst_set(buff, dst);
1618 idev = in6_dev_get(dst->dev); 1617 idev = in6_dev_get(dst->dev);
1619 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); 1618 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1620 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, 1619 err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
1621 dst_output); 1620 dst_output);
1622 if (!err) { 1621 if (!err) {
1623 ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT); 1622 ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);
@@ -1772,7 +1771,7 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *bu
1772 1771
1773#endif 1772#endif
1774 1773
1775static int ndisc_net_init(struct net *net) 1774static int __net_init ndisc_net_init(struct net *net)
1776{ 1775{
1777 struct ipv6_pinfo *np; 1776 struct ipv6_pinfo *np;
1778 struct sock *sk; 1777 struct sock *sk;
@@ -1797,7 +1796,7 @@ static int ndisc_net_init(struct net *net)
1797 return 0; 1796 return 0;
1798} 1797}
1799 1798
1800static void ndisc_net_exit(struct net *net) 1799static void __net_exit ndisc_net_exit(struct net *net)
1801{ 1800{
1802 inet_ctl_sock_destroy(net->ipv6.ndisc_sk); 1801 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1803} 1802}
@@ -1820,8 +1819,7 @@ int __init ndisc_init(void)
1820 neigh_table_init(&nd_tbl); 1819 neigh_table_init(&nd_tbl);
1821 1820
1822#ifdef CONFIG_SYSCTL 1821#ifdef CONFIG_SYSCTL
1823 err = neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, 1822 err = neigh_sysctl_register(NULL, &nd_tbl.parms, "ipv6",
1824 NET_IPV6_NEIGH, "ipv6",
1825 &ndisc_ifinfo_sysctl_change); 1823 &ndisc_ifinfo_sysctl_change);
1826 if (err) 1824 if (err)
1827 goto out_unregister_pernet; 1825 goto out_unregister_pernet;