Initial import package libnl: Convenience library for kernel netlink sockets
[external/libnl.git] / lib / route / addr.c
1 /*
2  * lib/route/addr.c             Addresses
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  *                         Baruch Even <baruch@ev-en.org>,
11  *                         Mediatrix Telecom, inc. <ericb@mediatrix.com>
12  */
13
14 /**
15  * @ingroup rtnl
16  * @defgroup rtaddr Addresses
17  * @brief
18  *
19  * @note The maximum size of an address label is IFNAMSIZ.
20  *
21  * @note The address may not contain a prefix length if the peer address
22  *       has been specified already.
23  *
24  * @par 1) Address Addition
25  * @code
26  * // Allocate an empty address object to be filled out with the attributes
27  * // of the new address.
28  * struct rtnl_addr *addr = rtnl_addr_alloc();
29  *
30  * // Fill out the mandatory attributes of the new address. Setting the
31  * // local address will automatically set the address family and the
32  * // prefix length to the correct values.
33  * rtnl_addr_set_ifindex(addr, ifindex);
34  * rtnl_addr_set_local(addr, local_addr);
35  *
36  * // The label of the address can be specified, currently only supported
37  * // by IPv4 and DECnet.
38  * rtnl_addr_set_label(addr, "mylabel");
39  *
40  * // The peer address can be specified if necessary, in either case a peer
41  * // address will be sent to the kernel in order to fullfil the interface
42  * // requirements. If none is set, it will equal the local address.
43  * // Note: Real peer addresses are only supported by IPv4 for now.
44  * rtnl_addr_set_peer(addr, peer_addr);
45  *
46  * // In case you want to have the address have a scope other than global
47  * // it may be overwritten using rtnl_addr_set_scope(). The scope currently
48  * // cannot be set for IPv6 addresses.
49  * rtnl_addr_set_scope(addr, rtnl_str2scope("site"));
50  *
51  * // Broadcast and anycast address may be specified using the relevant
52  * // functions, the address family will be verified if one of the other
53  * // addresses has been set already. Currently only works for IPv4.
54  * rtnl_addr_set_broadcast(addr, broadcast_addr);
55  * rtnl_addr_set_anycast(addr, anycast_addr);
56  *
57  * // Build the netlink message and send it to the kernel, the operation will
58  * // block until the operation has been completed. Alternatively the required
59  * // netlink message can be built using rtnl_addr_build_add_request() to be
60  * // sent out using nl_send_auto_complete().
61  * rtnl_addr_add(handle, addr, 0);
62  *
63  * // Free the memory
64  * rtnl_addr_put(addr);
65  * @endcode
66  *
67  * @par 2) Address Deletion
68  * @code
69  * // Allocate an empty address object to be filled out with the attributes
70  * // matching the address to be deleted. Alternatively a fully equipped
71  * // address object out of a cache can be used instead.
72  * struct rtnl_addr *addr = rtnl_addr_alloc();
73  *
74  * // The only mandatory parameter besides the address family is the interface
75  * // index the address is on, i.e. leaving out all other parameters will
76  * // result in all addresses of the specified address family interface tuple
77  * // to be deleted.
78  * rtnl_addr_set_ifindex(addr, ifindex);
79  *
80  * // Specyfing the address family manually is only required if neither the
81  * // local nor peer address have been specified.
82  * rtnl_addr_set_family(addr, AF_INET);
83  *
84  * // Specyfing the local address is optional but the best choice to delete
85  * // specific addresses.
86  * rtnl_addr_set_local(addr, local_addr);
87  *
88  * // The label of the address can be specified, currently only supported
89  * // by IPv4 and DECnet.
90  * rtnl_addr_set_label(addr, "mylabel");
91  *
92  * // The peer address can be specified if necessary, in either case a peer
93  * // address will be sent to the kernel in order to fullfil the interface
94  * // requirements. If none is set, it will equal the local address.
95  * // Note: Real peer addresses are only supported by IPv4 for now.
96  * rtnl_addr_set_peer(addr, peer_addr);
97  *
98  * // Build the netlink message and send it to the kernel, the operation will
99  * // block until the operation has been completed. Alternatively the required
100  * // netlink message can be built using rtnl_addr_build_delete_request()
101  * // to be sent out using nl_send_auto_complete().
102  * rtnl_addr_delete(handle, addr, 0);
103  *
104  * // Free the memory
105  * rtnl_addr_put(addr);
106  * @endcode
107  * @{
108  */
109
110 #include <netlink-local.h>
111 #include <netlink/netlink.h>
112 #include <netlink/route/rtnl.h>
113 #include <netlink/route/addr.h>
114 #include <netlink/route/route.h>
115 #include <netlink/route/link.h>
116 #include <netlink/utils.h>
117
118 /** @cond SKIP */
119 #define ADDR_ATTR_FAMILY        0x0001
120 #define ADDR_ATTR_PREFIXLEN     0x0002
121 #define ADDR_ATTR_FLAGS         0x0004
122 #define ADDR_ATTR_SCOPE         0x0008
123 #define ADDR_ATTR_IFINDEX       0x0010
124 #define ADDR_ATTR_LABEL         0x0020
125 #define ADDR_ATTR_CACHEINFO     0x0040
126 #define ADDR_ATTR_PEER          0x0080
127 #define ADDR_ATTR_LOCAL         0x0100
128 #define ADDR_ATTR_BROADCAST     0x0200
129 #define ADDR_ATTR_ANYCAST       0x0400
130 #define ADDR_ATTR_MULTICAST     0x0800
131
132 static struct nl_cache_ops rtnl_addr_ops;
133 static struct nl_object_ops addr_obj_ops;
134 /** @endcond */
135
136 static void addr_free_data(struct nl_object *obj)
137 {
138         struct rtnl_addr *addr = nl_object_priv(obj);
139
140         if (!addr)
141                 return;
142
143         nl_addr_put(addr->a_peer);
144         nl_addr_put(addr->a_local);
145         nl_addr_put(addr->a_bcast);
146         nl_addr_put(addr->a_anycast);
147         nl_addr_put(addr->a_multicast);
148 }
149
150 static int addr_clone(struct nl_object *_dst, struct nl_object *_src)
151 {
152         struct rtnl_addr *dst = nl_object_priv(_dst);
153         struct rtnl_addr *src = nl_object_priv(_src);
154
155         if (src->a_peer)
156                 if (!(dst->a_peer = nl_addr_clone(src->a_peer)))
157                         goto errout;
158         
159         if (src->a_local)
160                 if (!(dst->a_local = nl_addr_clone(src->a_local)))
161                         goto errout;
162
163         if (src->a_bcast)
164                 if (!(dst->a_bcast = nl_addr_clone(src->a_bcast)))
165                         goto errout;
166
167         if (src->a_anycast)
168                 if (!(dst->a_anycast = nl_addr_clone(src->a_anycast)))
169                         goto errout;
170
171         if (src->a_multicast)
172                 if (!(dst->a_multicast = nl_addr_clone(src->a_multicast)))
173                         goto errout;
174
175         return 0;
176 errout:
177         return nl_get_errno();
178 }
179
180 static struct nla_policy addr_policy[IFA_MAX+1] = {
181         [IFA_LABEL]     = { .type = NLA_STRING,
182                             .maxlen = IFNAMSIZ },
183         [IFA_CACHEINFO] = { .minlen = sizeof(struct ifa_cacheinfo) },
184 };
185
186 static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
187                            struct nlmsghdr *nlh, struct nl_parser_param *pp)
188 {
189         struct rtnl_addr *addr;
190         struct ifaddrmsg *ifa;
191         struct nlattr *tb[IFA_MAX+1];
192         int err = -ENOMEM, peer_prefix = 0;
193
194         addr = rtnl_addr_alloc();
195         if (!addr) {
196                 err = nl_errno(ENOMEM);
197                 goto errout;
198         }
199         addr->ce_msgtype = nlh->nlmsg_type;
200
201         err = nlmsg_parse(nlh, sizeof(*ifa), tb, IFA_MAX, addr_policy);
202         if (err < 0)
203                 goto errout_free;
204
205         ifa = nlmsg_data(nlh);
206         addr->a_family = ifa->ifa_family;
207         addr->a_prefixlen = ifa->ifa_prefixlen;
208         addr->a_flags = ifa->ifa_flags;
209         addr->a_scope = ifa->ifa_scope;
210         addr->a_ifindex = ifa->ifa_index;
211
212         addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN |
213                          ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX);
214
215         if (tb[IFA_LABEL]) {
216                 nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ);
217                 addr->ce_mask |= ADDR_ATTR_LABEL;
218         }
219
220         if (tb[IFA_CACHEINFO]) {
221                 struct ifa_cacheinfo *ca;
222                 
223                 ca = nla_data(tb[IFA_CACHEINFO]);
224                 addr->a_cacheinfo.aci_prefered = ca->ifa_prefered;
225                 addr->a_cacheinfo.aci_valid = ca->ifa_valid;
226                 addr->a_cacheinfo.aci_cstamp = ca->cstamp;
227                 addr->a_cacheinfo.aci_tstamp = ca->tstamp;
228                 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
229         }
230
231         if (tb[IFA_LOCAL]) {
232                 addr->a_local = nla_get_addr(tb[IFA_LOCAL], addr->a_family);
233                 if (!addr->a_local)
234                         goto errout_free;
235                 addr->ce_mask |= ADDR_ATTR_LOCAL;
236         }
237
238         if (tb[IFA_ADDRESS]) {
239                 struct nl_addr *a;
240
241                 a = nla_get_addr(tb[IFA_ADDRESS], addr->a_family);
242                 if (!a)
243                         goto errout_free;
244
245                 /* IPv6 sends the local address as IFA_ADDRESS with
246                  * no IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS
247                  * with IFA_ADDRESS being the peer address if they differ */
248                 if (!tb[IFA_LOCAL] || !nl_addr_cmp(a, addr->a_local)) {
249                         nl_addr_put(addr->a_local);
250                         addr->a_local = a;
251                         addr->ce_mask |= ADDR_ATTR_LOCAL;
252                 } else {
253                         addr->a_peer = a;
254                         addr->ce_mask |= ADDR_ATTR_PEER;
255                         peer_prefix = 1;
256                 }
257         }
258
259         nl_addr_set_prefixlen(peer_prefix ? addr->a_peer : addr->a_local,
260                               addr->a_prefixlen);
261
262         if (tb[IFA_BROADCAST]) {
263                 addr->a_bcast = nla_get_addr(tb[IFA_BROADCAST], addr->a_family);
264                 if (!addr->a_bcast)
265                         goto errout_free;
266
267                 addr->ce_mask |= ADDR_ATTR_BROADCAST;
268         }
269
270         if (tb[IFA_ANYCAST]) {
271                 addr->a_anycast = nla_get_addr(tb[IFA_ANYCAST], addr->a_family);
272                 if (!addr->a_anycast)
273                         goto errout_free;
274
275                 addr->ce_mask |= ADDR_ATTR_ANYCAST;
276         }
277
278         if (tb[IFA_MULTICAST]) {
279                 addr->a_multicast = nla_get_addr(tb[IFA_MULTICAST],
280                                                  addr->a_family);
281                 if (!addr->a_multicast)
282                         goto errout_free;
283
284                 addr->ce_mask |= ADDR_ATTR_MULTICAST;
285         }
286
287         err = pp->pp_cb((struct nl_object *) addr, pp);
288         if (err < 0)
289                 goto errout_free;
290
291         err = P_ACCEPT;
292
293 errout_free:
294         rtnl_addr_put(addr);
295 errout:
296         return err;
297 }
298
299 static int addr_request_update(struct nl_cache *cache, struct nl_handle *handle)
300 {
301         return nl_rtgen_request(handle, RTM_GETADDR, AF_UNSPEC, NLM_F_DUMP);
302 }
303
304 static int addr_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
305 {
306         struct rtnl_addr *addr = (struct rtnl_addr *) obj;
307         struct nl_cache *link_cache;
308         char buf[128];
309
310         link_cache = nl_cache_mngt_require("route/link");
311
312         if (addr->ce_mask & ADDR_ATTR_LOCAL)
313                 dp_dump(p, "%s",
314                         nl_addr2str(addr->a_local, buf, sizeof(buf)));
315         else
316                 dp_dump(p, "none");
317
318         if (addr->ce_mask & ADDR_ATTR_PEER)
319                 dp_dump(p, " peer %s",
320                         nl_addr2str(addr->a_peer, buf, sizeof(buf)));
321
322         dp_dump(p, " %s ", nl_af2str(addr->a_family, buf, sizeof(buf)));
323
324         if (link_cache)
325                 dp_dump(p, "dev %s ",
326                         rtnl_link_i2name(link_cache, addr->a_ifindex,
327                                          buf, sizeof(buf)));
328         else
329                 dp_dump(p, "dev %d ", addr->a_ifindex);
330
331         dp_dump(p, "scope %s",
332                 rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
333
334         rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
335         if (buf[0])
336                 dp_dump(p, " <%s>", buf);
337
338         dp_dump(p, "\n");
339
340         return 1;
341 }
342
343 static int addr_dump_full(struct nl_object *obj, struct nl_dump_params *p)
344 {
345         struct rtnl_addr *addr = (struct rtnl_addr *) obj;
346         int line = addr_dump_brief(obj, p);
347         char buf[128];
348
349         if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST |
350                             ADDR_ATTR_ANYCAST | ADDR_ATTR_MULTICAST)) {
351                 dp_dump_line(p, line++, "  ");
352
353                 if (addr->ce_mask & ADDR_ATTR_LABEL)
354                         dp_dump(p, " label %s", addr->a_label);
355
356                 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
357                         dp_dump(p, " broadcast %s",
358                                 nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
359
360                 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
361                         dp_dump(p, " anycast %s",
362                                 nl_addr2str(addr->a_anycast, buf,
363                                               sizeof(buf)));
364
365                 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
366                         dp_dump(p, " multicast %s",
367                                 nl_addr2str(addr->a_multicast, buf,
368                                               sizeof(buf)));
369
370                 dp_dump(p, "\n");
371         }
372
373         if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
374                 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
375
376                 dp_dump_line(p, line++, "   valid-lifetime %s",
377                              ci->aci_valid == 0xFFFFFFFFU ? "forever" :
378                              nl_msec2str(ci->aci_valid * 1000,
379                                            buf, sizeof(buf)));
380
381                 dp_dump(p, " preferred-lifetime %s\n",
382                         ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
383                         nl_msec2str(ci->aci_prefered * 1000,
384                                       buf, sizeof(buf)));
385
386                 dp_dump_line(p, line++, "   created boot-time+%s ",
387                              nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
388                                            buf, sizeof(buf)));
389                     
390                 dp_dump(p, "last-updated boot-time+%s\n",
391                         nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
392                                       buf, sizeof(buf)));
393         }
394
395         return line;
396 }
397
398 static int addr_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
399 {
400         return addr_dump_full(obj, p);
401 }
402
403 static int addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
404 {
405         struct rtnl_addr *addr = (struct rtnl_addr *) obj;
406         struct nl_cache *link_cache;
407         char buf[128];
408         int line = 0;
409
410         dp_dump_line(p, line++, "<address>\n");
411         dp_dump_line(p, line++, "  <family>%s</family>\n",
412                      nl_af2str(addr->a_family, buf, sizeof(buf)));
413
414         if (addr->ce_mask & ADDR_ATTR_LOCAL)
415                 dp_dump_line(p, line++, "  <local>%s</local>\n",
416                              nl_addr2str(addr->a_local, buf, sizeof(buf)));
417
418         if (addr->ce_mask & ADDR_ATTR_PEER)
419                 dp_dump_line(p, line++, "  <peer>%s</peer>\n",
420                              nl_addr2str(addr->a_peer, buf, sizeof(buf)));
421
422         if (addr->ce_mask & ADDR_ATTR_BROADCAST)
423                 dp_dump_line(p, line++, "  <broadcast>%s</broadcast>\n",
424                              nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
425
426         if (addr->ce_mask & ADDR_ATTR_ANYCAST)
427                 dp_dump_line(p, line++, "  <anycast>%s</anycast>\n",
428                              nl_addr2str(addr->a_anycast, buf, sizeof(buf)));
429
430         if (addr->ce_mask & ADDR_ATTR_MULTICAST)
431                 dp_dump_line(p, line++, "  <multicast>%s</multicast>\n",
432                              nl_addr2str(addr->a_multicast, buf,
433                                            sizeof(buf)));
434
435         if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
436                 dp_dump_line(p, line++, "  <prefixlen>%u</prefixlen>\n",
437                              addr->a_prefixlen);
438         link_cache = nl_cache_mngt_require("route/link");
439
440         if (link_cache)
441                 dp_dump_line(p, line++, "  <device>%s</device>\n",
442                              rtnl_link_i2name(link_cache, addr->a_ifindex,
443                                               buf, sizeof(buf)));
444         else
445                 dp_dump_line(p, line++, "  <device>%u</device>\n",
446                              addr->a_ifindex);
447
448         if (addr->ce_mask & ADDR_ATTR_SCOPE)
449                 dp_dump_line(p, line++, "  <scope>%s</scope>\n",
450                              rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
451
452         if (addr->ce_mask & ADDR_ATTR_LABEL)
453                 dp_dump_line(p, line++, "  <label>%s</label>\n", addr->a_label);
454
455         rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
456         if (buf[0])
457                 dp_dump_line(p, line++, "  <flags>%s</flags>\n", buf);
458
459         if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
460                 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
461
462                 dp_dump_line(p, line++, "  <cacheinfo>\n");
463
464                 dp_dump_line(p, line++, "    <valid>%s</valid>\n",
465                              ci->aci_valid == 0xFFFFFFFFU ? "forever" :
466                              nl_msec2str(ci->aci_valid * 1000,
467                                            buf, sizeof(buf)));
468
469                 dp_dump_line(p, line++, "    <prefered>%s</prefered>\n",
470                              ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
471                              nl_msec2str(ci->aci_prefered * 1000,
472                                          buf, sizeof(buf)));
473
474                 dp_dump_line(p, line++, "    <created>%s</created>\n",
475                              nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
476                                          buf, sizeof(buf)));
477
478                 dp_dump_line(p, line++, "    <last-update>%s</last-update>\n",
479                              nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
480                                          buf, sizeof(buf)));
481
482                 dp_dump_line(p, line++, "  </cacheinfo>\n");
483         }
484
485         dp_dump_line(p, line++, "</address>\n");
486
487         return line;
488 }
489
490 static int addr_dump_env(struct nl_object *obj, struct nl_dump_params *p)
491 {
492         struct rtnl_addr *addr = (struct rtnl_addr *) obj;
493         struct nl_cache *link_cache;
494         char buf[128];
495         int line = 0;
496
497         dp_dump_line(p, line++, "ADDR_FAMILY=%s\n",
498                      nl_af2str(addr->a_family, buf, sizeof(buf)));
499
500         if (addr->ce_mask & ADDR_ATTR_LOCAL)
501                 dp_dump_line(p, line++, "ADDR_LOCAL=%s\n",
502                              nl_addr2str(addr->a_local, buf, sizeof(buf)));
503
504         if (addr->ce_mask & ADDR_ATTR_PEER)
505                 dp_dump_line(p, line++, "ADDR_PEER=%s\n",
506                              nl_addr2str(addr->a_peer, buf, sizeof(buf)));
507
508         if (addr->ce_mask & ADDR_ATTR_BROADCAST)
509                 dp_dump_line(p, line++, "ADDR_BROADCAST=%s\n",
510                              nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
511
512         if (addr->ce_mask & ADDR_ATTR_ANYCAST)
513                 dp_dump_line(p, line++, "ADDR_ANYCAST=%s\n",
514                              nl_addr2str(addr->a_anycast, buf, sizeof(buf)));
515
516         if (addr->ce_mask & ADDR_ATTR_MULTICAST)
517                 dp_dump_line(p, line++, "ADDR_MULTICAST=%s\n",
518                              nl_addr2str(addr->a_multicast, buf,
519                                            sizeof(buf)));
520
521         if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
522                 dp_dump_line(p, line++, "ADDR_PREFIXLEN=%u\n",
523                              addr->a_prefixlen);
524         link_cache = nl_cache_mngt_require("route/link");
525
526         dp_dump_line(p, line++, "ADDR_IFINDEX=%u\n", addr->a_ifindex);
527         if (link_cache)
528                 dp_dump_line(p, line++, "ADDR_IFNAME=%s\n",
529                              rtnl_link_i2name(link_cache, addr->a_ifindex,
530                                               buf, sizeof(buf)));
531
532         if (addr->ce_mask & ADDR_ATTR_SCOPE)
533                 dp_dump_line(p, line++, "ADDR_SCOPE=%s\n",
534                              rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
535
536         if (addr->ce_mask & ADDR_ATTR_LABEL)
537                 dp_dump_line(p, line++, "ADDR_LABEL=%s\n", addr->a_label);
538
539         rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
540         if (buf[0])
541                 dp_dump_line(p, line++, "ADDR_FLAGS=%s\n", buf);
542
543         if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
544                 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
545
546                 dp_dump_line(p, line++, "ADDR_CACHEINFO_VALID=%s\n",
547                              ci->aci_valid == 0xFFFFFFFFU ? "forever" :
548                              nl_msec2str(ci->aci_valid * 1000,
549                                            buf, sizeof(buf)));
550
551                 dp_dump_line(p, line++, "ADDR_CACHEINFO_PREFERED=%s\n",
552                              ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
553                              nl_msec2str(ci->aci_prefered * 1000,
554                                          buf, sizeof(buf)));
555
556                 dp_dump_line(p, line++, "ADDR_CACHEINFO_CREATED=%s\n",
557                              nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
558                                          buf, sizeof(buf)));
559
560                 dp_dump_line(p, line++, "ADDR_CACHEINFO_LASTUPDATE=%s\n",
561                              nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
562                                          buf, sizeof(buf)));
563         }
564
565         return line;
566 }
567
568 static int addr_compare(struct nl_object *_a, struct nl_object *_b,
569                         uint32_t attrs, int flags)
570 {
571         struct rtnl_addr *a = (struct rtnl_addr *) _a;
572         struct rtnl_addr *b = (struct rtnl_addr *) _b;
573         int diff = 0;
574
575 #define ADDR_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ADDR_ATTR_##ATTR, a, b, EXPR)
576
577         diff |= ADDR_DIFF(IFINDEX,      a->a_ifindex != b->a_ifindex);
578         diff |= ADDR_DIFF(FAMILY,       a->a_family != b->a_family);
579         diff |= ADDR_DIFF(SCOPE,        a->a_scope != b->a_scope);
580         diff |= ADDR_DIFF(LABEL,        strcmp(a->a_label, b->a_label));
581         diff |= ADDR_DIFF(PEER,         nl_addr_cmp(a->a_peer, b->a_peer));
582         diff |= ADDR_DIFF(LOCAL,        nl_addr_cmp(a->a_local, b->a_local));
583         diff |= ADDR_DIFF(ANYCAST,      nl_addr_cmp(a->a_anycast,b->a_anycast));
584         diff |= ADDR_DIFF(MULTICAST,    nl_addr_cmp(a->a_multicast,
585                                                     b->a_multicast));
586         diff |= ADDR_DIFF(BROADCAST,    nl_addr_cmp(a->a_bcast, b->a_bcast));
587
588         if (flags & LOOSE_FLAG_COMPARISON)
589                 diff |= ADDR_DIFF(FLAGS,
590                                   (a->a_flags ^ b->a_flags) & b->a_flag_mask);
591         else
592                 diff |= ADDR_DIFF(FLAGS, a->a_flags != b->a_flags);
593
594 #undef ADDR_DIFF
595
596         return diff;
597 }
598
599 static struct trans_tbl addr_attrs[] = {
600         __ADD(ADDR_ATTR_FAMILY, family)
601         __ADD(ADDR_ATTR_PREFIXLEN, prefixlen)
602         __ADD(ADDR_ATTR_FLAGS, flags)
603         __ADD(ADDR_ATTR_SCOPE, scope)
604         __ADD(ADDR_ATTR_IFINDEX, ifindex)
605         __ADD(ADDR_ATTR_LABEL, label)
606         __ADD(ADDR_ATTR_CACHEINFO, cacheinfo)
607         __ADD(ADDR_ATTR_PEER, peer)
608         __ADD(ADDR_ATTR_LOCAL, local)
609         __ADD(ADDR_ATTR_BROADCAST, broadcast)
610         __ADD(ADDR_ATTR_ANYCAST, anycast)
611         __ADD(ADDR_ATTR_MULTICAST, multicast)
612 };
613
614 static char *addr_attrs2str(int attrs, char *buf, size_t len)
615 {
616         return __flags2str(attrs, buf, len, addr_attrs,
617                            ARRAY_SIZE(addr_attrs));
618 }
619
620 /**
621  * @name Allocation/Freeing
622  * @{
623  */
624
625 struct rtnl_addr *rtnl_addr_alloc(void)
626 {
627         return (struct rtnl_addr *) nl_object_alloc(&addr_obj_ops);
628 }
629
630 void rtnl_addr_put(struct rtnl_addr *addr)
631 {
632         nl_object_put((struct nl_object *) addr);
633 }
634
635 /** @} */
636
637 /**
638  * @name Cache Management
639  * @{
640  */
641
642 struct nl_cache *rtnl_addr_alloc_cache(struct nl_handle *handle)
643 {
644         struct nl_cache *cache;
645         
646         cache = nl_cache_alloc(&rtnl_addr_ops);
647         if (!cache)
648                 return NULL;
649
650         if (handle && nl_cache_refill(handle, cache) < 0) {
651                 nl_cache_free(cache);
652                 return NULL;
653         }
654
655         return cache;
656 }
657
658 /** @} */
659
660 static struct nl_msg *build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags)
661 {
662         struct nl_msg *msg;
663         struct ifaddrmsg am = {
664                 .ifa_family = tmpl->a_family,
665                 .ifa_index = tmpl->a_ifindex,
666                 .ifa_prefixlen = tmpl->a_prefixlen,
667         };
668
669         if (tmpl->ce_mask & ADDR_ATTR_SCOPE)
670                 am.ifa_scope = tmpl->a_scope;
671         else {
672                 /* compatibility hack */
673                 if (tmpl->a_family == AF_INET &&
674                     tmpl->ce_mask & ADDR_ATTR_LOCAL &&
675                     *((char *) nl_addr_get_binary_addr(tmpl->a_local)) == 127)
676                         am.ifa_scope = RT_SCOPE_HOST;
677                 else
678                         am.ifa_scope = RT_SCOPE_UNIVERSE;
679         }
680
681         msg = nlmsg_alloc_simple(cmd, flags);
682         if (!msg)
683                 goto nla_put_failure;
684
685         if (nlmsg_append(msg, &am, sizeof(am), NLMSG_ALIGNTO) < 0)
686                 goto nla_put_failure;
687
688         if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
689                 NLA_PUT_ADDR(msg, IFA_LOCAL, tmpl->a_local);
690
691         if (tmpl->ce_mask & ADDR_ATTR_PEER)
692                 NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_peer);
693         else
694                 NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_local);
695
696         if (tmpl->ce_mask & ADDR_ATTR_LABEL)
697                 NLA_PUT_STRING(msg, IFA_LABEL, tmpl->a_label);
698
699         if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
700                 NLA_PUT_ADDR(msg, IFA_BROADCAST, tmpl->a_bcast);
701
702         if (tmpl->ce_mask & ADDR_ATTR_ANYCAST)
703                 NLA_PUT_ADDR(msg, IFA_ANYCAST, tmpl->a_anycast);
704
705         return msg;
706
707 nla_put_failure:
708         nlmsg_free(msg);
709         return NULL;
710 }
711
712 /**
713  * @name Addition
714  * @{
715  */
716
717 /**
718  * Build netlink request message to request addition of new address
719  * @arg addr            Address object representing the new address.
720  * @arg flags           Additional netlink message flags.
721  *
722  * Builds a new netlink message requesting the addition of a new
723  * address. The netlink message header isn't fully equipped with
724  * all relevant fields and must thus be sent out via nl_send_auto_complete()
725  * or supplemented as needed.
726  *
727  * Minimal required attributes:
728  *   - interface index (rtnl_addr_set_ifindex())
729  *   - local address (rtnl_addr_set_local())
730  *
731  * The scope will default to universe except for loopback addresses in
732  * which case a host scope is used if not specified otherwise.
733  *
734  * @note Free the memory after usage using nlmsg_free().
735  * @return Newly allocated netlink message or NULL if an error occured.
736  */
737 struct nl_msg *rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags)
738 {
739         int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY |
740                        ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL;
741
742         if ((addr->ce_mask & required) != required) {
743                 nl_error(EINVAL, "Missing mandatory attributes, required are: "
744                                  "ifindex, family, prefixlen, local address.");
745                 return NULL;
746         }
747         
748         return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags);
749 }
750
751 /**
752  * Request addition of new address
753  * @arg handle          Netlink handle.
754  * @arg addr            Address object representing the new address.
755  * @arg flags           Additional netlink message flags.
756  *
757  * Builds a netlink message by calling rtnl_addr_build_add_request(),
758  * sends the request to the kernel and waits for the next ACK to be
759  * received and thus blocks until the request has been fullfilled.
760  *
761  * @see rtnl_addr_build_add_request()
762  *
763  * @return 0 on sucess or a negative error if an error occured.
764  */
765 int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags)
766 {
767         struct nl_msg *msg;
768         int err;
769
770         msg = rtnl_addr_build_add_request(addr, flags);
771         if (!msg)
772                 return nl_get_errno();
773
774         err = nl_send_auto_complete(handle, msg);
775         nlmsg_free(msg);
776         if (err < 0)
777                 return err;
778
779         return nl_wait_for_ack(handle);
780 }
781
782 /** @} */
783
784 /**
785  * @name Deletion
786  * @{
787  */
788
789 /**
790  * Build a netlink request message to request deletion of an address
791  * @arg addr            Address object to be deleteted.
792  * @arg flags           Additional netlink message flags.
793  *
794  * Builds a new netlink message requesting a deletion of an address.
795  * The netlink message header isn't fully equipped with all relevant
796  * fields and must thus be sent out via nl_send_auto_complete()
797  * or supplemented as needed.
798  *
799  * Minimal required attributes:
800  *   - interface index (rtnl_addr_set_ifindex())
801  *   - address family (rtnl_addr_set_family())
802  *
803  * Optional attributes:
804  *   - local address (rtnl_addr_set_local())
805  *   - label (rtnl_addr_set_label(), IPv4/DECnet only)
806  *   - peer address (rtnl_addr_set_peer(), IPv4 only)
807  *
808  * @note Free the memory after usage using nlmsg_free().
809  * @return Newly allocated netlink message or NULL if an error occured.
810  */
811 struct nl_msg *rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags)
812 {
813         int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY;
814
815         if ((addr->ce_mask & required) != required) {
816                 nl_error(EINVAL, "Missing mandatory attributes, required are: "
817                                  "ifindex, family");
818                 return NULL;
819         }
820         
821         return build_addr_msg(addr, RTM_DELADDR, flags);
822 }
823
824 /**
825  * Request deletion of an address
826  * @arg handle          Netlink handle.
827  * @arg addr            Address object to be deleted.
828  * @arg flags           Additional netlink message flags.
829  *
830  * Builds a netlink message by calling rtnl_addr_build_delete_request(),
831  * sends the request to the kernel and waits for the next ACK to be
832  * received and thus blocks until the request has been fullfilled.
833  *
834  * @see rtnl_addr_build_delete_request();
835  *
836  * @return 0 on sucess or a negative error if an error occured.
837  */
838 int rtnl_addr_delete(struct nl_handle *handle, struct rtnl_addr *addr,
839                      int flags)
840 {
841         struct nl_msg *msg;
842         int err;
843
844         msg = rtnl_addr_build_delete_request(addr, flags);
845         if (!msg)
846                 return nl_get_errno();
847
848         err = nl_send_auto_complete(handle, msg);
849         nlmsg_free(msg);
850         if (err < 0)
851                 return err;
852
853         return nl_wait_for_ack(handle);
854 }
855
856 /** @} */
857
858 /**
859  * @name Attributes
860  * @{
861  */
862
863 void rtnl_addr_set_label(struct rtnl_addr *addr, const char *label)
864 {
865         strncpy(addr->a_label, label, sizeof(addr->a_label) - 1);
866         addr->ce_mask |= ADDR_ATTR_LABEL;
867 }
868
869 char *rtnl_addr_get_label(struct rtnl_addr *addr)
870 {
871         if (addr->ce_mask & ADDR_ATTR_LABEL)
872                 return addr->a_label;
873         else
874                 return NULL;
875 }
876
877 void rtnl_addr_set_ifindex(struct rtnl_addr *addr, int ifindex)
878 {
879         addr->a_ifindex = ifindex;
880         addr->ce_mask |= ADDR_ATTR_IFINDEX;
881 }
882
883 int rtnl_addr_get_ifindex(struct rtnl_addr *addr)
884 {
885         if (addr->ce_mask & ADDR_ATTR_IFINDEX)
886                 return addr->a_ifindex;
887         else
888                 return RTNL_LINK_NOT_FOUND;
889 }
890
891 void rtnl_addr_set_family(struct rtnl_addr *addr, int family)
892 {
893         addr->a_family = family;
894         addr->ce_mask |= ADDR_ATTR_FAMILY;
895 }
896
897 int rtnl_addr_get_family(struct rtnl_addr *addr)
898 {
899         if (addr->ce_mask & ADDR_ATTR_FAMILY)
900                 return addr->a_family;
901         else
902                 return AF_UNSPEC;
903 }
904
905 void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefix)
906 {
907         addr->a_prefixlen = prefix;
908         addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
909 }
910
911 int rtnl_addr_get_prefixlen(struct rtnl_addr *addr)
912 {
913         if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
914                 return addr->a_prefixlen;
915         else
916                 return -1;
917 }
918
919 void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope)
920 {
921         addr->a_scope = scope;
922         addr->ce_mask |= ADDR_ATTR_SCOPE;
923 }
924
925 int rtnl_addr_get_scope(struct rtnl_addr *addr)
926 {
927         if (addr->ce_mask & ADDR_ATTR_SCOPE)
928                 return addr->a_scope;
929         else
930                 return -1;
931 }
932
933 void rtnl_addr_set_flags(struct rtnl_addr *addr, unsigned int flags)
934 {
935         addr->a_flag_mask |= flags;
936         addr->a_flags |= flags;
937         addr->ce_mask |= ADDR_ATTR_FLAGS;
938 }
939
940 void rtnl_addr_unset_flags(struct rtnl_addr *addr, unsigned int flags)
941 {
942         addr->a_flag_mask |= flags;
943         addr->a_flags &= ~flags;
944         addr->ce_mask |= ADDR_ATTR_FLAGS;
945 }
946
947 unsigned int rtnl_addr_get_flags(struct rtnl_addr *addr)
948 {
949         return addr->a_flags;
950 }
951
952 static inline int __assign_addr(struct rtnl_addr *addr, struct nl_addr **pos,
953                                 struct nl_addr *new, int flag)
954 {
955         if (addr->ce_mask & ADDR_ATTR_FAMILY) {
956                 if (new->a_family != addr->a_family)
957                         return nl_error(EINVAL, "Address family mismatch");
958         } else
959                 addr->a_family = new->a_family;
960
961         if (*pos)
962                 nl_addr_put(*pos);
963
964         *pos = nl_addr_get(new);
965         addr->ce_mask |= (flag | ADDR_ATTR_FAMILY);
966
967         return 0;
968 }
969
970 int rtnl_addr_set_local(struct rtnl_addr *addr, struct nl_addr *local)
971 {
972         int err;
973
974         err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL);
975         if (err < 0)
976                 return err;
977
978         if (!(addr->ce_mask & ADDR_ATTR_PEER)) {
979                 addr->a_prefixlen = nl_addr_get_prefixlen(addr->a_local);
980                 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
981         }
982
983         return 0;
984 }
985
986 struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *addr)
987 {
988         if (addr->ce_mask & ADDR_ATTR_LOCAL)
989                 return addr->a_local;
990         else
991                 return NULL;
992 }
993
994 int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer)
995 {
996         return __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER);
997
998         addr->a_prefixlen = nl_addr_get_prefixlen(addr->a_peer);
999         addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
1000
1001         return 0;
1002 }
1003
1004 struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *addr)
1005 {
1006         if (addr->ce_mask & ADDR_ATTR_PEER)
1007                 return addr->a_peer;
1008         else
1009                 return NULL;
1010 }
1011
1012 int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast)
1013 {
1014         return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST);
1015 }
1016
1017 struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *addr)
1018 {
1019         if (addr->ce_mask & ADDR_ATTR_BROADCAST)
1020                 return addr->a_bcast;
1021         else
1022                 return NULL;
1023 }
1024
1025 int rtnl_addr_set_anycast(struct rtnl_addr *addr, struct nl_addr *anycast)
1026 {
1027         return __assign_addr(addr, &addr->a_anycast, anycast,
1028                              ADDR_ATTR_ANYCAST);
1029 }
1030
1031 struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *addr)
1032 {
1033         if (addr->ce_mask & ADDR_ATTR_ANYCAST)
1034                 return addr->a_anycast;
1035         else
1036                 return NULL;
1037 }
1038
1039 int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast)
1040 {
1041         return __assign_addr(addr, &addr->a_multicast, multicast,
1042                              ADDR_ATTR_MULTICAST);
1043 }
1044
1045 struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
1046 {
1047         if (addr->ce_mask & ADDR_ATTR_MULTICAST)
1048                 return addr->a_multicast;
1049         else
1050                 return NULL;
1051 }
1052
1053 /** @} */
1054
1055 /**
1056  * @name Flags Translations
1057  * @{
1058  */
1059
1060 static struct trans_tbl addr_flags[] = {
1061         __ADD(IFA_F_SECONDARY, secondary)
1062         __ADD(IFA_F_DEPRECATED, deprecated)
1063         __ADD(IFA_F_TENTATIVE, tentative)
1064         __ADD(IFA_F_PERMANENT, permanent)
1065 };
1066
1067 char *rtnl_addr_flags2str(int flags, char *buf, size_t size)
1068 {
1069         return __flags2str(flags, buf, size, addr_flags,
1070                            ARRAY_SIZE(addr_flags));
1071 }
1072
1073 int rtnl_addr_str2flags(const char *name)
1074 {
1075         return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags));
1076 }
1077
1078 /** @} */
1079
1080 static struct nl_object_ops addr_obj_ops = {
1081         .oo_name                = "route/addr",
1082         .oo_size                = sizeof(struct rtnl_addr),
1083         .oo_free_data           = addr_free_data,
1084         .oo_clone               = addr_clone,
1085         .oo_dump[NL_DUMP_BRIEF] = addr_dump_brief,
1086         .oo_dump[NL_DUMP_FULL]  = addr_dump_full,
1087         .oo_dump[NL_DUMP_STATS] = addr_dump_stats,
1088         .oo_dump[NL_DUMP_XML]   = addr_dump_xml,
1089         .oo_dump[NL_DUMP_ENV]   = addr_dump_env,
1090         .oo_compare             = addr_compare,
1091         .oo_attrs2str           = addr_attrs2str,
1092         .oo_id_attrs            = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
1093                                    ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN |
1094                                    ADDR_ATTR_PEER),
1095 };
1096
1097 static struct nl_af_group addr_groups[] = {
1098         { AF_INET,      RTNLGRP_IPV4_IFADDR },
1099         { AF_INET6,     RTNLGRP_IPV6_IFADDR },
1100         { END_OF_GROUP_LIST },
1101 };
1102
1103 static struct nl_cache_ops rtnl_addr_ops = {
1104         .co_name                = "route/addr",
1105         .co_hdrsize             = sizeof(struct ifaddrmsg),
1106         .co_msgtypes            = {
1107                                         { RTM_NEWADDR, NL_ACT_NEW, "new" },
1108                                         { RTM_DELADDR, NL_ACT_DEL, "del" },
1109                                         { RTM_GETADDR, NL_ACT_GET, "get" },
1110                                         END_OF_MSGTYPES_LIST,
1111                                   },
1112         .co_protocol            = NETLINK_ROUTE,
1113         .co_groups              = addr_groups,
1114         .co_request_update      = addr_request_update,
1115         .co_msg_parser          = addr_msg_parser,
1116         .co_obj_ops             = &addr_obj_ops,
1117 };
1118
1119 static void __init addr_init(void)
1120 {
1121         nl_cache_mngt_register(&rtnl_addr_ops);
1122 }
1123
1124 static void __exit addr_exit(void)
1125 {
1126         nl_cache_mngt_unregister(&rtnl_addr_ops);
1127 }
1128
1129 /** @} */