~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/irda/irias_object.c

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*********************************************************************
  2  *
  3  * Filename:      irias_object.c
  4  * Version:       0.3
  5  * Description:   IAS object database and functions
  6  * Status:        Experimental.
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Thu Oct  1 22:50:04 1998
  9  * Modified at:   Wed Dec 15 11:23:16 1999
 10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
 11  *
 12  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
 13  *
 14  *     This program is free software; you can redistribute it and/or
 15  *     modify it under the terms of the GNU General Public License as
 16  *     published by the Free Software Foundation; either version 2 of
 17  *     the License, or (at your option) any later version.
 18  *
 19  *     Neither Dag Brattli nor University of Tromsø admit liability nor
 20  *     provide warranty for any of this software. This material is
 21  *     provided "AS-IS" and at no charge.
 22  *
 23  ********************************************************************/
 24 
 25 #include <linux/slab.h>
 26 #include <linux/string.h>
 27 #include <linux/socket.h>
 28 #include <linux/module.h>
 29 
 30 #include <net/irda/irda.h>
 31 #include <net/irda/irias_object.h>
 32 
 33 hashbin_t *irias_objects;
 34 
 35 /*
 36  *  Used when a missing value needs to be returned
 37  */
 38 struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
 39 
 40 
 41 /*
 42  * Function ias_new_object (name, id)
 43  *
 44  *    Create a new IAS object
 45  *
 46  */
 47 struct ias_object *irias_new_object( char *name, int id)
 48 {
 49         struct ias_object *obj;
 50 
 51         obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
 52         if (obj == NULL) {
 53                 net_warn_ratelimited("%s(), Unable to allocate object!\n",
 54                                      __func__);
 55                 return NULL;
 56         }
 57 
 58         obj->magic = IAS_OBJECT_MAGIC;
 59         obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
 60         if (!obj->name) {
 61                 net_warn_ratelimited("%s(), Unable to allocate name!\n",
 62                                      __func__);
 63                 kfree(obj);
 64                 return NULL;
 65         }
 66         obj->id = id;
 67 
 68         /* Locking notes : the attrib spinlock has lower precendence
 69          * than the objects spinlock. Never grap the objects spinlock
 70          * while holding any attrib spinlock (risk of deadlock). Jean II */
 71         obj->attribs = hashbin_new(HB_LOCK);
 72 
 73         if (obj->attribs == NULL) {
 74                 net_warn_ratelimited("%s(), Unable to allocate attribs!\n",
 75                                      __func__);
 76                 kfree(obj->name);
 77                 kfree(obj);
 78                 return NULL;
 79         }
 80 
 81         return obj;
 82 }
 83 EXPORT_SYMBOL(irias_new_object);
 84 
 85 /*
 86  * Function irias_delete_attrib (attrib)
 87  *
 88  *    Delete given attribute and deallocate all its memory
 89  *
 90  */
 91 static void __irias_delete_attrib(struct ias_attrib *attrib)
 92 {
 93         IRDA_ASSERT(attrib != NULL, return;);
 94         IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
 95 
 96         kfree(attrib->name);
 97 
 98         irias_delete_value(attrib->value);
 99         attrib->magic = ~IAS_ATTRIB_MAGIC;
100 
101         kfree(attrib);
102 }
103 
104 void __irias_delete_object(struct ias_object *obj)
105 {
106         IRDA_ASSERT(obj != NULL, return;);
107         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
108 
109         kfree(obj->name);
110 
111         hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
112 
113         obj->magic = ~IAS_OBJECT_MAGIC;
114 
115         kfree(obj);
116 }
117 
118 /*
119  * Function irias_delete_object (obj)
120  *
121  *    Remove object from hashbin and deallocate all attributes associated with
122  *    with this object and the object itself
123  *
124  */
125 int irias_delete_object(struct ias_object *obj)
126 {
127         struct ias_object *node;
128 
129         IRDA_ASSERT(obj != NULL, return -1;);
130         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
131 
132         /* Remove from list */
133         node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
134         if (!node)
135                 pr_debug("%s(), object already removed!\n",
136                          __func__);
137 
138         /* Destroy */
139         __irias_delete_object(obj);
140 
141         return 0;
142 }
143 EXPORT_SYMBOL(irias_delete_object);
144 
145 /*
146  * Function irias_delete_attrib (obj)
147  *
148  *    Remove attribute from hashbin and, if it was the last attribute of
149  *    the object, remove the object as well.
150  *
151  */
152 int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
153                         int cleanobject)
154 {
155         struct ias_attrib *node;
156 
157         IRDA_ASSERT(obj != NULL, return -1;);
158         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
159         IRDA_ASSERT(attrib != NULL, return -1;);
160 
161         /* Remove attribute from object */
162         node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
163         if (!node)
164                 return 0; /* Already removed or non-existent */
165 
166         /* Deallocate attribute */
167         __irias_delete_attrib(node);
168 
169         /* Check if object has still some attributes, destroy it if none.
170          * At first glance, this look dangerous, as the kernel reference
171          * various IAS objects. However, we only use this function on
172          * user attributes, not kernel attributes, so there is no risk
173          * of deleting a kernel object this way. Jean II */
174         node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
175         if (cleanobject && !node)
176                 irias_delete_object(obj);
177 
178         return 0;
179 }
180 
181 /*
182  * Function irias_insert_object (obj)
183  *
184  *    Insert an object into the LM-IAS database
185  *
186  */
187 void irias_insert_object(struct ias_object *obj)
188 {
189         IRDA_ASSERT(obj != NULL, return;);
190         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
191 
192         hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
193 }
194 EXPORT_SYMBOL(irias_insert_object);
195 
196 /*
197  * Function irias_find_object (name)
198  *
199  *    Find object with given name
200  *
201  */
202 struct ias_object *irias_find_object(char *name)
203 {
204         IRDA_ASSERT(name != NULL, return NULL;);
205 
206         /* Unsafe (locking), object might change */
207         return hashbin_lock_find(irias_objects, 0, name);
208 }
209 EXPORT_SYMBOL(irias_find_object);
210 
211 /*
212  * Function irias_find_attrib (obj, name)
213  *
214  *    Find named attribute in object
215  *
216  */
217 struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
218 {
219         struct ias_attrib *attrib;
220 
221         IRDA_ASSERT(obj != NULL, return NULL;);
222         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
223         IRDA_ASSERT(name != NULL, return NULL;);
224 
225         attrib = hashbin_lock_find(obj->attribs, 0, name);
226         if (attrib == NULL)
227                 return NULL;
228 
229         /* Unsafe (locking), attrib might change */
230         return attrib;
231 }
232 
233 /*
234  * Function irias_add_attribute (obj, attrib)
235  *
236  *    Add attribute to object
237  *
238  */
239 static void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
240                              int owner)
241 {
242         IRDA_ASSERT(obj != NULL, return;);
243         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
244 
245         IRDA_ASSERT(attrib != NULL, return;);
246         IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
247 
248         /* Set if attrib is owned by kernel or user space */
249         attrib->value->owner = owner;
250 
251         hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
252 }
253 
254 /*
255  * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
256  *
257  *    Change the value of an objects attribute.
258  *
259  */
260 int irias_object_change_attribute(char *obj_name, char *attrib_name,
261                                   struct ias_value *new_value)
262 {
263         struct ias_object *obj;
264         struct ias_attrib *attrib;
265         unsigned long flags;
266 
267         /* Find object */
268         obj = hashbin_lock_find(irias_objects, 0, obj_name);
269         if (obj == NULL) {
270                 net_warn_ratelimited("%s: Unable to find object: %s\n",
271                                      __func__, obj_name);
272                 return -1;
273         }
274 
275         /* Slightly unsafe (obj might get removed under us) */
276         spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
277 
278         /* Find attribute */
279         attrib = hashbin_find(obj->attribs, 0, attrib_name);
280         if (attrib == NULL) {
281                 net_warn_ratelimited("%s: Unable to find attribute: %s\n",
282                                      __func__, attrib_name);
283                 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
284                 return -1;
285         }
286 
287         if ( attrib->value->type != new_value->type) {
288                 pr_debug("%s(), changing value type not allowed!\n",
289                          __func__);
290                 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
291                 return -1;
292         }
293 
294         /* Delete old value */
295         irias_delete_value(attrib->value);
296 
297         /* Insert new value */
298         attrib->value = new_value;
299 
300         /* Success */
301         spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
302         return 0;
303 }
304 EXPORT_SYMBOL(irias_object_change_attribute);
305 
306 /*
307  * Function irias_object_add_integer_attrib (obj, name, value)
308  *
309  *    Add an integer attribute to an LM-IAS object
310  *
311  */
312 void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
313                               int owner)
314 {
315         struct ias_attrib *attrib;
316 
317         IRDA_ASSERT(obj != NULL, return;);
318         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
319         IRDA_ASSERT(name != NULL, return;);
320 
321         attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
322         if (attrib == NULL) {
323                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
324                                      __func__);
325                 return;
326         }
327 
328         attrib->magic = IAS_ATTRIB_MAGIC;
329         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
330 
331         /* Insert value */
332         attrib->value = irias_new_integer_value(value);
333         if (!attrib->name || !attrib->value) {
334                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
335                                      __func__);
336                 if (attrib->value)
337                         irias_delete_value(attrib->value);
338                 kfree(attrib->name);
339                 kfree(attrib);
340                 return;
341         }
342 
343         irias_add_attrib(obj, attrib, owner);
344 }
345 EXPORT_SYMBOL(irias_add_integer_attrib);
346 
347  /*
348  * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
349  *
350  *    Add a octet sequence attribute to an LM-IAS object
351  *
352  */
353 
354 void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
355                              int len, int owner)
356 {
357         struct ias_attrib *attrib;
358 
359         IRDA_ASSERT(obj != NULL, return;);
360         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
361 
362         IRDA_ASSERT(name != NULL, return;);
363         IRDA_ASSERT(octets != NULL, return;);
364 
365         attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
366         if (attrib == NULL) {
367                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
368                                      __func__);
369                 return;
370         }
371 
372         attrib->magic = IAS_ATTRIB_MAGIC;
373         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
374 
375         attrib->value = irias_new_octseq_value( octets, len);
376         if (!attrib->name || !attrib->value) {
377                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
378                                      __func__);
379                 if (attrib->value)
380                         irias_delete_value(attrib->value);
381                 kfree(attrib->name);
382                 kfree(attrib);
383                 return;
384         }
385 
386         irias_add_attrib(obj, attrib, owner);
387 }
388 EXPORT_SYMBOL(irias_add_octseq_attrib);
389 
390 /*
391  * Function irias_object_add_string_attrib (obj, string)
392  *
393  *    Add a string attribute to an LM-IAS object
394  *
395  */
396 void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
397                              int owner)
398 {
399         struct ias_attrib *attrib;
400 
401         IRDA_ASSERT(obj != NULL, return;);
402         IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
403 
404         IRDA_ASSERT(name != NULL, return;);
405         IRDA_ASSERT(value != NULL, return;);
406 
407         attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
408         if (attrib == NULL) {
409                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
410                                      __func__);
411                 return;
412         }
413 
414         attrib->magic = IAS_ATTRIB_MAGIC;
415         attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
416 
417         attrib->value = irias_new_string_value(value);
418         if (!attrib->name || !attrib->value) {
419                 net_warn_ratelimited("%s: Unable to allocate attribute!\n",
420                                      __func__);
421                 if (attrib->value)
422                         irias_delete_value(attrib->value);
423                 kfree(attrib->name);
424                 kfree(attrib);
425                 return;
426         }
427 
428         irias_add_attrib(obj, attrib, owner);
429 }
430 EXPORT_SYMBOL(irias_add_string_attrib);
431 
432 /*
433  * Function irias_new_integer_value (integer)
434  *
435  *    Create new IAS integer value
436  *
437  */
438 struct ias_value *irias_new_integer_value(int integer)
439 {
440         struct ias_value *value;
441 
442         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
443         if (value == NULL)
444                 return NULL;
445 
446         value->type = IAS_INTEGER;
447         value->len = 4;
448         value->t.integer = integer;
449 
450         return value;
451 }
452 EXPORT_SYMBOL(irias_new_integer_value);
453 
454 /*
455  * Function irias_new_string_value (string)
456  *
457  *    Create new IAS string value
458  *
459  * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
460  */
461 struct ias_value *irias_new_string_value(char *string)
462 {
463         struct ias_value *value;
464 
465         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
466         if (value == NULL)
467                 return NULL;
468 
469         value->type = IAS_STRING;
470         value->charset = CS_ASCII;
471         value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
472         if (!value->t.string) {
473                 net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__);
474                 kfree(value);
475                 return NULL;
476         }
477 
478         value->len = strlen(value->t.string);
479 
480         return value;
481 }
482 
483 /*
484  * Function irias_new_octseq_value (octets, len)
485  *
486  *    Create new IAS octet-sequence value
487  *
488  * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
489  */
490 struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
491 {
492         struct ias_value *value;
493 
494         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
495         if (value == NULL)
496                 return NULL;
497 
498         value->type = IAS_OCT_SEQ;
499         /* Check length */
500         if(len > IAS_MAX_OCTET_STRING)
501                 len = IAS_MAX_OCTET_STRING;
502         value->len = len;
503 
504         value->t.oct_seq = kmemdup(octseq, len, GFP_ATOMIC);
505         if (value->t.oct_seq == NULL){
506                 net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__);
507                 kfree(value);
508                 return NULL;
509         }
510         return value;
511 }
512 
513 struct ias_value *irias_new_missing_value(void)
514 {
515         struct ias_value *value;
516 
517         value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
518         if (value == NULL)
519                 return NULL;
520 
521         value->type = IAS_MISSING;
522 
523         return value;
524 }
525 
526 /*
527  * Function irias_delete_value (value)
528  *
529  *    Delete IAS value
530  *
531  */
532 void irias_delete_value(struct ias_value *value)
533 {
534         IRDA_ASSERT(value != NULL, return;);
535 
536         switch (value->type) {
537         case IAS_INTEGER: /* Fallthrough */
538         case IAS_MISSING:
539                 /* No need to deallocate */
540                 break;
541         case IAS_STRING:
542                 /* Deallocate string */
543                 kfree(value->t.string);
544                 break;
545         case IAS_OCT_SEQ:
546                 /* Deallocate byte stream */
547                  kfree(value->t.oct_seq);
548                  break;
549         default:
550                 pr_debug("%s(), Unknown value type!\n", __func__);
551                 break;
552         }
553         kfree(value);
554 }
555 EXPORT_SYMBOL(irias_delete_value);
556 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp