diff --git a/include/linux/if_map.h b/include/linux/if_map.h index e1aa3ce..0024227 100644 --- a/include/linux/if_map.h +++ b/include/linux/if_map.h @@ -19,6 +19,11 @@ #define SIOCGETMAPNAPTNUM (SIOCDEVPRIVATE + 10) #define SIOCGETMAPNAPT (SIOCDEVPRIVATE + 11) +#define SIOCGETMAPPOOLS (SIOCDEVPRIVATE + 12) +#define SIOCADDMAPPOOLS (SIOCDEVPRIVATE + 13) +#define SIOCDELMAPPOOLS (SIOCDEVPRIVATE + 14) +#define SIOCCHGMAPPOOLS (SIOCDEVPRIVATE + 15) + #define MAP_ROLE_BR (1 << 0) #define MAP_ROLE_CE (1 << 1) @@ -50,6 +55,11 @@ struct map_rule_parm { __u8 forwarding_rule; }; +struct map_pool_parm { + __be32 pool_prefix; + __u8 pool_prefix_length; +}; + struct map_parm { char name[IFNAMSIZ]; int tunnel_source; @@ -63,12 +73,15 @@ struct map_parm { __u8 napt_always; __u8 napt_force_recycle; unsigned long rule_num; + unsigned long pool_num; struct map_rule_parm rule[0]; + struct map_pool_parm pool[0]; }; struct map_napt_node_parm { __be32 raddr, laddr, maddr; __be16 rport, lport, mport; + struct in6_addr laddr6; __u8 proto; __u8 flags; struct timespec last_used; diff --git a/ip/ipmap.c b/ip/ipmap.c index d1300e7..45cdccf 100644 --- a/ip/ipmap.c +++ b/ip/ipmap.c @@ -25,17 +25,22 @@ static void usage(void) __attribute__((noreturn)); static void usage(void) { - fprintf(stderr, "Usage: ip map { add | change | del | add-rule | del-rule } [ NAME ]\n"); + fprintf(stderr, "Usage: ip map { add | change | del } [ NAME ]\n"); fprintf(stderr, " [ role { br | ce } ] [ tunnel-source STRING ] [ br-address ADDR ]\n"); fprintf(stderr, " [ default-forwarding-mode { translation | encapsulation } ]\n"); fprintf(stderr, " [ default-forwarding-rule BOOL ]\n"); fprintf(stderr, " [ napt-always BOOL ] [ napt-force-recycle BOOL ]\n"); fprintf(stderr, " [ ipv6-fragment-size SIZE ] [ ipv4-fragment-inner BOOL ]\n"); + fprintf(stderr, " [ dev PHYS_DEV ]\n"); + fprintf(stderr, "Usage: ip map { add-rule | del-rule } [ NAME ]\n"); fprintf(stderr, " [ ipv6-prefix ADDR ] [ ipv4-prefix ADDR ] [ psid-prefix NUM/LEN]\n"); fprintf(stderr, " [ ea-length NUMBER ]\n"); fprintf(stderr, " [ forwarding-mode { translation | encapsulation } ]\n"); fprintf(stderr, " [ forwarding-rule BOOL ] [ psid-offset NUMBER ] [ dev PHYS_DEV ]\n"); + fprintf(stderr, "Usage: ip map { add-pool | del-pool } [ NAME ]\n"); + fprintf(stderr, " [ pool-prefix ADDR ] [ dev PHYS_DEV ]\n"); fprintf(stderr, "Usage: ip map { show | show-parm | show-rule | show-napt } [ NAME ]\n"); + fprintf(stderr, " [ dev PHYS_DEV ]\n"); fprintf(stderr, "\n"); fprintf(stderr, "Where: NAME := STRING\n"); fprintf(stderr, " ADDR := IP_ADDRESS\n"); @@ -119,13 +124,14 @@ static int map_ioctl(const char *name, int cmd, void *p) return err; } -static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct map_rule_parm *r) +static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct map_rule_parm *rp, struct map_pool_parm *pp) { int count = 0; inet_prefix prefix; memset(p, 0, sizeof(*p)); - memset(r, 0, sizeof(*r)); + memset(rp, 0, sizeof(*rp)); + memset(pp, 0, sizeof(*pp)); /* default settings */ p->role = MAP_ROLE_CE; @@ -134,9 +140,11 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct p->ipv4_fragment_inner = MAP_IPV4_FRAG_INNER_T; p->napt_always = MAP_NAPT_ALWAYS_T; p->napt_force_recycle = MAP_NAPT_FORCE_RECYCLE_F; - r->psid_prefix = 0; - r->psid_prefix_length = 0; - r->psid_offset = 4; + rp->psid_prefix = 0; + rp->psid_prefix_length = 0; + rp->psid_offset = 4; + pp->pool_prefix = 0; + pp->pool_prefix_length = 0; while (argc > 0) { if (strcmp(*argv, "role") == 0) { @@ -232,16 +240,16 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct fprintf(stderr, "Invalid ipv6-prefix: %s.\n", *argv); exit(-1); } - memcpy(&r->ipv6_prefix, prefix.data, 16); - r->ipv6_prefix_length = prefix.bitlen; + memcpy(&rp->ipv6_prefix, prefix.data, 16); + rp->ipv6_prefix_length = prefix.bitlen; } else if (strcmp(*argv, "ipv4-prefix") == 0) { NEXT_ARG(); if (get_prefix(&prefix, *argv, AF_INET)) { fprintf(stderr, "Invalid ipv4-prefix: %s.\n", *argv); exit(-1); } - memcpy(&r->ipv4_prefix, prefix.data, 4); - r->ipv4_prefix_length = prefix.bitlen; + memcpy(&rp->ipv4_prefix, prefix.data, 4); + rp->ipv4_prefix_length = prefix.bitlen; } else if (strcmp(*argv, "psid-prefix") == 0) { __u16 psid_prefix; unsigned psid_prefix_length; @@ -265,7 +273,7 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct exit(-1); } } - r->psid_prefix = psid_prefix; + rp->psid_prefix = psid_prefix; if (get_unsigned(&psid_prefix_length, lenpos, 0)) { fprintf(stderr, "Invalid psid-prefix: %s.\n", lenpos); exit(-1); @@ -274,7 +282,7 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct fprintf(stderr, "Invalid psid-prefix: %s.\n", lenpos); exit(-1); } - r->psid_prefix_length = psid_prefix_length; + rp->psid_prefix_length = psid_prefix_length; } else if (strcmp(*argv, "ea-length") == 0) { unsigned uval; NEXT_ARG(); @@ -286,13 +294,13 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct fprintf(stderr, "Invalid ea-length: %s.\n", *argv); exit(-1); } - r->ea_length = uval; + rp->ea_length = uval; } else if (strcmp(*argv, "forwarding-mode") == 0) { NEXT_ARG(); if (strcmp(*argv, "translation") == 0) { - r->forwarding_mode = MAP_FORWARDING_MODE_T; + rp->forwarding_mode = MAP_FORWARDING_MODE_T; } else if (strcmp(*argv, "encapsulation") == 0) { - r->forwarding_mode = MAP_FORWARDING_MODE_E; + rp->forwarding_mode = MAP_FORWARDING_MODE_E; } else { fprintf(stderr, "Cannot guess forwarding mode.\n"); exit(-1); @@ -300,9 +308,9 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct } else if (strcmp(*argv, "forwarding-rule") == 0) { NEXT_ARG(); if (strcmp(*argv, "true") == 0) { - r->forwarding_rule = MAP_FORWARDING_RULE_T; + rp->forwarding_rule = MAP_FORWARDING_RULE_T; } else if (strcmp(*argv, "false") == 0) { - r->forwarding_rule = MAP_FORWARDING_RULE_F; + rp->forwarding_rule = MAP_FORWARDING_RULE_F; } else { fprintf(stderr, "Cannot guess forwarding rule.\n"); exit(-1); @@ -318,7 +326,15 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct fprintf(stderr, "Invalid psid-offset: %s.\n", *argv); exit(-1); } - r->psid_offset = uval; + rp->psid_offset = uval; + } else if (strcmp(*argv, "pool-prefix") == 0) { + NEXT_ARG(); + if (get_prefix(&prefix, *argv, AF_INET)) { + fprintf(stderr, "Invalid pool-prefix: %s.\n", *argv); + exit(-1); + } + memcpy(&pp->pool_prefix, prefix.data, 4); + pp->pool_prefix_length = prefix.bitlen; } else if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); strncpy(p->name, *argv, IFNAMSIZ - 1); @@ -379,26 +395,26 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct /* * ipv6-prefix validation. */ - if (ipv6_addr_any(&r->ipv6_prefix)) { + if (ipv6_addr_any(&rp->ipv6_prefix)) { fprintf(stderr, "ipv6-prefix required or invalid.\n"); exit(-1); } - ipv6_addr_prefix(&t, &r->ipv6_prefix, r->ipv6_prefix_length); - if (!ipv6_addr_equal(&t, &r->ipv6_prefix)) { + ipv6_addr_prefix(&t, &rp->ipv6_prefix, rp->ipv6_prefix_length); + if (!ipv6_addr_equal(&t, &rp->ipv6_prefix)) { fprintf(stderr, "ipv6-prefix invalid.\n"); exit(-1); } /* * ipv4-prefix validation. */ - if (!r->ipv4_prefix || !r->ipv4_prefix_length) { + if (!rp->ipv4_prefix || !rp->ipv4_prefix_length) { fprintf(stderr, "ipv4-prefix required or invalid.\n"); exit(-1); } amask = 0xffffffff; - if (r->ipv4_prefix_length < 32) - amask = ~((1 << (32 - r->ipv4_prefix_length)) - 1); - if ((ntohl(r->ipv4_prefix) & amask) != ntohl(r->ipv4_prefix)) { + if (rp->ipv4_prefix_length < 32) + amask = ~((1 << (32 - rp->ipv4_prefix_length)) - 1); + if ((ntohl(rp->ipv4_prefix) & amask) != ntohl(rp->ipv4_prefix)) { fprintf(stderr, "ipv4-prefix invalid.\n"); exit(-1); } @@ -406,55 +422,62 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct * psid-prefix validation. */ pmask = 0xffff; - if (r->psid_prefix_length < 16) - pmask = (1 << r->psid_prefix_length) - 1; - if ((r->psid_prefix & pmask) != r->psid_prefix) { + if (rp->psid_prefix_length < 16) + pmask = (1 << rp->psid_prefix_length) - 1; + if ((rp->psid_prefix & pmask) != rp->psid_prefix) { fprintf(stderr, "psid-prefix invalid.\n"); exit(-1); } /* * ipv4-prefix and psid-prefix validation. */ - if (r->ipv4_prefix_length != 32 && r->psid_prefix_length > 0) { + if (rp->ipv4_prefix_length != 32 && rp->psid_prefix_length > 0) { fprintf(stderr, "psid-prefix length > 0 but ipv4-prefix length != 32.\n"); exit(-1); } /* * other validations. */ - if (r->ea_length > 48) { + if (rp->ea_length > 48) { fprintf(stderr, "ea-length required or invalid.\n"); exit(-1); } - if (r->psid_offset > 16) { + if (rp->psid_offset > 16) { fprintf(stderr, "psid-offset invalid.\n"); exit(-1); } - if (r->psid_offset + r->psid_prefix_length > 16) { + if (rp->psid_offset + rp->psid_prefix_length > 16) { fprintf(stderr, "psid_offset or psid_prefix_length invalid.\n"); exit(-1); } - if (r->ipv6_prefix_length + r->ea_length > 64) { + if (rp->ipv6_prefix_length + rp->ea_length > 64) { fprintf(stderr, "ipv6-prefix length or ea-length invalid.\n"); exit(-1); } - if (r->ipv4_prefix_length + r->psid_prefix_length + r->ea_length + r->psid_offset > 48) { + if (rp->ipv4_prefix_length + rp->psid_prefix_length + rp->ea_length + rp->psid_offset > 48) { fprintf(stderr, "ipv4-prefix length or psid-prefix length or ea-length or psid-offset invalid.\n"); exit(-1); } } if (cmd == SIOCDELMAPRULES) { - if (ipv6_addr_any(&r->ipv6_prefix)) { + if (ipv6_addr_any(&rp->ipv6_prefix)) { fprintf(stderr, "ipv6-prefix required or invalid.\n"); exit(-1); } - if (!r->ipv4_prefix) { + if (!rp->ipv4_prefix) { fprintf(stderr, "ipv4-prefix required or invalid.\n"); exit(-1); } } + if (cmd == SIOCADDMAPPOOLS || cmd == SIOCCHGMAPPOOLS || cmd == SIOCDELMAPPOOLS) { + if (!pp->pool_prefix) { + fprintf(stderr, "pool-prefix required or invalid.\n"); + exit(-1); + } + } + /* XXX: */ //debug_dump_map_parm(p); //debug_dump_map_rule_parm(r); @@ -465,9 +488,10 @@ static int parse_args(int argc, char **argv, int cmd, struct map_parm *p, struct static int do_add(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; - if (parse_args(argc, argv, SIOCADDMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCADDMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCADDMAP, &p)) @@ -479,9 +503,10 @@ static int do_add(int argc, char **argv) static int do_change(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; - if (parse_args(argc, argv, SIOCCHGMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCCHGMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCCHGMAP, &p)) @@ -493,9 +518,10 @@ static int do_change(int argc, char **argv) static int do_del(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; - if (parse_args(argc, argv, SIOCDELMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCDELMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCDELMAP, &p)) @@ -507,14 +533,15 @@ static int do_del(int argc, char **argv) static int do_show(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; struct map_parm *pptr; struct map_rule_parm *rptr; char s1[1024]; char s2[1024]; int i; - if (parse_args(argc, argv, SIOCGETMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCGETMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCGETMAP, &p)) @@ -562,16 +589,53 @@ static int do_show(int argc, char **argv) return 0; } +static int do_show_pool(int argc, char **argv) +{ + struct map_parm p; + struct map_rule_parm rp; + struct map_pool_parm pp; + struct map_parm *pptr; + struct map_pool_parm *ppptr; + char s1[1024]; + int i; + + if (parse_args(argc, argv, SIOCGETMAP, &p, &rp, &pp) < 0) + return -1; + + if (map_ioctl(p.name, SIOCGETMAP, &p)) + return -1; + + pptr = malloc(sizeof(struct map_parm) + sizeof(struct map_pool_parm) * p.pool_num); + if (!pptr) + return -1; + if (map_ioctl(p.name, SIOCGETMAPPOOLS, pptr)) + return -1; + + printf(" IPv4 pool :\n"); + for (i = 0; i < pptr->pool_num; i++) { + ppptr = &pptr->pool[i]; + memset(s1, 0, 1024); + printf(" IPv4 pool #%04d : %s/%d\n", i, + format_host(AF_INET, 4, &ppptr->pool_prefix, s1, sizeof(s1)), + ppptr->pool_prefix_length); + } + + free(pptr); + + return 0; +} + static int do_show_parm(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; struct map_current_parm cp, *cpp; char s1[1024]; char s2[1024]; int i, num; - if (parse_args(argc, argv, SIOCGETMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCGETMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCGETMAP, &p)) @@ -599,6 +663,7 @@ static int do_show_parm(int argc, char **argv) printf(" Tunnel source : %s\n", s1); printf(" BR address : %s/%d\n", inet_ntop(AF_INET6, &p.br_address, s2, sizeof(s2)), p.br_address_length); + do_show_pool(argc, argv); printf(" Default forwarding mode : %s\n", (p.default_forwarding_mode == MAP_FORWARDING_MODE_T ? "translation" : "encapsulation")); printf(" Default forwarding rule : %s\n", @@ -610,7 +675,6 @@ static int do_show_parm(int argc, char **argv) (p.napt_always == MAP_NAPT_ALWAYS_T ? "true" : "false")); printf(" NAPT force recycle : %s\n", (p.napt_force_recycle == MAP_NAPT_FORCE_RECYCLE_T ? "true" : "false")); - printf("\n"); if (cpp->has_bmr) { printf(" Basic mapping rule :\n"); printf(" Rule IPv6 prefix : %s/%d\n", @@ -654,14 +718,15 @@ static int do_show_parm(int argc, char **argv) static int do_show_rule(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; struct map_parm *pptr; struct map_rule_parm *rptr; char s1[1024]; char s2[1024]; int i; - if (parse_args(argc, argv, SIOCGETMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCGETMAP, &p, &rp, &pp) < 0) return -1; if (map_ioctl(p.name, SIOCGETMAP, &p)) @@ -706,14 +771,18 @@ static int do_show_rule(int argc, char **argv) static int do_show_napt(int argc, char **argv) { struct map_parm p; - struct map_rule_parm r; + struct map_rule_parm rp; + struct map_pool_parm pp; struct map_napt_parm np, *npp; - char s1[16], s2[16], t[16], f[16], *proto; + char s1[64], s2[64], s3[64], s4[64], t[16], f[16], *proto; struct tm tmd; int i, num; time_t now, last_used; - if (parse_args(argc, argv, SIOCGETMAP, &p, &r) < 0) + if (parse_args(argc, argv, SIOCGETMAP, &p, &rp, &pp) < 0) + return -1; + + if (map_ioctl(p.name, SIOCGETMAP, &p)) return -1; if (map_ioctl(p.name, SIOCGETMAPNAPTNUM, &np)) @@ -737,7 +806,11 @@ static int do_show_napt(int argc, char **argv) printf(" Flags: SynOut, SynAckIn, AckOut, FinOut, FinAckIn, FinIn, FinAckOut, Rst.\n"); printf(" '!' = Up, '.' = Down.\n"); printf("\n"); - printf(" Last used, Local address:port, Mapped port, Remote address:port, Proto, Flags.\n"); + if (p.role == MAP_ROLE_CE) { + printf(" Last used, Local address:port, Mapped port, Remote address:port, Proto, Flags.\n"); + } else { + printf(" Last used, Local IPv6 address, Local address:port, Mapped address:port, Remote address:port, Proto, Flags.\n"); + } for (i = 0; i < num; ++i) { switch (npp->napt_node[i].proto) { case IPPROTO_UDP: @@ -770,16 +843,31 @@ static int do_show_napt(int argc, char **argv) } else { strftime(t, sizeof(t), "%H:%M:%S", &tmd); } - printf(" %8s %15s:%-5d %6d(0x%04x) %15s:%-5d %s %s\n", - t, - format_host(AF_INET, 4, &npp->napt_node[i].laddr, s1, sizeof(s1)), - ntohs(npp->napt_node[i].lport), - ntohs(npp->napt_node[i].mport), - ntohs(npp->napt_node[i].mport), - format_host(AF_INET, 4, &npp->napt_node[i].raddr, s2, sizeof(s2)), - ntohs(npp->napt_node[i].rport), - proto, - f); + if (p.role == MAP_ROLE_CE) { + printf(" %8s %15s:%-5d %6d(0x%04x) %15s:%-5d %s %s\n", + t, + format_host(AF_INET, 4, &npp->napt_node[i].laddr, s1, sizeof(s1)), + ntohs(npp->napt_node[i].lport), + ntohs(npp->napt_node[i].mport), + ntohs(npp->napt_node[i].mport), + format_host(AF_INET, 4, &npp->napt_node[i].raddr, s2, sizeof(s2)), + ntohs(npp->napt_node[i].rport), + proto, + f); + } else { + printf(" %8s %-40s %15s:%-5d %15s:(0x%04x)%-6d %15s:%-5d %s %s\n", + t, + inet_ntop(AF_INET6, &npp->napt_node[i].laddr6, s1, sizeof(s1)), + format_host(AF_INET, 4, &npp->napt_node[i].laddr, s2, sizeof(s2)), + ntohs(npp->napt_node[i].lport), + format_host(AF_INET, 4, &npp->napt_node[i].maddr, s3, sizeof(s3)), + ntohs(npp->napt_node[i].mport), + ntohs(npp->napt_node[i].mport), + format_host(AF_INET, 4, &npp->napt_node[i].raddr, s4, sizeof(s4)), + ntohs(npp->napt_node[i].rport), + proto, + f); + } } printf("\n"); @@ -792,30 +880,32 @@ static int do_add_rule(int argc, char **argv) { struct map_parm p; struct map_parm *pptr; - struct map_rule_parm *rptr; + struct map_rule_parm *rpptr; + struct map_pool_parm pp; pptr = malloc(sizeof(struct map_parm) + sizeof(struct map_rule_parm)); if (!pptr) return -1; - rptr = &pptr->rule[0]; + rpptr = &pptr->rule[0]; - //printf("pptr = %p, rptr = %p, sizeof(*pptr) = %d.\n", pptr, rptr, sizeof(*pptr)); + //printf("pptr = %p, rpptr = %p, sizeof(*pptr) = %d.\n", pptr, rpptr, sizeof(*pptr)); - if (parse_args(argc, argv, SIOCADDMAPRULES, pptr, rptr) < 0) + if (parse_args(argc, argv, SIOCADDMAPRULES, pptr, rpptr, &pp) < 0) return -1; - if (!rptr->forwarding_mode || !rptr->forwarding_rule) { + if (!rpptr->forwarding_mode || !rpptr->forwarding_rule) { if (map_ioctl(pptr->name, SIOCGETMAP, &p)) { //printf("XXX\n"); return -1; } - if (!rptr->forwarding_mode) - rptr->forwarding_mode = p.default_forwarding_mode; - if (!rptr->forwarding_rule) - rptr->forwarding_rule = p.default_forwarding_rule; + if (!rpptr->forwarding_mode) + rpptr->forwarding_mode = p.default_forwarding_mode; + if (!rpptr->forwarding_rule) + rpptr->forwarding_rule = p.default_forwarding_rule; } pptr->rule_num = 1; + pptr->pool_num = 0; if (map_ioctl(pptr->name, SIOCADDMAPRULES, pptr)) return -1; @@ -826,17 +916,19 @@ static int do_add_rule(int argc, char **argv) static int do_del_rule(int argc, char **argv) { struct map_parm *pptr; - struct map_rule_parm *rptr; + struct map_rule_parm *rpptr; + struct map_pool_parm pp; pptr = malloc(sizeof(struct map_parm) + sizeof(struct map_rule_parm)); if (!pptr) return -1; - rptr = &pptr->rule[0]; + rpptr = &pptr->rule[0]; - if (parse_args(argc, argv, SIOCDELMAPRULES, pptr, rptr) < 0) + if (parse_args(argc, argv, SIOCDELMAPRULES, pptr, rpptr, &pp) < 0) return -1; pptr->rule_num = 1; + pptr->pool_num = 0; if (map_ioctl(pptr->name, SIOCDELMAPRULES, pptr)) return -1; @@ -844,6 +936,66 @@ static int do_del_rule(int argc, char **argv) return 0; } +static int do_add_pool(int argc, char **argv) +{ + struct map_parm p; + struct map_parm *pptr; + struct map_pool_parm *ppptr; + struct map_rule_parm rp; + + pptr = malloc(sizeof(struct map_parm) + sizeof(struct map_pool_parm)); + if (!pptr) + return -1; + ppptr = &pptr->pool[0]; + + if (parse_args(argc, argv, SIOCADDMAPPOOLS, pptr, &rp, ppptr) < 0) + return -1; + + if (map_ioctl(pptr->name, SIOCGETMAP, &p)) + return -1; + + if (p.role != MAP_ROLE_BR) + return -1; + + pptr->rule_num = 0; + pptr->pool_num = 1; + + if (map_ioctl(pptr->name, SIOCADDMAPPOOLS, pptr)) + return -1; + + return 0; +} + +static int do_del_pool(int argc, char **argv) +{ + struct map_parm p; + struct map_parm *pptr; + struct map_pool_parm *ppptr; + struct map_rule_parm rp; + + pptr = malloc(sizeof(struct map_parm) + sizeof(struct map_pool_parm)); + if (!pptr) + return -1; + ppptr = &pptr->pool[0]; + + if (parse_args(argc, argv, SIOCDELMAPPOOLS, pptr, &rp, ppptr) < 0) + return -1; + + if (map_ioctl(pptr->name, SIOCGETMAP, &p)) + return -1; + + if (p.role != MAP_ROLE_BR) + return -1; + + pptr->rule_num = 0; + pptr->pool_num = 1; + + if (map_ioctl(pptr->name, SIOCDELMAPPOOLS, pptr)) + return -1; + + return 0; +} + int do_ipmap(int argc, char **argv) { if (argc > 0) { @@ -857,6 +1009,10 @@ int do_ipmap(int argc, char **argv) return do_add_rule(argc - 1, argv + 1); if (matches(*argv, "del-rule") == 0) return do_del_rule(argc - 1, argv + 1); + if (matches(*argv, "add-pool") == 0) + return do_add_pool(argc - 1, argv + 1); + if (matches(*argv, "del-pool") == 0) + return do_del_pool(argc - 1, argv + 1); if (matches(*argv, "show") == 0) return do_show(argc - 1, argv + 1); if (matches(*argv, "show-parm") == 0)