Merge branch 'inet_get_addr' into net-next
Serhey Popovych says: ==================== It looks confusing to have multiple independent routines to get internet address from it's string representation: get_addr() and inet_get_addr(). Most complicated users of inet_get_addr() is iplink_geneve.c and iplink_vxlan.c because they required to handle both AF_INET and AF_INET6 for their local/remote endpoints. On the other hand get_addr() does not provide additional information like address type: need to address this. to get rid of current and possible future code duplications. Note that this functionality is first step to make proto independent handling of local/remote endpoints in ip/tunnel code (there will be additional series based on this one). Also fix get_addr_1() and get_prefix() to make sure it always provide correct ->family and ->bitlen. As always comments, suggestions and criticism are welcome. ==================== Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
40cf5b0959
|
|
@ -54,7 +54,40 @@ typedef struct
|
||||||
__u32 data[64];
|
__u32 data[64];
|
||||||
} inet_prefix;
|
} inet_prefix;
|
||||||
|
|
||||||
#define PREFIXLEN_SPECIFIED 1
|
enum {
|
||||||
|
PREFIXLEN_SPECIFIED = (1 << 0),
|
||||||
|
ADDRTYPE_INET = (1 << 1),
|
||||||
|
ADDRTYPE_UNSPEC = (1 << 2),
|
||||||
|
ADDRTYPE_MULTI = (1 << 3),
|
||||||
|
|
||||||
|
ADDRTYPE_INET_UNSPEC = ADDRTYPE_INET | ADDRTYPE_UNSPEC,
|
||||||
|
ADDRTYPE_INET_MULTI = ADDRTYPE_INET | ADDRTYPE_MULTI
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool is_addrtype_inet(const inet_prefix *p)
|
||||||
|
{
|
||||||
|
return p->flags & ADDRTYPE_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_addrtype_inet_unspec(const inet_prefix *p)
|
||||||
|
{
|
||||||
|
return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET_UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_addrtype_inet_multi(const inet_prefix *p)
|
||||||
|
{
|
||||||
|
return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET_MULTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_addrtype_inet_not_unspec(const inet_prefix *p)
|
||||||
|
{
|
||||||
|
return (p->flags & ADDRTYPE_INET_UNSPEC) == ADDRTYPE_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_addrtype_inet_not_multi(const inet_prefix *p)
|
||||||
|
{
|
||||||
|
return (p->flags & ADDRTYPE_INET_MULTI) == ADDRTYPE_INET;
|
||||||
|
}
|
||||||
|
|
||||||
#define DN_MAXADDL 20
|
#define DN_MAXADDL 20
|
||||||
#ifndef AF_DECnet
|
#ifndef AF_DECnet
|
||||||
|
|
@ -236,7 +269,6 @@ void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
|
||||||
extern int cmdlineno;
|
extern int cmdlineno;
|
||||||
ssize_t getcmdline(char **line, size_t *len, FILE *in);
|
ssize_t getcmdline(char **line, size_t *len, FILE *in);
|
||||||
int makeargs(char *line, char *argv[], int maxargs);
|
int makeargs(char *line, char *argv[], int maxargs);
|
||||||
int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6);
|
|
||||||
|
|
||||||
struct iplink_req {
|
struct iplink_req {
|
||||||
struct nlmsghdr n;
|
struct nlmsghdr n;
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,8 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
|
||||||
static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
|
static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
struct nlmsghdr *n)
|
struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
|
inet_prefix daddr;
|
||||||
__u32 vni = 0;
|
__u32 vni = 0;
|
||||||
__u32 daddr = 0;
|
|
||||||
struct in6_addr daddr6 = IN6ADDR_ANY_INIT;
|
|
||||||
__u32 label = 0;
|
__u32 label = 0;
|
||||||
__u8 ttl = 0;
|
__u8 ttl = 0;
|
||||||
__u8 tos = 0;
|
__u8 tos = 0;
|
||||||
|
|
@ -72,6 +71,8 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
|
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
|
||||||
!(n->nlmsg_flags & NLM_F_CREATE));
|
!(n->nlmsg_flags & NLM_F_CREATE));
|
||||||
|
|
||||||
|
daddr.flags = 0;
|
||||||
|
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if (!matches(*argv, "id") ||
|
if (!matches(*argv, "id") ||
|
||||||
!matches(*argv, "vni")) {
|
!matches(*argv, "vni")) {
|
||||||
|
|
@ -84,11 +85,8 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
check_duparg(&attrs, IFLA_GENEVE_REMOTE, "remote",
|
check_duparg(&attrs, IFLA_GENEVE_REMOTE, "remote",
|
||||||
*argv);
|
*argv);
|
||||||
if (!inet_get_addr(*argv, &daddr, &daddr6)) {
|
get_addr(&daddr, *argv, AF_UNSPEC);
|
||||||
fprintf(stderr, "Invalid address \"%s\"\n", *argv);
|
if (!is_addrtype_inet_not_multi(&daddr))
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (IN6_IS_ADDR_MULTICAST(&daddr6) || IN_MULTICAST(ntohl(daddr)))
|
|
||||||
invarg("invalid remote address", *argv);
|
invarg("invalid remote address", *argv);
|
||||||
} else if (!matches(*argv, "ttl") ||
|
} else if (!matches(*argv, "ttl") ||
|
||||||
!matches(*argv, "hoplimit")) {
|
!matches(*argv, "hoplimit")) {
|
||||||
|
|
@ -191,18 +189,17 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
* ID (VNI) to identify the geneve device, and we do not need
|
* ID (VNI) to identify the geneve device, and we do not need
|
||||||
* the remote IP.
|
* the remote IP.
|
||||||
*/
|
*/
|
||||||
if (!set_op && !daddr && IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
|
if (!set_op && !is_addrtype_inet(&daddr)) {
|
||||||
fprintf(stderr, "geneve: remote link partner not specified\n");
|
fprintf(stderr, "geneve: remote link partner not specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addattr32(n, 1024, IFLA_GENEVE_ID, vni);
|
addattr32(n, 1024, IFLA_GENEVE_ID, vni);
|
||||||
if (daddr)
|
if (is_addrtype_inet(&daddr)) {
|
||||||
addattr_l(n, 1024, IFLA_GENEVE_REMOTE, &daddr, 4);
|
int type = (daddr.family == AF_INET) ? IFLA_GENEVE_REMOTE :
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
|
IFLA_GENEVE_REMOTE6;
|
||||||
addattr_l(n, 1024, IFLA_GENEVE_REMOTE6, &daddr6,
|
addattr_l(n, sizeof(1024), type, daddr.data, daddr.bytelen);
|
||||||
sizeof(struct in6_addr));
|
|
||||||
}
|
}
|
||||||
if (!set_op || GENEVE_ATTRSET(attrs, IFLA_GENEVE_LABEL))
|
if (!set_op || GENEVE_ATTRSET(attrs, IFLA_GENEVE_LABEL))
|
||||||
addattr32(n, 1024, IFLA_GENEVE_LABEL, label);
|
addattr32(n, 1024, IFLA_GENEVE_LABEL, label);
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,9 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
|
||||||
static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
struct nlmsghdr *n)
|
struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
|
inet_prefix saddr;
|
||||||
|
inet_prefix daddr;
|
||||||
__u32 vni = 0;
|
__u32 vni = 0;
|
||||||
__u32 gaddr = 0;
|
|
||||||
__u32 daddr = 0;
|
|
||||||
struct in6_addr gaddr6 = IN6ADDR_ANY_INIT;
|
|
||||||
struct in6_addr daddr6 = IN6ADDR_ANY_INIT;
|
|
||||||
__u8 learning = 1;
|
__u8 learning = 1;
|
||||||
__u16 dstport = 0;
|
__u16 dstport = 0;
|
||||||
__u8 metadata = 0;
|
__u8 metadata = 0;
|
||||||
|
|
@ -86,6 +84,9 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
|
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
|
||||||
!(n->nlmsg_flags & NLM_F_CREATE));
|
!(n->nlmsg_flags & NLM_F_CREATE));
|
||||||
|
|
||||||
|
saddr.family = daddr.family = AF_UNSPEC;
|
||||||
|
saddr.flags = daddr.flags = 0;
|
||||||
|
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if (!matches(*argv, "id") ||
|
if (!matches(*argv, "id") ||
|
||||||
!matches(*argv, "vni")) {
|
!matches(*argv, "vni")) {
|
||||||
|
|
@ -98,54 +99,33 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
vni >= 1u << 24)
|
vni >= 1u << 24)
|
||||||
invarg("invalid id", *argv);
|
invarg("invalid id", *argv);
|
||||||
} else if (!matches(*argv, "group")) {
|
} else if (!matches(*argv, "group")) {
|
||||||
if (daddr || !IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
|
if (is_addrtype_inet_not_multi(&daddr)) {
|
||||||
fprintf(stderr, "vxlan: both group and remote");
|
fprintf(stderr, "vxlan: both group and remote");
|
||||||
fprintf(stderr, " cannot be specified\n");
|
fprintf(stderr, " cannot be specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
check_duparg(&attrs, IFLA_VXLAN_GROUP, "group", *argv);
|
check_duparg(&attrs, IFLA_VXLAN_GROUP, "group", *argv);
|
||||||
if (!inet_get_addr(*argv, &gaddr, &gaddr6)) {
|
get_addr(&daddr, *argv, saddr.family);
|
||||||
fprintf(stderr, "Invalid address \"%s\"\n", *argv);
|
if (!is_addrtype_inet_multi(&daddr))
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!IN6_IS_ADDR_MULTICAST(&gaddr6) && !IN_MULTICAST(ntohl(gaddr)))
|
|
||||||
invarg("invalid group address", *argv);
|
invarg("invalid group address", *argv);
|
||||||
} else if (!matches(*argv, "remote")) {
|
} else if (!matches(*argv, "remote")) {
|
||||||
if (gaddr || !IN6_IS_ADDR_UNSPECIFIED(&gaddr6)) {
|
if (is_addrtype_inet_multi(&daddr)) {
|
||||||
fprintf(stderr, "vxlan: both group and remote");
|
fprintf(stderr, "vxlan: both group and remote");
|
||||||
fprintf(stderr, " cannot be specified\n");
|
fprintf(stderr, " cannot be specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
check_duparg(&attrs, IFLA_VXLAN_GROUP, "remote", *argv);
|
check_duparg(&attrs, IFLA_VXLAN_GROUP, "remote", *argv);
|
||||||
if (!inet_get_addr(*argv, &daddr, &daddr6)) {
|
get_addr(&daddr, *argv, saddr.family);
|
||||||
fprintf(stderr, "Invalid address \"%s\"\n", *argv);
|
if (!is_addrtype_inet_not_multi(&daddr))
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (IN6_IS_ADDR_MULTICAST(&daddr6) || IN_MULTICAST(ntohl(daddr)))
|
|
||||||
invarg("invalid remote address", *argv);
|
invarg("invalid remote address", *argv);
|
||||||
} else if (!matches(*argv, "local")) {
|
} else if (!matches(*argv, "local")) {
|
||||||
__u32 saddr = 0;
|
|
||||||
struct in6_addr saddr6 = IN6ADDR_ANY_INIT;
|
|
||||||
|
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
check_duparg(&attrs, IFLA_VXLAN_LOCAL, "local", *argv);
|
check_duparg(&attrs, IFLA_VXLAN_LOCAL, "local", *argv);
|
||||||
if (strcmp(*argv, "any")) {
|
get_addr(&saddr, *argv, daddr.family);
|
||||||
if (!inet_get_addr(*argv, &saddr, &saddr6)) {
|
if (!is_addrtype_inet_not_multi(&saddr))
|
||||||
fprintf(stderr, "Invalid address \"%s\"\n", *argv);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IN_MULTICAST(ntohl(saddr)) || IN6_IS_ADDR_MULTICAST(&saddr6))
|
|
||||||
invarg("invalid local address", *argv);
|
invarg("invalid local address", *argv);
|
||||||
|
|
||||||
if (saddr)
|
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_LOCAL, &saddr, 4);
|
|
||||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&saddr6))
|
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_LOCAL6, &saddr6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
} else if (!matches(*argv, "dev")) {
|
} else if (!matches(*argv, "dev")) {
|
||||||
unsigned int link;
|
unsigned int link;
|
||||||
|
|
||||||
|
|
@ -350,7 +330,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gaddr || !IN6_IS_ADDR_UNSPECIFIED(&gaddr6)) &&
|
if (is_addrtype_inet_multi(&daddr) &&
|
||||||
!VXLAN_ATTRSET(attrs, IFLA_VXLAN_LINK)) {
|
!VXLAN_ATTRSET(attrs, IFLA_VXLAN_LINK)) {
|
||||||
fprintf(stderr, "vxlan: 'group' requires 'dev' to be specified\n");
|
fprintf(stderr, "vxlan: 'group' requires 'dev' to be specified\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -369,18 +349,18 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
|
||||||
|
|
||||||
if (VXLAN_ATTRSET(attrs, IFLA_VXLAN_ID))
|
if (VXLAN_ATTRSET(attrs, IFLA_VXLAN_ID))
|
||||||
addattr32(n, 1024, IFLA_VXLAN_ID, vni);
|
addattr32(n, 1024, IFLA_VXLAN_ID, vni);
|
||||||
if (gaddr)
|
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP, &gaddr, 4);
|
if (is_addrtype_inet(&saddr)) {
|
||||||
else if (daddr)
|
int type = (saddr.family == AF_INET) ? IFLA_VXLAN_LOCAL
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP, &daddr, 4);
|
: IFLA_VXLAN_LOCAL6;
|
||||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&gaddr6))
|
addattr_l(n, 1024, type, saddr.data, saddr.bytelen);
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP6, &gaddr6, sizeof(struct in6_addr));
|
}
|
||||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&daddr6))
|
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP6, &daddr6, sizeof(struct in6_addr));
|
if (is_addrtype_inet(&daddr)) {
|
||||||
else if (preferred_family == AF_INET)
|
int type = (daddr.family == AF_INET) ? IFLA_VXLAN_GROUP
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP, &daddr, 4);
|
: IFLA_VXLAN_GROUP6;
|
||||||
else if (preferred_family == AF_INET6)
|
addattr_l(n, 1024, type, daddr.data, daddr.bytelen);
|
||||||
addattr_l(n, 1024, IFLA_VXLAN_GROUP6, &daddr6, sizeof(struct in6_addr));
|
}
|
||||||
|
|
||||||
if (!set_op || VXLAN_ATTRSET(attrs, IFLA_VXLAN_LEARNING))
|
if (!set_op || VXLAN_ATTRSET(attrs, IFLA_VXLAN_LEARNING))
|
||||||
addattr8(n, 1024, IFLA_VXLAN_LEARNING, learning);
|
addattr8(n, 1024, IFLA_VXLAN_LEARNING, learning);
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,10 @@ static struct ipv6_sr_hdr *parse_srh(char *segbuf, int hmac, bool encap)
|
||||||
|
|
||||||
i = srh->first_segment;
|
i = srh->first_segment;
|
||||||
for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
|
for (s = strtok(segbuf, ","); s; s = strtok(NULL, ",")) {
|
||||||
inet_get_addr(s, NULL, &srh->segments[i]);
|
inet_prefix addr;
|
||||||
|
|
||||||
|
get_addr(&addr, s, AF_INET6);
|
||||||
|
memcpy(&srh->segments[i], addr.data, sizeof(struct in6_addr));
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ static int genl_family = -1;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
unsigned int cmd;
|
unsigned int cmd;
|
||||||
struct in6_addr addr;
|
inet_prefix addr;
|
||||||
__u32 keyid;
|
__u32 keyid;
|
||||||
const char *pass;
|
const char *pass;
|
||||||
__u8 alg_id;
|
__u8 alg_id;
|
||||||
|
|
@ -152,7 +152,7 @@ static int seg6_do_cmd(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEG6_CMD_SET_TUNSRC:
|
case SEG6_CMD_SET_TUNSRC:
|
||||||
addattr_l(&req.n, sizeof(req), SEG6_ATTR_DST, &opts.addr,
|
addattr_l(&req.n, sizeof(req), SEG6_ATTR_DST, opts.addr.data,
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
break;
|
break;
|
||||||
case SEG6_CMD_DUMPHMAC:
|
case SEG6_CMD_DUMPHMAC:
|
||||||
|
|
@ -226,9 +226,7 @@ int do_seg6(int argc, char **argv)
|
||||||
} else if (matches(*argv, "set") == 0) {
|
} else if (matches(*argv, "set") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
opts.cmd = SEG6_CMD_SET_TUNSRC;
|
opts.cmd = SEG6_CMD_SET_TUNSRC;
|
||||||
if (!inet_get_addr(*argv, NULL, &opts.addr))
|
get_addr(&opts.addr, *argv, AF_INET6);
|
||||||
invarg("tunsrc ADDRESS value is invalid",
|
|
||||||
*argv);
|
|
||||||
} else {
|
} else {
|
||||||
invarg("unknown", *argv);
|
invarg("unknown", *argv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
106
lib/utils.c
106
lib/utils.c
|
|
@ -534,7 +534,7 @@ int get_addr64(__u64 *ap, const char *cp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_addr_1(inet_prefix *addr, const char *name, int family)
|
static int __get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
{
|
{
|
||||||
memset(addr, 0, sizeof(*addr));
|
memset(addr, 0, sizeof(*addr));
|
||||||
|
|
||||||
|
|
@ -543,9 +543,9 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
strcmp(name, "any") == 0) {
|
strcmp(name, "any") == 0) {
|
||||||
if ((family == AF_DECnet) || (family == AF_MPLS))
|
if ((family == AF_DECnet) || (family == AF_MPLS))
|
||||||
return -1;
|
return -1;
|
||||||
addr->family = family;
|
addr->family = (family != AF_UNSPEC) ? family : AF_INET;
|
||||||
addr->bytelen = (family == AF_INET6 ? 16 : 4);
|
addr->bytelen = af_byte_len(addr->family);
|
||||||
addr->bitlen = -1;
|
addr->bitlen = -2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -619,6 +619,36 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = __get_addr_1(addr, name, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int af_bit_len(int af)
|
int af_bit_len(int af)
|
||||||
{
|
{
|
||||||
switch (af) {
|
switch (af) {
|
||||||
|
|
@ -644,46 +674,46 @@ int af_byte_len(int af)
|
||||||
|
|
||||||
int get_prefix_1(inet_prefix *dst, char *arg, int family)
|
int get_prefix_1(inet_prefix *dst, char *arg, int family)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
unsigned int plen;
|
|
||||||
char *slash;
|
char *slash;
|
||||||
|
int err, bitlen, flags;
|
||||||
memset(dst, 0, sizeof(*dst));
|
|
||||||
|
|
||||||
if (strcmp(arg, "default") == 0 ||
|
|
||||||
strcmp(arg, "any") == 0 ||
|
|
||||||
strcmp(arg, "all") == 0) {
|
|
||||||
if ((family == AF_DECnet) || (family == AF_MPLS))
|
|
||||||
return -1;
|
|
||||||
dst->family = family;
|
|
||||||
dst->bytelen = 0;
|
|
||||||
dst->bitlen = 0;
|
|
||||||
dst->flags |= PREFIXLEN_SPECIFIED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
slash = strchr(arg, '/');
|
slash = strchr(arg, '/');
|
||||||
if (slash)
|
if (slash)
|
||||||
*slash = 0;
|
*slash = 0;
|
||||||
|
|
||||||
err = get_addr_1(dst, arg, family);
|
err = get_addr_1(dst, arg, family);
|
||||||
if (err == 0) {
|
|
||||||
dst->bitlen = af_bit_len(dst->family);
|
|
||||||
|
|
||||||
if (slash) {
|
|
||||||
if (get_netmask(&plen, slash+1, 0)
|
|
||||||
|| plen > dst->bitlen) {
|
|
||||||
err = -1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
dst->flags |= PREFIXLEN_SPECIFIED;
|
|
||||||
dst->bitlen = plen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
if (slash)
|
if (slash)
|
||||||
*slash = '/';
|
*slash = '/';
|
||||||
return err;
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
bitlen = af_bit_len(dst->family);
|
||||||
|
|
||||||
|
flags = PREFIXLEN_SPECIFIED;
|
||||||
|
if (slash) {
|
||||||
|
unsigned int plen;
|
||||||
|
|
||||||
|
if (dst->bitlen == -2)
|
||||||
|
return -1;
|
||||||
|
if (get_netmask(&plen, slash + 1, 0))
|
||||||
|
return -1;
|
||||||
|
if (plen > bitlen)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bitlen = plen;
|
||||||
|
} else {
|
||||||
|
if (dst->bitlen == -2)
|
||||||
|
bitlen = 0;
|
||||||
|
else
|
||||||
|
flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->flags |= flags;
|
||||||
|
dst->bitlen = bitlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *family_name_verbose(int family)
|
static const char *family_name_verbose(int family)
|
||||||
|
|
@ -1250,14 +1280,6 @@ int makeargs(char *line, char *argv[], int maxargs)
|
||||||
return argc;
|
return argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6)
|
|
||||||
{
|
|
||||||
if (strchr(src, ':'))
|
|
||||||
return inet_pton(AF_INET6, src, dst6);
|
|
||||||
else
|
|
||||||
return inet_pton(AF_INET, src, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
|
void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
char *tstr;
|
char *tstr;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue