add support for extended ifa_flags

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
This commit is contained in:
Jiri Pirko 2014-01-06 10:17:09 +01:00 committed by Stephen Hemminger
parent af9cd91228
commit 37c9b94ed2

View File

@ -541,6 +541,13 @@ static int set_lifetime(unsigned int *lifetime, char *argv)
return 0;
}
static unsigned int get_ifa_flags(struct ifaddrmsg *ifa,
struct rtattr *ifa_flags_attr)
{
return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) :
ifa->ifa_flags;
}
int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
{
@ -567,6 +574,8 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);
if (!rta_tb[IFA_LOCAL])
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
if (!rta_tb[IFA_ADDRESS])
@ -576,7 +585,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
return 0;
if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
return 0;
if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
if ((filter.flags ^ ifa_flags) & filter.flagmask)
return 0;
if (filter.label) {
SPRINT_BUF(b1);
@ -670,36 +679,35 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
abuf, sizeof(abuf)));
}
fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
ifa_flags = ifa->ifa_flags;
if (ifa->ifa_flags&IFA_F_SECONDARY) {
if (ifa_flags & IFA_F_SECONDARY) {
ifa_flags &= ~IFA_F_SECONDARY;
if (ifa->ifa_family == AF_INET6)
fprintf(fp, "temporary ");
else
fprintf(fp, "secondary ");
}
if (ifa->ifa_flags&IFA_F_TENTATIVE) {
if (ifa_flags & IFA_F_TENTATIVE) {
ifa_flags &= ~IFA_F_TENTATIVE;
fprintf(fp, "tentative ");
}
if (ifa->ifa_flags&IFA_F_DEPRECATED) {
if (ifa_flags & IFA_F_DEPRECATED) {
ifa_flags &= ~IFA_F_DEPRECATED;
deprecated = 1;
fprintf(fp, "deprecated ");
}
if (ifa->ifa_flags&IFA_F_HOMEADDRESS) {
if (ifa_flags & IFA_F_HOMEADDRESS) {
ifa_flags &= ~IFA_F_HOMEADDRESS;
fprintf(fp, "home ");
}
if (ifa->ifa_flags&IFA_F_NODAD) {
if (ifa_flags & IFA_F_NODAD) {
ifa_flags &= ~IFA_F_NODAD;
fprintf(fp, "nodad ");
}
if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
if (!(ifa_flags & IFA_F_PERMANENT)) {
fprintf(fp, "dynamic ");
} else
ifa_flags &= ~IFA_F_PERMANENT;
if (ifa->ifa_flags&IFA_F_DADFAILED) {
if (ifa_flags & IFA_F_DADFAILED) {
ifa_flags &= ~IFA_F_DADFAILED;
fprintf(fp, "dadfailed ");
}
@ -926,6 +934,8 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
for (a = ainfo->head; a; a = a->next) {
struct nlmsghdr *n = &a->h;
struct ifaddrmsg *ifa = NLMSG_DATA(n);
struct rtattr *tb[IFA_MAX + 1];
unsigned int ifa_flags;
if (ifa->ifa_index != ifi->ifi_index)
continue;
@ -934,11 +944,13 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
continue;
if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
continue;
if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]);
if ((filter.flags ^ ifa_flags) & filter.flagmask)
continue;
if (filter.pfx.family || filter.label) {
struct rtattr *tb[IFA_MAX+1];
parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
if (!tb[IFA_LOCAL])
tb[IFA_LOCAL] = tb[IFA_ADDRESS];
@ -1252,6 +1264,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
__u32 preferred_lft = INFINITY_LIFE_TIME;
__u32 valid_lft = INFINITY_LIFE_TIME;
struct ifa_cacheinfo cinfo;
unsigned int ifa_flags = 0;
memset(&req, 0, sizeof(req));
@ -1329,9 +1342,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
if (set_lifetime(&preferred_lft, *argv))
invarg("preferred_lft value", *argv);
} else if (strcmp(*argv, "home") == 0) {
req.ifa.ifa_flags |= IFA_F_HOMEADDRESS;
ifa_flags |= IFA_F_HOMEADDRESS;
} else if (strcmp(*argv, "nodad") == 0) {
req.ifa.ifa_flags |= IFA_F_NODAD;
ifa_flags |= IFA_F_NODAD;
} else {
if (strcmp(*argv, "local") == 0) {
NEXT_ARG();
@ -1349,6 +1362,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
}
argc--; argv++;
}
req.ifa.ifa_flags = ifa_flags;
addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
if (d == NULL) {
fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
return -1;