Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xfrm: Add support for xfrm interface ID in xfrm state #413

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/netlink/xfrm/sa.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ extern int xfrmnl_sa_set_coaddr (struct xfrmnl_sa*, struct
extern int xfrmnl_sa_get_mark (struct xfrmnl_sa*, unsigned int*, unsigned int*);
extern int xfrmnl_sa_set_mark (struct xfrmnl_sa*, unsigned int, unsigned int);

extern int xfrmnl_sa_get_if_id (struct xfrmnl_sa*, uint32_t*);
extern int xfrmnl_sa_set_if_id (struct xfrmnl_sa*, uint32_t);

extern int xfrmnl_sa_get_sec_ctx (struct xfrmnl_sa*, unsigned int*, unsigned int*,
unsigned int*, unsigned int*, char*);
extern int xfrmnl_sa_set_sec_ctx (struct xfrmnl_sa*, unsigned int, unsigned int,
Expand Down
3 changes: 3 additions & 0 deletions include/netlink/xfrm/sp.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ extern struct xfrmnl_user_tmpl* xfrmnl_sp_usertemplate_n(struct xfrmnl_sp*, int)
extern int xfrmnl_sp_get_mark (struct xfrmnl_sp*, unsigned int*, unsigned int*);
extern int xfrmnl_sp_set_mark (struct xfrmnl_sp*, unsigned int, unsigned int);

extern int xfrmnl_sp_get_if_id (struct xfrmnl_sp*, uint32_t*);
extern int xfrmnl_sp_set_if_id (struct xfrmnl_sp*, uint32_t);

extern char* xfrmnl_sp_action2str(int, char *, size_t);
extern int xfrmnl_sp_str2action(const char *);

Expand Down
38 changes: 38 additions & 0 deletions lib/xfrm/sa.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ struct xfrmnl_sa {
uint32_t seq;
uint32_t reqid;
uint16_t family;
uint32_t if_id;
uint8_t mode; /* XFRM_MODE_xxx */
uint8_t replay_window;
uint8_t flags;
Expand Down Expand Up @@ -157,6 +158,7 @@ struct xfrmnl_sa {
#define XFRM_SA_ATTR_REPLAY_STATE 0x2000000
#define XFRM_SA_ATTR_EXPIRE 0x4000000
#define XFRM_SA_ATTR_OFFLOAD_DEV 0x8000000
#define XFRM_SA_ATTR_IF_ID 0x10000000

static struct nl_cache_ops xfrmnl_sa_ops;
static struct nl_object_ops xfrm_sa_obj_ops;
Expand Down Expand Up @@ -360,6 +362,7 @@ static uint64_t xfrm_sa_compare(struct nl_object *_a, struct nl_object *_b,
diff |= _DIFF(XFRM_SA_ATTR_COADDR, nl_addr_cmp(a->coaddr, b->coaddr));
diff |= _DIFF(XFRM_SA_ATTR_MARK,
(a->mark.m != b->mark.m) || (a->mark.v != b->mark.v));
diff |= _DIFF(XFRM_SA_ATTR_IF_ID, a->if_id != b->if_id);
diff |= _DIFF(XFRM_SA_ATTR_SECCTX,
((a->sec_ctx->ctx_doi != b->sec_ctx->ctx_doi) ||
(a->sec_ctx->ctx_alg != b->sec_ctx->ctx_alg) ||
Expand Down Expand Up @@ -439,6 +442,7 @@ static const struct trans_tbl sa_attrs[] = {
__ADD(XFRM_SA_ATTR_REPLAY_STATE, replay_state),
__ADD(XFRM_SA_ATTR_EXPIRE, expire),
__ADD(XFRM_SA_ATTR_OFFLOAD_DEV, user_offload),
__ADD(XFRM_SA_ATTR_IF_ID, if_id),
};

static char* xfrm_sa_attrs2str(int attrs, char *buf, size_t len)
Expand Down Expand Up @@ -622,6 +626,9 @@ static void xfrm_sa_dump_line(struct nl_object *a, struct nl_dump_params *p)
if (sa->ce_mask & XFRM_SA_ATTR_MARK)
nl_dump_line(p, "\tMark mask: 0x%x Mark value: 0x%x\n", sa->mark.m, sa->mark.v);

if (sa->ce_mask & XFRM_SA_ATTR_IF_ID)
nl_dump_line(p, "\tXFRM interface ID: 0x%x\n", sa->if_id);

if (sa->ce_mask & XFRM_SA_ATTR_SECCTX)
nl_dump_line(p, "\tDOI: %d Algo: %d Len: %u ctx: %s\n", sa->sec_ctx->ctx_doi,
sa->sec_ctx->ctx_alg, sa->sec_ctx->ctx_len, sa->sec_ctx->ctx);
Expand Down Expand Up @@ -763,6 +770,7 @@ static struct nla_policy xfrm_sa_policy[XFRMA_MAX+1] = {
[XFRMA_MARK] = { .minlen = sizeof(struct xfrm_mark) },
[XFRMA_TFCPAD] = { .type = NLA_U32 },
[XFRMA_REPLAY_ESN_VAL] = { .minlen = sizeof(struct xfrm_replay_state_esn) },
[XFRMA_IF_ID] = { .type = NLA_U32 },
};

static int xfrm_sa_request_update(struct nl_cache *c, struct nl_sock *h)
Expand Down Expand Up @@ -1006,6 +1014,11 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
sa->ce_mask |= XFRM_SA_ATTR_OFFLOAD_DEV;
}

if (tb[XFRMA_IF_ID]) {
sa->if_id = nla_get_u32(tb[XFRMA_IF_ID]);
sa->ce_mask |= XFRM_SA_ATTR_IF_ID;
thom311 marked this conversation as resolved.
Show resolved Hide resolved
}

*result = _nl_steal_pointer(&sa);
return 0;
}
Expand Down Expand Up @@ -1365,6 +1378,10 @@ static int build_xfrm_sa_message(struct xfrmnl_sa *tmpl, int cmd, int flags, str
offload->flags = tmpl->user_offload->flags;
}

if (tmpl->ce_mask & XFRM_SA_ATTR_IF_ID) {
NLA_PUT_U32 (msg, XFRMA_IF_ID, tmpl->if_id);
}

*result = msg;
return 0;

Expand Down Expand Up @@ -1700,6 +1717,27 @@ int xfrmnl_sa_set_family (struct xfrmnl_sa* sa, unsigned int family)
return 0;
}

int xfrmnl_sa_get_if_id (struct xfrmnl_sa* sa, uint32_t* if_id)
{
if (if_id == NULL)
return -NLE_INVAL;

if (!(sa->ce_mask & XFRM_SA_ATTR_IF_ID))
return -NLE_NOATTR;

*if_id = sa->if_id;

return 0;
}

int xfrmnl_sa_set_if_id (struct xfrmnl_sa* sa, uint32_t if_id)
{
sa->if_id = if_id;
sa->ce_mask |= XFRM_SA_ATTR_IF_ID;

return 0;
}

int xfrmnl_sa_get_mode (struct xfrmnl_sa* sa)
{
if (sa->ce_mask & XFRM_SA_ATTR_MODE)
Expand Down
43 changes: 43 additions & 0 deletions lib/xfrm/sp.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct xfrmnl_sp {
uint32_t nr_user_tmpl;
struct nl_list_head usertmpl_list;
struct xfrmnl_mark mark;
uint32_t if_id;
};

/** @cond SKIP */
Expand All @@ -96,6 +97,7 @@ struct xfrmnl_sp {
#define XFRM_SP_ATTR_SECCTX 0x400
#define XFRM_SP_ATTR_TMPL 0x800
#define XFRM_SP_ATTR_MARK 0x1000
#define XFRM_SP_ATTR_IF_ID 0x2000

static struct nl_cache_ops xfrmnl_sp_ops;
static struct nl_object_ops xfrm_sp_obj_ops;
Expand Down Expand Up @@ -206,6 +208,7 @@ static uint64_t xfrm_sp_compare(struct nl_object *_a, struct nl_object *_b,
diff |= _DIFF(XFRM_SP_ATTR_TMPL, (a->nr_user_tmpl != b->nr_user_tmpl));
diff |= _DIFF(XFRM_SP_ATTR_MARK,
(a->mark.m != b->mark.m) || (a->mark.v != b->mark.v));
diff |= _DIFF(XFRM_SP_ATTR_IF_ID, a->if_id != b->if_id);

/* Compare the templates */
nl_list_for_each_entry(tmpl_b, &b->usertmpl_list, utmpl_list)
Expand Down Expand Up @@ -234,6 +237,7 @@ static const struct trans_tbl sp_attrs[] = {
__ADD(XFRM_SP_ATTR_SECCTX, security_context),
__ADD(XFRM_SP_ATTR_TMPL, user_template),
__ADD(XFRM_SP_ATTR_MARK, mark),
__ADD(XFRM_SP_ATTR_IF_ID, if_id),
};

static char* xfrm_sp_attrs2str(int attrs, char *buf, size_t len)
Expand Down Expand Up @@ -467,6 +471,10 @@ static void xfrm_sp_dump_line(struct nl_object *a, struct nl_dump_params *p)
if (sp->ce_mask & XFRM_SP_ATTR_MARK)
nl_dump_line(p, "\tMark mask: 0x%x Mark value: 0x%x\n", sp->mark.m, sp->mark.v);


if (sp->ce_mask & XFRM_SP_ATTR_IF_ID)
nl_dump_line(p, "\tXFRM interface ID: 0x%x\n", sp->if_id);

nl_dump(p, "\n");
}

Expand Down Expand Up @@ -555,6 +563,7 @@ static struct nla_policy xfrm_sp_policy[XFRMA_MAX+1] = {
[XFRMA_TMPL] = { .minlen = sizeof(struct xfrm_user_tmpl) },
[XFRMA_POLICY_TYPE] = { .minlen = sizeof(struct xfrm_userpolicy_type)},
[XFRMA_MARK] = { .minlen = sizeof(struct xfrm_mark) },
[XFRMA_IF_ID] = { .type = NLA_U32 },
};

static int xfrm_sp_request_update(struct nl_cache *c, struct nl_sock *h)
Expand Down Expand Up @@ -695,6 +704,11 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
sp->ce_mask |= XFRM_SP_ATTR_MARK;
}

if (tb[XFRMA_IF_ID]) {
sp->if_id = nla_get_u32(tb[XFRMA_IF_ID]);
sp->ce_mask |= XFRM_SP_ATTR_IF_ID;
}

*result = _nl_steal_pointer(&sp);
return 0;
}
Expand Down Expand Up @@ -902,6 +916,10 @@ static int build_xfrm_sp_message(struct xfrmnl_sp *tmpl, int cmd, int flags, str
NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrm_mark), &tmpl->mark);
}

if (tmpl->ce_mask & XFRM_SP_ATTR_IF_ID) {
NLA_PUT_U32 (msg, XFRMA_IF_ID, tmpl->if_id);
}

*result = msg;
return 0;

Expand Down Expand Up @@ -1029,6 +1047,10 @@ static int build_xfrm_sp_delete_message(struct xfrmnl_sp *tmpl, int cmd, int fla
NLA_PUT (msg, XFRMA_MARK, len, &tmpl->mark);
}

if (tmpl->ce_mask & XFRM_SP_ATTR_IF_ID) {
NLA_PUT_U32 (msg, XFRMA_IF_ID, tmpl->if_id);
}

*result = msg;
return 0;

Expand Down Expand Up @@ -1408,6 +1430,27 @@ int xfrmnl_sp_set_mark (struct xfrmnl_sp* sp, unsigned int value, unsigned int m
return 0;
}

int xfrmnl_sp_get_if_id (struct xfrmnl_sp* sp, uint32_t* if_id)
{
if (if_id == NULL)
return -NLE_INVAL;

if (!(sp->ce_mask & XFRM_SP_ATTR_IF_ID))
return -NLE_NOATTR;

*if_id = sp->if_id;

return 0;
}

int xfrmnl_sp_set_if_id (struct xfrmnl_sp* sp, uint32_t if_id)
{
sp->if_id = if_id;
sp->ce_mask |= XFRM_SP_ATTR_IF_ID;

return 0;
}

/** @} */

static struct nl_object_ops xfrm_sp_obj_ops = {
Expand Down
7 changes: 7 additions & 0 deletions libnl-xfrm-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,10 @@ libnl_3_6 {
xfrmnl_sa_get_user_offload;
xfrmnl_sa_set_user_offload;
} libnl_3;

libnl_3_12 {
xfrmnl_sa_get_if_id;
xfrmnl_sa_set_if_id;
xfrmnl_sp_get_if_id;
xfrmnl_sp_set_if_id;
} libnl_3_6;