コード例 #1
0
ファイル: exp.c プロジェクト: arend/libnl
static int exp_parse_ip(struct nfnl_exp *exp, int tuple, struct nlattr *attr)
{
	struct nlattr *tb[CTA_IP_MAX+1];
	struct nl_addr *addr;
	int err;

	err = nla_parse_nested(tb, CTA_IP_MAX, attr, exp_ip_policy);
	if (err < 0)
		goto errout;

	if (tb[CTA_IP_V4_SRC]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_exp_set_src(exp, tuple, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V4_DST]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_exp_set_dst(exp, tuple, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V6_SRC]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_exp_set_src(exp, tuple, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V6_DST]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_exp_set_dst(exp, tuple, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}

	return 0;

errout_enomem:
	err = -NLE_NOMEM;
errout:
	return err;
}
コード例 #2
0
ファイル: rule.c プロジェクト: DELUXx/android-wpasupplicant
static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
			   struct nlmsghdr *n, struct nl_parser_param *pp)
{
	struct rtnl_rule *rule;
	struct fib_rule_hdr *frh;
	struct nlattr *tb[FRA_MAX+1];
	int err = 1, family;

	rule = rtnl_rule_alloc();
	if (!rule) {
		err = -NLE_NOMEM;
		goto errout;
	}

	rule->ce_msgtype = n->nlmsg_type;
	frh = nlmsg_data(n);

	err = nlmsg_parse(n, sizeof(*frh), tb, FRA_MAX, rule_policy);
	if (err < 0)
		goto errout;

	rule->r_family = family = frh->family;
	rule->r_table = frh->table;
	rule->r_action = frh->action;
	rule->r_flags = frh->flags;

	rule->ce_mask = (RULE_ATTR_FAMILY | RULE_ATTR_TABLE | RULE_ATTR_ACTION |
			 RULE_ATTR_FLAGS);

	/* ipv4 only */
	if (frh->tos) {
		rule->r_dsfield = frh->tos;
		rule->ce_mask |= RULE_ATTR_DSFIELD;
	}

	if (tb[FRA_TABLE]) {
		rule->r_table = nla_get_u32(tb[FRA_TABLE]);
		rule->ce_mask |= RULE_ATTR_TABLE;
	}

	if (tb[FRA_IIFNAME]) {
		nla_strlcpy(rule->r_iifname, tb[FRA_IIFNAME], IFNAMSIZ);
		rule->ce_mask |= RULE_ATTR_IIFNAME;
	}

	if (tb[FRA_OIFNAME]) {
		nla_strlcpy(rule->r_oifname, tb[FRA_OIFNAME], IFNAMSIZ);
		rule->ce_mask |= RULE_ATTR_OIFNAME;
	}

	if (tb[FRA_PRIORITY]) {
		rule->r_prio = nla_get_u32(tb[FRA_PRIORITY]);
		rule->ce_mask |= RULE_ATTR_PRIO;
	}

	if (tb[FRA_FWMARK]) {
		rule->r_mark = nla_get_u32(tb[FRA_FWMARK]);
		rule->ce_mask |= RULE_ATTR_MARK;
	}

	if (tb[FRA_FWMASK]) {
		rule->r_mask = nla_get_u32(tb[FRA_FWMASK]);
		rule->ce_mask |= RULE_ATTR_MASK;
	}

	if (tb[FRA_GOTO]) {
		rule->r_goto = nla_get_u32(tb[FRA_GOTO]);
		rule->ce_mask |= RULE_ATTR_GOTO;
	}

	if (tb[FRA_SRC]) {
		if (!(rule->r_src = nl_addr_alloc_attr(tb[FRA_SRC], family)))
			goto errout_enomem;

		nl_addr_set_prefixlen(rule->r_src, frh->src_len);
		rule->ce_mask |= RULE_ATTR_SRC;
	}

	if (tb[FRA_DST]) {
		if (!(rule->r_dst = nl_addr_alloc_attr(tb[FRA_DST], family)))
			goto errout_enomem;
		nl_addr_set_prefixlen(rule->r_dst, frh->dst_len);
		rule->ce_mask |= RULE_ATTR_DST;
	}

	/* ipv4 only */
	if (tb[FRA_FLOW]) {
		rule->r_flow = nla_get_u32(tb[FRA_FLOW]);
		rule->ce_mask |= RULE_ATTR_FLOW;
	}

	err = pp->pp_cb((struct nl_object *) rule, pp);
errout:
	rtnl_rule_put(rule);
	return err;

errout_enomem:
	err = -NLE_NOMEM;
	goto errout;
}
コード例 #3
0
static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
			   struct nlmsghdr *n, struct nl_parser_param *pp)
{
	struct rtnl_rule *rule;
	struct rtmsg *r;
	struct nlattr *tb[RTA_MAX+1];
	int err = 1, family;

	rule = rtnl_rule_alloc();
	if (!rule) {
		err = -NLE_NOMEM;
		goto errout;
	}

	rule->ce_msgtype = n->nlmsg_type;
	r = nlmsg_data(n);

	err = nlmsg_parse(n, sizeof(*r), tb, RTA_MAX, rule_policy);
	if (err < 0)
		goto errout;

	rule->r_family = family = r->rtm_family;
	rule->r_type = r->rtm_type;
	rule->r_dsfield = r->rtm_tos;
	rule->r_src_len = r->rtm_src_len;
	rule->r_dst_len = r->rtm_dst_len;
	rule->r_table = r->rtm_table;
	rule->ce_mask = (RULE_ATTR_FAMILY | RULE_ATTR_TYPE | RULE_ATTR_DSFIELD |
			 RULE_ATTR_SRC_LEN | RULE_ATTR_DST_LEN |RULE_ATTR_TYPE |
			 RULE_ATTR_TABLE);

	if (tb[RTA_PRIORITY]) {
		rule->r_prio = nla_get_u32(tb[RTA_PRIORITY]);
		rule->ce_mask |= RULE_ATTR_PRIO;
	}

	if (tb[RTA_SRC]) {
		if (!(rule->r_src = nl_addr_alloc_attr(tb[RTA_SRC], family)))
			goto errout_enomem;
		nl_addr_set_prefixlen(rule->r_src, r->rtm_src_len);
		rule->ce_mask |= RULE_ATTR_SRC;
	}

	if (tb[RTA_DST]) {
		if (!(rule->r_dst = nl_addr_alloc_attr(tb[RTA_DST], family)))
			goto errout_enomem;
		nl_addr_set_prefixlen(rule->r_dst, r->rtm_dst_len);
		rule->ce_mask |= RULE_ATTR_DST;
	}

	if (tb[RTA_PROTOINFO]) {
		rule->r_mark = nla_get_u32(tb[RTA_PROTOINFO]);
		rule->ce_mask |= RULE_ATTR_MARK;
	}

	if (tb[RTA_IIF]) {
		nla_strlcpy(rule->r_iif, tb[RTA_IIF], IFNAMSIZ);
		rule->ce_mask |= RULE_ATTR_IIF;
	}

	if (tb[RTA_FLOW]) {
		rule->r_realms = nla_get_u32(tb[RTA_FLOW]);
		rule->ce_mask |= RULE_ATTR_REALMS;
	}

	if (tb[RTA_GATEWAY]) {
		rule->r_srcmap = nl_addr_alloc_attr(tb[RTA_GATEWAY], family);
		if (!rule->r_srcmap)
			goto errout_enomem;
		rule->ce_mask |= RULE_ATTR_SRCMAP;
	}

	if (tb[RTA_TABLE]) {
            rule->r_table = nla_get_u32(tb[RTA_TABLE]);
            rule->ce_mask |= RULE_ATTR_TABLE;
        }

	err = pp->pp_cb((struct nl_object *) rule, pp);
errout:
	rtnl_rule_put(rule);
	return err;

errout_enomem:
	err = -NLE_NOMEM;
	goto errout;
}