00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <netlink-local.h>
00020 #include <netlink/netlink.h>
00021 #include <netlink/attr.h>
00022 #include <netlink/utils.h>
00023 #include <netlink/object.h>
00024 #include <netlink/fib_lookup/request.h>
00025
00026 static struct nl_object_ops request_obj_ops;
00027
00028
00029 #define REQUEST_ATTR_ADDR 0x01
00030 #define REQUEST_ATTR_FWMARK 0x02
00031 #define REQUEST_ATTR_TOS 0x04
00032 #define REQUEST_ATTR_SCOPE 0x08
00033 #define REQUEST_ATTR_TABLE 0x10
00034
00035
00036 static void request_free_data(struct nl_object *obj)
00037 {
00038 struct flnl_request *req = REQUEST_CAST(obj);
00039
00040 if (req)
00041 nl_addr_put(req->lr_addr);
00042 }
00043
00044 static int request_clone(struct nl_object *_dst, struct nl_object *_src)
00045 {
00046 struct flnl_request *dst = nl_object_priv(_dst);
00047 struct flnl_request *src = nl_object_priv(_src);
00048
00049 if (src->lr_addr)
00050 if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
00051 return -NLE_NOMEM;
00052
00053 return 0;
00054 }
00055
00056 static int request_compare(struct nl_object *_a, struct nl_object *_b,
00057 uint32_t attrs, int flags)
00058 {
00059 struct flnl_request *a = (struct flnl_request *) _a;
00060 struct flnl_request *b = (struct flnl_request *) _b;
00061 int diff = 0;
00062
00063 #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR)
00064
00065 diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark);
00066 diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos);
00067 diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope);
00068 diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table);
00069 diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr));
00070
00071 #undef REQ_DIFF
00072
00073 return diff;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 struct flnl_request *flnl_request_alloc(void)
00083 {
00084 return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
00095 {
00096 req->lr_fwmark = fwmark;
00097 req->ce_mask |= REQUEST_ATTR_FWMARK;
00098 }
00099
00100 uint64_t flnl_request_get_fwmark(struct flnl_request *req)
00101 {
00102 if (req->ce_mask & REQUEST_ATTR_FWMARK)
00103 return req->lr_fwmark;
00104 else
00105 return UINT_LEAST64_MAX;
00106 }
00107
00108 void flnl_request_set_tos(struct flnl_request *req, int tos)
00109 {
00110 req->lr_tos = tos;
00111 req->ce_mask |= REQUEST_ATTR_TOS;
00112 }
00113
00114 int flnl_request_get_tos(struct flnl_request *req)
00115 {
00116 if (req->ce_mask & REQUEST_ATTR_TOS)
00117 return req->lr_tos;
00118 else
00119 return -1;
00120 }
00121
00122 void flnl_request_set_scope(struct flnl_request *req, int scope)
00123 {
00124 req->lr_scope = scope;
00125 req->ce_mask |= REQUEST_ATTR_SCOPE;
00126 }
00127
00128 int flnl_request_get_scope(struct flnl_request *req)
00129 {
00130 if (req->ce_mask & REQUEST_ATTR_SCOPE)
00131 return req->lr_scope;
00132 else
00133 return -1;
00134 }
00135
00136 void flnl_request_set_table(struct flnl_request *req, int table)
00137 {
00138 req->lr_table = table;
00139 req->ce_mask |= REQUEST_ATTR_TABLE;
00140 }
00141
00142 int flnl_request_get_table(struct flnl_request *req)
00143 {
00144 if (req->ce_mask & REQUEST_ATTR_TABLE)
00145 return req->lr_table;
00146 else
00147 return -1;
00148 }
00149
00150 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
00151 {
00152 if (addr->a_family != AF_INET)
00153 return -NLE_AF_NOSUPPORT;
00154
00155 if (req->lr_addr)
00156 nl_addr_put(req->lr_addr);
00157
00158 nl_addr_get(addr);
00159 req->lr_addr = addr;
00160
00161 req->ce_mask |= REQUEST_ATTR_ADDR;
00162
00163 return 0;
00164 }
00165
00166 struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
00167 {
00168 if (req->ce_mask & REQUEST_ATTR_ADDR)
00169 return req->lr_addr;
00170 else
00171 return NULL;
00172 }
00173
00174
00175
00176 static struct nl_object_ops request_obj_ops = {
00177 .oo_name = "fib_lookup/request",
00178 .oo_size = sizeof(struct flnl_request),
00179 .oo_free_data = request_free_data,
00180 .oo_clone = request_clone,
00181 .oo_compare = request_compare,
00182 .oo_id_attrs = ~0,
00183 };
00184
00185