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