12#include <netlink-private/netlink.h>
13#include <netlink-private/route/nexthop-encap.h>
14#include <netlink/netlink.h>
15#include <netlink/utils.h>
16#include <netlink/route/rtnl.h>
17#include <netlink/route/route.h>
20#define NH_ATTR_FLAGS 0x000001
21#define NH_ATTR_WEIGHT 0x000002
22#define NH_ATTR_IFINDEX 0x000004
23#define NH_ATTR_GATEWAY 0x000008
24#define NH_ATTR_REALMS 0x000010
25#define NH_ATTR_NEWDST 0x000020
26#define NH_ATTR_VIA 0x000040
27#define NH_ATTR_ENCAP 0x000080
35struct rtnl_nexthop *rtnl_route_nh_alloc(
void)
37 struct rtnl_nexthop *nh;
39 nh = calloc(1,
sizeof(*nh));
43 nl_init_list_head(&nh->rtnh_list);
48struct rtnl_nexthop *rtnl_route_nh_clone(
struct rtnl_nexthop *src)
50 struct rtnl_nexthop *nh;
52 nh = rtnl_route_nh_alloc();
56 nh->rtnh_flags = src->rtnh_flags;
57 nh->rtnh_flag_mask = src->rtnh_flag_mask;
58 nh->rtnh_weight = src->rtnh_weight;
59 nh->rtnh_ifindex = src->rtnh_ifindex;
60 nh->ce_mask = src->ce_mask;
62 if (src->rtnh_gateway) {
64 if (!nh->rtnh_gateway) {
70 if (src->rtnh_newdst) {
72 if (!nh->rtnh_newdst) {
92void rtnl_route_nh_free(
struct rtnl_nexthop *nh)
98 if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
99 nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
100 free(nh->rtnh_encap->priv);
101 free(nh->rtnh_encap);
108int rtnl_route_nh_compare(
struct rtnl_nexthop *a,
struct rtnl_nexthop *b,
109 uint32_t attrs,
int loose)
113#define NH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NH_ATTR_##ATTR, a, b, EXPR)
115 diff |= NH_DIFF(IFINDEX, a->rtnh_ifindex != b->rtnh_ifindex);
116 diff |= NH_DIFF(WEIGHT, a->rtnh_weight != b->rtnh_weight);
117 diff |= NH_DIFF(REALMS, a->rtnh_realms != b->rtnh_realms);
118 diff |= NH_DIFF(GATEWAY,
nl_addr_cmp(a->rtnh_gateway,
120 diff |= NH_DIFF(NEWDST,
nl_addr_cmp(a->rtnh_newdst,
124 diff |= NH_DIFF(ENCAP, nh_encap_compare(a->rtnh_encap,
128 diff |= NH_DIFF(FLAGS,
129 (a->rtnh_flags ^ b->rtnh_flags) & b->rtnh_flag_mask);
131 diff |= NH_DIFF(FLAGS, a->rtnh_flags != b->rtnh_flags);
138static void nh_dump_line(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
140 struct nl_cache *link_cache;
145 if (nh->ce_mask & NH_ATTR_ENCAP)
146 nh_encap_dump(nh->rtnh_encap, dp);
148 if (nh->ce_mask & NH_ATTR_NEWDST)
154 if (nh->ce_mask & NH_ATTR_VIA)
158 if (nh->ce_mask & NH_ATTR_GATEWAY)
162 if(nh->ce_mask & NH_ATTR_IFINDEX) {
169 nl_dump(dp,
" dev %d", nh->rtnh_ifindex);
175 nl_cache_put(link_cache);
178static void nh_dump_details(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
180 struct nl_cache *link_cache;
187 if (nh->ce_mask & NH_ATTR_ENCAP)
188 nh_encap_dump(nh->rtnh_encap, dp);
190 if (nh->ce_mask & NH_ATTR_NEWDST)
194 if (nh->ce_mask & NH_ATTR_VIA)
198 if (nh->ce_mask & NH_ATTR_GATEWAY)
202 if(nh->ce_mask & NH_ATTR_IFINDEX) {
209 nl_dump(dp,
" dev %d", nh->rtnh_ifindex);
212 if (nh->ce_mask & NH_ATTR_WEIGHT)
213 nl_dump(dp,
" weight %u", nh->rtnh_weight);
215 if (nh->ce_mask & NH_ATTR_REALMS)
216 nl_dump(dp,
" realm %04x:%04x",
220 if (nh->ce_mask & NH_ATTR_FLAGS)
221 nl_dump(dp,
" <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags,
225 nl_cache_put(link_cache);
228void rtnl_route_nh_dump(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
232 nh_dump_line(nh, dp);
237 if (dp->
dp_ivar == NH_DUMP_FROM_DETAILS)
238 nh_dump_details(nh, dp);
246void nh_set_encap(
struct rtnl_nexthop *nh,
struct rtnl_nh_encap *rtnh_encap)
248 if (nh->rtnh_encap) {
249 if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
250 nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
251 free(nh->rtnh_encap->priv);
252 free(nh->rtnh_encap);
256 nh->rtnh_encap = rtnh_encap;
257 nh->ce_mask |= NH_ATTR_ENCAP;
259 nh->rtnh_encap = NULL;
260 nh->ce_mask &= ~NH_ATTR_ENCAP;
269void rtnl_route_nh_set_weight(
struct rtnl_nexthop *nh, uint8_t weight)
271 nh->rtnh_weight = weight;
272 nh->ce_mask |= NH_ATTR_WEIGHT;
275uint8_t rtnl_route_nh_get_weight(
struct rtnl_nexthop *nh)
277 return nh->rtnh_weight;
280void rtnl_route_nh_set_ifindex(
struct rtnl_nexthop *nh,
int ifindex)
282 nh->rtnh_ifindex = ifindex;
283 nh->ce_mask |= NH_ATTR_IFINDEX;
286int rtnl_route_nh_get_ifindex(
struct rtnl_nexthop *nh)
288 return nh->rtnh_ifindex;
292void rtnl_route_nh_set_gateway(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
294 struct nl_addr *old = nh->rtnh_gateway;
298 nh->ce_mask |= NH_ATTR_GATEWAY;
300 nh->ce_mask &= ~NH_ATTR_GATEWAY;
301 nh->rtnh_gateway = NULL;
308struct nl_addr *rtnl_route_nh_get_gateway(
struct rtnl_nexthop *nh)
310 return nh->rtnh_gateway;
313void rtnl_route_nh_set_flags(
struct rtnl_nexthop *nh,
unsigned int flags)
315 nh->rtnh_flag_mask |= flags;
316 nh->rtnh_flags |= flags;
317 nh->ce_mask |= NH_ATTR_FLAGS;
320void rtnl_route_nh_unset_flags(
struct rtnl_nexthop *nh,
unsigned int flags)
322 nh->rtnh_flag_mask |= flags;
323 nh->rtnh_flags &= ~flags;
324 nh->ce_mask |= NH_ATTR_FLAGS;
327unsigned int rtnl_route_nh_get_flags(
struct rtnl_nexthop *nh)
329 return nh->rtnh_flags;
332void rtnl_route_nh_set_realms(
struct rtnl_nexthop *nh, uint32_t realms)
334 nh->rtnh_realms = realms;
335 nh->ce_mask |= NH_ATTR_REALMS;
338uint32_t rtnl_route_nh_get_realms(
struct rtnl_nexthop *nh)
340 return nh->rtnh_realms;
343int rtnl_route_nh_set_newdst(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
345 struct nl_addr *old = nh->rtnh_newdst;
349 nh->ce_mask |= NH_ATTR_NEWDST;
351 nh->ce_mask &= ~NH_ATTR_NEWDST;
352 nh->rtnh_newdst = NULL;
361struct nl_addr *rtnl_route_nh_get_newdst(
struct rtnl_nexthop *nh)
363 return nh->rtnh_newdst;
366int rtnl_route_nh_set_via(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
368 struct nl_addr *old = nh->rtnh_via;
372 nh->ce_mask |= NH_ATTR_VIA;
374 nh->ce_mask &= ~NH_ATTR_VIA;
384struct nl_addr *rtnl_route_nh_get_via(
struct rtnl_nexthop *nh)
396static const struct trans_tbl nh_flags[] = {
397 __ADD(RTNH_F_DEAD, dead),
398 __ADD(RTNH_F_PERVASIVE, pervasive),
399 __ADD(RTNH_F_ONLINK, onlink),
402char *rtnl_route_nh_flags2str(
int flags,
char *buf,
size_t len)
404 return __flags2str(flags, buf, len, nh_flags, ARRAY_SIZE(nh_flags));
407int rtnl_route_nh_str2flags(
const char *name)
409 return __str2flags(name, nh_flags, ARRAY_SIZE(nh_flags));
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
#define RTNL_REALM_TO(realm)
Extract TO realm from a realms field.
#define RTNL_REALM_FROM(realm)
Extract FROM realm from a realms field.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_STATS
Dump all attributes including statistics.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
enum nl_dump_type dp_type
Specifies the type of dump that is requested.
int dp_ivar
PRIVATE Owned by the current caller.