libnl  3.5.0
route.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * lib/route/route.c Routes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation version 2.1
8  * of the License.
9  *
10  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
11  */
12 
13 /**
14  * @ingroup rtnl
15  * @defgroup route Routing
16  * @brief
17  * @{
18  */
19 
20 #include <netlink-private/netlink.h>
21 #include <netlink/netlink.h>
22 #include <netlink/cache.h>
23 #include <netlink/utils.h>
24 #include <netlink/data.h>
25 #include <netlink/route/rtnl.h>
26 #include <netlink/route/route.h>
27 #include <netlink/route/link.h>
28 
29 static struct nl_cache_ops rtnl_route_ops;
30 
31 static int route_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
32  struct nlmsghdr *nlh, struct nl_parser_param *pp)
33 {
34  struct rtnl_route *route;
35  int err;
36 
37  if ((err = rtnl_route_parse(nlh, &route)) < 0)
38  return err;
39 
40  err = pp->pp_cb((struct nl_object *) route, pp);
41 
42  rtnl_route_put(route);
43  return err;
44 }
45 
46 static int route_request_update(struct nl_cache *c, struct nl_sock *h)
47 {
48  struct rtmsg rhdr = {
49  .rtm_family = c->c_iarg1,
50  };
51 
52  if (c->c_iarg2 & ROUTE_CACHE_CONTENT)
53  rhdr.rtm_flags |= RTM_F_CLONED;
54 
55  return nl_send_simple(h, RTM_GETROUTE, NLM_F_DUMP, &rhdr, sizeof(rhdr));
56 }
57 
58 /**
59  * @name Cache Management
60  * @{
61  */
62 
63 /**
64  * Build a route cache holding all routes currently configured in the kernel
65  * @arg sk Netlink socket.
66  * @arg family Address family of routes to cover or AF_UNSPEC
67  * @arg flags Flags
68  * @arg result Result pointer
69  *
70  * Allocates a new cache, initializes it properly and updates it to
71  * contain all routes currently configured in the kernel.
72  *
73  * Valid flags:
74  * * ROUTE_CACHE_CONTENT - Cache will contain contents of routing cache
75  * instead of actual routes.
76  *
77  * @note The caller is responsible for destroying and freeing the
78  * cache after using it.
79  * @return 0 on success or a negative error code.
80  */
81 int rtnl_route_alloc_cache(struct nl_sock *sk, int family, int flags,
82  struct nl_cache **result)
83 {
84  struct nl_cache *cache;
85  int err;
86 
87  if (!(cache = nl_cache_alloc(&rtnl_route_ops)))
88  return -NLE_NOMEM;
89 
90  cache->c_iarg1 = family;
91  cache->c_iarg2 = flags;
92 
93  if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
94  free(cache);
95  return err;
96  }
97 
98  *result = cache;
99  return 0;
100 }
101 
102 /** @} */
103 
104 /**
105  * @name Route Addition
106  * @{
107  */
108 
109 static int build_route_msg(struct rtnl_route *tmpl, int cmd, int flags,
110  struct nl_msg **result)
111 {
112  struct nl_msg *msg;
113  int err;
114 
115  if (!(msg = nlmsg_alloc_simple(cmd, flags)))
116  return -NLE_NOMEM;
117 
118  if ((err = rtnl_route_build_msg(msg, tmpl)) < 0) {
119  nlmsg_free(msg);
120  return err;
121  }
122 
123  *result = msg;
124  return 0;
125 }
126 
127 int rtnl_route_build_add_request(struct rtnl_route *tmpl, int flags,
128  struct nl_msg **result)
129 {
130  return build_route_msg(tmpl, RTM_NEWROUTE, NLM_F_CREATE | flags,
131  result);
132 }
133 
134 int rtnl_route_add(struct nl_sock *sk, struct rtnl_route *route, int flags)
135 {
136  struct nl_msg *msg;
137  int err;
138 
139  if ((err = rtnl_route_build_add_request(route, flags, &msg)) < 0)
140  return err;
141 
142  err = nl_send_auto_complete(sk, msg);
143  nlmsg_free(msg);
144  if (err < 0)
145  return err;
146 
147  return wait_for_ack(sk);
148 }
149 
150 int rtnl_route_build_del_request(struct rtnl_route *tmpl, int flags,
151  struct nl_msg **result)
152 {
153  return build_route_msg(tmpl, RTM_DELROUTE, flags, result);
154 }
155 
156 int rtnl_route_delete(struct nl_sock *sk, struct rtnl_route *route, int flags)
157 {
158  struct nl_msg *msg;
159  int err;
160 
161  if ((err = rtnl_route_build_del_request(route, flags, &msg)) < 0)
162  return err;
163 
164  err = nl_send_auto_complete(sk, msg);
165  nlmsg_free(msg);
166  if (err < 0)
167  return err;
168 
169  return wait_for_ack(sk);
170 }
171 
172 /** @} */
173 
174 static struct nl_af_group route_groups[] = {
175  { AF_INET, RTNLGRP_IPV4_ROUTE },
176  { AF_INET6, RTNLGRP_IPV6_ROUTE },
177  { AF_MPLS, RTNLGRP_MPLS_ROUTE },
178  { AF_DECnet, RTNLGRP_DECnet_ROUTE },
179  { END_OF_GROUP_LIST },
180 };
181 
182 static struct nl_cache_ops rtnl_route_ops = {
183  .co_name = "route/route",
184  .co_hdrsize = sizeof(struct rtmsg),
185  .co_msgtypes = {
186  { RTM_NEWROUTE, NL_ACT_NEW, "new" },
187  { RTM_DELROUTE, NL_ACT_DEL, "del" },
188  { RTM_GETROUTE, NL_ACT_GET, "get" },
189  END_OF_MSGTYPES_LIST,
190  },
191  .co_protocol = NETLINK_ROUTE,
192  .co_groups = route_groups,
193  .co_request_update = route_request_update,
194  .co_msg_parser = route_msg_parser,
195  .co_obj_ops = &route_obj_ops,
196 };
197 
198 static void __init route_init(void)
199 {
200  nl_cache_mngt_register(&rtnl_route_ops);
201 }
202 
203 static void __exit route_exit(void)
204 {
205  nl_cache_mngt_unregister(&rtnl_route_ops);
206 }
207 
208 /** @} */
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1248
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:565
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition: cache_mngt.c:288
#define ROUTE_CACHE_CONTENT
When passed to rtnl_route_alloc_cache() the cache will correspond to the contents of the routing cach...
Definition: route.h:33
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition: cache_mngt.c:253
int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf, size_t size)
Construct and transmit a Netlink message.
Definition: nl.c:581
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
Definition: cache.c:1041
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:348
int rtnl_route_alloc_cache(struct nl_sock *sk, int family, int flags, struct nl_cache **result)
Build a route cache holding all routes currently configured in the kernel.
Definition: route.c:81
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
Definition: cache.c:184