Beispiel #1
0
static int rsvp_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
    int family = strcmp(qu->id, "rsvp") == 0 ? AF_INET : AF_INET6;
    struct tc_rsvp_pinfo pinfo;
    struct tc_police tp;
    struct tcmsg *t = NLMSG_DATA(n);
    int pinfo_ok = 0;
    struct rtattr *tail;

    memset(&pinfo, 0, sizeof(pinfo));
    memset(&tp, 0, sizeof(tp));

    if (handle) {
        if (get_u32(&t->tcm_handle, handle, 0)) {
            my_printf("Illegal \"handle\"\n");
            return -1;
        }
    }

    if (argc == 0)
        return 0;

    tail = NLMSG_TAIL(n);
    addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

    while (argc > 0) {
        if (matches(*argv, "session") == 0) {
            inet_prefix addr;
            NEXT_ARG();
            if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 1, family)) {
                my_printf("Illegal \"session\"\n");
                return -1;
            }
            addattr_l(n, 4096, TCA_RSVP_DST, &addr.data, addr.bytelen);
            if (pinfo.dpi.mask || pinfo.protocol)
                pinfo_ok++;
            continue;
        } else if (matches(*argv, "sender") == 0 ||
                   matches(*argv, "flowspec") == 0) {
            inet_prefix addr;
            NEXT_ARG();
            if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 0, family)) {
                my_printf("Illegal \"sender\"\n");
                return -1;
            }
            addattr_l(n, 4096, TCA_RSVP_SRC, &addr.data, addr.bytelen);
            if (pinfo.spi.mask || pinfo.protocol)
                pinfo_ok++;
            continue;
        } else if (matches("ipproto", *argv) == 0) {
            int num;
            NEXT_ARG();
            num = inet_proto_a2n(*argv);
            if (num < 0) {
                my_printf("Illegal \"ipproto\"\n");
                return -1;
            }
            pinfo.protocol = num;
            pinfo_ok++;
        } else if (matches(*argv, "classid") == 0 ||
                   strcmp(*argv, "flowid") == 0) {
            unsigned handle;
            NEXT_ARG();
            if (get_tc_classid(&handle, *argv)) {
                my_printf("Illegal \"classid\"\n");
                return -1;
            }
            addattr_l(n, 4096, TCA_RSVP_CLASSID, &handle, 4);
        } else if (strcmp(*argv, "tunnelid") == 0) {
            unsigned tid;
            NEXT_ARG();
            if (get_unsigned(&tid, *argv, 0)) {
                my_printf("Illegal \"tunnelid\"\n");
                return -1;
            }
            pinfo.tunnelid = tid;
            pinfo_ok++;
        } else if (strcmp(*argv, "tunnel") == 0) {
            unsigned tid;
            NEXT_ARG();
            if (get_unsigned(&tid, *argv, 0)) {
                my_printf("Illegal \"tunnel\"\n");
                return -1;
            }
            addattr_l(n, 4096, TCA_RSVP_CLASSID, &tid, 4);
            NEXT_ARG();
            if (strcmp(*argv, "skip") == 0) {
                NEXT_ARG();
            }
            if (get_unsigned(&tid, *argv, 0)) {
                my_printf("Illegal \"skip\"\n");
                return -1;
            }
            pinfo.tunnelhdr = tid;
            pinfo_ok++;
        } else if (matches(*argv, "police") == 0) {
            NEXT_ARG();
            if (parse_police(&argc, &argv, TCA_RSVP_POLICE, n)) {
                my_printf("Illegal \"police\"\n");
                return -1;
            }
            continue;
        } else if (strcmp(*argv, "help") == 0) {
            explain();
            return -1;
        } else {
            my_printf("What is \"%s\"?\n", *argv);
            explain();
            return -1;
        }
        argc--;
        argv++;
    }

    if (pinfo_ok)
        addattr_l(n, 4096, TCA_RSVP_PINFO, &pinfo, sizeof(pinfo));
    tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
    return 0;
}
Beispiel #2
0
static int
parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
	      struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0;
	struct rtattr *tail;
	unsigned int tmp;
	__u16 queue_mapping, ptype;
	__u32 flags = 0, priority, mark;
	struct tc_skbedit sel = { 0 };

	if (matches(*argv, "skbedit") != 0)
		return -1;

	NEXT_ARG();

	while (argc > 0) {
		if (matches(*argv, "queue_mapping") == 0) {
			flags |= SKBEDIT_F_QUEUE_MAPPING;
			NEXT_ARG();
			if (get_unsigned(&tmp, *argv, 10) || tmp > 65535) {
				fprintf(stderr, "Illegal queue_mapping\n");
				return -1;
			}
			queue_mapping = tmp;
			ok++;
		} else if (matches(*argv, "priority") == 0) {
			flags |= SKBEDIT_F_PRIORITY;
			NEXT_ARG();
			if (get_tc_classid(&priority, *argv)) {
				fprintf(stderr, "Illegal priority\n");
				return -1;
			}
			ok++;
		} else if (matches(*argv, "mark") == 0) {
			flags |= SKBEDIT_F_MARK;
			NEXT_ARG();
			if (get_u32(&mark, *argv, 0)) {
				fprintf(stderr, "Illegal mark\n");
				return -1;
			}
			ok++;
		} else if (matches(*argv, "ptype") == 0) {

			NEXT_ARG();
			if (matches(*argv, "host") == 0) {
				ptype = PACKET_HOST;
			} else if (matches(*argv, "broadcast") == 0) {
				ptype = PACKET_BROADCAST;
			} else if (matches(*argv, "multicast") == 0) {
				ptype = PACKET_MULTICAST;
			} else if (matches(*argv, "otherhost") == 0) {
				ptype = PACKET_OTHERHOST;
			} else {
				fprintf(stderr, "Illegal ptype (%s)\n",
					*argv);
				return -1;
			}
			flags |= SKBEDIT_F_PTYPE;
			ok++;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			break;
		}
		argc--;
		argv++;
	}

	parse_action_control_dflt(&argc, &argv, &sel.action,
				  false, TC_ACT_PIPE);

	if (argc) {
		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&sel.index, *argv, 10)) {
				fprintf(stderr, "Pedit: Illegal \"index\"\n");
				return -1;
			}
			argc--;
			argv++;
			ok++;
		}
	}

	if (!ok) {
		explain();
		return -1;
	}


	tail = addattr_nest(n, MAX_MSG, tca_id);
	addattr_l(n, MAX_MSG, TCA_SKBEDIT_PARMS, &sel, sizeof(sel));
	if (flags & SKBEDIT_F_QUEUE_MAPPING)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_QUEUE_MAPPING,
			  &queue_mapping, sizeof(queue_mapping));
	if (flags & SKBEDIT_F_PRIORITY)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
			  &priority, sizeof(priority));
	if (flags & SKBEDIT_F_MARK)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
			  &mark, sizeof(mark));
	if (flags & SKBEDIT_F_PTYPE)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_PTYPE,
			  &ptype, sizeof(ptype));
	addattr_nest_end(n, tail);

	*argc_p = argc;
	*argv_p = argv;
	return 0;
}
Beispiel #3
0
int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)
{
	struct qdisc_util *q = NULL;
	struct tc_estimator est;
	char  d[16];
	char  k[16];
	struct {
		struct nlmsghdr 	n;
		struct tcmsg 		t;
		char   			buf[TCA_BUF_MAX];
	} req;

	memset(&req, 0, sizeof(req));
	memset(&est, 0, sizeof(est));
	memset(&d, 0, sizeof(d));
	memset(&k, 0, sizeof(k));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
	req.n.nlmsg_type = cmd;
	req.t.tcm_family = AF_UNSPEC;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (d[0])
				duparg("dev", *argv);
			strncpy(d, *argv, sizeof(d)-1);
		} else if (strcmp(*argv, "handle") == 0) {
			__u32 handle;
			if (req.t.tcm_handle)
				duparg("handle", *argv);
			NEXT_ARG();
			if (get_qdisc_handle(&handle, *argv))
				invarg(*argv, "invalid qdisc ID");
			req.t.tcm_handle = handle;
		} else if (strcmp(*argv, "root") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_ROOT;
#ifdef TC_H_INGRESS
		} else if (strcmp(*argv, "ingress") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"ingress\" is a duplicate parent ID\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_INGRESS;
			strncpy(k, "ingress", sizeof(k)-1);
			q = get_qdisc_kind(k);
			req.t.tcm_handle = 0xffff0000;

			argc--; argv++;
			break;
#endif
		} else if (strcmp(*argv, "parent") == 0) {
			__u32 handle;
			NEXT_ARG();
			if (req.t.tcm_parent)
				duparg("parent", *argv);
			if (get_tc_classid(&handle, *argv))
				invarg(*argv, "invalid parent ID");
			req.t.tcm_parent = handle;
		} else if (matches(*argv, "estimator") == 0) {
			if (parse_estimator(&argc, &argv, &est))
				return -1;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			strncpy(k, *argv, sizeof(k)-1);

			q = get_qdisc_kind(k);
			argc--; argv++;
			break;
		}
		argc--; argv++;
	}

	if (k[0])
		addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
	if (est.ewma_log)
		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));

	if (q) {
		if (!q->parse_qopt) {
			fprintf(stderr, "qdisc '%s' does not support option parsing\n", k);
			return -1;
		}
		if (q->parse_qopt(q, argc, argv, &req.n))
			return 1;
	} else {
		if (argc) {
			if (matches(*argv, "help") == 0)
				usage();

			fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc qdisc help\".\n", *argv);
			return -1;
		}
	}

	if (d[0])  {
		int idx;

 		ll_init_map(&rth);

		if ((idx = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			return 1;
		}
		req.t.tcm_ifindex = idx;
	}

 	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
		return 2;

	return 0;
}
Beispiel #4
0
static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv)
{
	struct qdisc_util *q = NULL;
	struct tc_estimator est;
	struct {
		struct tc_sizespec	szopts;
		__u16			*data;
	} stab;
	char  d[16];
	char  k[16];
	struct {
		struct nlmsghdr	n;
		struct tcmsg		t;
		char			buf[TCA_BUF_MAX];
	} req;

	memset(&req, 0, sizeof(req));
	memset(&stab, 0, sizeof(stab));
	memset(&est, 0, sizeof(est));
	memset(&d, 0, sizeof(d));
	memset(&k, 0, sizeof(k));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
	req.n.nlmsg_type = cmd;
	req.t.tcm_family = AF_UNSPEC;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (d[0])
				duparg("dev", *argv);
			strncpy(d, *argv, sizeof(d)-1);
		} else if (strcmp(*argv, "handle") == 0) {
			__u32 handle;

			if (req.t.tcm_handle)
				duparg("handle", *argv);
			NEXT_ARG();
			if (get_qdisc_handle(&handle, *argv))
				invarg("invalid qdisc ID", *argv);
			req.t.tcm_handle = handle;
		} else if (strcmp(*argv, "root") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_ROOT;
		} else if (strcmp(*argv, "clsact") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"clsact\" is a duplicate parent ID\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_CLSACT;
			strncpy(k, "clsact", sizeof(k) - 1);
			q = get_qdisc_kind(k);
			req.t.tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0);
			NEXT_ARG_FWD();
			break;
		} else if (strcmp(*argv, "ingress") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"ingress\" is a duplicate parent ID\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_INGRESS;
			strncpy(k, "ingress", sizeof(k) - 1);
			q = get_qdisc_kind(k);
			req.t.tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);
			NEXT_ARG_FWD();
			break;
		} else if (strcmp(*argv, "parent") == 0) {
			__u32 handle;

			NEXT_ARG();
			if (req.t.tcm_parent)
				duparg("parent", *argv);
			if (get_tc_classid(&handle, *argv))
				invarg("invalid parent ID", *argv);
			req.t.tcm_parent = handle;
		} else if (matches(*argv, "estimator") == 0) {
			if (parse_estimator(&argc, &argv, &est))
				return -1;
		} else if (matches(*argv, "stab") == 0) {
			if (parse_size_table(&argc, &argv, &stab.szopts) < 0)
				return -1;
			continue;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			strncpy(k, *argv, sizeof(k)-1);

			q = get_qdisc_kind(k);
			argc--; argv++;
			break;
		}
		argc--; argv++;
	}

	if (k[0])
		addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
	if (est.ewma_log)
		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));

	if (q) {
		if (q->parse_qopt) {
			if (q->parse_qopt(q, argc, argv, &req.n))
				return 1;
		} else if (argc) {
			fprintf(stderr, "qdisc '%s' does not support option parsing\n", k);
			return -1;
		}
	} else {
		if (argc) {
			if (matches(*argv, "help") == 0)
				usage();

			fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc qdisc help\".\n", *argv);
			return -1;
		}
	}

	if (check_size_table_opts(&stab.szopts)) {
		struct rtattr *tail;

		if (tc_calc_size_table(&stab.szopts, &stab.data) < 0) {
			fprintf(stderr, "failed to calculate size table.\n");
			return -1;
		}

		tail = NLMSG_TAIL(&req.n);
		addattr_l(&req.n, sizeof(req), TCA_STAB, NULL, 0);
		addattr_l(&req.n, sizeof(req), TCA_STAB_BASE, &stab.szopts,
			  sizeof(stab.szopts));
		if (stab.data)
			addattr_l(&req.n, sizeof(req), TCA_STAB_DATA, stab.data,
				  stab.szopts.tsize * sizeof(__u16));
		tail->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)tail;
		if (stab.data)
			free(stab.data);
	}

	if (d[0])  {
		int idx;

		ll_init_map(&rth);

		if ((idx = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			return 1;
		}
		req.t.tcm_ifindex = idx;
	}

	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
		return 2;

	return 0;
}
Beispiel #5
0
static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	if (argc == 0)
		return 0;

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "classid") == 0 ||
		    matches(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_FW_CLASSID, &handle, 4);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FW_ACT, n)) {
				fprintf(stderr, "Illegal fw \"action\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "indev") == 0) {
			char d[IFNAMSIZ+1];
			memset(d, 0, sizeof (d));
			argc--;
			argv++;
			if (argc < 1) {
				fprintf(stderr, "Illegal indev\n");
				return -1;
			}
			strncpy(d, *argv, sizeof (d) - 1);
			addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1);
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Beispiel #6
0
int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)
{
	struct qdisc_util *q = NULL;
	struct tc_estimator est;
	struct {
		struct tc_sizespec	szopts;
		__u16		*data;
	} stab;
	char  d[16];
	char  k[16];	
	struct {
		struct nlmsghdr 	n;
		struct tcmsg 		t;
		char  			buf[TCA_BUF_MAX];
	} * req;
	
	req = vmalloc(sizeof(*req));
	
	memset(req, 0, sizeof(*req));
	memset(&stab, 0, sizeof(stab));
	memset(&est, 0, sizeof(est));
	memset(&d, 0, sizeof(d));
	memset(&k, 0, sizeof(k));
		
	req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
	req->n.nlmsg_flags = NLM_F_REQUEST|flags;
	req->n.nlmsg_type = cmd;
	req->t.tcm_family = AF_UNSPEC;
	
	/*
	printk(KERN_DEBUG "NLM_F_CREATE:  %d\n", NLM_F_CREATE);
	printk(KERN_DEBUG "NLM_F_REPLACE: %d\n", NLM_F_REPLACE);
	printk(KERN_DEBUG "NLM_F_REQUEST: %d\n", NLM_F_REQUEST);
	printk(KERN_DEBUG "NLM_F_EXCL:    %d\n", NLM_F_EXCL);
	printk(KERN_DEBUG "RTM_NEWQDISC:  %d\n", RTM_NEWQDISC);
	printk(KERN_DEBUG "RTM_DELQDISC:  %d\n", RTM_DELQDISC);
	printk(KERN_DEBUG "cmd:           %d\n", cmd);
	printk(KERN_DEBUG "req:           %d\n", sizeof(*req));
	*/
	
	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG(); // Mangia un argomento
			if (d[0])
				duparg("dev", *argv);
			strncpy(d, *argv, sizeof(d)-1);
		} else if (strcmp(*argv, "handle") == 0) {
			__u32 handle; //unsigned long?
			if (req->t.tcm_handle)
				duparg("handle", *argv);
			NEXT_ARG(); // Mangia un argomento
			if (get_qdisc_handle(&handle, *argv))
				invarg("invalid qdisc ID", *argv);
			req->t.tcm_handle = handle;
		} else if (strcmp(*argv, "root") == 0) {
			if (req->t.tcm_parent) {
				printk(KERN_DEBUG "[MAT] Error: \"root\" is duplicate parent ID\n");
				return -1;
			}
			req->t.tcm_parent = TC_H_ROOT;
		} else if (strcmp(*argv, "parent") == 0) {
			__u32 handle;
			NEXT_ARG();
			if (req->t.tcm_parent)
				duparg("parent", *argv);
			if (get_tc_classid(&handle, *argv))
				invarg("invalid parent ID", *argv);
			req->t.tcm_parent = handle;
		} /* else if (matches(*argv, "estimator") == 0) {
			if (parse_estimator(&argc, &argv, &est))
				return -1;
		} */ else if (matches(*argv, "stab") == 0) {
			if (parse_size_table(&argc, &argv, &stab.szopts) < 0)
				return -1;
			continue;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			strncpy(k, *argv, sizeof(k)-1);
			q = get_qdisc_kind(k);
			argc--; argv++;
			break;
		}
		argc--; argv++;
	}
	
	if (k[0])
		addattr_l(&req->n, sizeof(*req), TCA_KIND, k, strlen(k)+1);
	if (est.ewma_log) 
		addattr_l(&req->n, sizeof(*req), TCA_RATE, &est, sizeof(est));

	if (q) {
		if (!q->parse_qopt) {
			printk(KERN_DEBUG "[MAT] qdisc '%s' does not support option parsing\n", k);
			return -1;
		}
		if (q->parse_qopt(q, argc, argv, &req->n))
			return 1;
	} else {
		if (argc) {
			if (matches(*argv, "help") == 0)
				usage();
			printk(KERN_DEBUG "[MAT] Garbage instead of arguments \"%s ...\". Try \"tc qdisc help\".\n", *argv);
			return -1;
		}
	}
	
	if (check_size_table_opts(&stab.szopts)) {
		struct rtattr *tail;
		if (tc_calc_size_table(&stab.szopts, &stab.data) < 0) {
			printk(KERN_DEBUG "[MAT] failed to calculate size table.\n");
			return -1;
		}
		tail = NLMSG_TAIL(&req->n);
		addattr_l(&req->n, sizeof(*req), TCA_STAB, NULL, 0);
		addattr_l(&req->n, sizeof(*req), TCA_STAB_BASE, &stab.szopts,
			  sizeof(stab.szopts));
		if (stab.data)
			addattr_l(&req->n, sizeof(*req), TCA_STAB_DATA, stab.data,
				  stab.szopts.tsize * sizeof(__u16));
		tail->rta_len = (void *)NLMSG_TAIL(&req->n) - (void *)tail;
		if (stab.data)
			vfree(stab.data);
	}
	
/*	
	if (d[0])  {
		int idx;

 		ll_init_map(&rth);

		if ((idx = ll_name_to_index(d)) == 0) {
			printk(KERN_DEBUG "[MAT] Cannot find device \"%s\"\n", d);
			return 1;
		}
		req->t.tcm_ifindex = idx;
      }
*/     
	if (rtnl_talk(&rth, &req->n, 0, 0, NULL) < 0)
		return 2;
	 
	return 0;
}
Beispiel #7
0
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned divisor;
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
			    divisor > 0x100) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
				htid = (htid&0xFF000)|(handle&0xFFF00000);
			else
				htid = (handle&0xFFFFF000);
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash<<12)&0xFF000)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
#ifdef TC_CONFIG_ALL
		} else if (matches(*argv, "police") == 0) {
Beispiel #8
0
static int basic_parse_opt(struct filter_util *qu, char *handle,
			   int argc, char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	long h = 0;

	if (argc == 0)
		return 0;

	if (handle) {
		h = strtol(handle, NULL, 0);
		if (h == LONG_MIN || h == LONG_MAX) {
			fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
			    handle);
			return -1;
		}
	}

	t->tcm_handle = h;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_ematch(&argc, &argv, TCA_BASIC_EMATCHES, n)) {
				fprintf(stderr, "Illegal \"ematch\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_BASIC_CLASSID, &handle, 4);
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_BASIC_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;

		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_BASIC_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
	return 0;
}
Beispiel #9
0
static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
   struct nlmsghdr *n)
{
	struct sockaddr_atmsvc addr;
	struct atm_qos qos;
	struct atm_sap sap;
	unsigned char hdr[MAX_HDR_LEN];
	__u32 excess = 0;
	struct rtattr *tail;
	int sndbuf = 0;
	int hdr_len = -1;
	int set_clip = 0;
	int s;

	memset(&addr,0,sizeof(addr));
	(void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0);
	(void) text2sap("blli:l2=iso8802",&sap,0);
	while (argc > 0) {
		if (!strcmp(*argv,"pvc")) {
			NEXT_ARG();
			if (text2atm(*argv,(struct sockaddr *) &addr,
			    sizeof(addr),T2A_PVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"svc")) {
			NEXT_ARG();
			if (text2atm(*argv,(struct sockaddr *) &addr,
			    sizeof(addr),T2A_SVC | T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"qos")) {
			NEXT_ARG();
			if (text2qos(*argv,&qos,0) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"sndbuf")) {
			char *end;

			NEXT_ARG();
			sndbuf = strtol(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"sap")) {
			NEXT_ARG();
			if (addr.sas_family != AF_ATMSVC ||
			    text2sap(*argv,&sap,T2A_NAME) < 0) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"hdr")) {
			unsigned char *ptr;
			char *walk;

			NEXT_ARG();
			ptr = hdr;
			for (walk = *argv; *walk; walk++) {
				int tmp;

				if (ptr == hdr+MAX_HDR_LEN) {
//					fprintf(stderr,"header is too long\n");
					return -1;
				}
				if (*walk == '.') continue;
				if (!isxdigit(walk[0]) || !walk[1] ||
				    !isxdigit(walk[1])) {
					explain();
					return -1;
				}
				sscanf(walk,"%2x",&tmp);
				*ptr++ = tmp;
				walk++;
			}
			hdr_len = ptr-hdr;
		}
		else if (!strcmp(*argv,"excess")) {
			NEXT_ARG();
			if (!strcmp(*argv,"clp")) excess = 0;
			else if (get_tc_classid(&excess,*argv)) {
					explain();
					return -1;
				}
		}
		else if (!strcmp(*argv,"clip")) {
			set_clip = 1;
		}
		else {
			explain();
			return 1;
		}
		argc--;
		argv++;
	}
	s = socket(addr.sas_family,SOCK_DGRAM,0);
	if (s < 0) {
//		perror("socket");
		return -1;
	}
	if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) {
//		perror("SO_ATMQOS");
		return -1;
	}
	if (sndbuf)
	    if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
//		perror("SO_SNDBUF");
	    return -1;
	}
	if (addr.sas_family == AF_ATMSVC && setsockopt(s,SOL_ATM,SO_ATMSAP,
	    &sap,sizeof(sap)) < 0) {
//		perror("SO_ATMSAP");
		return -1;
	}
	if (connect(s,(struct sockaddr *) &addr,addr.sas_family == AF_ATMPVC ?
	    sizeof(struct sockaddr_atmpvc) : sizeof(addr)) < 0) {
///		perror("connect");
		return -1;
	}
	if (set_clip)
		if (ioctl(s,ATMARP_MKIP,0) < 0) {
//			perror("ioctl ATMARP_MKIP");
			return -1;
		}
	tail = NLMSG_TAIL(n);
	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
	addattr_l(n,1024,TCA_ATM_FD,&s,sizeof(s));
	if (excess) addattr_l(n,1024,TCA_ATM_EXCESS,&excess,sizeof(excess));
	if (hdr_len != -1) addattr_l(n,1024,TCA_ATM_HDR,hdr,hdr_len);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
    char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	char *end;

	if (handle) {
		t->tcm_handle = strtoul(handle,&end,0);
		if (*end) {
			fprintf(stderr, "Illegal filter ID\n");
			return -1;
		}
	}
	if (!argc) return 0;
	tail = NLMSG_TAIL(n);
	addattr_l(n,4096,TCA_OPTIONS,NULL,0);
	while (argc) {
		if (!strcmp(*argv,"hash")) {
			int hash;

			NEXT_ARG();
			hash = strtoul(*argv,&end,0);
			if (*end || !hash || hash > 0x10000) {
				explain();
				return -1;
			}
			addattr_l(n,4096,TCA_TCINDEX_HASH,&hash,sizeof(hash));
		}
		else if (!strcmp(*argv,"mask")) {
			__u16 mask;

			NEXT_ARG();
			mask = strtoul(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n,4096,TCA_TCINDEX_MASK,&mask,sizeof(mask));
		}
		else if (!strcmp(*argv,"shift")) {
			int shift;

			NEXT_ARG();
			shift = strtoul(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n,4096,TCA_TCINDEX_SHIFT,&shift,
			    sizeof(shift));
		}
		else if (!strcmp(*argv,"fall_through")) {
			int value = 1;

			addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value,
			    sizeof(value));
		}
		else if (!strcmp(*argv,"pass_on")) {
			int value = 0;

			addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value,
			    sizeof(value));
		}
		else if (!strcmp(*argv,"classid")) {
			__u32 handle;

			NEXT_ARG();
			if (get_tc_classid(&handle,*argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
		}
		else if (!strcmp(*argv,"police")) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		}
		else {
			explain();
			return -1;
		}
		argc--;
		argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Beispiel #11
0
static int flow_parse_opt(struct filter_util *fu, char *handle,
			  int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_police tp;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	__u32 mask = ~0U, xor = 0;
	__u32 keys = 0, nkeys = 0;
	__u32 mode = FLOW_MODE_MAP;
	__u32 tmp;

	memset(&tp, 0, sizeof(tp));

	if (handle) {
		if (get_u32(&t->tcm_handle, handle, 0)) {
			fprintf(stderr, "Illegal \"handle\"\n");
			return -1;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "map") == 0) {
			mode = FLOW_MODE_MAP;
		} else if (matches(*argv, "hash") == 0) {
			mode = FLOW_MODE_HASH;
		} else if (matches(*argv, "keys") == 0) {
			NEXT_ARG();
			if (flow_parse_keys(&keys, &nkeys, *argv))
				return -1;
			addattr32(n, 4096, TCA_FLOW_KEYS, keys);
		} else if (matches(*argv, "and") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"mask\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, tmp, 0);
		} else if (matches(*argv, "or") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"or\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~tmp, tmp);
		} else if (matches(*argv, "xor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"xor\"\n");
				return -1;
			}
			transfer_bitop(&mask, &xor, ~0, tmp);
		} else if (matches(*argv, "rshift") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"rshift\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_RSHIFT, tmp);
		} else if (matches(*argv, "addend") == 0) {
			NEXT_ARG();
			if (get_addend(&tmp, *argv, keys)) {
				fprintf(stderr, "Illegal \"addend\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_ADDEND, tmp);
		} else if (matches(*argv, "divisor") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_DIVISOR, tmp);
		} else if (matches(*argv, "baseclass") == 0) {
			NEXT_ARG();
			if (get_tc_classid(&tmp, *argv) || TC_H_MIN(tmp) == 0) {
				fprintf(stderr, "Illegal \"baseclass\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_BASECLASS, tmp);
		} else if (matches(*argv, "perturb") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 0)) {
				fprintf(stderr, "Illegal \"perturb\"\n");
				return -1;
			}
			addattr32(n, 4096, TCA_FLOW_PERTURB, tmp);
		} else if (matches(*argv, "police") == 0) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_FLOW_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "action") == 0) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_FLOW_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_ematch(&argc, &argv, TCA_FLOW_EMATCHES, n)) {
				fprintf(stderr, "Illegal \"ematch\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argv++, argc--;
	}

	if (nkeys > 1 && mode != FLOW_MODE_HASH) {
		fprintf(stderr, "Invalid mode \"map\" for multiple keys\n");
		return -1;
	}
	addattr32(n, 4096, TCA_FLOW_MODE, mode);

	if (mask != ~0 || xor != 0) {
		addattr32(n, 4096, TCA_FLOW_MASK, mask);
		addattr32(n, 4096, TCA_FLOW_XOR, xor);
	}

	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
	return 0;
}
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

//fprintf(stderr, "handle[%s]\n", handle);

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;



	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel, n)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned int divisor;
fprintf(stderr, "parse divisor\n");
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || 
			    divisor == 0 ||
			   //divisor > 0x100 || ((divisor - 1) & divisor)) {//richie1124
			   divisor > 0x1000 || ((divisor - 1) & divisor)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
//fprintf(stderr, "f_u32, handle[%x]\n", handle);
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
			{
				//htid = (htid&0xFF000)|(handle&0xFFF00000);
				//htid = (htid&0xFFF00)|(handle&0xFFF00000);
				htid = (htid&0xFFF00)|(handle&0xFFF00000);//richie1124
			}
			else
			{
				//htid = (handle&0xFFFFF000);
				htid = (handle&0xFFFFFF00);
				//htid = (handle&0xFFFFFF00);//richie1124
			}
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			unsigned divisor = 0x100;

			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			memset(&sel2, 0, sizeof(sel2));
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel, n)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			if (*argv != 0 && strcmp(*argv, "divisor") == 0) {
				NEXT_ARG();
				if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
				    divisor > 0x100 || ((divisor - 1) & divisor)) {
					fprintf(stderr, "Illegal sample \"divisor\"\n");
					return -1;
				}
				NEXT_ARG();
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash%divisor)<<12)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
		} else if (strcmp(*argv, "indev") == 0) {
static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
	int wrr_ok=0, fopt_ok=0;
	struct tc_ratespec r;
	struct tc_cbq_lssopt lss;
	struct tc_cbq_wrropt wrr;
	struct tc_cbq_fopt fopt;
	struct tc_cbq_ovl ovl;
	__u32 rtab[256];
	unsigned mpu=0;
	int cell_log=-1; 
	int ewma_log=-1;
	unsigned bndw = 0;
	unsigned minburst=0, maxburst=0;
	struct rtattr *tail;

	memset(&r, 0, sizeof(r));
	memset(&lss, 0, sizeof(lss));
	memset(&wrr, 0, sizeof(wrr));
	memset(&fopt, 0, sizeof(fopt));
	memset(&ovl, 0, sizeof(ovl));

	while (argc > 0) {
		if (strcmp(*argv, "rate") == 0) {
			NEXT_ARG();
			if (get_rate(&r.rate, *argv)) {
				explain1("rate");
				return -1;
			}
		} else if (strcmp(*argv, "bandwidth") == 0) {
			NEXT_ARG();
			if (get_rate(&bndw, *argv)) {
				explain1("bandwidth");
				return -1;
			}
		} else if (strcmp(*argv, "minidle") == 0) {
			NEXT_ARG();
			if (get_u32(&lss.minidle, *argv, 0)) {
				explain1("minidle");
				return -1;
			}
			lss.change |= TCF_CBQ_LSS_MINIDLE;
		} else if (strcmp(*argv, "minburst") == 0) {
			NEXT_ARG();
			if (get_u32(&minburst, *argv, 0)) {
				explain1("minburst");
				return -1;
			}
			lss.change |= TCF_CBQ_LSS_OFFTIME;
		} else if (strcmp(*argv, "maxburst") == 0) {
			NEXT_ARG();
			if (get_u32(&maxburst, *argv, 0)) {
				explain1("maxburst");
				return -1;
			}
			lss.change |= TCF_CBQ_LSS_MAXIDLE;
		} else if (strcmp(*argv, "bounded") == 0) {
			lss.flags |= TCF_CBQ_LSS_BOUNDED;
			lss.change |= TCF_CBQ_LSS_FLAGS;
		} else if (strcmp(*argv, "borrow") == 0) {
			lss.flags &= ~TCF_CBQ_LSS_BOUNDED;
			lss.change |= TCF_CBQ_LSS_FLAGS;
		} else if (strcmp(*argv, "isolated") == 0) {
			lss.flags |= TCF_CBQ_LSS_ISOLATED;
			lss.change |= TCF_CBQ_LSS_FLAGS;
		} else if (strcmp(*argv, "sharing") == 0) {
			lss.flags &= ~TCF_CBQ_LSS_ISOLATED;
			lss.change |= TCF_CBQ_LSS_FLAGS;
		} else if (strcmp(*argv, "ewma") == 0) {
			NEXT_ARG();
			if (get_u32(&ewma_log, *argv, 0)) {
				explain1("ewma");
				return -1;
			}
			if (ewma_log > 31) {
				fprintf(stderr, "ewma_log must be < 32\n");
				return -1;
			}
			lss.change |= TCF_CBQ_LSS_EWMA;
		} else if (strcmp(*argv, "cell") == 0) {
			unsigned cell;
			int i;
			NEXT_ARG();
			if (get_size(&cell, *argv)) {
				explain1("cell");
				return -1;
			}
			for (i=0; i<32; i++)
				if ((1<<i) == cell)
					break;
			if (i>=32) {
				fprintf(stderr, "cell must be 2^n\n");
				return -1;
			}
			cell_log = i;
		} else if (strcmp(*argv, "prio") == 0) {
			unsigned prio;
			NEXT_ARG();
			if (get_u32(&prio, *argv, 0)) {
				explain1("prio");
				return -1;
			}
			if (prio > TC_CBQ_MAXPRIO) {
				fprintf(stderr, "\"prio\" must be number in the range 1...%d\n", TC_CBQ_MAXPRIO);
				return -1;
			}
			wrr.priority = prio;
			wrr_ok++;
		} else if (strcmp(*argv, "allot") == 0) {
			NEXT_ARG();
			if (get_size(&wrr.allot, *argv)) {
				explain1("allot");
				return -1;
			}
		} else if (strcmp(*argv, "avpkt") == 0) {
			NEXT_ARG();
			if (get_size(&lss.avpkt, *argv)) {
				explain1("avpkt");
				return -1;
			}
			lss.change |= TCF_CBQ_LSS_AVPKT;
		} else if (strcmp(*argv, "mpu") == 0) {
			NEXT_ARG();
			if (get_size(&mpu, *argv)) {
				explain1("mpu");
				return -1;
			}
		} else if (strcmp(*argv, "weight") == 0) {
			NEXT_ARG();
			if (get_size(&wrr.weight, *argv)) {
				explain1("weight");
				return -1;
			}
			wrr_ok++;
		} else if (strcmp(*argv, "split") == 0) {
			NEXT_ARG();
			if (get_tc_classid(&fopt.split, *argv)) {
				fprintf(stderr, "Invalid split node ID.\n");
				usage();
			}
			fopt_ok++;
		} else if (strcmp(*argv, "defmap") == 0) {
			int err;
			NEXT_ARG();
			err = sscanf(*argv, "%08x/%08x", &fopt.defmap, &fopt.defchange);
			if (err < 1) {
				fprintf(stderr, "Invalid defmap, should be MASK32[/MASK]\n");
				return -1;
			}
			if (err == 1)
				fopt.defchange = ~0;
			fopt_ok++;
		} else if (strcmp(*argv, "help") == 0) {
			explain_class();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain_class();
			return -1;
		}
		argc--; argv++;
	}

	/* OK. All options are parsed. */

	/* 1. Prepare link sharing scheduler parameters */
	if (r.rate) {
		unsigned pktsize = wrr.allot;
		if (wrr.allot < (lss.avpkt*3)/2)
			wrr.allot = (lss.avpkt*3)/2;
		if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, pktsize, mpu)) < 0) {
			fprintf(stderr, "CBQ: failed to calculate rate table.\n");
			return -1;
		}
		r.cell_log = cell_log;
		r.mpu = mpu;
	}
	if (ewma_log < 0)
		ewma_log = TC_CBQ_DEF_EWMA;
	lss.ewma_log = ewma_log;
	if (lss.change&(TCF_CBQ_LSS_OFFTIME|TCF_CBQ_LSS_MAXIDLE)) {
		if (lss.avpkt == 0) {
			fprintf(stderr, "CBQ: avpkt is required for max/minburst.\n");
			return -1;
		}
		if (bndw==0 || r.rate == 0) {
			fprintf(stderr, "CBQ: bandwidth&rate are required for max/minburst.\n");
			return -1;
		}
	}
	if (wrr.priority == 0 && (n->nlmsg_flags&NLM_F_EXCL)) {
		wrr_ok = 1;
		wrr.priority = TC_CBQ_MAXPRIO;
		if (wrr.allot == 0)
			wrr.allot = (lss.avpkt*3)/2;
	}
	if (wrr_ok) {
		if (wrr.weight == 0)
			wrr.weight = (wrr.priority == TC_CBQ_MAXPRIO) ? 1 : r.rate;
		if (wrr.allot == 0) {
			fprintf(stderr, "CBQ: \"allot\" is required to set WRR parameters.\n");
			return -1;
		}
	}
	if (lss.change&TCF_CBQ_LSS_MAXIDLE) {
		lss.maxidle = tc_cbq_calc_maxidle(bndw, r.rate, lss.avpkt, ewma_log, maxburst);
		lss.change |= TCF_CBQ_LSS_MAXIDLE;
		lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT;
	}
	if (lss.change&TCF_CBQ_LSS_OFFTIME) {
		lss.offtime = tc_cbq_calc_offtime(bndw, r.rate, lss.avpkt, ewma_log, minburst);
		lss.change |= TCF_CBQ_LSS_OFFTIME;
		lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT;
	}
	if (lss.change&TCF_CBQ_LSS_MINIDLE) {
		lss.minidle <<= lss.ewma_log;
		lss.change |= TCF_CBQ_LSS_EWMA;
	}

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	if (lss.change) {
		lss.change |= TCF_CBQ_LSS_FLAGS;
		addattr_l(n, 1024, TCA_CBQ_LSSOPT, &lss, sizeof(lss));
	}
	if (wrr_ok)
		addattr_l(n, 1024, TCA_CBQ_WRROPT, &wrr, sizeof(wrr));
	if (fopt_ok)
		addattr_l(n, 1024, TCA_CBQ_FOPT, &fopt, sizeof(fopt));
	if (r.rate) {
		addattr_l(n, 1024, TCA_CBQ_RATE, &r, sizeof(r));
		addattr_l(n, 3024, TCA_CBQ_RTAB, rtab, 1024);
		if (show_raw) {
			int i;
			for (i=0; i<256; i++)
				printf("%u ", rtab[i]);
			printf("\n");
		}
	}
	tail->rta_len = (((void*)n)+NLMSG_ALIGN(n->nlmsg_len)) - (void*)tail;
	return 0;
}
Beispiel #14
0
static int
parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
	      struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0;
	struct rtattr *tail;
	unsigned int tmp;
	__u16 queue_mapping;
	__u32 flags = 0, priority, mark;
	struct tc_skbedit sel = { 0 };

	if (matches(*argv, "skbedit") != 0)
		return -1;

	NEXT_ARG();

	while (argc > 0) {
		if (matches(*argv, "queue_mapping") == 0) {
			flags |= SKBEDIT_F_QUEUE_MAPPING;
			NEXT_ARG();
			if (get_unsigned(&tmp, *argv, 10) || tmp > 65535) {
				fprintf(stderr, "Illegal queue_mapping\n");
				return -1;
			}
			queue_mapping = tmp;
			ok++;
		} else if (matches(*argv, "priority") == 0) {
			flags |= SKBEDIT_F_PRIORITY;
			NEXT_ARG();
			if (get_tc_classid(&priority, *argv)) {
				fprintf(stderr, "Illegal priority\n");
				return -1;
			}
			ok++;
		} else if (matches(*argv, "mark") == 0) {
			flags |= SKBEDIT_F_MARK;
			NEXT_ARG();
			if (get_tc_classid(&mark, *argv)) {
				fprintf(stderr, "Illegal mark\n");
				return -1;
			}
			ok++;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			break;
		}
		argc--;
		argv++;
	}

	if (argc) {
		if (matches(*argv, "reclassify") == 0) {
			sel.action = TC_ACT_RECLASSIFY;
			NEXT_ARG();
		} else if (matches(*argv, "pipe") == 0) {
			sel.action = TC_ACT_PIPE;
			NEXT_ARG();
		} else if (matches(*argv, "drop") == 0 ||
			matches(*argv, "shot") == 0) {
			sel.action = TC_ACT_SHOT;
			NEXT_ARG();
		} else if (matches(*argv, "continue") == 0) {
			sel.action = TC_ACT_UNSPEC;
			NEXT_ARG();
		} else if (matches(*argv, "pass") == 0) {
			sel.action = TC_ACT_OK;
			NEXT_ARG();
		}
	}

	if (argc) {
		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&sel.index, *argv, 10)) {
				fprintf(stderr, "Pedit: Illegal \"index\"\n");
				return -1;
			}
			argc--;
			argv++;
			ok++;
		}
	}

	if (!ok) {
		explain();
		return -1;
	}


	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	addattr_l(n, MAX_MSG, TCA_SKBEDIT_PARMS, &sel, sizeof(sel));
	if (flags & SKBEDIT_F_QUEUE_MAPPING)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_QUEUE_MAPPING,
			  &queue_mapping, sizeof(queue_mapping));
	if (flags & SKBEDIT_F_PRIORITY)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
			  &priority, sizeof(priority));
	if (flags & SKBEDIT_F_MARK)
		addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
			  &mark, sizeof(mark));
	tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;

	*argc_p = argc;
	*argv_p = argv;
	return 0;
}