~ubuntu-branches/ubuntu/trusty/libnl3/trusty

« back to all changes in this revision

Viewing changes to lib/route/link/inet.c

  • Committer: Bazaar Package Importer
  • Author(s): Heiko Stuebner
  • Date: 2011-05-21 19:25:13 UTC
  • Revision ID: james.westby@ubuntu.com-20110521192513-1ieyu9w9kym4bt16
Tags: upstream-3.0
ImportĀ upstreamĀ versionĀ 3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/route/link/inet.c        AF_INET link operations
 
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) 2010 Thomas Graf <tgraf@suug.ch>
 
10
 */
 
11
 
 
12
/**
 
13
 * @ingroup link_API
 
14
 * @defgroup link_inet IPv4 Link Module
 
15
 * @brief Implementation of IPv4 specific link attributes
 
16
 *
 
17
 *
 
18
 *
 
19
 * @par Example: Reading the value of IPV4_DEVCONF_FORWARDING
 
20
 * @code
 
21
 * struct nl_cache *cache;
 
22
 * struct rtnl_link *link;
 
23
 * uint32_t value;
 
24
 *
 
25
 * // Allocate a link cache
 
26
 * rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache);
 
27
 *
 
28
 * // Search for the link we wish to see the value from
 
29
 * link = rtnl_link_get_by_name(cache, "eth0");
 
30
 *
 
31
 * // Read the value of the setting IPV4_DEVCONF_FORWARDING
 
32
 * if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_FORWARDING, &value) < 0)
 
33
 *         // Error: Unable to read config setting
 
34
 *
 
35
 * printf("forwarding is %s\n", value ? "enabled" : "disabled");
 
36
 * @endcode
 
37
 *
 
38
 * @par Example: Changing the value of IPV4_DEVCONF_FOWARDING
 
39
 * @code
 
40
 * //
 
41
 * // ... Continueing from the previous example ...
 
42
 * //
 
43
 *
 
44
 * struct rtnl_link *new;
 
45
 *
 
46
 * // Allocate a new link to store the changes we wish to make.
 
47
 * new = rtnl_link_alloc();
 
48
 *
 
49
 * // Set IPV4_DEVCONF_FORWARDING to '1'
 
50
 * rtnl_link_inet_set_conf(new, IPV4_DEVCONF_FORWARDING, 1);
 
51
 *
 
52
 * // Send the change request to the kernel.
 
53
 * rtnl_link_change(sock, link, new, 0);
 
54
 * @endcode
 
55
 *
 
56
 * @{
 
57
 */
 
58
 
 
59
 
 
60
#include <netlink-local.h>
 
61
#include <netlink/netlink.h>
 
62
#include <netlink/attr.h>
 
63
#include <netlink/route/rtnl.h>
 
64
#include <netlink/route/link/api.h>
 
65
 
 
66
/** @cond SKIP */
 
67
struct inet_data
 
68
{
 
69
        uint8_t                 i_confset[IPV4_DEVCONF_MAX];
 
70
        uint32_t                i_conf[IPV4_DEVCONF_MAX];
 
71
};
 
72
/** @endcond */
 
73
 
 
74
static void *inet_alloc(struct rtnl_link *link)
 
75
{
 
76
        return calloc(1, sizeof(struct inet_data));
 
77
}
 
78
 
 
79
static void *inet_clone(struct rtnl_link *link, void *data)
 
80
{
 
81
        struct inet_data *id;
 
82
 
 
83
        if ((id = inet_alloc(link)))
 
84
                memcpy(id, data, sizeof(*id));
 
85
 
 
86
        return id;
 
87
}
 
88
 
 
89
static void inet_free(struct rtnl_link *link, void *data)
 
90
{
 
91
        free(data);
 
92
}
 
93
 
 
94
static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = {
 
95
        [IFLA_INET_CONF]        = { .minlen = IPV4_DEVCONF_MAX * 4 },
 
96
};
 
97
 
 
98
static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data)
 
99
{
 
100
        struct inet_data *id = data;
 
101
        struct nlattr *tb[IFLA_INET_MAX+1];
 
102
        int err;
 
103
 
 
104
        err = nla_parse_nested(tb, IFLA_INET_MAX, attr, inet_policy);
 
105
        if (err < 0)
 
106
                return err;
 
107
 
 
108
        if (tb[IFLA_INET_CONF])
 
109
                nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
 
110
 
 
111
        return 0;
 
112
}
 
113
 
 
114
static int inet_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data)
 
115
{
 
116
        struct inet_data *id = data;
 
117
        struct nlattr *nla;
 
118
        int i;
 
119
 
 
120
        if (!(nla = nla_nest_start(msg, IFLA_INET_CONF)))
 
121
                return -NLE_MSGSIZE;
 
122
 
 
123
        for (i = 0; i < IPV4_DEVCONF_MAX; i++)
 
124
                if (id->i_confset[i])
 
125
                        NLA_PUT_U32(msg, i+1, id->i_conf[i]);
 
126
 
 
127
        nla_nest_end(msg, nla);
 
128
 
 
129
        return 0;
 
130
 
 
131
nla_put_failure:
 
132
        return -NLE_MSGSIZE;
 
133
}
 
134
 
 
135
static const struct trans_tbl inet_devconf[] = {
 
136
        __ADD(IPV4_DEVCONF_FORWARDING, forwarding)
 
137
        __ADD(IPV4_DEVCONF_MC_FORWARDING, mc_forwarding)
 
138
        __ADD(IPV4_DEVCONF_PROXY_ARP, proxy_arp)
 
139
        __ADD(IPV4_DEVCONF_ACCEPT_REDIRECTS, accept_redirects)
 
140
        __ADD(IPV4_DEVCONF_SECURE_REDIRECTS, secure_redirects)
 
141
        __ADD(IPV4_DEVCONF_SEND_REDIRECTS, send_redirects)
 
142
        __ADD(IPV4_DEVCONF_SHARED_MEDIA, shared_media)
 
143
        __ADD(IPV4_DEVCONF_RP_FILTER, rp_filter)
 
144
        __ADD(IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route)
 
145
        __ADD(IPV4_DEVCONF_BOOTP_RELAY, bootp_relay)
 
146
        __ADD(IPV4_DEVCONF_LOG_MARTIANS, log_martians)
 
147
        __ADD(IPV4_DEVCONF_TAG, tag)
 
148
        __ADD(IPV4_DEVCONF_ARPFILTER, arpfilter)
 
149
        __ADD(IPV4_DEVCONF_MEDIUM_ID, medium_id)
 
150
        __ADD(IPV4_DEVCONF_NOXFRM, noxfrm)
 
151
        __ADD(IPV4_DEVCONF_NOPOLICY, nopolicy)
 
152
        __ADD(IPV4_DEVCONF_FORCE_IGMP_VERSION, force_igmp_version)
 
153
        __ADD(IPV4_DEVCONF_ARP_ANNOUNCE, arp_announce)
 
154
        __ADD(IPV4_DEVCONF_ARP_IGNORE, arp_ignore)
 
155
        __ADD(IPV4_DEVCONF_PROMOTE_SECONDARIES, promote_secondaries)
 
156
        __ADD(IPV4_DEVCONF_ARP_ACCEPT, arp_accept)
 
157
        __ADD(IPV4_DEVCONF_ARP_NOTIFY, arp_notify)
 
158
        __ADD(IPV4_DEVCONF_ACCEPT_LOCAL, accept_local)
 
159
        __ADD(IPV4_DEVCONF_SRC_VMARK, src_vmark)
 
160
        __ADD(IPV4_DEVCONF_PROXY_ARP_PVLAN, proxy_arp_pvlan)
 
161
};
 
162
 
 
163
const char *rtnl_link_inet_devconf2str(int type, char *buf, size_t len)
 
164
{
 
165
        return __type2str(type, buf, len, inet_devconf,
 
166
                          ARRAY_SIZE(inet_devconf));
 
167
}
 
168
 
 
169
unsigned int rtnl_link_inet_str2devconf(const char *name)
 
170
{
 
171
        return __str2type(name, inet_devconf, ARRAY_SIZE(inet_devconf));
 
172
}
 
173
 
 
174
static void inet_dump_details(struct rtnl_link *link,
 
175
                              struct nl_dump_params *p, void *data)
 
176
{
 
177
        struct inet_data *id = data;
 
178
        char buf[64];
 
179
        int i, n = 0;
 
180
 
 
181
        nl_dump_line(p, "    ipv4 devconf:\n");
 
182
        nl_dump_line(p, "      ");
 
183
 
 
184
        for (i = 0; i < IPV4_DEVCONF_MAX; i++) {
 
185
                nl_dump_line(p, "%-19s %3u",
 
186
                        rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)),
 
187
                        id->i_conf[i]);
 
188
 
 
189
                if (++n == 3) {
 
190
                        nl_dump(p, "\n");
 
191
                        nl_dump_line(p, "      ");
 
192
                        n = 0;
 
193
                } else
 
194
                        nl_dump(p, "  ");
 
195
        }
 
196
 
 
197
        if (n != 0)
 
198
                nl_dump(p, "\n");
 
199
}
 
200
 
 
201
static struct rtnl_link_af_ops inet_ops = {
 
202
        .ao_family                      = AF_INET,
 
203
        .ao_alloc                       = &inet_alloc,
 
204
        .ao_clone                       = &inet_clone,
 
205
        .ao_free                        = &inet_free,
 
206
        .ao_parse_af                    = &inet_parse_af,
 
207
        .ao_fill_af                     = &inet_fill_af,
 
208
        .ao_dump[NL_DUMP_DETAILS]       = &inet_dump_details,
 
209
};
 
210
 
 
211
/**
 
212
 * Get value of a ipv4 link configuration setting
 
213
 * @arg link            Link object
 
214
 * @arg cfgid           Configuration identifier
 
215
 * @arg res             Result pointer
 
216
 *
 
217
 * Stores the value of the specified configuration setting in the provided
 
218
 * result pointer.
 
219
 *
 
220
 * @return 0 on success or a negative error code.
 
221
 * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX
 
222
 * @return -NLE_NOATTR configuration setting not available
 
223
 */
 
224
int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 
225
                            uint32_t *res)
 
226
{
 
227
        struct inet_data *id;
 
228
 
 
229
        if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX)
 
230
                return -NLE_RANGE;
 
231
 
 
232
        if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
 
233
                return -NLE_NOATTR;
 
234
 
 
235
        *res = id->i_conf[cfgid - 1];
 
236
 
 
237
        return 0;
 
238
}
 
239
 
 
240
/**
 
241
 * Change value of a ipv4 link configuration setting
 
242
 * @arg link            Link object
 
243
 * @arg cfgid           Configuration identifier
 
244
 * @arg value           New value
 
245
 *
 
246
 * Changes the value in the per link ipv4 configuration array. 
 
247
 *
 
248
 * @return 0 on success or a negative error code.
 
249
 * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX
 
250
 * @return -NLE_NOMEM memory allocation failed
 
251
 */
 
252
int rtnl_link_inet_set_conf(struct rtnl_link *link, const unsigned int cfgid,
 
253
                            uint32_t value)
 
254
{
 
255
        struct inet_data *id;
 
256
 
 
257
        if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
 
258
                return -NLE_NOMEM;
 
259
 
 
260
        if (cfgid == 0 || cfgid > IPV4_DEVCONF_MAX)
 
261
                return -NLE_RANGE;
 
262
 
 
263
        id->i_confset[cfgid - 1] = 1;
 
264
        id->i_conf[cfgid - 1] = value;
 
265
 
 
266
        return 0;
 
267
}
 
268
 
 
269
 
 
270
static void __init inet_init(void)
 
271
{
 
272
        rtnl_link_af_register(&inet_ops);
 
273
}
 
274
 
 
275
static void __exit inet_exit(void)
 
276
{
 
277
        rtnl_link_af_unregister(&inet_ops);
 
278
}
 
279
 
 
280
/** @} */