コード例 #1
0
ファイル: vrrp_iprule.c プロジェクト: rivy/keepalived
/* Add/Delete IP rule to/from a specific IP/network */
int
netlink_rule(ip_rule_t *iprule, int cmd)
{
	int status = 1;
	struct {
		struct nlmsghdr n;
		struct rtmsg r;
		char buf[1024];
	} req;

	memset(&req, 0, sizeof (req));

	req.n.nlmsg_len    = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags  = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
	req.n.nlmsg_type   = cmd ? RTM_NEWRULE : RTM_DELRULE;
	req.r.rtm_family   = IP_FAMILY(iprule->addr);
	if (iprule->table < 256)
		req.r.rtm_table = iprule->table ? iprule->table : RT_TABLE_MAIN;
	else {
		req.r.rtm_table = RT_TABLE_UNSPEC;
		addattr32(&req.n, sizeof(req), FRA_TABLE, iprule->table);
	}
	req.r.rtm_type     = RTN_UNSPEC;
	req.r.rtm_scope    = RT_SCOPE_UNIVERSE;
	req.r.rtm_flags    = 0;

	if (cmd) {
		req.r.rtm_protocol = RTPROT_BOOT;
		req.r.rtm_type     = RTN_UNICAST;
	}

	/* Set rule entry */
	if (iprule->dir == VRRP_RULE_FROM) {
		req.r.rtm_src_len = iprule->mask;
		add_addr2req(&req.n, sizeof(req), FRA_SRC, iprule->addr);
	} else if (iprule->dir == VRRP_RULE_TO) {
		req.r.rtm_dst_len = iprule->mask;
		add_addr2req(&req.n, sizeof(req), FRA_DST, iprule->addr);
	}

	if (netlink_talk(&nl_cmd, &req.n) < 0)
		status = -1;
	return status;
}
コード例 #2
0
ファイル: vrrp_parser.c プロジェクト: vrit/keepalived
static void
vrrp_vip_handler(vector_t *strvec)
{
	vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
	char *buf;
	char *str = NULL;
	vector_t *vec = NULL;
	int address_family;

	buf = (char *) MALLOC(MAXBUF);
	while (read_line(buf, MAXBUF)) {
		address_family = AF_UNSPEC;
		vec = alloc_strvec(buf);
		if (vec) {
			str = vector_slot(vec, 0);
			if (!strcmp(str, EOB)) {
				free_strvec(vec);
				break;
			}

			if (vector_size(vec)) {
				alloc_vrrp_vip(vec);
				if (!LIST_ISEMPTY(vrrp->vip))
					address_family = IP_FAMILY((ip_address_t*)LIST_TAIL_DATA(vrrp->vip));
			}

			if (address_family != AF_UNSPEC) {
				if (vrrp->family == AF_UNSPEC)
					vrrp->family = address_family;
				else if (address_family != vrrp->family) {
					log_message(LOG_INFO, "(%s): address family must match VRRP instance [%s] - ignoring", vrrp->iname, buf);
					free_list_element(vrrp->vip, LIST_TAIL_DATA(vrrp->vip));
				}
			}

			free_strvec(vec);
		}
		memset(buf, 0, MAXBUF);
	}
	FREE(buf);
}
コード例 #3
0
ファイル: vrrp_iproute.c プロジェクト: Zex/keepalived
/* Add/Delete IP route to/from a specific interface */
static int
netlink_route(ip_route_t *iproute, int cmd)
{
	int status = 1;
	struct {
		struct nlmsghdr n;
		struct rtmsg r;
		char buf[1024];
	} req;

	char buf[1024];
	struct rtattr *rta = (void*)buf;
	struct rtnexthop *rtnh;

	memset(&req, 0, sizeof (req));

	req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
	req.n.nlmsg_type  = cmd ? RTM_NEWROUTE : RTM_DELROUTE;
	req.r.rtm_family  = (iproute->dst) ? IP_FAMILY(iproute->dst) :
			    (iproute->src) ? IP_FAMILY(iproute->src) :
			    AF_INET;
	if (iproute->table < 256)
		req.r.rtm_table   = iproute->table ? iproute->table : RT_TABLE_MAIN;
	else {
		req.r.rtm_table = RT_TABLE_UNSPEC;
		addattr32(&req.n, sizeof(req), RTA_TABLE, iproute->table);
	}
	req.r.rtm_scope   = RT_SCOPE_NOWHERE;

	if (cmd == IPROUTE_ADD) {
		req.r.rtm_protocol = RTPROT_BOOT;
		req.r.rtm_scope = iproute->scope;
		req.r.rtm_type = RTN_UNICAST;
	}
	if (iproute->blackhole)
		req.r.rtm_type = RTN_BLACKHOLE;

	/* Set routing entry */
	if (iproute->dst) {
		req.r.rtm_dst_len = iproute->dmask;
		add_addr2req(&req.n, sizeof(req), RTA_DST, iproute->dst);
	}
	if ((!iproute->blackhole) && (!iproute->gw2))
		add_addr2req(&req.n, sizeof(req), RTA_GATEWAY, iproute->gw);
	if (iproute->gw && iproute->gw2) {
		rta->rta_type = RTA_MULTIPATH;
		rta->rta_len = RTA_LENGTH(0);
		rtnh = RTA_DATA(rta);
#define MULTIPATH_ADD_GW(x) \
	memset(rtnh, 0, sizeof(*rtnh)); \
	rtnh->rtnh_len = sizeof(*rtnh); \
	if (iproute->index) rtnh->rtnh_ifindex = iproute->index; \
	rta->rta_len += rtnh->rtnh_len;	\
	add_addr2rta(rta, 1024, RTA_GATEWAY, x); \
	rtnh->rtnh_len += sizeof(struct rtattr) + IP_SIZE(x); \
	rtnh = RTNH_NEXT(rtnh);
		MULTIPATH_ADD_GW(iproute->gw);
		MULTIPATH_ADD_GW(iproute->gw2);
		addattr_l(&req.n, sizeof(req), RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta));
	}
	if ((iproute->index) && (!iproute->gw2))
		addattr32(&req.n, sizeof(req), RTA_OIF, iproute->index);
	if (iproute->src)
		add_addr2req(&req.n, sizeof(req), RTA_PREFSRC, iproute->src);
	if (iproute->metric)
		addattr32(&req.n, sizeof(req), RTA_PRIORITY, iproute->metric);

	/* This returns ESRCH if the address of via address doesn't exist */
	/* ENETDOWN if dev p33p1.40 for example is down */
	if (netlink_talk(&nl_cmd, &req.n) < 0)
		status = -1;
	return status;
}