static int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) { struct m_pedit_sel sel = {}; int argc = *argc_p; char **argv = *argv_p; int ok = 0, iok = 0; struct rtattr *tail; while (argc > 0) { if (pedit_debug > 1) fprintf(stderr, "while pedit (%d:%s)\n", argc, *argv); if (matches(*argv, "pedit") == 0) { NEXT_ARG(); ok++; if (matches(*argv, "ex") == 0) { if (ok > 1) { fprintf(stderr, "'ex' must be before first 'munge'\n"); explain(); return -1; } sel.extended = true; NEXT_ARG(); } continue; } else if (matches(*argv, "help") == 0) { usage(); } else if (matches(*argv, "munge") == 0) { if (!ok) { fprintf(stderr, "Bad pedit construct (%s)\n", *argv); explain(); return -1; } NEXT_ARG(); if (parse_munge(&argc, &argv, &sel)) { fprintf(stderr, "Bad pedit construct (%s)\n", *argv); explain(); return -1; } ok++; } else { break; } } if (!ok) { explain(); return -1; } parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK); if (argc) { if (matches(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&sel.sel.index, *argv, 10)) { fprintf(stderr, "Pedit: Illegal \"index\"\n"); return -1; } argc--; argv++; iok++; } } tail = addattr_nest(n, MAX_MSG, tca_id); if (!sel.extended) { addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS, &sel, sizeof(sel.sel) + sel.sel.nkeys * sizeof(struct tc_pedit_key)); } else { addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS_EX, &sel, sizeof(sel.sel) + sel.sel.nkeys * sizeof(struct tc_pedit_key)); pedit_keys_ex_addattr(&sel, n); } addattr_nest_end(n, tail); *argc_p = argc; *argv_p = argv; return 0; }
int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) { struct { struct tc_pedit_sel sel; struct tc_pedit_key keys[MAX_OFFS]; } sel; int argc = *argc_p; char **argv = *argv_p; int ok = 0, iok = 0; struct rtattr *tail; memset(&sel, 0, sizeof(sel)); while (argc > 0) { if (pedit_debug > 1) fprintf(stderr, "while pedit (%d:%s)\n",argc, *argv); if (matches(*argv, "pedit") == 0) { NEXT_ARG(); ok++; continue; } else if (matches(*argv, "help") == 0) { usage(); } else if (matches(*argv, "munge") == 0) { if (!ok) { fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); explain(); return -1; } NEXT_ARG(); if (parse_munge(&argc, &argv,&sel.sel)) { fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); explain(); return -1; } ok++; } else { break; } } if (!ok) { explain(); return -1; } if (argc) { if (matches(*argv, "reclassify") == 0) { sel.sel.action = TC_ACT_RECLASSIFY; NEXT_ARG(); } else if (matches(*argv, "pipe") == 0) { sel.sel.action = TC_ACT_PIPE; NEXT_ARG(); } else if (matches(*argv, "drop") == 0 || matches(*argv, "shot") == 0) { sel.sel.action = TC_ACT_SHOT; NEXT_ARG(); } else if (matches(*argv, "continue") == 0) { sel.sel.action = TC_ACT_UNSPEC; NEXT_ARG(); } else if (matches(*argv, "pass") == 0) { sel.sel.action = TC_ACT_OK; NEXT_ARG(); } } if (argc) { if (matches(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&sel.sel.index, *argv, 10)) { fprintf(stderr, "Pedit: Illegal \"index\"\n"); return -1; } argc--; argv++; iok++; } } tail = NLMSG_TAIL(n); addattr_l(n, MAX_MSG, tca_id, NULL, 0); addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS,&sel, sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_pedit_key)); tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; *argc_p = argc; *argv_p = argv; return 0; }