route_obj.c revision 464988628802b76d5b3e50af99158413ac28bd18
144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/route/route_obj.c Route Object 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @ingroup route 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup route_obj Route Object 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Attributes 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Name Default 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf * ------------------------------------------------------------- 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf * routing table RT_TABLE_MAIN 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf * scope RT_SCOPE_NOWHERE 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf * tos 0 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf * realms 0 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf * protocol RTPROT_STATIC 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf * prio 0 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf * family AF_UNSPEC 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf * type RTN_UNICAST 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf * oif RTNL_LINK_NOT_FOUND 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf * iif NULL 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf * mpalgo IP_MP_ALG_NONE 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/cache.h> 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/data.h> 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/rtnl.h> 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/route.h> 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/link.h> 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */ 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_FAMILY 0x000001 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_TOS 0x000002 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_TABLE 0x000004 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_PROTOCOL 0x000008 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_SCOPE 0x000010 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_TYPE 0x000020 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_FLAGS 0x000040 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_DST 0x000080 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_SRC 0x000100 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_IIF 0x000200 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_OIF 0x000400 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_GATEWAY 0x000800 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_PRIO 0x001000 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_PREF_SRC 0x002000 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_METRICS 0x004000 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_MULTIPATH 0x008000 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_REALMS 0x010000 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_CACHEINFO 0x020000 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_ATTR_MP_ALGO 0x040000 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */ 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 6744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_brief(struct nl_object *a, struct nl_dump_params *p); 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf 6944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void route_constructor(struct nl_object *c) 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *r = (struct rtnl_route *) c; 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_init_list_head(&r->rt_nexthops); 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf 7644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void route_free_data(struct nl_object *c) 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *r = (struct rtnl_route *) c; 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_nexthop *nh, *tmp; 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r == NULL) 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(r->rt_dst); 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(r->rt_src); 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(r->rt_gateway); 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(r->rt_pref_src); 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry_safe(nh, tmp, &r->rt_nexthops, rtnh_list) { 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_remove_nexthop(nh); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_nh_free(nh); 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf 9544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_clone(struct nl_object *_dst, struct nl_object *_src) 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *dst = (struct rtnl_route *) _dst; 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *src = (struct rtnl_route *) _src; 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_nexthop *nh, *new; 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->rt_dst) 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->rt_dst = nl_addr_clone(src->rt_dst))) 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->rt_src) 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->rt_src = nl_addr_clone(src->rt_src))) 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->rt_gateway) 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->rt_gateway = nl_addr_clone(src->rt_gateway))) 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->rt_pref_src) 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->rt_pref_src = nl_addr_clone(src->rt_pref_src))) 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_init_list_head(&dst->rt_nexthops); 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(nh, &src->rt_nexthops, rtnh_list) { 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf new = rtnl_route_nh_clone(nh); 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!new) 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_add_nexthop(dst, new); 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 12744d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_get_errno(); 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf 13144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_brief(struct nl_object *a, struct nl_dump_params *p) 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *r = (struct rtnl_route *) a; 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *link_cache; 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf link_cache = nl_cache_mngt_require("route/link"); 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf 139464988628802b76d5b3e50af99158413ac28bd18Thomas Graf if (!(r->ce_mask & ROUTE_ATTR_DST) || 140464988628802b76d5b3e50af99158413ac28bd18Thomas Graf nl_addr_get_len(r->rt_dst) == 0) 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "default "); 142464988628802b76d5b3e50af99158413ac28bd18Thomas Graf else 143464988628802b76d5b3e50af99158413ac28bd18Thomas Graf dp_dump(p, "%s ", nl_addr2str(r->rt_dst, buf, sizeof(buf))); 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_OIF) { 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link_cache) 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dev %s ", 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_i2name(link_cache, r->rt_oif, 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dev %d ", r->rt_oif); 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_GATEWAY) 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "via %s ", nl_addr2str(r->rt_gateway, buf, 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf sizeof(buf))); 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (r->ce_mask & ROUTE_ATTR_MULTIPATH) 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "via nexthops "); 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_SCOPE) 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "scope %s ", 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_scope2str(r->rt_scope, buf, sizeof(buf))); 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_FLAGS && r->rt_flags) { 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf int flags = r->rt_flags; 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "<"); 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define PRINT_FLAG(f) if (flags & RTNH_F_##f) { \ 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf flags &= ~RTNH_F_##f; dp_dump(p, #f "%s", flags ? "," : ""); } 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(DEAD); 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(ONLINK); 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(PERVASIVE); 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef PRINT_FLAG 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define PRINT_FLAG(f) if (flags & RTM_F_##f) { \ 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf flags &= ~RTM_F_##f; dp_dump(p, #f "%s", flags ? "," : ""); } 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(NOTIFY); 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(CLONED); 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(EQUALIZE); 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf PRINT_FLAG(PREFIX); 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef PRINT_FLAG 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, ">"); 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf return 1; 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf 19244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_full(struct nl_object *a, struct nl_dump_params *p) 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *r = (struct rtnl_route *) a; 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *link_cache; 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, line; 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf link_cache = nl_cache_mngt_require("route/link"); 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf line = route_dump_brief(a, p); 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_MULTIPATH) { 20344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_nexthop *nh; 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(nh, &r->rt_nexthops, rtnh_list) { 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " via "); 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nh->rtnh_mask & NEXTHOP_HAS_GATEWAY) 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s ", 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(nh->rtnh_gateway, 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link_cache) { 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dev %s ", 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_i2name(link_cache, 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf nh->rtnh_ifindex, 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dev %d ", nh->rtnh_ifindex); 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "weight %u <%s>\n", nh->rtnh_weight, 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_nh_flags2str(nh->rtnh_flags, 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " "); 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_PREF_SRC) 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "preferred-src %s ", 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(r->rt_pref_src, buf, sizeof(buf))); 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_TABLE) 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "table %s ", 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_table2str(r->rt_table, buf, sizeof(buf))); 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_TYPE) 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "type %s ", 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_rtntype2str(r->rt_type, buf, sizeof(buf))); 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_PRIO) 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "metric %#x ", r->rt_prio); 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_FAMILY) 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "family %s ", 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(r->rt_family, buf, sizeof(buf))); 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_PROTOCOL) 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "protocol %s ", 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_proto2str(r->rt_protocol, buf, sizeof(buf))); 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf if ((r->ce_mask & (ROUTE_ATTR_IIF | ROUTE_ATTR_SRC | ROUTE_ATTR_TOS | 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf ROUTE_ATTR_REALMS)) || 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf ((r->ce_mask & ROUTE_ATTR_CACHEINFO) && 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf r->rt_cacheinfo.rtci_error)) { 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " "); 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_IIF) 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "iif %s ", r->rt_iif); 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_SRC) 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "src %s ", 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(r->rt_src, buf, sizeof(buf))); 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_TOS) 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "tos %#x ", r->rt_tos); 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_REALMS) 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "realm %04x:%04x ", 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf RTNL_REALM_FROM(r->rt_realms), 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf RTNL_REALM_TO(r->rt_realms)); 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf if ((r->ce_mask & ROUTE_ATTR_CACHEINFO) && 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf r->rt_cacheinfo.rtci_error) 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "error %d (%s) ", r->rt_cacheinfo.rtci_error, 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf strerror(-r->rt_cacheinfo.rtci_error)); 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->ce_mask & ROUTE_ATTR_METRICS) { 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " "); 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < RTAX_MAX; i++) 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (r->rt_metrics_mask & (1 << i)) 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s %u ", 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_metric2str(i+1, 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf)), 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf r->rt_metrics[i]); 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf 29644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *route = (struct rtnl_route *) obj; 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf int line; 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf line = route_dump_full(obj, p); 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_CACHEINFO) { 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_rtcacheinfo *ci = &route->rt_cacheinfo; 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " used %u refcnt %u ", 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf ci->rtci_used, ci->rtci_clntref); 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "last-use %us expires %us\n", 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf ci->rtci_last_use / nl_get_hz(), 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf ci->rtci_expires / nl_get_hz()); 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf 31544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_xml(struct nl_object *obj, struct nl_dump_params *p) 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *route = (struct rtnl_route *) obj; 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf int line = 0; 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "<route>\n"); 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <family>%s</family>\n", 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(route->rt_family, buf, sizeof(buf))); 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_DST) 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <dst>%s</dst>\n", 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_dst, buf, sizeof(buf))); 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SRC) 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <src>%s</src>\n", 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_src, buf, sizeof(buf))); 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_GATEWAY) 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <gateway>%s</gateway>\n", 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_gateway, buf, sizeof(buf))); 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_PREF_SRC) 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <prefsrc>%s</prefsrc>\n", 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_pref_src, buf, sizeof(buf))); 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_IIF) 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <iif>%s</iif>\n", route->rt_iif); 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_REALMS) 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <realms>%u</realms>\n", 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_realms); 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TOS) 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <tos>%u</tos>\n", route->rt_tos); 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TABLE) 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <table>%u</table>\n", 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_table); 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SCOPE) 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <scope>%s</scope>\n", 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_scope2str(route->rt_scope, buf, sizeof(buf))); 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_PRIO) 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <metric>%u</metric>\n", 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_prio); 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_OIF) { 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *link_cache; 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf link_cache = nl_cache_mngt_require("route/link"); 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link_cache) 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <oif>%s</oif>\n", 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_i2name(link_cache, 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_oif, 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <oif>%u</oif>\n", 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_oif); 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TYPE) 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <type>%s</type>\n", 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_rtntype2str(route->rt_type, buf, sizeof(buf))); 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "</route>\n"); 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf uint8_t rt_protocol; 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t rt_flags; 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t rt_metrics[RTAX_MAX]; 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t rt_metrics_mask; 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_nexthop * rt_nexthops; 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_rtcacheinfo rt_cacheinfo; 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t rt_mp_algo; 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf 39744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_dump_env(struct nl_object *obj, struct nl_dump_params *p) 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *route = (struct rtnl_route *) obj; 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf int line = 0; 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_FAMILY=%s\n", 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(route->rt_family, buf, sizeof(buf))); 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_DST) 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_DST=%s\n", 40844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_dst, buf, sizeof(buf))); 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SRC) 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_SRC=%s\n", 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_src, buf, sizeof(buf))); 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_GATEWAY) 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_GATEWAY=%s\n", 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_gateway, buf, sizeof(buf))); 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_PREF_SRC) 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_PREFSRC=%s\n", 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(route->rt_pref_src, buf, sizeof(buf))); 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_IIF) 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_IIF=%s\n", route->rt_iif); 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_REALMS) 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_REALM=%u\n", 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_realms); 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TOS) 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_TOS=%u\n", route->rt_tos); 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TABLE) 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_TABLE=%u\n", 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_table); 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SCOPE) 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_SCOPE=%s\n", 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_scope2str(route->rt_scope, buf, sizeof(buf))); 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_PRIO) 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_METRIC=%u\n", 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_prio); 44344d362409d5469aed47d19e7908d19bd194493aThomas Graf 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_OIF) { 44544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *link_cache; 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_OIF_IFINDEX=%u\n", 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_oif); 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf link_cache = nl_cache_mngt_require("route/link"); 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link_cache) 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_OIF_IFNAME=%s\n", 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_i2name(link_cache, 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_oif, 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 45744d362409d5469aed47d19e7908d19bd194493aThomas Graf 45844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TYPE) 45944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "ROUTE_TYPE=%s\n", 46044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_rtntype2str(route->rt_type, buf, sizeof(buf))); 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 46344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf 46544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int route_compare(struct nl_object *_a, struct nl_object *_b, 46644d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 46744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *a = (struct rtnl_route *) _a; 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *b = (struct rtnl_route *) _b; 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define ROUTE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ROUTE_ATTR_##ATTR, a, b, EXPR) 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf 47444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(FAMILY, a->rt_family != b->rt_family); 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(TOS, a->rt_tos != b->rt_tos); 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(TABLE, a->rt_table != b->rt_table); 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(PROTOCOL, a->rt_protocol != b->rt_protocol); 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(SCOPE, a->rt_scope != b->rt_scope); 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(TYPE, a->rt_type != b->rt_type); 48044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(OIF, a->rt_oif != b->rt_oif); 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(PRIO, a->rt_prio != b->rt_prio); 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(REALMS, a->rt_realms != b->rt_realms); 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(MP_ALGO, a->rt_mp_algo != b->rt_mp_algo); 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(DST, nl_addr_cmp(a->rt_dst, b->rt_dst)); 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(SRC, nl_addr_cmp(a->rt_src, b->rt_src)); 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(IIF, strcmp(a->rt_iif, b->rt_iif)); 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(PREF_SRC, nl_addr_cmp(a->rt_pref_src, 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf b->rt_pref_src)); 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(GATEWAY, nl_addr_cmp(a->rt_gateway, 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf b->rt_gateway)); 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf /* FIXME: Compare metrics, multipath config */ 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (flags & LOOSE_FLAG_COMPARISON) 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(FLAGS, 49644d362409d5469aed47d19e7908d19bd194493aThomas Graf (a->rt_flags ^ b->rt_flags) & b->rt_flag_mask); 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 49844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= ROUTE_DIFF(FLAGS, a->rt_flags != b->rt_flags); 49944d362409d5469aed47d19e7908d19bd194493aThomas Graf 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef ROUTE_DIFF 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf 50544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl route_attrs[] = { 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_FAMILY, family) 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_TOS, tos) 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_TABLE, table) 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_PROTOCOL, protocol) 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_SCOPE, scope) 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_TYPE, type) 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_FLAGS, flags) 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_DST, dst) 51444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_SRC, src) 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_IIF, iif) 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_OIF, oif) 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_GATEWAY, gateway) 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_PRIO, prio) 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_PREF_SRC, pref_src) 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_METRICS, metrics) 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_MULTIPATH, multipath) 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_REALMS, realms) 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_CACHEINFO, cacheinfo) 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(ROUTE_ATTR_MP_ALGO, mp_algo) 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf 52744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *route_attrs2str(int attrs, char *buf, size_t len) 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, route_attrs, 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(route_attrs)); 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf 53844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_route *rtnl_route_alloc(void) 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct rtnl_route *) nl_object_alloc(&route_obj_ops); 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf 54344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_get(struct rtnl_route *route) 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) route); 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf 54844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_put(struct rtnl_route *route) 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) route); 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf 56044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_table(struct rtnl_route *route, int table) 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_table = table; 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_TABLE; 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56544d362409d5469aed47d19e7908d19bd194493aThomas Graf 56644d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_table(struct rtnl_route *route) 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TABLE) 56944d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_table; 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf return RT_TABLE_MAIN; 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf 57444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_scope(struct rtnl_route *route, int scope) 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_scope = scope; 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_SCOPE; 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf 58044d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_scope(struct rtnl_route *route) 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SCOPE) 58344d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_scope; 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf return RT_SCOPE_NOWHERE; 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 58744d362409d5469aed47d19e7908d19bd194493aThomas Graf 58844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_tos(struct rtnl_route *route, int tos) 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_tos = tos; 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_TOS; 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf 59444d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_tos(struct rtnl_route *route) 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_tos; 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf 59944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_realms(struct rtnl_route *route, realm_t realms) 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_realms = realms; 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_REALMS; 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf 60544d362409d5469aed47d19e7908d19bd194493aThomas Grafrealm_t rtnl_route_get_realms(struct rtnl_route *route) 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_realms; 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60944d362409d5469aed47d19e7908d19bd194493aThomas Graf 61044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_protocol(struct rtnl_route *route, int proto) 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_protocol = proto; 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_PROTOCOL; 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 61544d362409d5469aed47d19e7908d19bd194493aThomas Graf 61644d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_protocol(struct rtnl_route *route) 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_PROTOCOL) 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_protocol; 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTPROT_STATIC; 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf 62444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_prio(struct rtnl_route *route, int prio) 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_prio = prio; 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_PRIO; 62844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf 63044d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_prio(struct rtnl_route *route) 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_prio; 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf 63544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_family(struct rtnl_route *route, int family) 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_family = family; 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_FAMILY; 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf 64144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_family(struct rtnl_route *route) 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_FAMILY) 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_family; 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf else 64644d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf 64944d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_set_dst(struct rtnl_route *route, struct nl_addr *addr) 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_FAMILY) { 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != route->rt_family) 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Address family mismatch"); 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_family = addr->a_family; 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->rt_dst) 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(route->rt_dst); 65944d362409d5469aed47d19e7908d19bd194493aThomas Graf 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_dst = addr; 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= (ROUTE_ATTR_DST | ROUTE_ATTR_FAMILY); 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf 66844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_route_get_dst(struct rtnl_route *route) 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 67044d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_dst; 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf 67344d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_dst_len(struct rtnl_route *route) 67444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_DST) 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_addr_get_prefixlen(route->rt_dst); 67744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 67844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 67944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 68044d362409d5469aed47d19e7908d19bd194493aThomas Graf 68144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_set_src(struct rtnl_route *route, struct nl_addr *addr) 68244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 68344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_FAMILY) { 68444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != route->rt_family) 68544d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Address family mismatch"); 68644d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 68744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_family = addr->a_family; 68844d362409d5469aed47d19e7908d19bd194493aThomas Graf 68944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->rt_src) 69044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(route->rt_src); 69144d362409d5469aed47d19e7908d19bd194493aThomas Graf 69244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 69344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_src = addr; 69444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= (ROUTE_ATTR_SRC | ROUTE_ATTR_FAMILY); 69544d362409d5469aed47d19e7908d19bd194493aThomas Graf 69644d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 69744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 69844d362409d5469aed47d19e7908d19bd194493aThomas Graf 69944d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_route_get_src(struct rtnl_route *route) 70044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 70144d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_src; 70244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 70344d362409d5469aed47d19e7908d19bd194493aThomas Graf 70444d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_src_len(struct rtnl_route *route) 70544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 70644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_SRC) 70744d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_addr_get_prefixlen(route->rt_src); 70844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 70944d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 71044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 71144d362409d5469aed47d19e7908d19bd194493aThomas Graf 71244d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_set_gateway(struct rtnl_route *route, struct nl_addr *addr) 71344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 71444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_FAMILY) { 71544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != route->rt_family) 71644d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Address family mismatch"); 71744d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 71844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_family = addr->a_family; 71944d362409d5469aed47d19e7908d19bd194493aThomas Graf 72044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->rt_gateway) 72144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(route->rt_gateway); 72244d362409d5469aed47d19e7908d19bd194493aThomas Graf 72344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 72444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_gateway = addr; 72544d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= (ROUTE_ATTR_GATEWAY | ROUTE_ATTR_FAMILY); 72644d362409d5469aed47d19e7908d19bd194493aThomas Graf 72744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 72844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 72944d362409d5469aed47d19e7908d19bd194493aThomas Graf 73044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_route_get_gateway(struct rtnl_route *route) 73144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 73244d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_gateway; 73344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 73444d362409d5469aed47d19e7908d19bd194493aThomas Graf 73544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_type(struct rtnl_route *route, int type) 73644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 73744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_type = type; 73844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_TYPE; 73944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 74044d362409d5469aed47d19e7908d19bd194493aThomas Graf 74144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_type(struct rtnl_route *route) 74244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 74344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_TYPE) 74444d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_type; 74544d362409d5469aed47d19e7908d19bd194493aThomas Graf else 74644d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTN_UNICAST; 74744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 74844d362409d5469aed47d19e7908d19bd194493aThomas Graf 74944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_flags(struct rtnl_route *route, unsigned int flags) 75044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 75144d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_flag_mask |= flags; 75244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_flags |= flags; 75344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_FLAGS; 75444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 75544d362409d5469aed47d19e7908d19bd194493aThomas Graf 75644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_unset_flags(struct rtnl_route *route, unsigned int flags) 75744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 75844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_flag_mask |= flags; 75944d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_flags &= ~flags; 76044d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_FLAGS; 76144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 76244d362409d5469aed47d19e7908d19bd194493aThomas Graf 76344d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_route_get_flags(struct rtnl_route *route) 76444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 76544d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_flags; 76644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 76744d362409d5469aed47d19e7908d19bd194493aThomas Graf 76844d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_set_metric(struct rtnl_route *route, int metric, uint32_t value) 76944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 77044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (metric > RTAX_MAX || metric < 1) 77144d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Metric out of range (1..%d)", 77244d362409d5469aed47d19e7908d19bd194493aThomas Graf RTAX_MAX); 77344d362409d5469aed47d19e7908d19bd194493aThomas Graf 77444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_metrics[metric - 1] = value; 77544d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_metrics_mask |= (1 << (metric - 1)); 77644d362409d5469aed47d19e7908d19bd194493aThomas Graf 77744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 77844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 77944d362409d5469aed47d19e7908d19bd194493aThomas Graf 78044d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_unset_metric(struct rtnl_route *route, int metric) 78144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 78244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (metric > RTAX_MAX || metric < 1) 78344d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Metric out of range (1..%d)", 78444d362409d5469aed47d19e7908d19bd194493aThomas Graf RTAX_MAX); 78544d362409d5469aed47d19e7908d19bd194493aThomas Graf 78644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_metrics_mask &= ~(1 << (metric - 1)); 78744d362409d5469aed47d19e7908d19bd194493aThomas Graf 78844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 78944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 79044d362409d5469aed47d19e7908d19bd194493aThomas Graf 79144d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_route_get_metric(struct rtnl_route *route, int metric) 79244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 79344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (metric > RTAX_MAX || metric < 1) 79444d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 79544d362409d5469aed47d19e7908d19bd194493aThomas Graf 79644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(route->rt_metrics_mask & (1 << (metric - 1)))) 79744d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 79844d362409d5469aed47d19e7908d19bd194493aThomas Graf 79944d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_metrics[metric - 1]; 80044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 80144d362409d5469aed47d19e7908d19bd194493aThomas Graf 80244d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_set_pref_src(struct rtnl_route *route, struct nl_addr *addr) 80344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 80444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_FAMILY) { 80544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != route->rt_family) 80644d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Address family mismatch"); 80744d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 80844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_family = addr->a_family; 80944d362409d5469aed47d19e7908d19bd194493aThomas Graf 81044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->rt_pref_src) 81144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(route->rt_pref_src); 81244d362409d5469aed47d19e7908d19bd194493aThomas Graf 81344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 81444d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_pref_src = addr; 81544d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= (ROUTE_ATTR_PREF_SRC | ROUTE_ATTR_FAMILY); 81644d362409d5469aed47d19e7908d19bd194493aThomas Graf 81744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 81844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 81944d362409d5469aed47d19e7908d19bd194493aThomas Graf 82044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *route) 82144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 82244d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_pref_src; 82344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 82444d362409d5469aed47d19e7908d19bd194493aThomas Graf 82544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_oif(struct rtnl_route *route, int ifindex) 82644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 82744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_oif = ifindex; 82844d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_OIF; 82944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 83044d362409d5469aed47d19e7908d19bd194493aThomas Graf 83144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_route_get_oif(struct rtnl_route *route) 83244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 83344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_OIF) 83444d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_oif; 83544d362409d5469aed47d19e7908d19bd194493aThomas Graf else 83644d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTNL_LINK_NOT_FOUND; 83744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 83844d362409d5469aed47d19e7908d19bd194493aThomas Graf 83944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_iif(struct rtnl_route *route, const char *name) 84044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 84144d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(route->rt_iif, name, sizeof(route->rt_iif) - 1); 84244d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_IIF; 84344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 84444d362409d5469aed47d19e7908d19bd194493aThomas Graf 84544d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_route_get_iif(struct rtnl_route *route) 84644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 84744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_IIF) 84844d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_iif; 84944d362409d5469aed47d19e7908d19bd194493aThomas Graf else 85044d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 85144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 85244d362409d5469aed47d19e7908d19bd194493aThomas Graf 85344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_add_nexthop(struct rtnl_route *route, struct rtnl_nexthop *nh) 85444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 85544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_add_tail(&nh->rtnh_list, &route->rt_nexthops); 85644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_MULTIPATH; 85744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 85844d362409d5469aed47d19e7908d19bd194493aThomas Graf 85944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_remove_nexthop(struct rtnl_nexthop *nh) 86044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 86144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_del(&nh->rtnh_list); 86244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 86344d362409d5469aed47d19e7908d19bd194493aThomas Graf 86444d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_list_head *rtnl_route_get_nexthops(struct rtnl_route *route) 86544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 86644d362409d5469aed47d19e7908d19bd194493aThomas Graf return &route->rt_nexthops; 86744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 86844d362409d5469aed47d19e7908d19bd194493aThomas Graf 86944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_cacheinfo(struct rtnl_route *route, 87044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_rtcacheinfo *ci) 87144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 87244d362409d5469aed47d19e7908d19bd194493aThomas Graf memcpy(&route->rt_cacheinfo, ci, sizeof(*ci)); 87344d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_CACHEINFO; 87444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 87544d362409d5469aed47d19e7908d19bd194493aThomas Graf 87644d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t rtnl_route_get_mp_algo(struct rtnl_route *route) 87744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 87844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (route->ce_mask & ROUTE_ATTR_MP_ALGO) 87944d362409d5469aed47d19e7908d19bd194493aThomas Graf return route->rt_mp_algo; 88044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 88144d362409d5469aed47d19e7908d19bd194493aThomas Graf return IP_MP_ALG_NONE; 88244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 88344d362409d5469aed47d19e7908d19bd194493aThomas Graf 88444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_route_set_mp_algo(struct rtnl_route *route, uint32_t algo) 88544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 88644d362409d5469aed47d19e7908d19bd194493aThomas Graf route->rt_mp_algo = algo; 88744d362409d5469aed47d19e7908d19bd194493aThomas Graf route->ce_mask |= ROUTE_ATTR_MP_ALGO; 88844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 88944d362409d5469aed47d19e7908d19bd194493aThomas Graf 89044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 89144d362409d5469aed47d19e7908d19bd194493aThomas Graf 89244d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_object_ops route_obj_ops = { 89344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "route/route", 89444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct rtnl_route), 89544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_constructor = route_constructor, 89644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = route_free_data, 89744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = route_clone, 89844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_BRIEF] = route_dump_brief, 89944d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_FULL] = route_dump_full, 90044d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_STATS] = route_dump_stats, 90144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_XML] = route_dump_xml, 90244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_ENV] = route_dump_env, 90344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = route_compare, 90444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = route_attrs2str, 90544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_id_attrs = (ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS | 90644d362409d5469aed47d19e7908d19bd194493aThomas Graf ROUTE_ATTR_TABLE | ROUTE_ATTR_DST), 90744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 90844d362409d5469aed47d19e7908d19bd194493aThomas Graf 90944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 910