Replace malloc for DAD with kmem and move them out of the lock for DADdiff -r1.242 -r1.243 src/sys/netinet/if_arp.c
(ozaki-r)
--- src/sys/netinet/if_arp.c 2017/02/11 15:37:30 1.242
+++ src/sys/netinet/if_arp.c 2017/02/21 03:58:23 1.243
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_arp.c,v 1.242 2017/02/11 15:37:30 roy Exp $ */ | 1 | /* $NetBSD: if_arp.c,v 1.243 2017/02/21 03:58:23 ozaki-r Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Public Access Networks Corporation ("Panix"). It was developed under | 8 | * by Public Access Networks Corporation ("Panix"). It was developed under | |
9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. | 9 | * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -58,43 +58,43 @@ | @@ -58,43 +58,43 @@ | |||
58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
59 | * SUCH DAMAGE. | 59 | * SUCH DAMAGE. | |
60 | * | 60 | * | |
61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 | 61 | * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 | |
62 | */ | 62 | */ | |
63 | 63 | |||
64 | /* | 64 | /* | |
65 | * Ethernet address resolution protocol. | 65 | * Ethernet address resolution protocol. | |
66 | * TODO: | 66 | * TODO: | |
67 | * add "inuse/lock" bit (or ref. count) along with valid bit | 67 | * add "inuse/lock" bit (or ref. count) along with valid bit | |
68 | */ | 68 | */ | |
69 | 69 | |||
70 | #include <sys/cdefs.h> | 70 | #include <sys/cdefs.h> | |
71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.242 2017/02/11 15:37:30 roy Exp $"); | 71 | __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.243 2017/02/21 03:58:23 ozaki-r Exp $"); | |
72 | 72 | |||
73 | #ifdef _KERNEL_OPT | 73 | #ifdef _KERNEL_OPT | |
74 | #include "opt_ddb.h" | 74 | #include "opt_ddb.h" | |
75 | #include "opt_inet.h" | 75 | #include "opt_inet.h" | |
76 | #include "opt_net_mpsafe.h" | 76 | #include "opt_net_mpsafe.h" | |
77 | #endif | 77 | #endif | |
78 | 78 | |||
79 | #ifdef INET | 79 | #ifdef INET | |
80 | 80 | |||
81 | #include "arp.h" | 81 | #include "arp.h" | |
82 | #include "bridge.h" | 82 | #include "bridge.h" | |
83 | 83 | |||
84 | #include <sys/param.h> | 84 | #include <sys/param.h> | |
85 | #include <sys/systm.h> | 85 | #include <sys/systm.h> | |
86 | #include <sys/callout.h> | 86 | #include <sys/callout.h> | |
87 | #include <sys/malloc.h> | 87 | #include <sys/kmem.h> | |
88 | #include <sys/mbuf.h> | 88 | #include <sys/mbuf.h> | |
89 | #include <sys/socket.h> | 89 | #include <sys/socket.h> | |
90 | #include <sys/time.h> | 90 | #include <sys/time.h> | |
91 | #include <sys/timetc.h> | 91 | #include <sys/timetc.h> | |
92 | #include <sys/kernel.h> | 92 | #include <sys/kernel.h> | |
93 | #include <sys/errno.h> | 93 | #include <sys/errno.h> | |
94 | #include <sys/ioctl.h> | 94 | #include <sys/ioctl.h> | |
95 | #include <sys/syslog.h> | 95 | #include <sys/syslog.h> | |
96 | #include <sys/proc.h> | 96 | #include <sys/proc.h> | |
97 | #include <sys/protosw.h> | 97 | #include <sys/protosw.h> | |
98 | #include <sys/domain.h> | 98 | #include <sys/domain.h> | |
99 | #include <sys/sysctl.h> | 99 | #include <sys/sysctl.h> | |
100 | #include <sys/socketvar.h> | 100 | #include <sys/socketvar.h> | |
@@ -1505,27 +1505,26 @@ arp_ifinit(struct ifnet *ifp, struct ifa | @@ -1505,27 +1505,26 @@ arp_ifinit(struct ifnet *ifp, struct ifa | |||
1505 | } | 1505 | } | |
1506 | 1506 | |||
1507 | TAILQ_HEAD(dadq_head, dadq); | 1507 | TAILQ_HEAD(dadq_head, dadq); | |
1508 | struct dadq { | 1508 | struct dadq { | |
1509 | TAILQ_ENTRY(dadq) dad_list; | 1509 | TAILQ_ENTRY(dadq) dad_list; | |
1510 | struct ifaddr *dad_ifa; | 1510 | struct ifaddr *dad_ifa; | |
1511 | int dad_count; /* max ARP to send */ | 1511 | int dad_count; /* max ARP to send */ | |
1512 | int dad_arp_tcount; /* # of trials to send ARP */ | 1512 | int dad_arp_tcount; /* # of trials to send ARP */ | |
1513 | int dad_arp_ocount; /* ARP sent so far */ | 1513 | int dad_arp_ocount; /* ARP sent so far */ | |
1514 | int dad_arp_announce; /* max ARP announcements */ | 1514 | int dad_arp_announce; /* max ARP announcements */ | |
1515 | int dad_arp_acount; /* # of announcements */ | 1515 | int dad_arp_acount; /* # of announcements */ | |
1516 | struct callout dad_timer_ch; | 1516 | struct callout dad_timer_ch; | |
1517 | }; | 1517 | }; | |
1518 | MALLOC_JUSTDEFINE(M_IPARP, "ARP DAD", "ARP DAD Structure"); | |||
1519 | 1518 | |||
1520 | static struct dadq_head dadq; | 1519 | static struct dadq_head dadq; | |
1521 | static int dad_init = 0; | 1520 | static int dad_init = 0; | |
1522 | static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ | 1521 | static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ | |
1523 | static kmutex_t arp_dad_lock; | 1522 | static kmutex_t arp_dad_lock; | |
1524 | 1523 | |||
1525 | static struct dadq * | 1524 | static struct dadq * | |
1526 | arp_dad_find(struct ifaddr *ifa) | 1525 | arp_dad_find(struct ifaddr *ifa) | |
1527 | { | 1526 | { | |
1528 | struct dadq *dp; | 1527 | struct dadq *dp; | |
1529 | 1528 | |||
1530 | KASSERT(mutex_owned(&arp_dad_lock)); | 1529 | KASSERT(mutex_owned(&arp_dad_lock)); | |
1531 | 1530 | |||
@@ -1603,48 +1602,50 @@ arp_dad_start(struct ifaddr *ifa) | @@ -1603,48 +1602,50 @@ arp_dad_start(struct ifaddr *ifa) | |||
1603 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1602 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1604 | return; | 1603 | return; | |
1605 | } | 1604 | } | |
1606 | if (!ip_dad_count) { | 1605 | if (!ip_dad_count) { | |
1607 | ia->ia4_flags &= ~IN_IFF_TENTATIVE; | 1606 | ia->ia4_flags &= ~IN_IFF_TENTATIVE; | |
1608 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | 1607 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | |
1609 | arpannounce1(ifa); | 1608 | arpannounce1(ifa); | |
1610 | return; | 1609 | return; | |
1611 | } | 1610 | } | |
1612 | KASSERT(ifa->ifa_ifp != NULL); | 1611 | KASSERT(ifa->ifa_ifp != NULL); | |
1613 | if (!(ifa->ifa_ifp->if_flags & IFF_UP)) | 1612 | if (!(ifa->ifa_ifp->if_flags & IFF_UP)) | |
1614 | return; | 1613 | return; | |
1615 | 1614 | |||
1615 | dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP); | |||
1616 | ||||
1616 | mutex_enter(&arp_dad_lock); | 1617 | mutex_enter(&arp_dad_lock); | |
1617 | if (arp_dad_find(ifa) != NULL) { | 1618 | if (arp_dad_find(ifa) != NULL) { | |
1618 | mutex_exit(&arp_dad_lock); | 1619 | mutex_exit(&arp_dad_lock); | |
1619 | /* DAD already in progress */ | 1620 | /* DAD already in progress */ | |
1621 | if (dp != NULL) | |||
1622 | kmem_intr_free(dp, sizeof(*dp)); | |||
1620 | return; | 1623 | return; | |
1621 | } | 1624 | } | |
1622 | 1625 | |||
1623 | dp = malloc(sizeof(*dp), M_IPARP, M_NOWAIT); | |||
1624 | if (dp == NULL) { | 1626 | if (dp == NULL) { | |
1625 | mutex_exit(&arp_dad_lock); | 1627 | mutex_exit(&arp_dad_lock); | |
1626 | log(LOG_ERR, "%s: memory allocation failed for %s(%s)\n", | 1628 | log(LOG_ERR, "%s: memory allocation failed for %s(%s)\n", | |
1627 | __func__, in_fmtaddr(ipbuf, ia->ia_addr.sin_addr), | 1629 | __func__, in_fmtaddr(ipbuf, ia->ia_addr.sin_addr), | |
1628 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1630 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1629 | return; | 1631 | return; | |
1630 | } | 1632 | } | |
1631 | memset(dp, 0, sizeof(*dp)); | |||
1632 | callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); | |||
1633 | 1633 | |||
1634 | /* | 1634 | /* | |
1635 | * Send ARP packet for DAD, ip_dad_count times. | 1635 | * Send ARP packet for DAD, ip_dad_count times. | |
1636 | * Note that we must delay the first transmission. | 1636 | * Note that we must delay the first transmission. | |
1637 | */ | 1637 | */ | |
1638 | callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); | |||
1638 | dp->dad_ifa = ifa; | 1639 | dp->dad_ifa = ifa; | |
1639 | ifaref(ifa); /* just for safety */ | 1640 | ifaref(ifa); /* just for safety */ | |
1640 | dp->dad_count = ip_dad_count; | 1641 | dp->dad_count = ip_dad_count; | |
1641 | dp->dad_arp_announce = 0; /* Will be set when starting to announce */ | 1642 | dp->dad_arp_announce = 0; /* Will be set when starting to announce */ | |
1642 | dp->dad_arp_acount = dp->dad_arp_ocount = dp->dad_arp_tcount = 0; | 1643 | dp->dad_arp_acount = dp->dad_arp_ocount = dp->dad_arp_tcount = 0; | |
1643 | TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); | 1644 | TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); | |
1644 | 1645 | |||
1645 | ARPLOG(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), | 1646 | ARPLOG(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), | |
1646 | ARPLOGADDR(ia->ia_addr.sin_addr)); | 1647 | ARPLOGADDR(ia->ia_addr.sin_addr)); | |
1647 | 1648 | |||
1648 | arp_dad_starttimer(dp, cprng_fast32() % (PROBE_WAIT * hz)); | 1649 | arp_dad_starttimer(dp, cprng_fast32() % (PROBE_WAIT * hz)); | |
1649 | 1650 | |||
1650 | mutex_exit(&arp_dad_lock); | 1651 | mutex_exit(&arp_dad_lock); | |
@@ -1665,37 +1666,37 @@ arp_dad_stop(struct ifaddr *ifa) | @@ -1665,37 +1666,37 @@ arp_dad_stop(struct ifaddr *ifa) | |||
1665 | dp = arp_dad_find(ifa); | 1666 | dp = arp_dad_find(ifa); | |
1666 | if (dp == NULL) { | 1667 | if (dp == NULL) { | |
1667 | mutex_exit(&arp_dad_lock); | 1668 | mutex_exit(&arp_dad_lock); | |
1668 | /* DAD wasn't started yet */ | 1669 | /* DAD wasn't started yet */ | |
1669 | return; | 1670 | return; | |
1670 | } | 1671 | } | |
1671 | 1672 | |||
1672 | /* Prevent the timer from running anymore. */ | 1673 | /* Prevent the timer from running anymore. */ | |
1673 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1674 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1674 | mutex_exit(&arp_dad_lock); | 1675 | mutex_exit(&arp_dad_lock); | |
1675 | 1676 | |||
1676 | arp_dad_stoptimer(dp); | 1677 | arp_dad_stoptimer(dp); | |
1677 | 1678 | |||
1678 | free(dp, M_IPARP); | 1679 | kmem_intr_free(dp, sizeof(*dp)); | |
1679 | dp = NULL; | |||
1680 | ifafree(ifa); | 1680 | ifafree(ifa); | |
1681 | } | 1681 | } | |
1682 | 1682 | |||
1683 | static void | 1683 | static void | |
1684 | arp_dad_timer(struct ifaddr *ifa) | 1684 | arp_dad_timer(struct ifaddr *ifa) | |
1685 | { | 1685 | { | |
1686 | struct in_ifaddr *ia = (struct in_ifaddr *)ifa; | 1686 | struct in_ifaddr *ia = (struct in_ifaddr *)ifa; | |
1687 | struct dadq *dp; | 1687 | struct dadq *dp; | |
1688 | char ipbuf[INET_ADDRSTRLEN]; | 1688 | char ipbuf[INET_ADDRSTRLEN]; | |
1689 | bool need_free = false; | |||
1689 | 1690 | |||
1690 | #ifndef NET_MPSAFE | 1691 | #ifndef NET_MPSAFE | |
1691 | mutex_enter(softnet_lock); | 1692 | mutex_enter(softnet_lock); | |
1692 | KERNEL_LOCK(1, NULL); | 1693 | KERNEL_LOCK(1, NULL); | |
1693 | #endif | 1694 | #endif | |
1694 | mutex_enter(&arp_dad_lock); | 1695 | mutex_enter(&arp_dad_lock); | |
1695 | 1696 | |||
1696 | /* Sanity check */ | 1697 | /* Sanity check */ | |
1697 | if (ia == NULL) { | 1698 | if (ia == NULL) { | |
1698 | log(LOG_ERR, "%s: called with null parameter\n", __func__); | 1699 | log(LOG_ERR, "%s: called with null parameter\n", __func__); | |
1699 | goto done; | 1700 | goto done; | |
1700 | } | 1701 | } | |
1701 | dp = arp_dad_find(ifa); | 1702 | dp = arp_dad_find(ifa); | |
@@ -1713,29 +1714,27 @@ arp_dad_timer(struct ifaddr *ifa) | @@ -1713,29 +1714,27 @@ arp_dad_timer(struct ifaddr *ifa) | |||
1713 | { | 1714 | { | |
1714 | log(LOG_ERR, "%s: called with non-tentative address %s(%s)\n", | 1715 | log(LOG_ERR, "%s: called with non-tentative address %s(%s)\n", | |
1715 | __func__, in_fmtaddr(ipbuf, ia->ia_addr.sin_addr), | 1716 | __func__, in_fmtaddr(ipbuf, ia->ia_addr.sin_addr), | |
1716 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1717 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1717 | goto done; | 1718 | goto done; | |
1718 | } | 1719 | } | |
1719 | 1720 | |||
1720 | /* timeouted with IFF_{RUNNING,UP} check */ | 1721 | /* timeouted with IFF_{RUNNING,UP} check */ | |
1721 | if (dp->dad_arp_tcount > dad_maxtry) { | 1722 | if (dp->dad_arp_tcount > dad_maxtry) { | |
1722 | ARPLOG(LOG_INFO, "%s: could not run DAD, driver problem?\n", | 1723 | ARPLOG(LOG_INFO, "%s: could not run DAD, driver problem?\n", | |
1723 | if_name(ifa->ifa_ifp)); | 1724 | if_name(ifa->ifa_ifp)); | |
1724 | 1725 | |||
1725 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1726 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1726 | free(dp, M_IPARP); | 1727 | need_free = true; | |
1727 | dp = NULL; | |||
1728 | ifafree(ifa); | |||
1729 | goto done; | 1728 | goto done; | |
1730 | } | 1729 | } | |
1731 | 1730 | |||
1732 | /* Need more checks? */ | 1731 | /* Need more checks? */ | |
1733 | if (dp->dad_arp_ocount < dp->dad_count) { | 1732 | if (dp->dad_arp_ocount < dp->dad_count) { | |
1734 | int adelay; | 1733 | int adelay; | |
1735 | 1734 | |||
1736 | /* | 1735 | /* | |
1737 | * We have more ARP to go. Send ARP packet for DAD. | 1736 | * We have more ARP to go. Send ARP packet for DAD. | |
1738 | */ | 1737 | */ | |
1739 | arp_dad_output(dp, ifa); | 1738 | arp_dad_output(dp, ifa); | |
1740 | if (dp->dad_arp_ocount < dp->dad_count) | 1739 | if (dp->dad_arp_ocount < dp->dad_count) | |
1741 | adelay = (PROBE_MIN * hz) + | 1740 | adelay = (PROBE_MIN * hz) + | |
@@ -1764,32 +1763,35 @@ announce: | @@ -1764,32 +1763,35 @@ announce: | |||
1764 | */ | 1763 | */ | |
1765 | arpannounce1(ifa); | 1764 | arpannounce1(ifa); | |
1766 | dp->dad_arp_acount++; | 1765 | dp->dad_arp_acount++; | |
1767 | if (dp->dad_arp_acount < dp->dad_arp_announce) { | 1766 | if (dp->dad_arp_acount < dp->dad_arp_announce) { | |
1768 | arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz); | 1767 | arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz); | |
1769 | goto done; | 1768 | goto done; | |
1770 | } | 1769 | } | |
1771 | ARPLOG(LOG_DEBUG, | 1770 | ARPLOG(LOG_DEBUG, | |
1772 | "%s: ARP announcement complete for %s\n", | 1771 | "%s: ARP announcement complete for %s\n", | |
1773 | if_name(ifa->ifa_ifp), ARPLOGADDR(ia->ia_addr.sin_addr)); | 1772 | if_name(ifa->ifa_ifp), ARPLOGADDR(ia->ia_addr.sin_addr)); | |
1774 | } | 1773 | } | |
1775 | 1774 | |||
1776 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1775 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1777 | free(dp, M_IPARP); | 1776 | need_free = true; | |
1778 | dp = NULL; | |||
1779 | ifafree(ifa); | |||
1780 | ||||
1781 | done: | 1777 | done: | |
1782 | mutex_exit(&arp_dad_lock); | 1778 | mutex_exit(&arp_dad_lock); | |
1779 | ||||
1780 | if (need_free) { | |||
1781 | kmem_intr_free(dp, sizeof(*dp)); | |||
1782 | ifafree(ifa); | |||
1783 | } | |||
1784 | ||||
1783 | #ifndef NET_MPSAFE | 1785 | #ifndef NET_MPSAFE | |
1784 | KERNEL_UNLOCK_ONE(NULL); | 1786 | KERNEL_UNLOCK_ONE(NULL); | |
1785 | mutex_exit(softnet_lock); | 1787 | mutex_exit(softnet_lock); | |
1786 | #endif | 1788 | #endif | |
1787 | } | 1789 | } | |
1788 | 1790 | |||
1789 | static void | 1791 | static void | |
1790 | arp_dad_duplicated(struct ifaddr *ifa, const char *sha) | 1792 | arp_dad_duplicated(struct ifaddr *ifa, const char *sha) | |
1791 | { | 1793 | { | |
1792 | struct in_ifaddr *ia = (struct in_ifaddr *)ifa; | 1794 | struct in_ifaddr *ia = (struct in_ifaddr *)ifa; | |
1793 | struct ifnet *ifp = ifa->ifa_ifp; | 1795 | struct ifnet *ifp = ifa->ifa_ifp; | |
1794 | char ipbuf[INET_ADDRSTRLEN]; | 1796 | char ipbuf[INET_ADDRSTRLEN]; | |
1795 | const char *iastr; | 1797 | const char *iastr; |
--- src/sys/netinet/if_inarp.h 2016/10/11 12:32:30 1.50
+++ src/sys/netinet/if_inarp.h 2017/02/21 03:58:24 1.51
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_inarp.h,v 1.50 2016/10/11 12:32:30 roy Exp $ */ | 1 | /* $NetBSD: if_inarp.h,v 1.51 2017/02/21 03:58:24 ozaki-r Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1982, 1986, 1993 | 4 | * Copyright (c) 1982, 1986, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -59,29 +59,26 @@ struct sockaddr_inarp { | @@ -59,29 +59,26 @@ struct sockaddr_inarp { | |||
59 | 59 | |||
60 | /* ARP timings from RFC5227 */ | 60 | /* ARP timings from RFC5227 */ | |
61 | #define PROBE_WAIT 1 | 61 | #define PROBE_WAIT 1 | |
62 | #define PROBE_NUM 3 | 62 | #define PROBE_NUM 3 | |
63 | #define PROBE_MIN 1 | 63 | #define PROBE_MIN 1 | |
64 | #define PROBE_MAX 2 | 64 | #define PROBE_MAX 2 | |
65 | #define ANNOUNCE_WAIT 2 | 65 | #define ANNOUNCE_WAIT 2 | |
66 | #define ANNOUNCE_NUM 2 | 66 | #define ANNOUNCE_NUM 2 | |
67 | #define ANNOUNCE_INTERVAL 2 | 67 | #define ANNOUNCE_INTERVAL 2 | |
68 | #define MAX_CONFLICTS 10 | 68 | #define MAX_CONFLICTS 10 | |
69 | #define RATE_LIMIT_INTERVAL 60 | 69 | #define RATE_LIMIT_INTERVAL 60 | |
70 | #define DEFEND_INTERVAL 10 | 70 | #define DEFEND_INTERVAL 10 | |
71 | 71 | |||
72 | #include <sys/malloc.h> | |||
73 | MALLOC_DECLARE(M_IPARP); | |||
74 | ||||
75 | extern struct ifqueue arpintrq; | 72 | extern struct ifqueue arpintrq; | |
76 | void arp_ifinit(struct ifnet *, struct ifaddr *); | 73 | void arp_ifinit(struct ifnet *, struct ifaddr *); | |
77 | void arp_rtrequest(int, struct rtentry *, const struct rt_addrinfo *); | 74 | void arp_rtrequest(int, struct rtentry *, const struct rt_addrinfo *); | |
78 | int arpresolve(struct ifnet *, const struct rtentry *, struct mbuf *, | 75 | int arpresolve(struct ifnet *, const struct rtentry *, struct mbuf *, | |
79 | const struct sockaddr *, void *, size_t); | 76 | const struct sockaddr *, void *, size_t); | |
80 | void arpintr(void); | 77 | void arpintr(void); | |
81 | void arpannounce(struct ifnet *, struct ifaddr *, const uint8_t *); | 78 | void arpannounce(struct ifnet *, struct ifaddr *, const uint8_t *); | |
82 | void arp_drain(void); | 79 | void arp_drain(void); | |
83 | int arpioctl(u_long, void *); | 80 | int arpioctl(u_long, void *); | |
84 | void arpwhohas(struct ifnet *, struct in_addr *); | 81 | void arpwhohas(struct ifnet *, struct in_addr *); | |
85 | 82 | |||
86 | void revarpinput(struct mbuf *); | 83 | void revarpinput(struct mbuf *); | |
87 | int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *); | 84 | int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *); |
--- src/sys/netinet6/nd6_nbr.c 2017/01/16 15:44:47 1.136
+++ src/sys/netinet6/nd6_nbr.c 2017/02/21 03:58:24 1.137
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: nd6_nbr.c,v 1.136 2017/01/16 15:44:47 christos Exp $ */ | 1 | /* $NetBSD: nd6_nbr.c,v 1.137 2017/02/21 03:58:24 ozaki-r Exp $ */ | |
2 | /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ | 2 | /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -21,36 +21,36 @@ | @@ -21,36 +21,36 @@ | |||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
30 | * SUCH DAMAGE. | 30 | * SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.136 2017/01/16 15:44:47 christos Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.137 2017/02/21 03:58:24 ozaki-r Exp $"); | |
35 | 35 | |||
36 | #ifdef _KERNEL_OPT | 36 | #ifdef _KERNEL_OPT | |
37 | #include "opt_inet.h" | 37 | #include "opt_inet.h" | |
38 | #include "opt_net_mpsafe.h" | 38 | #include "opt_net_mpsafe.h" | |
39 | #endif | 39 | #endif | |
40 | 40 | |||
41 | #include <sys/param.h> | 41 | #include <sys/param.h> | |
42 | #include <sys/systm.h> | 42 | #include <sys/systm.h> | |
43 | #include <sys/malloc.h> | 43 | #include <sys/kmem.h> | |
44 | #include <sys/mbuf.h> | 44 | #include <sys/mbuf.h> | |
45 | #include <sys/socket.h> | 45 | #include <sys/socket.h> | |
46 | #include <sys/socketvar.h> | 46 | #include <sys/socketvar.h> | |
47 | #include <sys/sockio.h> | 47 | #include <sys/sockio.h> | |
48 | #include <sys/time.h> | 48 | #include <sys/time.h> | |
49 | #include <sys/kernel.h> | 49 | #include <sys/kernel.h> | |
50 | #include <sys/errno.h> | 50 | #include <sys/errno.h> | |
51 | #include <sys/ioctl.h> | 51 | #include <sys/ioctl.h> | |
52 | #include <sys/syslog.h> | 52 | #include <sys/syslog.h> | |
53 | #include <sys/queue.h> | 53 | #include <sys/queue.h> | |
54 | #include <sys/callout.h> | 54 | #include <sys/callout.h> | |
55 | 55 | |||
56 | #include <net/if.h> | 56 | #include <net/if.h> | |
@@ -1144,51 +1144,53 @@ nd6_dad_start(struct ifaddr *ifa, int xt | @@ -1144,51 +1144,53 @@ nd6_dad_start(struct ifaddr *ifa, int xt | |||
1144 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | 1144 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | |
1145 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1145 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1146 | return; | 1146 | return; | |
1147 | } | 1147 | } | |
1148 | if (ia->ia6_flags & IN6_IFF_ANYCAST || !ip6_dad_count) { | 1148 | if (ia->ia6_flags & IN6_IFF_ANYCAST || !ip6_dad_count) { | |
1149 | ia->ia6_flags &= ~IN6_IFF_TENTATIVE; | 1149 | ia->ia6_flags &= ~IN6_IFF_TENTATIVE; | |
1150 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | 1150 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | |
1151 | return; | 1151 | return; | |
1152 | } | 1152 | } | |
1153 | KASSERT(ifa->ifa_ifp != NULL); | 1153 | KASSERT(ifa->ifa_ifp != NULL); | |
1154 | if (!(ifa->ifa_ifp->if_flags & IFF_UP)) | 1154 | if (!(ifa->ifa_ifp->if_flags & IFF_UP)) | |
1155 | return; | 1155 | return; | |
1156 | 1156 | |||
1157 | dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP); | |||
1158 | ||||
1157 | mutex_enter(&nd6_dad_lock); | 1159 | mutex_enter(&nd6_dad_lock); | |
1158 | if (nd6_dad_find(ifa) != NULL) { | 1160 | if (nd6_dad_find(ifa) != NULL) { | |
1159 | mutex_exit(&nd6_dad_lock); | 1161 | mutex_exit(&nd6_dad_lock); | |
1160 | /* DAD already in progress */ | 1162 | /* DAD already in progress */ | |
1163 | if (dp != NULL) | |||
1164 | kmem_intr_free(dp, sizeof(*dp)); | |||
1161 | return; | 1165 | return; | |
1162 | } | 1166 | } | |
1163 | 1167 | |||
1164 | dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT); | |||
1165 | if (dp == NULL) { | 1168 | if (dp == NULL) { | |
1166 | mutex_exit(&nd6_dad_lock); | 1169 | mutex_exit(&nd6_dad_lock); | |
1167 | log(LOG_ERR, "nd6_dad_start: memory allocation failed for " | 1170 | log(LOG_ERR, "nd6_dad_start: memory allocation failed for " | |
1168 | "%s(%s)\n", | 1171 | "%s(%s)\n", | |
1169 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | 1172 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | |
1170 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1173 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1171 | return; | 1174 | return; | |
1172 | } | 1175 | } | |
1173 | memset(dp, 0, sizeof(*dp)); | |||
1174 | callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); | |||
1175 | 1176 | |||
1176 | /* | 1177 | /* | |
1177 | * Send NS packet for DAD, ip6_dad_count times. | 1178 | * Send NS packet for DAD, ip6_dad_count times. | |
1178 | * Note that we must delay the first transmission, if this is the | 1179 | * Note that we must delay the first transmission, if this is the | |
1179 | * first packet to be sent from the interface after interface | 1180 | * first packet to be sent from the interface after interface | |
1180 | * (re)initialization. | 1181 | * (re)initialization. | |
1181 | */ | 1182 | */ | |
1183 | callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); | |||
1182 | dp->dad_ifa = ifa; | 1184 | dp->dad_ifa = ifa; | |
1183 | ifaref(ifa); /* just for safety */ | 1185 | ifaref(ifa); /* just for safety */ | |
1184 | dp->dad_count = ip6_dad_count; | 1186 | dp->dad_count = ip6_dad_count; | |
1185 | dp->dad_ns_icount = dp->dad_na_icount = 0; | 1187 | dp->dad_ns_icount = dp->dad_na_icount = 0; | |
1186 | dp->dad_ns_ocount = dp->dad_ns_tcount = 0; | 1188 | dp->dad_ns_ocount = dp->dad_ns_tcount = 0; | |
1187 | TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); | 1189 | TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); | |
1188 | 1190 | |||
1189 | nd6log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), | 1191 | nd6log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), | |
1190 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); | 1192 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); | |
1191 | 1193 | |||
1192 | if (xtick == 0) { | 1194 | if (xtick == 0) { | |
1193 | nd6_dad_ns_output(dp, ifa); | 1195 | nd6_dad_ns_output(dp, ifa); | |
1194 | nd6_dad_starttimer(dp, | 1196 | nd6_dad_starttimer(dp, | |
@@ -1213,38 +1215,38 @@ nd6_dad_stop(struct ifaddr *ifa) | @@ -1213,38 +1215,38 @@ nd6_dad_stop(struct ifaddr *ifa) | |||
1213 | dp = nd6_dad_find(ifa); | 1215 | dp = nd6_dad_find(ifa); | |
1214 | if (dp == NULL) { | 1216 | if (dp == NULL) { | |
1215 | mutex_exit(&nd6_dad_lock); | 1217 | mutex_exit(&nd6_dad_lock); | |
1216 | /* DAD wasn't started yet */ | 1218 | /* DAD wasn't started yet */ | |
1217 | return; | 1219 | return; | |
1218 | } | 1220 | } | |
1219 | 1221 | |||
1220 | /* Prevent the timer from running anymore. */ | 1222 | /* Prevent the timer from running anymore. */ | |
1221 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1223 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1222 | mutex_exit(&nd6_dad_lock); | 1224 | mutex_exit(&nd6_dad_lock); | |
1223 | 1225 | |||
1224 | nd6_dad_stoptimer(dp); | 1226 | nd6_dad_stoptimer(dp); | |
1225 | 1227 | |||
1226 | free(dp, M_IP6NDP); | 1228 | kmem_intr_free(dp, sizeof(*dp)); | |
1227 | dp = NULL; | |||
1228 | ifafree(ifa); | 1229 | ifafree(ifa); | |
1229 | } | 1230 | } | |
1230 | 1231 | |||
1231 | static void | 1232 | static void | |
1232 | nd6_dad_timer(struct ifaddr *ifa) | 1233 | nd6_dad_timer(struct ifaddr *ifa) | |
1233 | { | 1234 | { | |
1234 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | 1235 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | |
1235 | struct dadq *dp; | 1236 | struct dadq *dp; | |
1236 | int duplicate = 0; | 1237 | int duplicate = 0; | |
1237 | char ip6buf[INET6_ADDRSTRLEN]; | 1238 | char ip6buf[INET6_ADDRSTRLEN]; | |
1239 | bool need_free = false; | |||
1238 | 1240 | |||
1239 | #ifndef NET_MPSAFE | 1241 | #ifndef NET_MPSAFE | |
1240 | mutex_enter(softnet_lock); | 1242 | mutex_enter(softnet_lock); | |
1241 | KERNEL_LOCK(1, NULL); | 1243 | KERNEL_LOCK(1, NULL); | |
1242 | #endif | 1244 | #endif | |
1243 | mutex_enter(&nd6_dad_lock); | 1245 | mutex_enter(&nd6_dad_lock); | |
1244 | 1246 | |||
1245 | /* Sanity check */ | 1247 | /* Sanity check */ | |
1246 | if (ia == NULL) { | 1248 | if (ia == NULL) { | |
1247 | log(LOG_ERR, "nd6_dad_timer: called with null parameter\n"); | 1249 | log(LOG_ERR, "nd6_dad_timer: called with null parameter\n"); | |
1248 | goto done; | 1250 | goto done; | |
1249 | } | 1251 | } | |
1250 | dp = nd6_dad_find(ifa); | 1252 | dp = nd6_dad_find(ifa); | |
@@ -1263,29 +1265,27 @@ nd6_dad_timer(struct ifaddr *ifa) | @@ -1263,29 +1265,27 @@ nd6_dad_timer(struct ifaddr *ifa) | |||
1263 | log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " | 1265 | log(LOG_ERR, "nd6_dad_timer: called with non-tentative address " | |
1264 | "%s(%s)\n", | 1266 | "%s(%s)\n", | |
1265 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | 1267 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), | |
1266 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | 1268 | ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); | |
1267 | goto done; | 1269 | goto done; | |
1268 | } | 1270 | } | |
1269 | 1271 | |||
1270 | /* timeouted with IFF_{RUNNING,UP} check */ | 1272 | /* timeouted with IFF_{RUNNING,UP} check */ | |
1271 | if (dp->dad_ns_tcount > dad_maxtry) { | 1273 | if (dp->dad_ns_tcount > dad_maxtry) { | |
1272 | nd6log(LOG_INFO, "%s: could not run DAD, driver problem?\n", | 1274 | nd6log(LOG_INFO, "%s: could not run DAD, driver problem?\n", | |
1273 | if_name(ifa->ifa_ifp)); | 1275 | if_name(ifa->ifa_ifp)); | |
1274 | 1276 | |||
1275 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1277 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1276 | free(dp, M_IP6NDP); | 1278 | need_free = true; | |
1277 | dp = NULL; | |||
1278 | ifafree(ifa); | |||
1279 | goto done; | 1279 | goto done; | |
1280 | } | 1280 | } | |
1281 | 1281 | |||
1282 | /* Need more checks? */ | 1282 | /* Need more checks? */ | |
1283 | if (dp->dad_ns_ocount < dp->dad_count) { | 1283 | if (dp->dad_ns_ocount < dp->dad_count) { | |
1284 | /* | 1284 | /* | |
1285 | * We have more NS to go. Send NS packet for DAD. | 1285 | * We have more NS to go. Send NS packet for DAD. | |
1286 | */ | 1286 | */ | |
1287 | nd6_dad_ns_output(dp, ifa); | 1287 | nd6_dad_ns_output(dp, ifa); | |
1288 | nd6_dad_starttimer(dp, | 1288 | nd6_dad_starttimer(dp, | |
1289 | (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); | 1289 | (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); | |
1290 | } else { | 1290 | } else { | |
1291 | /* | 1291 | /* | |
@@ -1312,35 +1312,38 @@ nd6_dad_timer(struct ifaddr *ifa) | @@ -1312,35 +1312,38 @@ nd6_dad_timer(struct ifaddr *ifa) | |||
1312 | /* | 1312 | /* | |
1313 | * We are done with DAD. No NA came, no NS came. | 1313 | * We are done with DAD. No NA came, no NS came. | |
1314 | * No duplicate address found. | 1314 | * No duplicate address found. | |
1315 | */ | 1315 | */ | |
1316 | ia->ia6_flags &= ~IN6_IFF_TENTATIVE; | 1316 | ia->ia6_flags &= ~IN6_IFF_TENTATIVE; | |
1317 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | 1317 | rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); | |
1318 | 1318 | |||
1319 | nd6log(LOG_DEBUG, | 1319 | nd6log(LOG_DEBUG, | |
1320 | "%s: DAD complete for %s - no duplicates found\n", | 1320 | "%s: DAD complete for %s - no duplicates found\n", | |
1321 | if_name(ifa->ifa_ifp), | 1321 | if_name(ifa->ifa_ifp), | |
1322 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); | 1322 | IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); | |
1323 | 1323 | |||
1324 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1324 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1325 | free(dp, M_IP6NDP); | 1325 | need_free = true; | |
1326 | dp = NULL; | |||
1327 | ifafree(ifa); | |||
1328 | } | 1326 | } | |
1329 | } | 1327 | } | |
1330 | ||||
1331 | done: | 1328 | done: | |
1332 | mutex_exit(&nd6_dad_lock); | 1329 | mutex_exit(&nd6_dad_lock); | |
1333 | 1330 | |||
1331 | if (need_free) { | |||
1332 | kmem_intr_free(dp, sizeof(*dp)); | |||
1333 | ifafree(ifa); | |||
1334 | ifa = NULL; | |||
1335 | } | |||
1336 | ||||
1334 | if (duplicate) | 1337 | if (duplicate) | |
1335 | nd6_dad_duplicated(ifa); | 1338 | nd6_dad_duplicated(ifa); | |
1336 | 1339 | |||
1337 | #ifndef NET_MPSAFE | 1340 | #ifndef NET_MPSAFE | |
1338 | KERNEL_UNLOCK_ONE(NULL); | 1341 | KERNEL_UNLOCK_ONE(NULL); | |
1339 | mutex_exit(softnet_lock); | 1342 | mutex_exit(softnet_lock); | |
1340 | #endif | 1343 | #endif | |
1341 | } | 1344 | } | |
1342 | 1345 | |||
1343 | static void | 1346 | static void | |
1344 | nd6_dad_duplicated(struct ifaddr *ifa) | 1347 | nd6_dad_duplicated(struct ifaddr *ifa) | |
1345 | { | 1348 | { | |
1346 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | 1349 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | |
@@ -1403,28 +1406,27 @@ nd6_dad_duplicated(struct ifaddr *ifa) | @@ -1403,28 +1406,27 @@ nd6_dad_duplicated(struct ifaddr *ifa) | |||
1403 | IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) { | 1406 | IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) { | |
1404 | ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; | 1407 | ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; | |
1405 | log(LOG_ERR, "%s: possible hardware address " | 1408 | log(LOG_ERR, "%s: possible hardware address " | |
1406 | "duplication detected, disable IPv6\n", | 1409 | "duplication detected, disable IPv6\n", | |
1407 | if_name(ifp)); | 1410 | if_name(ifp)); | |
1408 | } | 1411 | } | |
1409 | break; | 1412 | break; | |
1410 | } | 1413 | } | |
1411 | } | 1414 | } | |
1412 | 1415 | |||
1413 | TAILQ_REMOVE(&dadq, dp, dad_list); | 1416 | TAILQ_REMOVE(&dadq, dp, dad_list); | |
1414 | mutex_exit(&nd6_dad_lock); | 1417 | mutex_exit(&nd6_dad_lock); | |
1415 | 1418 | |||
1416 | free(dp, M_IP6NDP); | 1419 | kmem_intr_free(dp, sizeof(*dp)); | |
1417 | dp = NULL; | |||
1418 | ifafree(ifa); | 1420 | ifafree(ifa); | |
1419 | } | 1421 | } | |
1420 | 1422 | |||
1421 | static void | 1423 | static void | |
1422 | nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) | 1424 | nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) | |
1423 | { | 1425 | { | |
1424 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | 1426 | struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; | |
1425 | struct ifnet *ifp = ifa->ifa_ifp; | 1427 | struct ifnet *ifp = ifa->ifa_ifp; | |
1426 | 1428 | |||
1427 | dp->dad_ns_tcount++; | 1429 | dp->dad_ns_tcount++; | |
1428 | if ((ifp->if_flags & IFF_UP) == 0) { | 1430 | if ((ifp->if_flags & IFF_UP) == 0) { | |
1429 | #if 0 | 1431 | #if 0 | |
1430 | printf("%s: interface down?\n", if_name(ifp)); | 1432 | printf("%s: interface down?\n", if_name(ifp)); |