diff options
Diffstat (limited to 'net/netfilter/nfnetlink.c')
-rw-r--r-- | net/netfilter/nfnetlink.c | 39 |
1 files changed, 6 insertions, 33 deletions
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 032224c1409..3cfa76b89a2 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -111,44 +111,17 @@ nfnetlink_find_client(u_int16_t type, const struct nfnetlink_subsystem *ss) | |||
111 | return &ss->cb[cb_id]; | 111 | return &ss->cb[cb_id]; |
112 | } | 112 | } |
113 | 113 | ||
114 | void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen, | ||
115 | const void *data) | ||
116 | { | ||
117 | struct nfattr *nfa; | ||
118 | int size = NFA_LENGTH(attrlen); | ||
119 | |||
120 | nfa = (struct nfattr *)skb_put(skb, NFA_ALIGN(size)); | ||
121 | nfa->nfa_type = attrtype; | ||
122 | nfa->nfa_len = size; | ||
123 | memcpy(NFA_DATA(nfa), data, attrlen); | ||
124 | memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size); | ||
125 | } | ||
126 | EXPORT_SYMBOL_GPL(__nfa_fill); | ||
127 | |||
128 | void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len) | ||
129 | { | ||
130 | memset(tb, 0, sizeof(struct nfattr *) * maxattr); | ||
131 | |||
132 | while (NFA_OK(nfa, len)) { | ||
133 | unsigned flavor = NFA_TYPE(nfa); | ||
134 | if (flavor && flavor <= maxattr) | ||
135 | tb[flavor-1] = nfa; | ||
136 | nfa = NFA_NEXT(nfa, len); | ||
137 | } | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(nfattr_parse); | ||
140 | |||
141 | /** | 114 | /** |
142 | * nfnetlink_check_attributes - check and parse nfnetlink attributes | 115 | * nfnetlink_check_attributes - check and parse nfnetlink attributes |
143 | * | 116 | * |
144 | * subsys: nfnl subsystem for which this message is to be parsed | 117 | * subsys: nfnl subsystem for which this message is to be parsed |
145 | * nlmsghdr: netlink message to be checked/parsed | 118 | * nlmsghdr: netlink message to be checked/parsed |
146 | * cda: array of pointers, needs to be at least subsys->attr_count big | 119 | * cda: array of pointers, needs to be at least subsys->attr_count+1 big |
147 | * | 120 | * |
148 | */ | 121 | */ |
149 | static int | 122 | static int |
150 | nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, | 123 | nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, |
151 | struct nlmsghdr *nlh, struct nfattr *cda[]) | 124 | struct nlmsghdr *nlh, struct nlattr *cda[]) |
152 | { | 125 | { |
153 | int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); | 126 | int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); |
154 | u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); | 127 | u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); |
@@ -156,9 +129,9 @@ nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, | |||
156 | 129 | ||
157 | /* check attribute lengths. */ | 130 | /* check attribute lengths. */ |
158 | if (likely(nlh->nlmsg_len > min_len)) { | 131 | if (likely(nlh->nlmsg_len > min_len)) { |
159 | struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh)); | 132 | struct nlattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); |
160 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | 133 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); |
161 | nfattr_parse(cda, attr_count, attr, attrlen); | 134 | nla_parse(cda, attr_count, attr, attrlen, NULL); |
162 | } | 135 | } |
163 | 136 | ||
164 | /* implicit: if nlmsg_len == min_len, we return 0, and an empty | 137 | /* implicit: if nlmsg_len == min_len, we return 0, and an empty |
@@ -230,9 +203,9 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
230 | { | 203 | { |
231 | u_int16_t attr_count = | 204 | u_int16_t attr_count = |
232 | ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; | 205 | ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; |
233 | struct nfattr *cda[attr_count]; | 206 | struct nlattr *cda[attr_count+1]; |
234 | 207 | ||
235 | memset(cda, 0, sizeof(struct nfattr *) * attr_count); | 208 | memset(cda, 0, sizeof(struct nlattr *) * attr_count); |
236 | 209 | ||
237 | err = nfnetlink_check_attributes(ss, nlh, cda); | 210 | err = nfnetlink_check_attributes(ss, nlh, cda); |
238 | if (err < 0) | 211 | if (err < 0) |