Пример #1
0
static int build_rule_snat(int index, const char *address,
				struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct nftnl_expr *expr;
	uint32_t snat;
	int err;

	/*
	 * # nft --debug netlink add rule connman nat-postrouting \
	 *	oif eth0 snat 1.2.3.4
	 *	ip connman nat-postrouting
	 *	  [ meta load oif => reg 1 ]
	 *	  [ cmp eq reg 1 0x0000000b ]
	 *	  [ immediate reg 1 0x04030201 ]
	 *	  [ nat snat ip addr_min reg 1 addr_max reg 0 ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_NAT_POST);

	/* OIF */
	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_OIF);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &index, sizeof(index));
	if (err < 0)
		goto err;

	/* snat */
	expr = nftnl_expr_alloc("immediate");
	if (!expr)
		goto err;
	snat = inet_addr(address);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_1);
	nftnl_expr_set(expr, NFTNL_EXPR_IMM_DATA, &snat, sizeof(snat));
	nftnl_rule_add_expr(rule, expr);

	expr = nftnl_expr_alloc("nat");
        if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_TYPE, NFT_NAT_SNAT);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_FAMILY, NFPROTO_IPV4);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_NAT_REG_ADDR_MIN, NFT_REG_1);
        nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	nftnl_rule_free(rule);
	return -ENOMEM;
}
Пример #2
0
static int rule_delete(struct firewall_handle *handle)
{
	struct nftnl_rule *rule;
	struct mnl_socket *nl;
	int err;

	DBG("");

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, handle->chain);
	nftnl_rule_set_u64(rule, NFTNL_RULE_HANDLE, handle->handle);

	err = socket_open_and_bind(&nl);
	if (err < 0) {
		nftnl_rule_free(rule);
		return err;
	}

	err = rule_cmd(nl, rule, NFT_MSG_DELRULE, NFPROTO_IPV4,
			NLM_F_ACK, 0, NULL);
	nftnl_rule_free(rule);
	mnl_socket_close(nl);

	return err;
}
Пример #3
0
static int build_rule_src_ip(const char *src_ip, uint32_t mark, struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct nftnl_expr *expr;
	int err;
	in_addr_t s_addr;

	/*
	 * # nft --debug netlink add rule connman route-output \
	 *	ip saddr 192.168.10.31 mark set 1234
	 *
	 *	ip connman route-output
	 *	  [ payload load 4b @ network header + 12 => reg 1 ]
	 *	  [ cmp eq reg 1 0x1f0aa8c0 ]
	 *	  [ immediate reg 1 0x000004d2 ]
	 *	  [ meta set mark with reg 1 ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_ROUTE_OUTPUT);

	/* family ipv4 */
	nftnl_rule_set_u32(rule, NFTNL_RULE_FAMILY, NFPROTO_IPV4);

	/* source IP */
	err = add_payload(rule, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
			offsetof(struct iphdr, saddr), sizeof(struct in_addr));
	if (err < 0)
		goto err;

	s_addr = inet_addr(src_ip);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &s_addr, sizeof(s_addr));
	if (err < 0)
		goto err;

	expr = nftnl_expr_alloc("immediate");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_1);
	nftnl_expr_set(expr, NFTNL_EXPR_IMM_DATA, &mark, sizeof(mark));
	nftnl_rule_add_expr(rule, expr);

	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_MARK);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_SREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	return -ENOMEM;
}
Пример #4
0
static int build_rule_marking(uid_t uid, uint32_t mark, struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct nftnl_expr *expr;
	int err;

	/*
	 * http://wiki.nftables.org/wiki-nftables/index.php/Setting_packet_metainformation
	 * http://wiki.nftables.org/wiki-nftables/index.php/Matching_packet_metainformation
	 *
	 * # nft --debug netlink add rule connman route-output	\
	 *	meta skuid wagi mark set 1234
	 *
	 *	ip connman route-output
	 *	  [ meta load skuid => reg 1 ]
	 *	  [ cmp eq reg 1 0x000003e8 ]
	 *	  [ immediate reg 1 0x000004d2 ]
	 *	  [ meta set mark with reg 1 ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_ROUTE_OUTPUT);

	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_SKUID);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &uid, sizeof(uid));
	if (err < 0)
		goto err;

	expr = nftnl_expr_alloc("immediate");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG_1);
	nftnl_expr_set(expr, NFTNL_EXPR_IMM_DATA, &mark, sizeof(mark));
	nftnl_rule_add_expr(rule, expr);

	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_MARK);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_SREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	return -ENOMEM;
}
Пример #5
0
static struct nftnl_rule *setup_rule(uint8_t family, const char *table,
				   const char *chain, const char *handle)
{
	struct nftnl_rule *r = NULL;
	uint8_t proto;
	uint16_t dport;
	uint64_t handle_num;

	r = nftnl_rule_alloc();
	if (r == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}

	nftnl_rule_set(r, NFTNL_RULE_TABLE, table);
	nftnl_rule_set(r, NFTNL_RULE_CHAIN, chain);
	nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);

	if (handle != NULL) {
		handle_num = atoll(handle);
		nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle_num);
	}

	proto = IPPROTO_TCP;
	add_payload(r, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
		    offsetof(struct iphdr, protocol), sizeof(uint8_t));
	add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &proto, sizeof(uint8_t));

	dport = htons(22);
	add_payload(r, NFT_PAYLOAD_TRANSPORT_HEADER, NFT_REG_1,
		    offsetof(struct tcphdr, dest), sizeof(uint16_t));
	add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &dport, sizeof(uint16_t));

	add_counter(r);

	return r;
}
Пример #6
0
static int build_rule_nat(const char *address, unsigned char prefixlen,
				const char *interface, struct nftnl_rule **res)
{
	struct nftnl_rule *rule;
	struct in_addr ipv4_addr, ipv4_mask;
	struct nftnl_expr *expr;
	int err;

	/*
	 * # nft --debug netlink add rule connman nat-postrouting	\
	 *	oifname eth0 ip saddr 10.10.0.0/24 masquerade
	 *
	 *	ip connman nat-postrouting
	 *	  [ meta load oifname => reg 1 ]
	 *	  [ cmp eq reg 1 0x30687465 0x00000000 0x00000000 0x00000000 ]
	 *	  [ payload load 4b @ network header + 12 => reg 1 ]
	 *	  [ bitwise reg 1 = (reg=1 & 0x00ffffff ) ^ 0x00000000 ]
	 *	  [ cmp eq reg 1 0x00000a0a ]
	 *	  [ masq ]
	 */

	rule = nftnl_rule_alloc();
	if (!rule)
		return -ENOMEM;

	nftnl_rule_set(rule, NFTNL_RULE_TABLE, CONNMAN_TABLE);
	nftnl_rule_set(rule, NFTNL_RULE_CHAIN, CONNMAN_CHAIN_NAT_POST);

	/* family ipv4 */
	nftnl_rule_set_u32(rule, NFTNL_RULE_FAMILY, NFPROTO_IPV4);

	/* oifname */
	expr = nftnl_expr_alloc("meta");
	if (!expr)
		goto err;
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_OIFNAME);
	nftnl_expr_set_u32(expr, NFTNL_EXPR_META_DREG, NFT_REG_1);
	nftnl_rule_add_expr(rule, expr);
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, interface,
			strlen(interface) + 1);
	if (err < 0)
		goto err;

	/* source */
	ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
	ipv4_addr.s_addr = inet_addr(address);
	ipv4_addr.s_addr &= ipv4_mask.s_addr;

	err = add_payload(rule, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
			offsetof(struct iphdr, saddr), sizeof(struct in_addr));
	if (err < 0)
		goto err;
	err = add_bitwise(rule, NFT_REG_1, &ipv4_mask.s_addr,
				sizeof(struct in_addr));
	if (err < 0)
		goto err;
	err = add_cmp(rule, NFT_REG_1, NFT_CMP_EQ, &ipv4_addr.s_addr,
			sizeof(struct in_addr));
	if (err < 0)
		goto err;

	/* masquerade */
        expr = nftnl_expr_alloc("masq");
        if (!expr)
		goto err;
        nftnl_rule_add_expr(rule, expr);

	*res = rule;
	return 0;

err:
	nftnl_rule_free(rule);
	return -ENOMEM;
}