bool
ovs_router_lookup4(ovs_be32 ip_dst, char output_bridge[], ovs_be32 *gw)
{
- struct in6_addr ip6_dst;
+ struct in6_addr ip6_dst = in6_addr_mapped_ipv4(ip_dst);
struct in6_addr gw6;
- in6_addr_set_mapped_ipv4(&ip6_dst, ip_dst);
if (ovs_router_lookup(&ip6_dst, output_bridge, &gw6)) {
*gw = in6_addr_get_mapped_ipv4(&gw6);
return true;
static bool
scan_ipv6_route(const char *s, struct in6_addr *addr, unsigned int *plen)
{
- int len, n;
- int slen = strlen(s);
- char ipv6_s[IPV6_SCAN_LEN + 1];
-
- if (ovs_scan(s, IPV6_SCAN_FMT"%n", ipv6_s, &len)
- && inet_pton(AF_INET6, ipv6_s, addr) == 1) {
- if (len == slen) {
- *plen = 128;
- return true;
- }
- if (ovs_scan(s + len, "/%u%n", plen, &n)
- && len + n == slen && *plen <= 128) {
- return true;
- }
+ char *error = ipv6_parse_cidr(s, addr, plen);
+ if (error) {
+ free(error);
+ return false;
}
- return false;
+ return true;
}
static bool
scan_ipv4_route(const char *s, ovs_be32 *addr, unsigned int *plen)
{
- int len, max_plen, n;
- int slen = strlen(s);
- uint8_t *ip = (uint8_t *)addr;
-
- *addr = htonl(0);
- if (!ovs_scan(s, "%"SCNu8"%n", &ip[0], &n)) {
+ char *error = ip_parse_cidr(s, addr, plen);
+ if (error) {
+ free(error);
return false;
}
- len = n;
- max_plen = 8;
- for (int i = 1; i < 4; i++) {
- if (ovs_scan(s + len, ".%"SCNu8"%n", &ip[i], &n)) {
- len += n;
- max_plen += 8;
- } else {
- break;
- }
- }
- if (len == slen && max_plen == 32) {
- *plen = 32;
- return true;
- }
- if (ovs_scan(s + len, "/%u%n", plen, &n)
- && len + n == slen && *plen <= max_plen) {
- return true;
- }
- return false;
+ return true;
}
static void
ovs_router_add(struct unixctl_conn *conn, int argc,
const char *argv[], void *aux OVS_UNUSED)
{
- ovs_be32 ip, gw;
+ ovs_be32 ip;
unsigned int plen;
struct in6_addr ip6;
struct in6_addr gw6;
if (scan_ipv4_route(argv[1], &ip, &plen)) {
- if (argc > 3) {
- inet_pton(AF_INET, argv[3], (struct in_addr *)&gw);
- } else {
- gw = 0;
+ ovs_be32 gw = 0;
+ if (argc > 3 && !ip_parse(argv[3], &gw)) {
+ unixctl_command_reply_error(conn, "Invalid gateway");
+ return;
}
in6_addr_set_mapped_ipv4(&ip6, ip);
in6_addr_set_mapped_ipv4(&gw6, gw);
plen += 96;
} else if (scan_ipv6_route(argv[1], &ip6, &plen)) {
- if (argc > 3) {
- inet_pton(AF_INET6, argv[3], &gw6);
- } else {
- gw6 = in6addr_any;
+ gw6 = in6addr_any;
+ if (argc > 3 && !ipv6_parse(argv[3], &gw6)) {
+ unixctl_command_reply_error(conn, "Invalid IPv6 gateway");
+ return;
}
} else {
- unixctl_command_reply(conn, "Invalid parameters");
+ unixctl_command_reply_error(conn, "Invalid parameters");
+ return;
}
ovs_router_insert__(plen + 32, &ip6, plen, argv[2], &gw6);
unixctl_command_reply(conn, "OK");
in6_addr_set_mapped_ipv4(&ip6, ip);
plen += 96;
} else if (!scan_ipv6_route(argv[1], &ip6, &plen)) {
- unixctl_command_reply(conn, "Invalid parameters");
+ unixctl_command_reply_error(conn, "Invalid parameters");
+ return;
}
if (rt_entry_delete(plen + 32, &ip6, plen)) {
unixctl_command_reply(conn, "OK");
seq_change(tnl_conf_seq);
} else {
- unixctl_command_reply(conn, "Not found");
+ unixctl_command_reply_error(conn, "Not found");
}
}
if (scan_ipv4_route(argv[1], &ip, &plen) && plen == 32) {
in6_addr_set_mapped_ipv4(&ip6, ip);
} else if (!(scan_ipv6_route(argv[1], &ip6, &plen) && plen == 128)) {
- unixctl_command_reply(conn, "Invalid parameters");
+ unixctl_command_reply_error(conn, "Invalid parameters");
+ return;
}
if (ovs_router_lookup(&ip6, iface, &gw)) {
unixctl_command_reply(conn, ds_cstr(&ds));
ds_destroy(&ds);
} else {
- unixctl_command_reply(conn, "Not found");
+ unixctl_command_reply_error(conn, "Not found");
}
}