18 #include <netlink-private/netlink.h> 19 #include <netlink-private/route/nexthop-encap.h> 20 #include <netlink/netlink.h> 21 #include <netlink/utils.h> 22 #include <netlink/route/rtnl.h> 23 #include <netlink/route/route.h> 26 #define NH_ATTR_FLAGS 0x000001 27 #define NH_ATTR_WEIGHT 0x000002 28 #define NH_ATTR_IFINDEX 0x000004 29 #define NH_ATTR_GATEWAY 0x000008 30 #define NH_ATTR_REALMS 0x000010 31 #define NH_ATTR_NEWDST 0x000020 32 #define NH_ATTR_VIA 0x000040 33 #define NH_ATTR_ENCAP 0x000080 41 struct rtnl_nexthop *rtnl_route_nh_alloc(
void)
43 struct rtnl_nexthop *nh;
45 nh = calloc(1,
sizeof(*nh));
49 nl_init_list_head(&nh->rtnh_list);
54 struct rtnl_nexthop *rtnl_route_nh_clone(
struct rtnl_nexthop *src)
56 struct rtnl_nexthop *nh;
58 nh = rtnl_route_nh_alloc();
62 nh->rtnh_flags = src->rtnh_flags;
63 nh->rtnh_flag_mask = src->rtnh_flag_mask;
64 nh->rtnh_weight = src->rtnh_weight;
65 nh->rtnh_ifindex = src->rtnh_ifindex;
66 nh->ce_mask = src->ce_mask;
68 if (src->rtnh_gateway) {
70 if (!nh->rtnh_gateway) {
76 if (src->rtnh_newdst) {
78 if (!nh->rtnh_newdst) {
98 void rtnl_route_nh_free(
struct rtnl_nexthop *nh)
103 if (nh->rtnh_encap) {
104 if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
105 nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
106 free(nh->rtnh_encap->priv);
107 free(nh->rtnh_encap);
114 int rtnl_route_nh_compare(
struct rtnl_nexthop *a,
struct rtnl_nexthop *b,
115 uint32_t attrs,
int loose)
119 #define NH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NH_ATTR_##ATTR, a, b, EXPR) 121 diff |= NH_DIFF(IFINDEX, a->rtnh_ifindex != b->rtnh_ifindex);
122 diff |= NH_DIFF(WEIGHT, a->rtnh_weight != b->rtnh_weight);
123 diff |= NH_DIFF(REALMS, a->rtnh_realms != b->rtnh_realms);
124 diff |= NH_DIFF(GATEWAY,
nl_addr_cmp(a->rtnh_gateway,
126 diff |= NH_DIFF(NEWDST,
nl_addr_cmp(a->rtnh_newdst,
130 diff |= NH_DIFF(ENCAP, nh_encap_compare(a->rtnh_encap,
134 diff |= NH_DIFF(FLAGS,
135 (a->rtnh_flags ^ b->rtnh_flags) & b->rtnh_flag_mask);
137 diff |= NH_DIFF(FLAGS, a->rtnh_flags != b->rtnh_flags);
144 static void nh_dump_line(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
146 struct nl_cache *link_cache;
151 if (nh->ce_mask & NH_ATTR_ENCAP)
152 nh_encap_dump(nh->rtnh_encap, dp);
154 if (nh->ce_mask & NH_ATTR_NEWDST)
160 if (nh->ce_mask & NH_ATTR_VIA)
164 if (nh->ce_mask & NH_ATTR_GATEWAY)
168 if(nh->ce_mask & NH_ATTR_IFINDEX) {
175 nl_dump(dp,
" dev %d", nh->rtnh_ifindex);
181 nl_cache_put(link_cache);
184 static void nh_dump_details(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
186 struct nl_cache *link_cache;
193 if (nh->ce_mask & NH_ATTR_ENCAP)
194 nh_encap_dump(nh->rtnh_encap, dp);
196 if (nh->ce_mask & NH_ATTR_NEWDST)
200 if (nh->ce_mask & NH_ATTR_VIA)
204 if (nh->ce_mask & NH_ATTR_GATEWAY)
208 if(nh->ce_mask & NH_ATTR_IFINDEX) {
215 nl_dump(dp,
" dev %d", nh->rtnh_ifindex);
218 if (nh->ce_mask & NH_ATTR_WEIGHT)
219 nl_dump(dp,
" weight %u", nh->rtnh_weight);
221 if (nh->ce_mask & NH_ATTR_REALMS)
222 nl_dump(dp,
" realm %04x:%04x",
226 if (nh->ce_mask & NH_ATTR_FLAGS)
227 nl_dump(dp,
" <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags,
231 nl_cache_put(link_cache);
234 void rtnl_route_nh_dump(
struct rtnl_nexthop *nh,
struct nl_dump_params *dp)
238 nh_dump_line(nh, dp);
243 if (dp->
dp_ivar == NH_DUMP_FROM_DETAILS)
244 nh_dump_details(nh, dp);
252 void nh_set_encap(
struct rtnl_nexthop *nh,
struct rtnl_nh_encap *rtnh_encap)
254 if (nh->rtnh_encap) {
255 if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
256 nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
257 free(nh->rtnh_encap->priv);
258 free(nh->rtnh_encap);
262 nh->rtnh_encap = rtnh_encap;
263 nh->ce_mask |= NH_ATTR_ENCAP;
265 nh->rtnh_encap = NULL;
266 nh->ce_mask &= ~NH_ATTR_ENCAP;
275 void rtnl_route_nh_set_weight(
struct rtnl_nexthop *nh, uint8_t weight)
277 nh->rtnh_weight = weight;
278 nh->ce_mask |= NH_ATTR_WEIGHT;
281 uint8_t rtnl_route_nh_get_weight(
struct rtnl_nexthop *nh)
283 return nh->rtnh_weight;
286 void rtnl_route_nh_set_ifindex(
struct rtnl_nexthop *nh,
int ifindex)
288 nh->rtnh_ifindex = ifindex;
289 nh->ce_mask |= NH_ATTR_IFINDEX;
292 int rtnl_route_nh_get_ifindex(
struct rtnl_nexthop *nh)
294 return nh->rtnh_ifindex;
298 void rtnl_route_nh_set_gateway(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
300 struct nl_addr *old = nh->rtnh_gateway;
304 nh->ce_mask |= NH_ATTR_GATEWAY;
306 nh->ce_mask &= ~NH_ATTR_GATEWAY;
307 nh->rtnh_gateway = NULL;
314 struct nl_addr *rtnl_route_nh_get_gateway(
struct rtnl_nexthop *nh)
316 return nh->rtnh_gateway;
319 void rtnl_route_nh_set_flags(
struct rtnl_nexthop *nh,
unsigned int flags)
321 nh->rtnh_flag_mask |= flags;
322 nh->rtnh_flags |= flags;
323 nh->ce_mask |= NH_ATTR_FLAGS;
326 void rtnl_route_nh_unset_flags(
struct rtnl_nexthop *nh,
unsigned int flags)
328 nh->rtnh_flag_mask |= flags;
329 nh->rtnh_flags &= ~flags;
330 nh->ce_mask |= NH_ATTR_FLAGS;
333 unsigned int rtnl_route_nh_get_flags(
struct rtnl_nexthop *nh)
335 return nh->rtnh_flags;
338 void rtnl_route_nh_set_realms(
struct rtnl_nexthop *nh, uint32_t realms)
340 nh->rtnh_realms = realms;
341 nh->ce_mask |= NH_ATTR_REALMS;
344 uint32_t rtnl_route_nh_get_realms(
struct rtnl_nexthop *nh)
346 return nh->rtnh_realms;
349 int rtnl_route_nh_set_newdst(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
351 struct nl_addr *old = nh->rtnh_newdst;
359 nh->ce_mask |= NH_ATTR_NEWDST;
361 nh->ce_mask &= ~NH_ATTR_NEWDST;
362 nh->rtnh_newdst = NULL;
371 struct nl_addr *rtnl_route_nh_get_newdst(
struct rtnl_nexthop *nh)
373 return nh->rtnh_newdst;
376 int rtnl_route_nh_set_via(
struct rtnl_nexthop *nh,
struct nl_addr *addr)
378 struct nl_addr *old = nh->rtnh_via;
386 nh->ce_mask |= NH_ATTR_VIA;
388 nh->ce_mask &= ~NH_ATTR_VIA;
398 struct nl_addr *rtnl_route_nh_get_via(
struct rtnl_nexthop *nh)
410 static const struct trans_tbl nh_flags[] = {
411 __ADD(RTNH_F_DEAD, dead),
412 __ADD(RTNH_F_PERVASIVE, pervasive),
413 __ADD(RTNH_F_ONLINK, onlink),
416 char *rtnl_route_nh_flags2str(
int flags,
char *buf,
size_t len)
418 return __flags2str(flags, buf, len, nh_flags, ARRAY_SIZE(nh_flags));
421 int rtnl_route_nh_str2flags(
const char *name)
423 return __str2flags(name, nh_flags, ARRAY_SIZE(nh_flags));
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Dump object briefly on one line.
#define RTNL_REALM_TO(realm)
Extract TO realm from a realms field.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
#define RTNL_REALM_FROM(realm)
Extract FROM realm from a realms field.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
enum nl_dump_type dp_type
Specifies the type of dump that is requested.
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Dump all attributes but no statistics.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
int nl_addr_valid(const char *addr, int family)
Check if address string is parseable for a specific address family.
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
int dp_ivar
PRIVATE Owned by the current caller.
Dump all attributes including statistics.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.