diff options
Diffstat (limited to 'lib/route/route_obj.c')
-rw-r--r-- | lib/route/route_obj.c | 109 |
1 files changed, 77 insertions, 32 deletions
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c index 9441b77a..ce68259c 100644 --- a/lib/route/route_obj.c +++ b/lib/route/route_obj.c @@ -24,9 +24,10 @@ * @{ */ -#include <netlink-private/netlink.h> -#include <netlink-private/utils.h> -#include <netlink-private/route/nexthop-encap.h> +#include "nl-default.h" + +#include <linux/in_route.h> + #include <netlink/netlink.h> #include <netlink/cache.h> #include <netlink/utils.h> @@ -36,9 +37,40 @@ #include <netlink/route/route.h> #include <netlink/route/link.h> #include <netlink/route/nexthop.h> -#include <linux/in_route.h> + +#include "nl-route.h" +#include "nl-aux-route/nl-route.h" +#include "nl-priv-dynamic-core/nl-core.h" +#include "nexthop-encap.h" /** @cond SKIP */ +struct rtnl_route { + NLHDR_COMMON + + uint8_t rt_family; + uint8_t rt_dst_len; + uint8_t rt_src_len; + uint8_t rt_tos; + uint8_t rt_protocol; + uint8_t rt_scope; + uint8_t rt_type; + uint8_t rt_nmetrics; + uint8_t rt_ttl_propagate; + uint32_t rt_flags; + struct nl_addr *rt_dst; + struct nl_addr *rt_src; + uint32_t rt_table; + uint32_t rt_iif; + uint32_t rt_prio; + uint32_t rt_metrics[RTAX_MAX]; + uint32_t rt_metrics_mask; + uint32_t rt_nr_nh; + struct nl_addr *rt_pref_src; + struct nl_list_head rt_nexthops; + struct rtnl_rtcacheinfo rt_cacheinfo; + uint32_t rt_flag_mask; +}; + #define ROUTE_ATTR_FAMILY 0x000001 #define ROUTE_ATTR_TOS 0x000002 #define ROUTE_ATTR_TABLE 0x000004 @@ -145,7 +177,8 @@ static void route_dump_line(struct nl_object *a, struct nl_dump_params *p) nl_dump(p, "cache "); if (!(r->ce_mask & ROUTE_ATTR_DST) || - nl_addr_get_len(r->rt_dst) == 0) + (nl_addr_get_prefixlen(r->rt_dst) == 0 && + nl_addr_get_len(r->rt_dst) > 0 && nl_addr_iszero(r->rt_dst))) nl_dump(p, "default "); else nl_dump(p, "%s ", nl_addr2str(r->rt_dst, buf, sizeof(buf))); @@ -311,7 +344,7 @@ static void route_keygen(struct nl_object *obj, uint32_t *hashkey, uint32_t rt_table; uint32_t rt_prio; char rt_addr[0]; - } __attribute__((packed)) *rkey = NULL; + } _nl_packed *rkey = NULL; #ifdef NL_DEBUG char buf[INET6_ADDRSTRLEN+5]; #endif @@ -368,22 +401,21 @@ static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b, int i, found; uint64_t diff = 0; -#define ROUTE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ROUTE_ATTR_##ATTR, a, b, EXPR) - - diff |= ROUTE_DIFF(FAMILY, a->rt_family != b->rt_family); - diff |= ROUTE_DIFF(TOS, a->rt_tos != b->rt_tos); - diff |= ROUTE_DIFF(TABLE, a->rt_table != b->rt_table); - diff |= ROUTE_DIFF(PROTOCOL, a->rt_protocol != b->rt_protocol); - diff |= ROUTE_DIFF(SCOPE, a->rt_scope != b->rt_scope); - diff |= ROUTE_DIFF(TYPE, a->rt_type != b->rt_type); - diff |= ROUTE_DIFF(PRIO, a->rt_prio != b->rt_prio); - diff |= ROUTE_DIFF(DST, nl_addr_cmp(a->rt_dst, b->rt_dst)); - diff |= ROUTE_DIFF(SRC, nl_addr_cmp(a->rt_src, b->rt_src)); - diff |= ROUTE_DIFF(IIF, a->rt_iif != b->rt_iif); - diff |= ROUTE_DIFF(PREF_SRC, nl_addr_cmp(a->rt_pref_src, - b->rt_pref_src)); - diff |= ROUTE_DIFF(TTL_PROPAGATE, - a->rt_ttl_propagate != b->rt_ttl_propagate); +#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR) + diff |= _DIFF(ROUTE_ATTR_FAMILY, a->rt_family != b->rt_family); + diff |= _DIFF(ROUTE_ATTR_TOS, a->rt_tos != b->rt_tos); + diff |= _DIFF(ROUTE_ATTR_TABLE, a->rt_table != b->rt_table); + diff |= _DIFF(ROUTE_ATTR_PROTOCOL, a->rt_protocol != b->rt_protocol); + diff |= _DIFF(ROUTE_ATTR_SCOPE, a->rt_scope != b->rt_scope); + diff |= _DIFF(ROUTE_ATTR_TYPE, a->rt_type != b->rt_type); + diff |= _DIFF(ROUTE_ATTR_PRIO, a->rt_prio != b->rt_prio); + diff |= _DIFF(ROUTE_ATTR_DST, nl_addr_cmp(a->rt_dst, b->rt_dst)); + diff |= _DIFF(ROUTE_ATTR_SRC, nl_addr_cmp(a->rt_src, b->rt_src)); + diff |= _DIFF(ROUTE_ATTR_IIF, a->rt_iif != b->rt_iif); + diff |= _DIFF(ROUTE_ATTR_PREF_SRC, + nl_addr_cmp(a->rt_pref_src, b->rt_pref_src)); + diff |= _DIFF(ROUTE_ATTR_TTL_PROPAGATE, + a->rt_ttl_propagate != b->rt_ttl_propagate); if (flags & LOOSE_COMPARISON) { nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) { @@ -405,10 +437,10 @@ static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b, if (a->rt_metrics_mask & (1 << i) && (!(b->rt_metrics_mask & (1 << i)) || a->rt_metrics[i] != b->rt_metrics[i])) - diff |= ROUTE_DIFF(METRICS, 1); + diff |= _DIFF(ROUTE_ATTR_METRICS, 1); } - diff |= ROUTE_DIFF(FLAGS, + diff |= _DIFF(ROUTE_ATTR_FLAGS, (a->rt_flags ^ b->rt_flags) & b->rt_flag_mask); } else { if (a->rt_nr_nh != b->rt_nr_nh) @@ -446,23 +478,22 @@ static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b, for (i = 0; i < RTAX_MAX - 1; i++) { if ((a->rt_metrics_mask & (1 << i)) ^ (b->rt_metrics_mask & (1 << i))) - diff |= ROUTE_DIFF(METRICS, 1); + diff |= _DIFF(ROUTE_ATTR_METRICS, 1); else - diff |= ROUTE_DIFF(METRICS, + diff |= _DIFF(ROUTE_ATTR_METRICS, a->rt_metrics[i] != b->rt_metrics[i]); } - diff |= ROUTE_DIFF(FLAGS, a->rt_flags != b->rt_flags); + diff |= _DIFF(ROUTE_ATTR_FLAGS, a->rt_flags != b->rt_flags); } out: return diff; nh_mismatch: - diff |= ROUTE_DIFF(MULTIPATH, 1); + diff |= _DIFF(ROUTE_ATTR_MULTIPATH, 1); goto out; - -#undef ROUTE_DIFF +#undef _DIFF } static int route_update(struct nl_object *old_obj, struct nl_object *new_obj) @@ -1156,9 +1187,23 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result) if (!(dst = nl_addr_alloc_attr(tb[RTA_DST], family))) return -NLE_NOMEM; } else { - if (!(dst = nl_addr_alloc(0))) + int len; + + switch (family) { + case AF_INET: + len = 4; + break; + + case AF_INET6: + len = 16; + break; + default: + len = 0; + break; + } + + if (!(dst = nl_addr_build(family, NULL, len))) return -NLE_NOMEM; - nl_addr_set_family(dst, rtm->rtm_family); } nl_addr_set_prefixlen(dst, rtm->rtm_dst_len); |