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 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? */
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
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
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;
1461
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 }
1467 }
1468 KASSERT(im6o->im6o_mfilters == NULL,
1469 ("%s: im6o_mfilters != NULL", __func__));
1470 im6o->im6o_num_memberships = 0;
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;
1649 struct in6_addr in6;
1650 int own, error;
1651
1652 error = 0;
1653
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
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;
1711 in6m = NULL;
1712 error = in6_mc_join(ifp, &in6, NULL, &in6m, 0);
1713 if (error)
1714 goto cleanup;
1715 im6o->im6o_membership[0] = in6m;
1716 im6o->im6o_num_memberships++;
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;
1727 in6m = NULL;
1728 error = in6_mc_join(ifp, &in6, NULL, &in6m, 0);
1729 if (error)
1730 goto cleanup;
1731 im6o->im6o_membership[1] = in6m;
1732 im6o->im6o_num_memberships++;
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:
1804 if (!sc->sc_naddrs6)
1805 carp_multicast6_cleanup(sc);
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;
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;
1822 carp_multicast6_cleanup(sc);
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 ---