+ switch (action) {
+ case IPRULE_SAVE:
+ if (save_rule_prep())
+ return -1;
+ filter_fn = save_rule;
+ break;
+ case IPRULE_FLUSH:
+ filter_fn = flush_rule;
+ break;
+ default:
+ filter_fn = print_rule;
+ }
+
+ memset(&filter, 0, sizeof(filter));
+
+ while (argc > 0) {
+ if (matches(*argv, "preference") == 0 ||
+ matches(*argv, "order") == 0 ||
+ matches(*argv, "priority") == 0) {
+ __u32 pref;
+
+ NEXT_ARG();
+ if (get_u32(&pref, *argv, 0))
+ invarg("preference value is invalid\n", *argv);
+ filter.pref = pref;
+ filter.prefmask = 1;
+ } else if (strcmp(*argv, "not") == 0) {
+ filter.not = 1;
+ } else if (strcmp(*argv, "tos") == 0) {
+ __u32 tos;
+
+ NEXT_ARG();
+ if (rtnl_dsfield_a2n(&tos, *argv))
+ invarg("TOS value is invalid\n", *argv);
+ filter.tos = tos;
+ filter.tosmask = 1;
+ } else if (strcmp(*argv, "fwmark") == 0) {
+ char *slash;
+ __u32 fwmark, fwmask;
+
+ NEXT_ARG();
+ slash = strchr(*argv, '/');
+ if (slash != NULL)
+ *slash = '\0';
+ if (get_u32(&fwmark, *argv, 0))
+ invarg("fwmark value is invalid\n", *argv);
+ filter.fwmark = fwmark;
+ if (slash) {
+ if (get_u32(&fwmask, slash+1, 0))
+ invarg("fwmask value is invalid\n",
+ slash+1);
+ filter.fwmask = fwmask;
+ }
+ } else if (strcmp(*argv, "dev") == 0 ||
+ strcmp(*argv, "iif") == 0) {
+ NEXT_ARG();
+ if (get_ifname(filter.iif, *argv))
+ invarg("\"iif\"/\"dev\" not a valid ifname", *argv);
+ filter.iifmask = 1;
+ } else if (strcmp(*argv, "oif") == 0) {
+ NEXT_ARG();
+ if (get_ifname(filter.oif, *argv))
+ invarg("\"oif\" not a valid ifname", *argv);
+ filter.oifmask = 1;
+ } else if (strcmp(*argv, "l3mdev") == 0) {
+ filter.l3mdev = 1;
+ } else if (strcmp(*argv, "uidrange") == 0) {
+ NEXT_ARG();
+ filter.uidrange = 1;
+ if (sscanf(*argv, "%u-%u",
+ &filter.range.start,
+ &filter.range.end) != 2)
+ invarg("invalid UID range\n", *argv);
+
+ } else if (matches(*argv, "lookup") == 0 ||
+ matches(*argv, "table") == 0) {
+ __u32 tid;
+
+ NEXT_ARG();
+ if (rtnl_rttable_a2n(&tid, *argv))
+ invarg("table id value is invalid\n", *argv);
+ filter.tb = tid;
+ } else if (matches(*argv, "from") == 0 ||
+ matches(*argv, "src") == 0) {
+ NEXT_ARG();
+ if (get_prefix(&filter.src, *argv, af))
+ invarg("from value is invalid\n", *argv);
+ } else if (matches(*argv, "protocol") == 0) {
+ __u32 prot;
+ NEXT_ARG();
+ filter.protocolmask = -1;
+ if (rtnl_rtprot_a2n(&prot, *argv)) {
+ if (strcmp(*argv, "all") != 0)
+ invarg("invalid \"protocol\"\n", *argv);
+ prot = 0;
+ filter.protocolmask = 0;
+ }
+ filter.protocol = prot;
+ } else{
+ if (matches(*argv, "dst") == 0 ||
+ matches(*argv, "to") == 0) {
+ NEXT_ARG();
+ }
+ if (get_prefix(&filter.dst, *argv, af))
+ invarg("to value is invalid\n", *argv);
+ }
+ argc--; argv++;
+ }
+
+ if (rtnl_ruledump_req(&rth, af) < 0) {