Example #1
0
static void
vrrp_vmac_handler(vector_t *strvec)
{
	vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
	vrrp->vmac |= 1;
	if (!vrrp->saddr)
		vrrp->saddr  = IF_ADDR(vrrp->ifp);
	if (vector_size(strvec) == 2) {
		strncpy(vrrp->vmac_ifname, vector_slot(strvec, 1),
			IFNAMSIZ - 1);
	} else if (vrrp->vrid) {
		snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d", vrrp->vrid);
	}

	if (strlen(vrrp->vmac_ifname)) {
		log_message(LOG_INFO, "vmac_ifname=%s for vrrp_instace %s"
				    , vrrp->vmac_ifname
				    , vrrp->iname);
	}
	if (vrrp->ifp && !(vrrp->vmac & 2)) {
		unsigned int base_ifindex = vrrp->ifp->base_ifindex;
		netlink_link_add_vmac(vrrp);
		/* restore base ifindex (deleted when adding VMAC) */
		vrrp->ifp->base_ifindex = base_ifindex;
        }

        /* flag interface as a VMAC interface */
        vrrp->ifp->vmac = 1;
}
Example #2
0
int
if_join_vrrp_group(sa_family_t family, int *sd, interface_t *ifp, int proto)
{
	struct ip_mreqn imr;
	struct ipv6_mreq imr6;
	int ret = 0;

	if (*sd < 0)
		return -1;

	/* -> outbound processing option
	 * join the multicast group.
	 * binding the socket to the interface for outbound multicast
	 * traffic.
	 */

	if (family == AF_INET) {
		memset(&imr, 0, sizeof(imr));
		imr.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
		imr.imr_address.s_addr = IF_ADDR(ifp);
		imr.imr_ifindex = IF_INDEX(ifp);

		/* -> Need to handle multicast convergance after takeover.
		 * We retry until multicast is available on the interface.
		 */
		ret = setsockopt(*sd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
				 (char *) &imr, sizeof(struct ip_mreqn));
	} else {
		memset(&imr6, 0, sizeof(imr6));
		imr6.ipv6mr_multiaddr.s6_addr16[0] = htons(0xff02);
		imr6.ipv6mr_multiaddr.s6_addr16[7] = htons(0x12);
		imr6.ipv6mr_interface = IF_INDEX(ifp);
		ret = setsockopt(*sd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
				 (char *) &imr6, sizeof(struct ipv6_mreq));
	}

	if (ret < 0) {
		log_message(LOG_INFO, "cant do IP%s_ADD_MEMBERSHIP errno=%s (%d)",
			    (family == AF_INET) ? "" : "V6", strerror(errno), errno);
		close(*sd);
		*sd = -1;
        }

	return *sd;
}
Example #3
0
static void
vrrp_vmac_handler(vector_t *strvec)
{
	vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
	vrrp->vmac_flags |= VRRP_VMAC_FL_SET;
	if (!vrrp->saddr.ss_family && vrrp->family == AF_INET)
		inet_ip4tosockaddr(IF_ADDR(vrrp->ifp), &vrrp->saddr);
	if (vector_size(strvec) == 2) {
		strncpy(vrrp->vmac_ifname, vector_slot(strvec, 1),
			IFNAMSIZ - 1);
	} else if (vrrp->vrid) {
		snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d", vrrp->vrid);
	} else {
		return;
	}

	netlink_link_add_vmac(vrrp);
}
static void
vrrp_vmac_handler(vector strvec)
{
	vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
	vrrp->vmac = 1;
	if (!(vrrp->mcast_saddr))
		vrrp->mcast_saddr  = IF_ADDR(vrrp->ifp);
	if (strvec && (strvec->allocated == 2))
		strncpy(vrrp->vmac_ifname, VECTOR_SLOT(strvec, 1),
			IFNAMSIZ - 1);
	else 
		snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d", vrrp->vrid);
	log_message(LOG_INFO, "vrrp_vmac_handler: vmac ifname is %s",
			    vrrp->vmac_ifname);

	if (vrrp->ifp && !(vrrp->vmac & 2))
		netlink_link_add_vmac(vrrp);
}
Example #5
0
int
if_leave_vrrp_group(sa_family_t family, int sd, interface_t *ifp)
{
	struct ip_mreqn imr;
	struct ipv6_mreq imr6;
	int ret = 0;

	/* If fd is -1 then we add a membership trouble */
	if (sd < 0 || !ifp)
		return -1;

	/* Leaving the VRRP multicast group */
	if (family == AF_INET) {
		memset(&imr, 0, sizeof(imr));
		/* FIXME: change this to use struct ip_mreq */
		imr.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
		imr.imr_address.s_addr = IF_ADDR(ifp);
		imr.imr_ifindex = IF_INDEX(ifp);
		ret = setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
				 (char *) &imr, sizeof (struct ip_mreqn));
	} else {
		memset(&imr6, 0, sizeof(imr6));
		/* rfc5798.5.1.2.2 : destination IPv6 mcast group is
		 * ff02:0:0:0:0:0:0:12.
		 */
		imr6.ipv6mr_multiaddr.s6_addr16[0] = htons(0xff02);
		imr6.ipv6mr_multiaddr.s6_addr16[7] = htons(0x12);
		imr6.ipv6mr_interface = IF_INDEX(ifp);
		ret = setsockopt(sd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
				 (char *) &imr6, sizeof(struct ipv6_mreq));
	}

	if (ret < 0) {
		log_message(LOG_INFO, "cant do IP%s_DROP_MEMBERSHIP errno=%s (%d)",
			    (family == AF_INET) ? "" : "V6", strerror(errno), errno);
		close(sd);
		return -1;
	}

	/* Finally close the desc */
	close(sd);
	return 0;
}