ip_carp.c (191528) | ip_carp.c (191672) |
---|---|
1/* 2 * Copyright (c) 2002 Michael Shalayeff. All rights reserved. 3 * Copyright (c) 2003 Ryan McBride. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2002 Michael Shalayeff. All rights reserved. 3 * Copyright (c) 2003 Ryan McBride. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 * THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/netinet/ip_carp.c 191528 2009-04-26 19:05:40Z rwatson $"); | 28__FBSDID("$FreeBSD: head/sys/netinet/ip_carp.c 191672 2009-04-29 19:19:13Z bms $"); |
29 30#include "opt_carp.h" 31#include "opt_bpf.h" 32#include "opt_inet.h" 33#include "opt_inet6.h" 34 35#include <sys/types.h> 36#include <sys/param.h> --- 358 unchanged lines hidden (view full) --- 395 396 sc->sc_flags_backup = 0; 397 sc->sc_suppress = 0; 398 sc->sc_advbase = CARP_DFLTINTV; 399 sc->sc_vhid = -1; /* required setting */ 400 sc->sc_advskew = 0; 401 sc->sc_init_counter = 1; 402 sc->sc_naddrs = sc->sc_naddrs6 = 0; /* M_ZERO? */ | 29 30#include "opt_carp.h" 31#include "opt_bpf.h" 32#include "opt_inet.h" 33#include "opt_inet6.h" 34 35#include <sys/types.h> 36#include <sys/param.h> --- 358 unchanged lines hidden (view full) --- 395 396 sc->sc_flags_backup = 0; 397 sc->sc_suppress = 0; 398 sc->sc_advbase = CARP_DFLTINTV; 399 sc->sc_vhid = -1; /* required setting */ 400 sc->sc_advskew = 0; 401 sc->sc_init_counter = 1; 402 sc->sc_naddrs = sc->sc_naddrs6 = 0; /* M_ZERO? */ |
403#ifdef INET6 404 sc->sc_im6o.im6o_multicast_hlim = CARP_DFLTTL; 405#endif | |
406 sc->sc_imo.imo_membership = (struct in_multi **)malloc( 407 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_CARP, 408 M_WAITOK); 409 sc->sc_imo.imo_mfilters = NULL; 410 sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS; 411 sc->sc_imo.imo_multicast_vif = -1; | 403 sc->sc_imo.imo_membership = (struct in_multi **)malloc( 404 (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_CARP, 405 M_WAITOK); 406 sc->sc_imo.imo_mfilters = NULL; 407 sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS; 408 sc->sc_imo.imo_multicast_vif = -1; |
409#ifdef INET6 410 sc->sc_im6o.im6o_membership = (struct in6_multi **)malloc( 411 (sizeof(struct in6_multi *) * IPV6_MIN_MEMBERSHIPS), M_CARP, 412 M_WAITOK); 413 sc->sc_im6o.im6o_mfilters = NULL; 414 sc->sc_im6o.im6o_max_memberships = IPV6_MIN_MEMBERSHIPS; 415 sc->sc_im6o.im6o_multicast_hlim = CARP_DFLTTL; 416#endif |
|
412 413 callout_init(&sc->sc_ad_tmo, CALLOUT_MPSAFE); 414 callout_init(&sc->sc_md_tmo, CALLOUT_MPSAFE); 415 callout_init(&sc->sc_md6_tmo, CALLOUT_MPSAFE); 416 417 ifp->if_softc = sc; 418 if_initname(ifp, CARP_IFNAME, unit); 419 ifp->if_mtu = ETHERMTU; --- 23 unchanged lines hidden (view full) --- 443 444 mtx_lock(&carp_mtx); 445 LIST_REMOVE(sc, sc_next); 446 mtx_unlock(&carp_mtx); 447 bpfdetach(ifp); 448 if_detach(ifp); 449 if_free_type(ifp, IFT_ETHER); 450 free(sc->sc_imo.imo_membership, M_CARP); | 417 418 callout_init(&sc->sc_ad_tmo, CALLOUT_MPSAFE); 419 callout_init(&sc->sc_md_tmo, CALLOUT_MPSAFE); 420 callout_init(&sc->sc_md6_tmo, CALLOUT_MPSAFE); 421 422 ifp->if_softc = sc; 423 if_initname(ifp, CARP_IFNAME, unit); 424 ifp->if_mtu = ETHERMTU; --- 23 unchanged lines hidden (view full) --- 448 449 mtx_lock(&carp_mtx); 450 LIST_REMOVE(sc, sc_next); 451 mtx_unlock(&carp_mtx); 452 bpfdetach(ifp); 453 if_detach(ifp); 454 if_free_type(ifp, IFT_ETHER); 455 free(sc->sc_imo.imo_membership, M_CARP); |
456#ifdef INET6 457 free(sc->sc_im6o.im6o_membership, M_CARP); 458#endif |
|
451 free(sc, M_CARP); 452} 453 454/* 455 * This function can be called on CARP interface destroy path, 456 * and in case of the removal of the underlying interface as 457 * well. We differentiate these two cases. In the latter case 458 * we do not cleanup our multicast memberships, since they --- 985 unchanged lines hidden (view full) --- 1444 imo->imo_multicast_ifp = NULL; 1445} 1446 1447#ifdef INET6 1448static void 1449carp_multicast6_cleanup(struct carp_softc *sc) 1450{ 1451 struct ip6_moptions *im6o = &sc->sc_im6o; | 459 free(sc, M_CARP); 460} 461 462/* 463 * This function can be called on CARP interface destroy path, 464 * and in case of the removal of the underlying interface as 465 * well. We differentiate these two cases. In the latter case 466 * we do not cleanup our multicast memberships, since they --- 985 unchanged lines hidden (view full) --- 1452 imo->imo_multicast_ifp = NULL; 1453} 1454 1455#ifdef INET6 1456static void 1457carp_multicast6_cleanup(struct carp_softc *sc) 1458{ 1459 struct ip6_moptions *im6o = &sc->sc_im6o; |
1460 u_int16_t n = im6o->im6o_num_memberships; |
|
1452 | 1461 |
1453 while (!LIST_EMPTY(&im6o->im6o_memberships)) { 1454 struct in6_multi_mship *imm = 1455 LIST_FIRST(&im6o->im6o_memberships); 1456 1457 LIST_REMOVE(imm, i6mm_chain); 1458 in6_leavegroup(imm); | 1462 while (n-- > 0) { 1463 if (im6o->im6o_membership[n] != NULL) { 1464 in6_mc_leave(im6o->im6o_membership[n], NULL); 1465 im6o->im6o_membership[n] = NULL; 1466 } |
1459 } | 1467 } |
1468 KASSERT(im6o->im6o_mfilters == NULL, 1469 ("%s: im6o_mfilters != NULL", __func__)); 1470 im6o->im6o_num_memberships = 0; |
|
1460 im6o->im6o_multicast_ifp = NULL; 1461} 1462#endif 1463 1464static int 1465carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin) 1466{ 1467 INIT_VNET_INET(curvnet); --- 162 unchanged lines hidden (view full) --- 1630static int 1631carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) 1632{ 1633 INIT_VNET_INET6(curvnet); 1634 struct ifnet *ifp; 1635 struct carp_if *cif; 1636 struct in6_ifaddr *ia, *ia_if; 1637 struct ip6_moptions *im6o = &sc->sc_im6o; | 1471 im6o->im6o_multicast_ifp = NULL; 1472} 1473#endif 1474 1475static int 1476carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin) 1477{ 1478 INIT_VNET_INET(curvnet); --- 162 unchanged lines hidden (view full) --- 1641static int 1642carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) 1643{ 1644 INIT_VNET_INET6(curvnet); 1645 struct ifnet *ifp; 1646 struct carp_if *cif; 1647 struct in6_ifaddr *ia, *ia_if; 1648 struct ip6_moptions *im6o = &sc->sc_im6o; |
1638 struct in6_multi_mship *imm; | |
1639 struct in6_addr in6; 1640 int own, error; 1641 | 1649 struct in6_addr in6; 1650 int own, error; 1651 |
1652 error = 0; 1653 |
|
1642 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1643 if (!(SC2IFP(sc)->if_flags & IFF_UP)) 1644 carp_set_state(sc, INIT); 1645 if (sc->sc_naddrs6) 1646 SC2IFP(sc)->if_flags |= IFF_UP; 1647 if (sc->sc_carpdev) 1648 CARP_SCLOCK(sc); 1649 carp_setrun(sc, 0); --- 31 unchanged lines hidden (view full) --- 1681 ia = ia_if; 1682 ifp = ia->ia_ifp; 1683 1684 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0 || 1685 (im6o->im6o_multicast_ifp && im6o->im6o_multicast_ifp != ifp)) 1686 return (EADDRNOTAVAIL); 1687 1688 if (!sc->sc_naddrs6) { | 1654 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1655 if (!(SC2IFP(sc)->if_flags & IFF_UP)) 1656 carp_set_state(sc, INIT); 1657 if (sc->sc_naddrs6) 1658 SC2IFP(sc)->if_flags |= IFF_UP; 1659 if (sc->sc_carpdev) 1660 CARP_SCLOCK(sc); 1661 carp_setrun(sc, 0); --- 31 unchanged lines hidden (view full) --- 1693 ia = ia_if; 1694 ifp = ia->ia_ifp; 1695 1696 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0 || 1697 (im6o->im6o_multicast_ifp && im6o->im6o_multicast_ifp != ifp)) 1698 return (EADDRNOTAVAIL); 1699 1700 if (!sc->sc_naddrs6) { |
1701 struct in6_multi *in6m; 1702 |
|
1689 im6o->im6o_multicast_ifp = ifp; 1690 1691 /* join CARP multicast address */ 1692 bzero(&in6, sizeof(in6)); 1693 in6.s6_addr16[0] = htons(0xff02); 1694 in6.s6_addr8[15] = 0x12; 1695 if (in6_setscope(&in6, ifp, NULL) != 0) 1696 goto cleanup; | 1703 im6o->im6o_multicast_ifp = ifp; 1704 1705 /* join CARP multicast address */ 1706 bzero(&in6, sizeof(in6)); 1707 in6.s6_addr16[0] = htons(0xff02); 1708 in6.s6_addr8[15] = 0x12; 1709 if (in6_setscope(&in6, ifp, NULL) != 0) 1710 goto cleanup; |
1697 if ((imm = in6_joingroup(ifp, &in6, &error, 0)) == NULL) | 1711 in6m = NULL; 1712 error = in6_mc_join(ifp, &in6, NULL, &in6m, 0); 1713 if (error) |
1698 goto cleanup; | 1714 goto cleanup; |
1699 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain); | 1715 im6o->im6o_membership[0] = in6m; 1716 im6o->im6o_num_memberships++; |
1700 1701 /* join solicited multicast address */ 1702 bzero(&in6, sizeof(in6)); 1703 in6.s6_addr16[0] = htons(0xff02); 1704 in6.s6_addr32[1] = 0; 1705 in6.s6_addr32[2] = htonl(1); 1706 in6.s6_addr32[3] = sin6->sin6_addr.s6_addr32[3]; 1707 in6.s6_addr8[12] = 0xff; 1708 if (in6_setscope(&in6, ifp, NULL) != 0) 1709 goto cleanup; | 1717 1718 /* join solicited multicast address */ 1719 bzero(&in6, sizeof(in6)); 1720 in6.s6_addr16[0] = htons(0xff02); 1721 in6.s6_addr32[1] = 0; 1722 in6.s6_addr32[2] = htonl(1); 1723 in6.s6_addr32[3] = sin6->sin6_addr.s6_addr32[3]; 1724 in6.s6_addr8[12] = 0xff; 1725 if (in6_setscope(&in6, ifp, NULL) != 0) 1726 goto cleanup; |
1710 if ((imm = in6_joingroup(ifp, &in6, &error, 0)) == NULL) | 1727 in6m = NULL; 1728 error = in6_mc_join(ifp, &in6, NULL, &in6m, 0); 1729 if (error) |
1711 goto cleanup; | 1730 goto cleanup; |
1712 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain); | 1731 im6o->im6o_membership[1] = in6m; 1732 im6o->im6o_num_memberships++; |
1713 } 1714 1715 if (!ifp->if_carp) { 1716 cif = malloc(sizeof(*cif), M_CARP, 1717 M_WAITOK|M_ZERO); 1718 if (!cif) { 1719 error = ENOBUFS; 1720 goto cleanup; --- 55 unchanged lines hidden (view full) --- 1776 carp_sc_state_locked(sc); 1777 carp_setrun(sc, 0); 1778 1779 CARP_UNLOCK(cif); 1780 1781 return (0); 1782 1783cleanup: | 1733 } 1734 1735 if (!ifp->if_carp) { 1736 cif = malloc(sizeof(*cif), M_CARP, 1737 M_WAITOK|M_ZERO); 1738 if (!cif) { 1739 error = ENOBUFS; 1740 goto cleanup; --- 55 unchanged lines hidden (view full) --- 1796 carp_sc_state_locked(sc); 1797 carp_setrun(sc, 0); 1798 1799 CARP_UNLOCK(cif); 1800 1801 return (0); 1802 1803cleanup: |
1784 /* clean up multicast memberships */ 1785 if (!sc->sc_naddrs6) { 1786 while (!LIST_EMPTY(&im6o->im6o_memberships)) { 1787 imm = LIST_FIRST(&im6o->im6o_memberships); 1788 LIST_REMOVE(imm, i6mm_chain); 1789 in6_leavegroup(imm); 1790 } 1791 } | 1804 if (!sc->sc_naddrs6) 1805 carp_multicast6_cleanup(sc); |
1792 return (error); 1793} 1794 1795static int 1796carp_del_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) 1797{ 1798 int error = 0; 1799 1800 if (!--sc->sc_naddrs6) { 1801 struct carp_if *cif = (struct carp_if *)sc->sc_carpdev->if_carp; | 1806 return (error); 1807} 1808 1809static int 1810carp_del_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) 1811{ 1812 int error = 0; 1813 1814 if (!--sc->sc_naddrs6) { 1815 struct carp_if *cif = (struct carp_if *)sc->sc_carpdev->if_carp; |
1802 struct ip6_moptions *im6o = &sc->sc_im6o; | |
1803 1804 CARP_LOCK(cif); 1805 callout_stop(&sc->sc_ad_tmo); 1806 SC2IFP(sc)->if_flags &= ~IFF_UP; 1807 SC2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING; 1808 sc->sc_vhid = -1; | 1816 1817 CARP_LOCK(cif); 1818 callout_stop(&sc->sc_ad_tmo); 1819 SC2IFP(sc)->if_flags &= ~IFF_UP; 1820 SC2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING; 1821 sc->sc_vhid = -1; |
1809 while (!LIST_EMPTY(&im6o->im6o_memberships)) { 1810 struct in6_multi_mship *imm = 1811 LIST_FIRST(&im6o->im6o_memberships); 1812 1813 LIST_REMOVE(imm, i6mm_chain); 1814 in6_leavegroup(imm); 1815 } 1816 im6o->im6o_multicast_ifp = NULL; | 1822 carp_multicast6_cleanup(sc); |
1817 TAILQ_REMOVE(&cif->vhif_vrs, sc, sc_list); 1818 if (!--cif->vhif_nvrs) { 1819 CARP_LOCK_DESTROY(cif); 1820 sc->sc_carpdev->if_carp = NULL; 1821 free(cif, M_IFADDR); 1822 } else 1823 CARP_UNLOCK(cif); 1824 } --- 450 unchanged lines hidden --- | 1823 TAILQ_REMOVE(&cif->vhif_vrs, sc, sc_list); 1824 if (!--cif->vhif_nvrs) { 1825 CARP_LOCK_DESTROY(cif); 1826 sc->sc_carpdev->if_carp = NULL; 1827 free(cif, M_IFADDR); 1828 } else 1829 CARP_UNLOCK(cif); 1830 } --- 450 unchanged lines hidden --- |