Commit 8f4c1f9b authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

[NETLINK]: Introduce nested and byteorder flag to netlink attribute

This change allows the generic attribute interface to be used within
the netfilter subsystem where this flag was initially introduced.

The byte-order flag is yet unused, it's intended use is to
allow automatic byte order convertions for all atomic types.
Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9d5010db
...@@ -131,6 +131,20 @@ struct nlattr ...@@ -131,6 +131,20 @@ struct nlattr
__u16 nla_type; __u16 nla_type;
}; };
/*
* nla_type (16 bits)
* +---+---+-------------------------------+
* | N | O | Attribute Type |
* +---+---+-------------------------------+
* N := Carries nested attributes
* O := Payload stored in network byte order
*
* Note: The N and O flag are mutually exclusive.
*/
#define NLA_F_NESTED (1 << 15)
#define NLA_F_NET_BYTEORDER (1 << 14)
#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
#define NLA_ALIGNTO 4 #define NLA_ALIGNTO 4
#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
......
...@@ -666,6 +666,15 @@ static inline int nla_padlen(int payload) ...@@ -666,6 +666,15 @@ static inline int nla_padlen(int payload)
return nla_total_size(payload) - nla_attr_size(payload); return nla_total_size(payload) - nla_attr_size(payload);
} }
/**
* nla_type - attribute type
* @nla: netlink attribute
*/
static inline int nla_type(const struct nlattr *nla)
{
return nla->nla_type & NLA_TYPE_MASK;
}
/** /**
* nla_data - head of payload * nla_data - head of payload
* @nla: netlink attribute * @nla: netlink attribute
......
...@@ -487,7 +487,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -487,7 +487,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
} }
nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
switch (attr->nla_type) { switch (nla_type(attr)) {
case RTA_DST: case RTA_DST:
cfg->fc_dst = nla_get_be32(attr); cfg->fc_dst = nla_get_be32(attr);
break; break;
......
...@@ -743,7 +743,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) ...@@ -743,7 +743,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
int remaining; int remaining;
nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
int type = nla->nla_type; int type = nla_type(nla);
if (type) { if (type) {
if (type > RTAX_MAX) if (type > RTAX_MAX)
......
...@@ -1279,7 +1279,7 @@ int ip6_route_add(struct fib6_config *cfg) ...@@ -1279,7 +1279,7 @@ int ip6_route_add(struct fib6_config *cfg)
int remaining; int remaining;
nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
int type = nla->nla_type; int type = nla_type(nla);
if (type) { if (type) {
if (type > RTAX_MAX) { if (type > RTAX_MAX) {
......
...@@ -130,7 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, ...@@ -130,7 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
return -EINVAL; return -EINVAL;
nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem) nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
if (nla->nla_type == NLBL_CIPSOV4_A_TAG) { if (nla_type(nla) == NLBL_CIPSOV4_A_TAG) {
if (iter >= CIPSO_V4_TAG_MAXCNT) if (iter >= CIPSO_V4_TAG_MAXCNT)
return -EINVAL; return -EINVAL;
doi_def->tags[iter++] = nla_get_u8(nla); doi_def->tags[iter++] = nla_get_u8(nla);
...@@ -192,13 +192,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -192,13 +192,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_a, nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
nla_a_rem) nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
if (nla_validate_nested(nla_a, if (nla_validate_nested(nla_a,
NLBL_CIPSOV4_A_MAX, NLBL_CIPSOV4_A_MAX,
netlbl_cipsov4_genl_policy) != 0) netlbl_cipsov4_genl_policy) != 0)
goto add_std_failure; goto add_std_failure;
nla_for_each_nested(nla_b, nla_a, nla_b_rem) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) { switch (nla_type(nla_b)) {
case NLBL_CIPSOV4_A_MLSLVLLOC: case NLBL_CIPSOV4_A_MLSLVLLOC:
if (nla_get_u32(nla_b) > if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_LOC_LVLS) CIPSO_V4_MAX_LOC_LVLS)
...@@ -240,7 +240,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -240,7 +240,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_a, nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
nla_a_rem) nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
struct nlattr *lvl_loc; struct nlattr *lvl_loc;
struct nlattr *lvl_rem; struct nlattr *lvl_rem;
...@@ -265,13 +265,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -265,13 +265,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_a, nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSCATLST], info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
nla_a_rem) nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSCAT) { if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
if (nla_validate_nested(nla_a, if (nla_validate_nested(nla_a,
NLBL_CIPSOV4_A_MAX, NLBL_CIPSOV4_A_MAX,
netlbl_cipsov4_genl_policy) != 0) netlbl_cipsov4_genl_policy) != 0)
goto add_std_failure; goto add_std_failure;
nla_for_each_nested(nla_b, nla_a, nla_b_rem) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) { switch (nla_type(nla_b)) {
case NLBL_CIPSOV4_A_MLSCATLOC: case NLBL_CIPSOV4_A_MLSCATLOC:
if (nla_get_u32(nla_b) > if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_LOC_CATS) CIPSO_V4_MAX_LOC_CATS)
...@@ -315,7 +315,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -315,7 +315,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_a, nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSCATLST], info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
nla_a_rem) nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSCAT) { if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
struct nlattr *cat_loc; struct nlattr *cat_loc;
struct nlattr *cat_rem; struct nlattr *cat_rem;
......
...@@ -27,12 +27,12 @@ static int validate_nla(struct nlattr *nla, int maxtype, ...@@ -27,12 +27,12 @@ static int validate_nla(struct nlattr *nla, int maxtype,
const struct nla_policy *policy) const struct nla_policy *policy)
{ {
const struct nla_policy *pt; const struct nla_policy *pt;
int minlen = 0, attrlen = nla_len(nla); int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);
if (nla->nla_type <= 0 || nla->nla_type > maxtype) if (type <= 0 || type > maxtype)
return 0; return 0;
pt = &policy[nla->nla_type]; pt = &policy[type];
BUG_ON(pt->type > NLA_TYPE_MAX); BUG_ON(pt->type > NLA_TYPE_MAX);
...@@ -149,7 +149,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, ...@@ -149,7 +149,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
nla_for_each_attr(nla, head, len, rem) { nla_for_each_attr(nla, head, len, rem) {
u16 type = nla->nla_type; u16 type = nla_type(nla);
if (type > 0 && type <= maxtype) { if (type > 0 && type <= maxtype) {
if (policy) { if (policy) {
...@@ -185,7 +185,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) ...@@ -185,7 +185,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
int rem; int rem;
nla_for_each_attr(nla, head, len, rem) nla_for_each_attr(nla, head, len, rem)
if (nla->nla_type == attrtype) if (nla_type(nla) == attrtype)
return nla; return nla;
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment