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 (at) suug.ch> 10 */ 11 12 /** 13 * @ingroup fib_lookup 14 * @defgroup flreq Request 15 * @brief 16 * @{ 17 */ 18 19 #include <netlink-local.h> 20 #include <netlink/netlink.h> 21 #include <netlink/attr.h> 22 #include <netlink/utils.h> 23 #include <netlink/object.h> 24 #include <netlink/fib_lookup/request.h> 25 26 static struct nl_object_ops request_obj_ops; 27 28 /** @cond SKIP */ 29 #define REQUEST_ATTR_ADDR 0x01 30 #define REQUEST_ATTR_FWMARK 0x02 31 #define REQUEST_ATTR_TOS 0x04 32 #define REQUEST_ATTR_SCOPE 0x08 33 #define REQUEST_ATTR_TABLE 0x10 34 /** @endcond */ 35 36 static void request_free_data(struct nl_object *obj) 37 { 38 struct flnl_request *req = REQUEST_CAST(obj); 39 40 if (req) 41 nl_addr_put(req->lr_addr); 42 } 43 44 static int request_clone(struct nl_object *_dst, struct nl_object *_src) 45 { 46 struct flnl_request *dst = nl_object_priv(_dst); 47 struct flnl_request *src = nl_object_priv(_src); 48 49 if (src->lr_addr) 50 if (!(dst->lr_addr = nl_addr_clone(src->lr_addr))) 51 return -NLE_NOMEM; 52 53 return 0; 54 } 55 56 static int request_compare(struct nl_object *_a, struct nl_object *_b, 57 uint32_t attrs, int flags) 58 { 59 struct flnl_request *a = (struct flnl_request *) _a; 60 struct flnl_request *b = (struct flnl_request *) _b; 61 int diff = 0; 62 63 #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR) 64 65 diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark); 66 diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos); 67 diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope); 68 diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table); 69 diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)); 70 71 #undef REQ_DIFF 72 73 return diff; 74 } 75 76 77 /** 78 * @name Lookup Request Creation/Deletion 79 * @{ 80 */ 81 82 struct flnl_request *flnl_request_alloc(void) 83 { 84 return REQUEST_CAST(nl_object_alloc(&request_obj_ops)); 85 } 86 87 /** @} */ 88 89 /** 90 * @name Attributes 91 * @{ 92 */ 93 94 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) 95 { 96 req->lr_fwmark = fwmark; 97 req->ce_mask |= REQUEST_ATTR_FWMARK; 98 } 99 100 uint64_t flnl_request_get_fwmark(struct flnl_request *req) 101 { 102 if (req->ce_mask & REQUEST_ATTR_FWMARK) 103 return req->lr_fwmark; 104 else 105 return UINT_LEAST64_MAX; 106 } 107 108 void flnl_request_set_tos(struct flnl_request *req, int tos) 109 { 110 req->lr_tos = tos; 111 req->ce_mask |= REQUEST_ATTR_TOS; 112 } 113 114 int flnl_request_get_tos(struct flnl_request *req) 115 { 116 if (req->ce_mask & REQUEST_ATTR_TOS) 117 return req->lr_tos; 118 else 119 return -1; 120 } 121 122 void flnl_request_set_scope(struct flnl_request *req, int scope) 123 { 124 req->lr_scope = scope; 125 req->ce_mask |= REQUEST_ATTR_SCOPE; 126 } 127 128 int flnl_request_get_scope(struct flnl_request *req) 129 { 130 if (req->ce_mask & REQUEST_ATTR_SCOPE) 131 return req->lr_scope; 132 else 133 return -1; 134 } 135 136 void flnl_request_set_table(struct flnl_request *req, int table) 137 { 138 req->lr_table = table; 139 req->ce_mask |= REQUEST_ATTR_TABLE; 140 } 141 142 int flnl_request_get_table(struct flnl_request *req) 143 { 144 if (req->ce_mask & REQUEST_ATTR_TABLE) 145 return req->lr_table; 146 else 147 return -1; 148 } 149 150 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr) 151 { 152 if (addr->a_family != AF_INET) 153 return -NLE_AF_NOSUPPORT; 154 155 if (req->lr_addr) 156 nl_addr_put(req->lr_addr); 157 158 nl_addr_get(addr); 159 req->lr_addr = addr; 160 161 req->ce_mask |= REQUEST_ATTR_ADDR; 162 163 return 0; 164 } 165 166 struct nl_addr *flnl_request_get_addr(struct flnl_request *req) 167 { 168 if (req->ce_mask & REQUEST_ATTR_ADDR) 169 return req->lr_addr; 170 else 171 return NULL; 172 } 173 174 /** @} */ 175 176 static struct nl_object_ops request_obj_ops = { 177 .oo_name = "fib_lookup/request", 178 .oo_size = sizeof(struct flnl_request), 179 .oo_free_data = request_free_data, 180 .oo_clone = request_clone, 181 .oo_compare = request_compare, 182 .oo_id_attrs = ~0, 183 }; 184 185 /** @} */ 186