request.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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-2006 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup fib_lookup
  13. * @defgroup flreq Request
  14. * @brief
  15. * @{
  16. */
  17. #include <netlink-local.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. goto errout;
  44. return 0;
  45. errout:
  46. return nl_get_errno();
  47. }
  48. static int request_compare(struct nl_object *_a, struct nl_object *_b,
  49. uint32_t attrs, int flags)
  50. {
  51. struct flnl_request *a = (struct flnl_request *) _a;
  52. struct flnl_request *b = (struct flnl_request *) _b;
  53. int diff = 0;
  54. #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR)
  55. diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark);
  56. diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos);
  57. diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope);
  58. diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table);
  59. diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr));
  60. #undef REQ_DIFF
  61. return diff;
  62. }
  63. /**
  64. * @name Lookup Request Creation/Deletion
  65. * @{
  66. */
  67. struct flnl_request *flnl_request_alloc(void)
  68. {
  69. return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
  70. }
  71. /** @} */
  72. /**
  73. * @name Attributes
  74. * @{
  75. */
  76. void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
  77. {
  78. req->lr_fwmark = fwmark;
  79. req->ce_mask |= REQUEST_ATTR_FWMARK;
  80. }
  81. uint64_t flnl_request_get_fwmark(struct flnl_request *req)
  82. {
  83. if (req->ce_mask & REQUEST_ATTR_FWMARK)
  84. return req->lr_fwmark;
  85. else
  86. return UINT_LEAST64_MAX;
  87. }
  88. void flnl_request_set_tos(struct flnl_request *req, int tos)
  89. {
  90. req->lr_tos = tos;
  91. req->ce_mask |= REQUEST_ATTR_TOS;
  92. }
  93. int flnl_request_get_tos(struct flnl_request *req)
  94. {
  95. if (req->ce_mask & REQUEST_ATTR_TOS)
  96. return req->lr_tos;
  97. else
  98. return -1;
  99. }
  100. void flnl_request_set_scope(struct flnl_request *req, int scope)
  101. {
  102. req->lr_scope = scope;
  103. req->ce_mask |= REQUEST_ATTR_SCOPE;
  104. }
  105. int flnl_request_get_scope(struct flnl_request *req)
  106. {
  107. if (req->ce_mask & REQUEST_ATTR_SCOPE)
  108. return req->lr_scope;
  109. else
  110. return -1;
  111. }
  112. void flnl_request_set_table(struct flnl_request *req, int table)
  113. {
  114. req->lr_table = table;
  115. req->ce_mask |= REQUEST_ATTR_TABLE;
  116. }
  117. int flnl_request_get_table(struct flnl_request *req)
  118. {
  119. if (req->ce_mask & REQUEST_ATTR_TABLE)
  120. return req->lr_table;
  121. else
  122. return -1;
  123. }
  124. int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
  125. {
  126. if (addr->a_family != AF_INET)
  127. return nl_error(EINVAL, "Address must be an IPv4 address");
  128. if (req->lr_addr)
  129. nl_addr_put(req->lr_addr);
  130. nl_addr_get(addr);
  131. req->lr_addr = addr;
  132. req->ce_mask |= REQUEST_ATTR_ADDR;
  133. return 0;
  134. }
  135. struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
  136. {
  137. if (req->ce_mask & REQUEST_ATTR_ADDR)
  138. return req->lr_addr;
  139. else
  140. return NULL;
  141. }
  142. /** @} */
  143. static struct nl_object_ops request_obj_ops = {
  144. .oo_name = "fib_lookup/request",
  145. .oo_size = sizeof(struct flnl_request),
  146. .oo_free_data = request_free_data,
  147. .oo_clone = request_clone,
  148. .oo_compare = request_compare,
  149. .oo_id_attrs = ~0,
  150. };
  151. /** @} */