Merge branch 'get_addr_rta' into iproute2-next
Serhey Popovych says: ==================== Now we enhance get_addr() to return additional information about address (e.g. if it unspecified or multicast) we want to have same functionality for attributes in netlink message. Introduce and use get_addr_rta() that parses given netlink attribute into @inet_prefix data structure in the same way similar get_addr() parses address from it's string representation. Use attribute length to guess address family: force it by giving non AF_UNSPEC @family to get_addr_rta() to ensure address is of expected family. Introduce and use inet_addr_match_rta() to further simplify and unify code where get_addr_rta() intended to be used together with inet_addr_match(). This is next step in ipv4 and ipv6 modules unification to prepare for merge in the future. ==================== Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
db9fd71038
|
|
@ -120,6 +120,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family);
|
|||
int get_addr(inet_prefix *dst, const char *arg, int family);
|
||||
int get_prefix(inet_prefix *dst, char *arg, int family);
|
||||
int mask2bits(__u32 netmask);
|
||||
int get_addr_rta(inet_prefix *dst, const struct rtattr *rta, int family);
|
||||
int get_addr_ila(__u64 *val, const char *arg);
|
||||
|
||||
int read_prop(const char *dev, char *prop, long *value);
|
||||
|
|
@ -174,6 +175,7 @@ int check_ifname(const char *);
|
|||
int get_ifname(char *, const char *);
|
||||
int matches(const char *arg, const char *pattern);
|
||||
int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
|
||||
int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta);
|
||||
|
||||
const char *dnet_ntop(int af, const void *addr, char *str, size_t len);
|
||||
int dnet_pton(int af, const char *src, void *addr);
|
||||
|
|
|
|||
|
|
@ -1523,19 +1523,13 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
if (fnmatch(filter.label, label, 0) != 0)
|
||||
return 0;
|
||||
}
|
||||
if (filter.pfx.family) {
|
||||
if (rta_tb[IFA_LOCAL]) {
|
||||
inet_prefix dst = { .family = ifa->ifa_family };
|
||||
|
||||
memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
|
||||
if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.family && filter.family != ifa->ifa_family)
|
||||
return 0;
|
||||
|
||||
if (inet_addr_match_rta(&filter.pfx, rta_tb[IFA_LOCAL]))
|
||||
return 0;
|
||||
|
||||
if (filter.flushb) {
|
||||
struct nlmsghdr *fn;
|
||||
|
||||
|
|
@ -1889,18 +1883,12 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
|
|||
if ((filter.flags ^ ifa_flags) & filter.flagmask)
|
||||
continue;
|
||||
if (filter.pfx.family || filter.label) {
|
||||
if (!tb[IFA_LOCAL])
|
||||
tb[IFA_LOCAL] = tb[IFA_ADDRESS];
|
||||
struct rtattr *rta =
|
||||
tb[IFA_LOCAL] ? : tb[IFA_ADDRESS];
|
||||
|
||||
if (filter.pfx.family && tb[IFA_LOCAL]) {
|
||||
inet_prefix dst = {
|
||||
.family = ifa->ifa_family
|
||||
};
|
||||
if (inet_addr_match_rta(&filter.pfx, rta))
|
||||
continue;
|
||||
|
||||
memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
|
||||
if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
|
||||
continue;
|
||||
}
|
||||
if (filter.label) {
|
||||
SPRINT_BUF(b1);
|
||||
const char *label;
|
||||
|
|
@ -2072,7 +2060,8 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
while (argc > 0) {
|
||||
if (strcmp(*argv, "to") == 0) {
|
||||
NEXT_ARG();
|
||||
get_prefix(&filter.pfx, *argv, filter.family);
|
||||
if (get_prefix(&filter.pfx, *argv, filter.family))
|
||||
invarg("invalid \"to\"\n", *argv);
|
||||
if (filter.family == AF_UNSPEC)
|
||||
filter.family = filter.pfx.family;
|
||||
} else if (strcmp(*argv, "scope") == 0) {
|
||||
|
|
|
|||
37
ip/ipl2tp.c
37
ip/ipl2tp.c
|
|
@ -296,7 +296,7 @@ static int get_response(struct nlmsghdr *n, void *arg)
|
|||
struct l2tp_data *data = arg;
|
||||
struct l2tp_parm *p = &data->config;
|
||||
struct rtattr *attrs[L2TP_ATTR_MAX + 1];
|
||||
struct rtattr *nla_stats;
|
||||
struct rtattr *nla_stats, *rta;
|
||||
int len;
|
||||
|
||||
/* Validate message and parse attributes */
|
||||
|
|
@ -352,30 +352,25 @@ static int get_response(struct nlmsghdr *n, void *arg)
|
|||
|
||||
if (attrs[L2TP_ATTR_RECV_TIMEOUT])
|
||||
p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]);
|
||||
if (attrs[L2TP_ATTR_IP_SADDR]) {
|
||||
p->local_ip.family = AF_INET;
|
||||
p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]);
|
||||
p->local_ip.bytelen = 4;
|
||||
p->local_ip.bitlen = -1;
|
||||
}
|
||||
if (attrs[L2TP_ATTR_IP_DADDR]) {
|
||||
p->peer_ip.family = AF_INET;
|
||||
p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]);
|
||||
p->peer_ip.bytelen = 4;
|
||||
p->peer_ip.bitlen = -1;
|
||||
}
|
||||
if (attrs[L2TP_ATTR_IP6_SADDR]) {
|
||||
|
||||
rta = attrs[L2TP_ATTR_IP_SADDR];
|
||||
p->local_ip.family = AF_INET;
|
||||
if (!rta) {
|
||||
rta = attrs[L2TP_ATTR_IP6_SADDR];
|
||||
p->local_ip.family = AF_INET6;
|
||||
memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]),
|
||||
p->local_ip.bytelen = 16);
|
||||
p->local_ip.bitlen = -1;
|
||||
}
|
||||
if (attrs[L2TP_ATTR_IP6_DADDR]) {
|
||||
if (rta && get_addr_rta(&p->local_ip, rta, p->local_ip.family))
|
||||
return -1;
|
||||
|
||||
rta = attrs[L2TP_ATTR_IP_DADDR];
|
||||
p->peer_ip.family = AF_INET;
|
||||
if (!rta) {
|
||||
rta = attrs[L2TP_ATTR_IP6_DADDR];
|
||||
p->peer_ip.family = AF_INET6;
|
||||
memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]),
|
||||
p->peer_ip.bytelen = 16);
|
||||
p->peer_ip.bitlen = -1;
|
||||
}
|
||||
if (rta && get_addr_rta(&p->peer_ip, rta, p->peer_ip.family))
|
||||
return -1;
|
||||
|
||||
if (attrs[L2TP_ATTR_UDP_SPORT])
|
||||
p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]);
|
||||
if (attrs[L2TP_ATTR_UDP_DPORT])
|
||||
|
|
|
|||
|
|
@ -95,21 +95,11 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
if (filter.af && filter.af != r->rtm_family)
|
||||
return 0;
|
||||
|
||||
if (tb[RTA_DST] && filter.mdst.bitlen > 0) {
|
||||
inet_prefix dst = { .family = r->rtm_family };
|
||||
if (inet_addr_match_rta(&filter.mdst, tb[RTA_DST]))
|
||||
return 0;
|
||||
|
||||
memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), RTA_PAYLOAD(tb[RTA_DST]));
|
||||
if (inet_addr_match(&dst, &filter.mdst, filter.mdst.bitlen))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tb[RTA_SRC] && filter.msrc.bitlen > 0) {
|
||||
inet_prefix src = { .family = r->rtm_family };
|
||||
|
||||
memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), RTA_PAYLOAD(tb[RTA_SRC]));
|
||||
if (inet_addr_match(&src, &filter.msrc, filter.msrc.bitlen))
|
||||
return 0;
|
||||
}
|
||||
if (inet_addr_match_rta(&filter.msrc, tb[RTA_SRC]))
|
||||
return 0;
|
||||
|
||||
family = get_real_family(r->rtm_type, r->rtm_family);
|
||||
|
||||
|
|
@ -213,6 +203,8 @@ static int mroute_list(int argc, char **argv)
|
|||
} else
|
||||
filter.af = RTNL_FAMILY_IP6MR;
|
||||
|
||||
filter.msrc.family = filter.mdst.family = family;
|
||||
|
||||
while (argc > 0) {
|
||||
if (matches(*argv, "table") == 0) {
|
||||
__u32 tid;
|
||||
|
|
@ -233,14 +225,16 @@ static int mroute_list(int argc, char **argv)
|
|||
id = *argv;
|
||||
} else if (matches(*argv, "from") == 0) {
|
||||
NEXT_ARG();
|
||||
get_prefix(&filter.msrc, *argv, family);
|
||||
if (get_prefix(&filter.msrc, *argv, family))
|
||||
invarg("from value is invalid\n", *argv);
|
||||
} else {
|
||||
if (strcmp(*argv, "to") == 0) {
|
||||
NEXT_ARG();
|
||||
}
|
||||
if (matches(*argv, "help") == 0)
|
||||
usage();
|
||||
get_prefix(&filter.mdst, *argv, family);
|
||||
if (get_prefix(&filter.mdst, *argv, family))
|
||||
invarg("to value is invalid\n", *argv);
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
|
|
|
|||
13
ip/ipneigh.c
13
ip/ipneigh.c
|
|
@ -234,15 +234,9 @@ int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
|
||||
parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
||||
|
||||
if (tb[NDA_DST]) {
|
||||
if (filter.pfx.family) {
|
||||
inet_prefix dst = { .family = r->ndm_family };
|
||||
if (inet_addr_match_rta(&filter.pfx, tb[NDA_DST]))
|
||||
return 0;
|
||||
|
||||
memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
|
||||
if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (filter.unused_only && tb[NDA_CACHEINFO]) {
|
||||
struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
|
||||
|
||||
|
|
@ -418,7 +412,8 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
|||
}
|
||||
if (matches(*argv, "help") == 0)
|
||||
usage();
|
||||
get_prefix(&filter.pfx, *argv, filter.family);
|
||||
if (get_prefix(&filter.pfx, *argv, filter.family))
|
||||
invarg("to value is invalid\n", *argv);
|
||||
if (filter.family == AF_UNSPEC)
|
||||
filter.family = filter.pfx.family;
|
||||
}
|
||||
|
|
|
|||
36
ip/iprule.c
36
ip/iprule.c
|
|
@ -76,8 +76,6 @@ static struct
|
|||
static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
||||
{
|
||||
struct rtmsg *r = NLMSG_DATA(n);
|
||||
inet_prefix src = { .family = r->rtm_family };
|
||||
inet_prefix dst = { .family = r->rtm_family };
|
||||
__u32 table;
|
||||
|
||||
if (preferred_family != AF_UNSPEC && r->rtm_family != preferred_family)
|
||||
|
|
@ -90,24 +88,24 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||
return false;
|
||||
|
||||
if (filter.src.family) {
|
||||
if (tb[FRA_SRC]) {
|
||||
memcpy(&src.data, RTA_DATA(tb[FRA_SRC]),
|
||||
(r->rtm_src_len + 7) / 8);
|
||||
}
|
||||
if (filter.src.family != r->rtm_family ||
|
||||
filter.src.bitlen > r->rtm_src_len ||
|
||||
inet_addr_match(&src, &filter.src, filter.src.bitlen))
|
||||
inet_prefix *f_src = &filter.src;
|
||||
|
||||
if (f_src->family != r->rtm_family ||
|
||||
f_src->bitlen > r->rtm_src_len)
|
||||
return false;
|
||||
|
||||
if (inet_addr_match_rta(f_src, tb[FRA_SRC]))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filter.dst.family) {
|
||||
if (tb[FRA_DST]) {
|
||||
memcpy(&dst.data, RTA_DATA(tb[FRA_DST]),
|
||||
(r->rtm_dst_len + 7) / 8);
|
||||
}
|
||||
if (filter.dst.family != r->rtm_family ||
|
||||
filter.dst.bitlen > r->rtm_dst_len ||
|
||||
inet_addr_match(&dst, &filter.dst, filter.dst.bitlen))
|
||||
inet_prefix *f_dst = &filter.dst;
|
||||
|
||||
if (f_dst->family != r->rtm_family ||
|
||||
f_dst->bitlen > r->rtm_dst_len)
|
||||
return false;
|
||||
|
||||
if (inet_addr_match_rta(f_dst, tb[FRA_DST]))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -500,13 +498,15 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
|||
} else if (matches(*argv, "from") == 0 ||
|
||||
matches(*argv, "src") == 0) {
|
||||
NEXT_ARG();
|
||||
get_prefix(&filter.src, *argv, af);
|
||||
if (get_prefix(&filter.src, *argv, af))
|
||||
invarg("from value is invalid\n", *argv);
|
||||
} else {
|
||||
if (matches(*argv, "dst") == 0 ||
|
||||
matches(*argv, "to") == 0) {
|
||||
NEXT_ARG();
|
||||
}
|
||||
get_prefix(&filter.dst, *argv, af);
|
||||
if (get_prefix(&filter.dst, *argv, af))
|
||||
invarg("to value is invalid\n", *argv);
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,8 +395,6 @@ get_failed:
|
|||
static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
{
|
||||
char s2[64];
|
||||
const char *local = "any";
|
||||
const char *remote = "any";
|
||||
unsigned int iflags = 0;
|
||||
unsigned int oflags = 0;
|
||||
__u8 ttl = 0;
|
||||
|
|
@ -410,23 +408,8 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|||
return;
|
||||
}
|
||||
|
||||
if (tb[IFLA_GRE_REMOTE]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_GRE_REMOTE]);
|
||||
|
||||
if (addr)
|
||||
remote = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "remote", "remote %s ", remote);
|
||||
|
||||
if (tb[IFLA_GRE_LOCAL]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_GRE_LOCAL]);
|
||||
|
||||
if (addr)
|
||||
local = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "local", "local %s ", local);
|
||||
tnl_print_endpoint("remote", tb[IFLA_GRE_REMOTE], AF_INET);
|
||||
tnl_print_endpoint("local", tb[IFLA_GRE_LOCAL], AF_INET);
|
||||
|
||||
if (tb[IFLA_GRE_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_GRE_LINK]);
|
||||
|
|
|
|||
|
|
@ -429,13 +429,10 @@ get_failed:
|
|||
static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
{
|
||||
char s2[64];
|
||||
const char *local = "any";
|
||||
const char *remote = "any";
|
||||
unsigned int iflags = 0;
|
||||
unsigned int oflags = 0;
|
||||
unsigned int flags = 0;
|
||||
__u32 flowinfo = 0;
|
||||
struct in6_addr in6_addr_any = IN6ADDR_ANY_INIT;
|
||||
__u8 ttl = 0;
|
||||
|
||||
if (!tb)
|
||||
|
|
@ -452,27 +449,8 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|||
if (tb[IFLA_GRE_FLOWINFO])
|
||||
flowinfo = rta_getattr_u32(tb[IFLA_GRE_FLOWINFO]);
|
||||
|
||||
if (tb[IFLA_GRE_REMOTE]) {
|
||||
struct in6_addr addr;
|
||||
|
||||
memcpy(&addr, RTA_DATA(tb[IFLA_GRE_REMOTE]), sizeof(addr));
|
||||
|
||||
if (memcmp(&addr, &in6_addr_any, sizeof(addr)))
|
||||
remote = format_host(AF_INET6, sizeof(addr), &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "remote", "remote %s ", remote);
|
||||
|
||||
if (tb[IFLA_GRE_LOCAL]) {
|
||||
struct in6_addr addr;
|
||||
|
||||
memcpy(&addr, RTA_DATA(tb[IFLA_GRE_LOCAL]), sizeof(addr));
|
||||
|
||||
if (memcmp(&addr, &in6_addr_any, sizeof(addr)))
|
||||
local = format_host(AF_INET6, sizeof(addr), &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "local", "local %s ", local);
|
||||
tnl_print_endpoint("remote", tb[IFLA_GRE_REMOTE], AF_INET6);
|
||||
tnl_print_endpoint("local", tb[IFLA_GRE_LOCAL], AF_INET6);
|
||||
|
||||
if (tb[IFLA_GRE_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_GRE_LINK]);
|
||||
|
|
|
|||
|
|
@ -366,19 +366,8 @@ static void ip6tunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb
|
|||
}
|
||||
}
|
||||
|
||||
if (tb[IFLA_IPTUN_REMOTE]) {
|
||||
print_string(PRINT_ANY,
|
||||
"remote",
|
||||
"remote %s ",
|
||||
rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_REMOTE]));
|
||||
}
|
||||
|
||||
if (tb[IFLA_IPTUN_LOCAL]) {
|
||||
print_string(PRINT_ANY,
|
||||
"local",
|
||||
"local %s ",
|
||||
rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_LOCAL]));
|
||||
}
|
||||
tnl_print_endpoint("remote", tb[IFLA_IPTUN_REMOTE], AF_INET6);
|
||||
tnl_print_endpoint("local", tb[IFLA_IPTUN_LOCAL], AF_INET6);
|
||||
|
||||
if (tb[IFLA_IPTUN_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_IPTUN_LINK]);
|
||||
|
|
|
|||
|
|
@ -362,8 +362,6 @@ get_failed:
|
|||
static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
{
|
||||
char s2[64];
|
||||
const char *local = "any";
|
||||
const char *remote = "any";
|
||||
__u16 prefixlen;
|
||||
__u8 ttl = 0;
|
||||
__u8 tos = 0;
|
||||
|
|
@ -393,23 +391,8 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
|
|||
}
|
||||
}
|
||||
|
||||
if (tb[IFLA_IPTUN_REMOTE]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_IPTUN_REMOTE]);
|
||||
|
||||
if (addr)
|
||||
remote = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "remote", "remote %s ", remote);
|
||||
|
||||
if (tb[IFLA_IPTUN_LOCAL]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_IPTUN_LOCAL]);
|
||||
|
||||
if (addr)
|
||||
local = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "local", "local %s ", local);
|
||||
tnl_print_endpoint("remote", tb[IFLA_IPTUN_REMOTE], AF_INET);
|
||||
tnl_print_endpoint("local", tb[IFLA_IPTUN_LOCAL], AF_INET);
|
||||
|
||||
if (tb[IFLA_IPTUN_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_IPTUN_LINK]);
|
||||
|
|
|
|||
|
|
@ -165,30 +165,13 @@ get_failed:
|
|||
|
||||
static void vti_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
{
|
||||
const char *local = "any";
|
||||
const char *remote = "any";
|
||||
char s2[64];
|
||||
|
||||
if (!tb)
|
||||
return;
|
||||
|
||||
if (tb[IFLA_VTI_REMOTE]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_REMOTE]);
|
||||
|
||||
if (addr)
|
||||
remote = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "remote", "remote %s ", remote);
|
||||
|
||||
if (tb[IFLA_VTI_LOCAL]) {
|
||||
unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_LOCAL]);
|
||||
|
||||
if (addr)
|
||||
local = format_host(AF_INET, 4, &addr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "local", "local %s ", local);
|
||||
tnl_print_endpoint("remote", tb[IFLA_VTI_REMOTE], AF_INET);
|
||||
tnl_print_endpoint("local", tb[IFLA_VTI_LOCAL], AF_INET);
|
||||
|
||||
if (tb[IFLA_VTI_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_VTI_LINK]);
|
||||
|
|
|
|||
|
|
@ -171,30 +171,13 @@ get_failed:
|
|||
|
||||
static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
||||
{
|
||||
const char *local = "any";
|
||||
const char *remote = "any";
|
||||
struct in6_addr saddr;
|
||||
struct in6_addr daddr;
|
||||
char s2[64];
|
||||
|
||||
if (!tb)
|
||||
return;
|
||||
|
||||
if (tb[IFLA_VTI_REMOTE]) {
|
||||
memcpy(&daddr, RTA_DATA(tb[IFLA_VTI_REMOTE]), sizeof(daddr));
|
||||
|
||||
remote = format_host(AF_INET6, 16, &daddr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "remote", "remote %s ", remote);
|
||||
|
||||
if (tb[IFLA_VTI_LOCAL]) {
|
||||
memcpy(&saddr, RTA_DATA(tb[IFLA_VTI_LOCAL]), sizeof(saddr));
|
||||
|
||||
local = format_host(AF_INET6, 16, &saddr);
|
||||
}
|
||||
|
||||
print_string(PRINT_ANY, "local", "local %s ", local);
|
||||
tnl_print_endpoint("remote", tb[IFLA_VTI_REMOTE], AF_INET6);
|
||||
tnl_print_endpoint("local", tb[IFLA_VTI_LOCAL], AF_INET6);
|
||||
|
||||
if (tb[IFLA_VTI_LINK]) {
|
||||
unsigned int link = rta_getattr_u32(tb[IFLA_VTI_LINK]);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
struct rtattr *attrs[TCP_METRICS_ATTR_MAX + 1], *a;
|
||||
int len = n->nlmsg_len;
|
||||
inet_prefix daddr, saddr;
|
||||
int family, i, atype, stype, dlen = 0, slen = 0;
|
||||
int i, atype, stype;
|
||||
|
||||
if (n->nlmsg_type != genl_family)
|
||||
return -1;
|
||||
|
|
@ -116,61 +116,61 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
if (f.daddr.family && f.daddr.family != AF_INET)
|
||||
return 0;
|
||||
a = attrs[TCP_METRICS_ATTR_ADDR_IPV4];
|
||||
memcpy(&daddr.data, RTA_DATA(a), 4);
|
||||
daddr.bytelen = 4;
|
||||
family = AF_INET;
|
||||
daddr.family = AF_INET;
|
||||
atype = TCP_METRICS_ATTR_ADDR_IPV4;
|
||||
dlen = RTA_PAYLOAD(a);
|
||||
} else if (attrs[TCP_METRICS_ATTR_ADDR_IPV6]) {
|
||||
if (f.daddr.family && f.daddr.family != AF_INET6)
|
||||
return 0;
|
||||
a = attrs[TCP_METRICS_ATTR_ADDR_IPV6];
|
||||
memcpy(&daddr.data, RTA_DATA(a), 16);
|
||||
daddr.bytelen = 16;
|
||||
family = AF_INET6;
|
||||
daddr.family = AF_INET6;
|
||||
atype = TCP_METRICS_ATTR_ADDR_IPV6;
|
||||
dlen = RTA_PAYLOAD(a);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (get_addr_rta(&daddr, a, daddr.family))
|
||||
return 0;
|
||||
|
||||
if (f.daddr.family && f.daddr.bitlen >= 0 &&
|
||||
inet_addr_match(&daddr, &f.daddr, f.daddr.bitlen))
|
||||
return 0;
|
||||
|
||||
if (attrs[TCP_METRICS_ATTR_SADDR_IPV4]) {
|
||||
if (f.saddr.family && f.saddr.family != AF_INET)
|
||||
return 0;
|
||||
a = attrs[TCP_METRICS_ATTR_SADDR_IPV4];
|
||||
memcpy(&saddr.data, RTA_DATA(a), 4);
|
||||
saddr.bytelen = 4;
|
||||
saddr.family = AF_INET;
|
||||
stype = TCP_METRICS_ATTR_SADDR_IPV4;
|
||||
slen = RTA_PAYLOAD(a);
|
||||
} else if (attrs[TCP_METRICS_ATTR_SADDR_IPV6]) {
|
||||
if (f.saddr.family && f.saddr.family != AF_INET6)
|
||||
return 0;
|
||||
a = attrs[TCP_METRICS_ATTR_SADDR_IPV6];
|
||||
memcpy(&saddr.data, RTA_DATA(a), 16);
|
||||
saddr.bytelen = 16;
|
||||
saddr.family = AF_INET6;
|
||||
stype = TCP_METRICS_ATTR_SADDR_IPV6;
|
||||
slen = RTA_PAYLOAD(a);
|
||||
} else {
|
||||
saddr.family = AF_UNSPEC;
|
||||
stype = 0;
|
||||
}
|
||||
|
||||
if (f.daddr.family && f.daddr.bitlen >= 0 &&
|
||||
inet_addr_match(&daddr, &f.daddr, f.daddr.bitlen))
|
||||
return 0;
|
||||
/* Only check for the source-address if the kernel supports it,
|
||||
* meaning slen != 0.
|
||||
*/
|
||||
if (slen && f.saddr.family && f.saddr.bitlen >= 0 &&
|
||||
inet_addr_match(&saddr, &f.saddr, f.saddr.bitlen))
|
||||
return 0;
|
||||
/* Only get/check for the source-address if the kernel supports it. */
|
||||
if (saddr.family) {
|
||||
if (get_addr_rta(&saddr, a, saddr.family))
|
||||
return 0;
|
||||
|
||||
if (f.saddr.family && f.saddr.bitlen >= 0 &&
|
||||
inet_addr_match(&saddr, &f.saddr, f.saddr.bitlen))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f.flushb) {
|
||||
struct nlmsghdr *fn;
|
||||
|
||||
TCPM_REQUEST(req2, 128, TCP_METRICS_CMD_DEL, NLM_F_REQUEST);
|
||||
|
||||
addattr_l(&req2.n, sizeof(req2), atype, &daddr.data,
|
||||
addattr_l(&req2.n, sizeof(req2), atype, daddr.data,
|
||||
daddr.bytelen);
|
||||
if (slen)
|
||||
addattr_l(&req2.n, sizeof(req2), stype, &saddr.data,
|
||||
if (saddr.family)
|
||||
addattr_l(&req2.n, sizeof(req2), stype, saddr.data,
|
||||
saddr.bytelen);
|
||||
|
||||
if (NLMSG_ALIGN(f.flushp) + req2.n.nlmsg_len > f.flushe) {
|
||||
|
|
@ -190,7 +190,7 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
fprintf(fp, "Deleted ");
|
||||
|
||||
fprintf(fp, "%s",
|
||||
format_host(family, dlen, &daddr.data));
|
||||
format_host(daddr.family, daddr.bytelen, daddr.data));
|
||||
|
||||
a = attrs[TCP_METRICS_ATTR_AGE];
|
||||
if (a) {
|
||||
|
|
@ -292,9 +292,9 @@ static int process_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
fprintf(fp, " fo_cookie %s", cookie);
|
||||
}
|
||||
|
||||
if (slen) {
|
||||
if (saddr.family) {
|
||||
fprintf(fp, " source %s",
|
||||
format_host(family, slen, &saddr.data));
|
||||
format_host(saddr.family, saddr.bytelen, saddr.data));
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
|
|
|||
27
ip/tunnel.c
27
ip/tunnel.c
|
|
@ -280,6 +280,33 @@ void tnl_print_encap(struct rtattr *tb[],
|
|||
}
|
||||
}
|
||||
|
||||
void tnl_print_endpoint(const char *name, const struct rtattr *rta, int family)
|
||||
{
|
||||
const char *value;
|
||||
inet_prefix dst;
|
||||
|
||||
if (!rta) {
|
||||
value = "any";
|
||||
} else if (get_addr_rta(&dst, rta, family)) {
|
||||
value = "unknown";
|
||||
} else if (dst.flags & ADDRTYPE_UNSPEC) {
|
||||
value = "any";
|
||||
} else {
|
||||
value = format_host(family, dst.bytelen, dst.data);
|
||||
if (!value)
|
||||
value = "unknown";
|
||||
}
|
||||
|
||||
if (is_json_context()) {
|
||||
print_string(PRINT_JSON, name, NULL, value);
|
||||
} else {
|
||||
SPRINT_BUF(b1);
|
||||
|
||||
snprintf(b1, sizeof(b1), "%s %%s ", name);
|
||||
print_string(PRINT_FP, NULL, b1, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* tnl_print_stats - print tunnel statistics
|
||||
*
|
||||
* @buf - tunnel interface's line in /proc/net/dev,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ __be32 tnl_parse_key(const char *name, const char *key);
|
|||
void tnl_print_encap(struct rtattr *tb[],
|
||||
int encap_type, int encap_flags,
|
||||
int encap_sport, int encap_dport);
|
||||
void tnl_print_endpoint(const char *name,
|
||||
const struct rtattr *rta, int family);
|
||||
void tnl_print_stats(const char *buf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
95
lib/utils.c
95
lib/utils.c
|
|
@ -534,6 +534,28 @@ int get_addr64(__u64 *ap, const char *cp)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void set_address_type(inet_prefix *addr)
|
||||
{
|
||||
switch (addr->family) {
|
||||
case AF_INET:
|
||||
if (!addr->data[0])
|
||||
addr->flags |= ADDRTYPE_INET_UNSPEC;
|
||||
else if (IN_MULTICAST(ntohl(addr->data[0])))
|
||||
addr->flags |= ADDRTYPE_INET_MULTI;
|
||||
else
|
||||
addr->flags |= ADDRTYPE_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(addr->data))
|
||||
addr->flags |= ADDRTYPE_INET_UNSPEC;
|
||||
else if (IN6_IS_ADDR_MULTICAST(addr->data))
|
||||
addr->flags |= ADDRTYPE_INET_MULTI;
|
||||
else
|
||||
addr->flags |= ADDRTYPE_INET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int __get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||
{
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
|
|
@ -627,25 +649,7 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (addr->family) {
|
||||
case AF_INET:
|
||||
if (!addr->data[0])
|
||||
addr->flags |= ADDRTYPE_INET_UNSPEC;
|
||||
else if (IN_MULTICAST(ntohl(addr->data[0])))
|
||||
addr->flags |= ADDRTYPE_INET_MULTI;
|
||||
else
|
||||
addr->flags |= ADDRTYPE_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(addr->data))
|
||||
addr->flags |= ADDRTYPE_INET_UNSPEC;
|
||||
else if (IN6_IS_ADDR_MULTICAST(addr->data))
|
||||
addr->flags |= ADDRTYPE_INET_MULTI;
|
||||
else
|
||||
addr->flags |= ADDRTYPE_INET;
|
||||
break;
|
||||
}
|
||||
|
||||
set_address_type(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +738,46 @@ int get_addr(inet_prefix *dst, const char *arg, int family)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int get_addr_rta(inet_prefix *dst, const struct rtattr *rta, int family)
|
||||
{
|
||||
const int len = RTA_PAYLOAD(rta);
|
||||
const void *data = RTA_DATA(rta);
|
||||
|
||||
switch (len) {
|
||||
case 4:
|
||||
dst->family = AF_INET;
|
||||
dst->bytelen = 4;
|
||||
memcpy(dst->data, data, 4);
|
||||
break;
|
||||
case 16:
|
||||
dst->family = AF_INET6;
|
||||
dst->bytelen = 16;
|
||||
memcpy(dst->data, data, 16);
|
||||
break;
|
||||
case 2:
|
||||
dst->family = AF_DECnet;
|
||||
dst->bytelen = 2;
|
||||
memcpy(dst->data, data, 2);
|
||||
break;
|
||||
case 10:
|
||||
dst->family = AF_IPX;
|
||||
dst->bytelen = 10;
|
||||
memcpy(dst->data, data, 10);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (family != AF_UNSPEC && family != dst->family)
|
||||
return -2;
|
||||
|
||||
dst->bitlen = -1;
|
||||
dst->flags = 0;
|
||||
|
||||
set_address_type(dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_prefix(inet_prefix *dst, char *arg, int family)
|
||||
{
|
||||
if (family == AF_PACKET) {
|
||||
|
|
@ -864,6 +908,19 @@ int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta)
|
||||
{
|
||||
inet_prefix dst;
|
||||
|
||||
if (!rta || m->family == AF_UNSPEC || m->bitlen <= 0)
|
||||
return 0;
|
||||
|
||||
if (get_addr_rta(&dst, rta, m->family))
|
||||
return -1;
|
||||
|
||||
return inet_addr_match(&dst, m, m->bitlen);
|
||||
}
|
||||
|
||||
int __iproute2_hz_internal;
|
||||
|
||||
int __get_hz(void)
|
||||
|
|
|
|||
Loading…
Reference in New Issue