libnl 1.1

lib/fib_lookup/request.c

00001 /*
00002  * lib/fib_lookup/request.c     FIB Lookup Request
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup fib_lookup
00014  * @defgroup flreq Request
00015  * @brief
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 /** @cond SKIP */
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 /** @endcond */
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                         goto errout;
00052 
00053         return 0;
00054 errout:
00055         return nl_get_errno();
00056 }
00057 
00058 static int request_compare(struct nl_object *_a, struct nl_object *_b,
00059                            uint32_t attrs, int flags)
00060 {
00061         struct flnl_request *a = (struct flnl_request *) _a;
00062         struct flnl_request *b = (struct flnl_request *) _b;
00063         int diff = 0;
00064 
00065 #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR)
00066 
00067         diff |= REQ_DIFF(FWMARK,        a->lr_fwmark != b->lr_fwmark);
00068         diff |= REQ_DIFF(TOS,           a->lr_tos != b->lr_tos);
00069         diff |= REQ_DIFF(SCOPE,         a->lr_scope != b->lr_scope);
00070         diff |= REQ_DIFF(TABLE,         a->lr_table != b->lr_table);
00071         diff |= REQ_DIFF(ADDR,          nl_addr_cmp(a->lr_addr, b->lr_addr));
00072 
00073 #undef REQ_DIFF
00074 
00075         return diff;
00076 }
00077 
00078 
00079 /**
00080  * @name Lookup Request Creation/Deletion
00081  * @{
00082  */
00083 
00084 struct flnl_request *flnl_request_alloc(void)
00085 {
00086         return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
00087 }
00088 
00089 /** @} */
00090 
00091 /**
00092  * @name Attributes
00093  * @{
00094  */
00095 
00096 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
00097 {
00098         req->lr_fwmark = fwmark;
00099         req->ce_mask |= REQUEST_ATTR_FWMARK;
00100 }
00101 
00102 uint64_t flnl_request_get_fwmark(struct flnl_request *req)
00103 {
00104         if (req->ce_mask & REQUEST_ATTR_FWMARK)
00105                 return req->lr_fwmark;
00106         else
00107                 return UINT_LEAST64_MAX;
00108 }
00109 
00110 void flnl_request_set_tos(struct flnl_request *req, int tos)
00111 {
00112         req->lr_tos = tos;
00113         req->ce_mask |= REQUEST_ATTR_TOS;
00114 }
00115 
00116 int flnl_request_get_tos(struct flnl_request *req)
00117 {
00118         if (req->ce_mask & REQUEST_ATTR_TOS)
00119                 return req->lr_tos;
00120         else
00121                 return -1;
00122 }
00123 
00124 void flnl_request_set_scope(struct flnl_request *req, int scope)
00125 {
00126         req->lr_scope = scope;
00127         req->ce_mask |= REQUEST_ATTR_SCOPE;
00128 }
00129 
00130 int flnl_request_get_scope(struct flnl_request *req)
00131 {
00132         if (req->ce_mask & REQUEST_ATTR_SCOPE)
00133                 return req->lr_scope;
00134         else
00135                 return -1;
00136 }
00137 
00138 void flnl_request_set_table(struct flnl_request *req, int table)
00139 {
00140         req->lr_table = table;
00141         req->ce_mask |= REQUEST_ATTR_TABLE;
00142 }
00143 
00144 int flnl_request_get_table(struct flnl_request *req)
00145 {
00146         if (req->ce_mask & REQUEST_ATTR_TABLE)
00147                 return req->lr_table;
00148         else
00149                 return -1;
00150 }
00151 
00152 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
00153 {
00154         if (addr->a_family != AF_INET)
00155                 return nl_error(EINVAL, "Address must be an IPv4 address");
00156 
00157         if (req->lr_addr)
00158                 nl_addr_put(req->lr_addr);
00159 
00160         nl_addr_get(addr);
00161         req->lr_addr = addr;
00162 
00163         req->ce_mask |= REQUEST_ATTR_ADDR;
00164 
00165         return 0;
00166 }
00167 
00168 struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
00169 {
00170         if (req->ce_mask & REQUEST_ATTR_ADDR)
00171                 return req->lr_addr;
00172         else
00173                 return NULL;
00174 }
00175 
00176 /** @} */
00177 
00178 static struct nl_object_ops request_obj_ops = {
00179         .oo_name                = "fib_lookup/request",
00180         .oo_size                = sizeof(struct flnl_request),
00181         .oo_free_data           = request_free_data,
00182         .oo_clone               = request_clone,
00183         .oo_compare             = request_compare,
00184         .oo_id_attrs            = ~0,
00185 };
00186 
00187 /** @} */