request.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * lib/fib_lookup/request.c FIB Lookup Request
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup fib_lookup
  13. * @defgroup flreq Request
  14. * @brief
  15. * @{
  16. */
  17. #include <netlink-private/netlink.h>
  18. #include <netlink/netlink.h>
  19. #include <netlink/attr.h>
  20. #include <netlink/utils.h>
  21. #include <netlink/object.h>
  22. #include <netlink/fib_lookup/request.h>
  23. static struct nl_object_ops request_obj_ops;
  24. /** @cond SKIP */
  25. #define REQUEST_ATTR_ADDR 0x01
  26. #define REQUEST_ATTR_FWMARK 0x02
  27. #define REQUEST_ATTR_TOS 0x04
  28. #define REQUEST_ATTR_SCOPE 0x08
  29. #define REQUEST_ATTR_TABLE 0x10
  30. /** @endcond */
  31. static void request_free_data(struct nl_object *obj)
  32. {
  33. struct flnl_request *req = REQUEST_CAST(obj);
  34. if (req)
  35. nl_addr_put(req->lr_addr);
  36. }
  37. static int request_clone(struct nl_object *_dst, struct nl_object *_src)
  38. {
  39. struct flnl_request *dst = nl_object_priv(_dst);
  40. struct flnl_request *src = nl_object_priv(_src);
  41. if (src->lr_addr)
  42. if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
  43. return -NLE_NOMEM;
  44. return 0;
  45. }
  46. static int request_compare(struct nl_object *_a, struct nl_object *_b,
  47. uint32_t attrs, int flags)
  48. {
  49. struct flnl_request *a = (struct flnl_request *) _a;
  50. struct flnl_request *b = (struct flnl_request *) _b;
  51. int diff = 0;
  52. #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR)
  53. diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark);
  54. diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos);
  55. diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope);
  56. diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table);
  57. diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr));
  58. #undef REQ_DIFF
  59. return diff;
  60. }
  61. /**
  62. * @name Lookup Request Creation/Deletion
  63. * @{
  64. */
  65. struct flnl_request *flnl_request_alloc(void)
  66. {
  67. return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
  68. }
  69. /** @} */
  70. /**
  71. * @name Attributes
  72. * @{
  73. */
  74. void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
  75. {
  76. req->lr_fwmark = fwmark;
  77. req->ce_mask |= REQUEST_ATTR_FWMARK;
  78. }
  79. uint64_t flnl_request_get_fwmark(struct flnl_request *req)
  80. {
  81. if (req->ce_mask & REQUEST_ATTR_FWMARK)
  82. return req->lr_fwmark;
  83. else
  84. return UINT_LEAST64_MAX;
  85. }
  86. void flnl_request_set_tos(struct flnl_request *req, int tos)
  87. {
  88. req->lr_tos = tos;
  89. req->ce_mask |= REQUEST_ATTR_TOS;
  90. }
  91. int flnl_request_get_tos(struct flnl_request *req)
  92. {
  93. if (req->ce_mask & REQUEST_ATTR_TOS)
  94. return req->lr_tos;
  95. else
  96. return -1;
  97. }
  98. void flnl_request_set_scope(struct flnl_request *req, int scope)
  99. {
  100. req->lr_scope = scope;
  101. req->ce_mask |= REQUEST_ATTR_SCOPE;
  102. }
  103. int flnl_request_get_scope(struct flnl_request *req)
  104. {
  105. if (req->ce_mask & REQUEST_ATTR_SCOPE)
  106. return req->lr_scope;
  107. else
  108. return -1;
  109. }
  110. void flnl_request_set_table(struct flnl_request *req, int table)
  111. {
  112. req->lr_table = table;
  113. req->ce_mask |= REQUEST_ATTR_TABLE;
  114. }
  115. int flnl_request_get_table(struct flnl_request *req)
  116. {
  117. if (req->ce_mask & REQUEST_ATTR_TABLE)
  118. return req->lr_table;
  119. else
  120. return -1;
  121. }
  122. int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
  123. {
  124. if (addr->a_family != AF_INET)
  125. return -NLE_AF_NOSUPPORT;
  126. if (req->lr_addr)
  127. nl_addr_put(req->lr_addr);
  128. nl_addr_get(addr);
  129. req->lr_addr = addr;
  130. req->ce_mask |= REQUEST_ATTR_ADDR;
  131. return 0;
  132. }
  133. struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
  134. {
  135. if (req->ce_mask & REQUEST_ATTR_ADDR)
  136. return req->lr_addr;
  137. else
  138. return NULL;
  139. }
  140. /** @} */
  141. static struct nl_object_ops request_obj_ops = {
  142. .oo_name = "fib_lookup/request",
  143. .oo_size = sizeof(struct flnl_request),
  144. .oo_free_data = request_free_data,
  145. .oo_clone = request_clone,
  146. .oo_compare = request_compare,
  147. .oo_id_attrs = ~0,
  148. };
  149. /** @} */