Example #1
0
/**
 * Append new 32-bit key to the selector
 *
 * @arg cls	classifier to be modifier
 * @arg val	value to be matched (network byte-order)
 * @arg mask	mask to be applied before matching (network byte-order)
 * @arg off	offset, in bytes, to start matching
 * @arg offmask	offset mask
 *
 * General selectors define the pattern, mask and offset the pattern will be
 * matched to the packet contents. Using the general selectors you can match
 * virtually any single bit in the IP (or upper layer) header.
 *
*/
int rtnl_u32_add_key(struct rtnl_cls *cls, uint32_t val, uint32_t mask,
		     int off, int offmask)
{
	struct tc_u32_sel *sel;
	struct rtnl_u32 *u;
	int err;

	if (!(u = rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	sel = u32_selector_alloc(u);
	if (!sel)
		return -NLE_NOMEM;

	if (sel->nkeys == UCHAR_MAX)
		return -NLE_NOMEM;

	err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
	if (err < 0)
		return err;

	/* the selector might have been moved by realloc */
	sel = u32_selector(u);

	sel->keys[sel->nkeys].mask = mask;
	sel->keys[sel->nkeys].val = val & mask;
	sel->keys[sel->nkeys].off = off;
	sel->keys[sel->nkeys].offmask = offmask;
	sel->nkeys++;
	u->cu_mask |= U32_ATTR_SELECTOR;

	return 0;
}
Example #2
0
static inline struct tc_u32_sel *u32_selector_alloc(struct rtnl_u32 *u)
{
	if (!u->cu_selector)
		u->cu_selector = nl_data_alloc(NULL, sizeof(struct tc_u32_sel));

	return u32_selector(u);
}
Example #3
0
File: u32.c Project: celebdor/libnl
int rtnl_u32_set_hashmask(struct rtnl_cls *cls, uint32_t hashmask, uint32_t offset)
{
	struct rtnl_u32 *u;
	struct tc_u32_sel *sel;
	int err;

	hashmask = htonl(hashmask);

	if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	sel = u32_selector_alloc(u);
	if (!sel)
		return -NLE_NOMEM;

	err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
	if(err < 0)
		return err;

	sel = u32_selector(u);

	sel->hmask = hashmask;
	sel->hoff = offset;
	return 0;
}
Example #4
0
/**
 * Get the 32-bit key from the selector
 *
 * @arg cls	classifier to be retrieve
 * @arg index	the index of the array of keys, start with 0
 * @arg val	pointer to store value after masked (network byte-order)
 * @arg mask	pointer to store the mask (network byte-order)
 * @arg off	pointer to store the offset
 * @arg offmask	pointer to store offset mask
 *
*/
int rtnl_u32_get_key(struct rtnl_cls *cls, uint8_t index,
		     uint32_t *val, uint32_t *mask, int *off, int *offmask)
{
	struct tc_u32_sel *sel;
	struct rtnl_u32 *u;

	if (!(u = rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	if (!(u->cu_mask & U32_ATTR_SELECTOR))
		return -NLE_INVAL;

	sel = u32_selector(u);
	if (index >= sel->nkeys)
		return -NLE_RANGE;

	*mask = sel->keys[index].mask;
	*val = sel->keys[index].val;
	*off = sel->keys[index].off;
	*offmask = sel->keys[index].offmask;
	return 0;
}
Example #5
0
File: u32.c Project: celebdor/libnl
int rtnl_u32_set_cls_terminal(struct rtnl_cls *cls)
{
	struct rtnl_u32 *u;
	struct tc_u32_sel *sel;
	int err;

	if (!(u = (struct rtnl_u32 *) rtnl_tc_data(TC_CAST(cls))))
		return -NLE_NOMEM;

	sel = u32_selector_alloc(u);
	if (!sel)
		return -NLE_NOMEM;

	err = nl_data_append(u->cu_selector, NULL, sizeof(struct tc_u32_key));
	if(err < 0)
		return err;

	sel = u32_selector(u);

	sel->flags |= TC_U32_TERMINAL;
	return 0;
}