This change updates the "pm_nl_ctl" testing sample with a "rem" (remove) option to support the newly added netlink interface command MPTCP_PM_CMD_REMOVE to issue a REMOVE_ADDR signal over the chosen MPTCP connection. E.g. ./pm_nl_ctl rem token 823274047 id 23
Unified · Split
| @@ -28,6 +28,7 @@ static void syntax(char *argv[]) · 27 unmodified lines | |||
| 28 | fprintf(stderr, "%s add|get|set|del|flush|dump|accept [<args>]\n", argv[0]); | 28 | fprintf(stderr, "%s add|get|set|del|flush|dump|accept [<args>]\n", argv[0]); |
| 29 | fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n"); | 29 | fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n"); |
| 30 | fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n"); | 30 | fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n"); |
| 31 | fprintf(stderr, "\trem id <local-id> token <token>\n"); | ||
| 31 | fprintf(stderr, "\tdel <id> [<ip>]\n"); | 32 | fprintf(stderr, "\tdel <id> [<ip>]\n"); |
| 32 | fprintf(stderr, "\tget <id>\n"); | 33 | fprintf(stderr, "\tget <id>\n"); |
| 33 | fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n"); | 34 | fprintf(stderr, "\tset [<ip>] [id <nr>] flags [no]backup|[no]fullmesh [port <nr>]\n"); |
| @@ -172,6 +173,55 @@ static int resolve_mptcp_pm_netlink(int fd) · 138 unmodified lines | |||
| 172 | return genl_parse_getfamily((void *)data); | 173 | return genl_parse_getfamily((void *)data); |
| 173 | } | 174 | } |
| 174 | 175 | ||
| 176 | int remove_addr(int fd, int pm_family, int argc, char *argv[]) | ||
| 177 | { | ||
| 178 | char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + | ||
| 179 | NLMSG_ALIGN(sizeof(struct genlmsghdr)) + | ||
| 180 | 1024]; | ||
| 181 | struct nlmsghdr *nh; | ||
| 182 | struct rtattr *rta; | ||
| 183 | u_int32_t token; | ||
| 184 | u_int8_t id; | ||
| 185 | int off = 0; | ||
| 186 | int arg; | ||
| 187 | |||
| 188 | memset(data, 0, sizeof(data)); | ||
| 189 | nh = (void *)data; | ||
| 190 | off = init_genl_req(data, pm_family, MPTCP_PM_CMD_REMOVE, | ||
| 191 | MPTCP_PM_VER); | ||
| 192 | |||
| 193 | if (argc < 6) | ||
| 194 | syntax(argv); | ||
| 195 | |||
| 196 | for (arg = 2; arg < argc; arg++) { | ||
| 197 | if (!strcmp(argv[arg], "id")) { | ||
| 198 | if (++arg >= argc) | ||
| 199 | error(1, 0, " missing id value"); | ||
| 200 | |||
| 201 | id = atoi(argv[arg]); | ||
| 202 | rta = (void *)(data + off); | ||
| 203 | rta->rta_type = MPTCP_PM_ATTR_LOC_ID; | ||
| 204 | rta->rta_len = RTA_LENGTH(1); | ||
| 205 | memcpy(RTA_DATA(rta), &id, 1); | ||
| 206 | off += NLMSG_ALIGN(rta->rta_len); | ||
| 207 | } else if (!strcmp(argv[arg], "token")) { | ||
| 208 | if (++arg >= argc) | ||
| 209 | error(1, 0, " missing token value"); | ||
| 210 | |||
| 211 | token = atoi(argv[arg]); | ||
| 212 | rta = (void *)(data + off); | ||
| 213 | rta->rta_type = MPTCP_PM_ATTR_TOKEN; | ||
| 214 | rta->rta_len = RTA_LENGTH(4); | ||
| 215 | memcpy(RTA_DATA(rta), &token, 4); | ||
| 216 | off += NLMSG_ALIGN(rta->rta_len); | ||
| 217 | } else | ||
| 218 | error(1, 0, "unknown keyword %s", argv[arg]); | ||
| 219 | } | ||
| 220 | |||
| 221 | do_nl_req(fd, nh, off, 0); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 175 | int announce_addr(int fd, int pm_family, int argc, char *argv[]) | 225 | int announce_addr(int fd, int pm_family, int argc, char *argv[]) |
| 176 | { | 226 | { |
| 177 | char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + | 227 | char data[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + |
| @@ -917,6 +967,8 @@ int main(int argc, char *argv[]) · 739 unmodified lines | |||
| 917 | return add_addr(fd, pm_family, argc, argv); | 967 | return add_addr(fd, pm_family, argc, argv); |
| 918 | else if (!strcmp(argv[1], "ann")) | 968 | else if (!strcmp(argv[1], "ann")) |
| 919 | return announce_addr(fd, pm_family, argc, argv); | 969 | return announce_addr(fd, pm_family, argc, argv); |
| 970 | else if (!strcmp(argv[1], "rem")) | ||
| 971 | return remove_addr(fd, pm_family, argc, argv); | ||
| 920 | else if (!strcmp(argv[1], "del")) | 972 | else if (!strcmp(argv[1], "del")) |
| 921 | return del_addr(fd, pm_family, argc, argv); | 973 | return del_addr(fd, pm_family, argc, argv); |
| 922 | else if (!strcmp(argv[1], "flush")) | 974 | else if (!strcmp(argv[1], "flush")) |