Deleted Added
sdiff udiff text old ( 191528 ) new ( 191672 )
full compact
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 $");
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;
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);
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;
1452
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);
1459 }
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;
1638 struct in6_multi_mship *imm;
1639 struct in6_addr in6;
1640 int own, error;
1641
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) {
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;
1697 if ((imm = in6_joingroup(ifp, &in6, &error, 0)) == NULL)
1698 goto cleanup;
1699 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
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;
1710 if ((imm = in6_joingroup(ifp, &in6, &error, 0)) == NULL)
1711 goto cleanup;
1712 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
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:
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 }
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;
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;
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;
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 ---