Exemple #1
0
static int vlan_parse_qos_map(int *argcp, char ***argvp, struct nlmsghdr *n,
			      int attrtype)
{
	int argc = *argcp;
	char **argv = *argvp;
	struct ifla_vlan_qos_mapping m;
	struct rtattr *tail;

	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, attrtype, NULL, 0);

	while (argc > 0) {
		char *colon = strchr(*argv, ':');

		if (!colon)
			break;
		*colon = '\0';

		if (get_u32(&m.from, *argv, 0))
			return 1;
		if (get_u32(&m.to, colon + 1, 0))
			return 1;
		argc--, argv++;

		addattr_l(n, 1024, IFLA_VLAN_QOS_MAPPING, &m, sizeof(m));
	}

	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *)tail;

	*argcp = argc;
	*argvp = argv;
	return 0;
}
Exemple #2
0
static int qdisc_tbf(struct qdisc_opt *qopt, struct nlmsghdr *n)
{
	struct tc_tbf_qopt opt;
	__u32 rtab[256];
	int Rcell_log = -1;
	unsigned int linklayer = LINKLAYER_ETHERNET; /* Assume ethernet */
	struct rtattr *tail;

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

	opt.rate.rate = qopt->rate;
	opt.limit = (double)qopt->rate * qopt->latency + qopt->buffer;
	opt.rate.mpu = conf_mpu;
	if (tc_calc_rtable(&opt.rate, rtab, Rcell_log, conf_mtu, linklayer) < 0) {
		log_ppp_error("shaper: failed to calculate rate table.\n");
		return -1;
	}
	opt.buffer = tc_calc_xmittime(opt.rate.rate, qopt->buffer);

	tail = NLMSG_TAIL(n);
	addattr_l(n, TCA_BUF_MAX, TCA_OPTIONS, NULL, 0);
	addattr_l(n, TCA_BUF_MAX, TCA_TBF_PARMS, &opt, sizeof(opt));
	addattr_l(n, TCA_BUF_MAX, TCA_TBF_RTAB, rtab, 1024);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

	return 0;
}
Exemple #3
0
int form_request_add()
{
	int ifcn = 1; //interface number

	bzero(&req, sizeof(req));
	req.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	rtap = NLMSG_TAIL(&req.nl);
	rtap->rta_type = RTA_DST;
	rtap->rta_len = RTA_LENGTH(4);
	inet_pton(AF_INET, dsts,
			((char *)rtap) + sizeof(struct rtattr));
	req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + RTA_ALIGN(rtap->rta_len);

	rtap = NLMSG_TAIL(&req.nl);;
	rtap->rta_type = RTA_OIF;//Output interface index
	rtap->rta_len = RTA_LENGTH(sizeof(int));
	memcpy(((char *)rtap) + sizeof(struct rtattr),
			&ifcn, sizeof(int));

	req.nl.nlmsg_len = NLMSG_ALIGN(req.nl.nlmsg_len) + RTA_ALIGN(rtap->rta_len);
	req.nl.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
	req.nl.nlmsg_type = RTM_NEWROUTE;

	req.rt.rtm_family = AF_INET;
	req.rt.rtm_table = RT_TABLE_MAIN;
	req.rt.rtm_protocol = RTPROT_STATIC;
	req.rt.rtm_scope = RT_SCOPE_UNIVERSE;
	req.rt.rtm_type = RTN_UNICAST;
	req.rt.rtm_dst_len = pn;
	return 0;
}
Exemple #4
0
static int drr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
			       struct nlmsghdr *n)
{
	struct rtattr *tail;
	__u32 tmp;

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

	while (argc > 0) {
		if (strcmp(*argv, "quantum") == 0) {
			NEXT_ARG();
			if (get_size(&tmp, *argv)) {
				fprintf(stderr, "Illegal \"quantum\"\n");
				return -1;
			}
			addattr_l(n, 1024, TCA_DRR_QUANTUM, &tmp, sizeof(tmp));
		} else if (strcmp(*argv, "help") == 0) {
			explain2();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain2();
			return -1;
		}
		argc--; argv++;
	}

	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *)tail;
	return 0;
}
Exemple #5
0
static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
			  struct nlmsghdr *hdr)
{
	char *name = NULL;
	char *type = NULL;
	char *link = NULL;
	char *dev = NULL;
	int err, len;
	struct rtattr * data;

	if (strcmp(argv[0], "peer") != 0) {
		usage();
		return -1;
	}

	data = NLMSG_TAIL(hdr);
	addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0);

	hdr->nlmsg_len += sizeof(struct ifinfomsg);

	err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
			   &name, &type, &link, &dev);
	if (err < 0)
		return err;

	if (name) {
		len = strlen(name) + 1;
		if (len > IFNAMSIZ)
			invarg("\"name\" too long\n", *argv);
		addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
	}

	data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data;
	return argc - 1 - err;
}
Exemple #6
0
int
netlink_link_add_vmac(vrrp_rt *vrrp)
{
	struct rtattr *linkinfo;
	interface *ifp;
	char ifname[IFNAMSIZ];
	struct {
		struct nlmsghdr n;
		struct ifinfomsg ifi;
		char buf[256];
	} req;

	if (!vrrp->ifp)
		return -1;

	memset(&req, 0, sizeof (req));
	memset(ifname, 0, IFNAMSIZ);
	strncpy(ifname, vrrp->vmac_ifname, IFNAMSIZ - 1);

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
	req.n.nlmsg_type = RTM_NEWLINK;
	req.ifi.ifi_family = AF_INET;

	/* macvlan settings */
	linkinfo = NLMSG_TAIL(&req.n);
	addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
	addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)ll_kind, strlen(ll_kind));
	linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
	addattr_l(&req.n, sizeof(req), IFLA_LINK, &IF_INDEX(vrrp->ifp), sizeof(uint32_t));
	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, ifname, strlen(ifname));

	if (netlink_talk(&nl_cmd, &req.n) < 0)
		return -1;

	/*
	 * Update interface queue and vrrp instance interface binding.
	 * bring it UP !
	 */
	netlink_interface_lookup();
	ifp = if_get_by_ifname(ifname);
	if (!ifp)
		return -1;
	vrrp->ifp = ifp;
	vrrp->vmac |= 2;
	netlink_link_setlladdr(vrrp);
	netlink_link_up(vrrp);

	/*
	 * By default MACVLAN interface are in VEPA mode which filters
	 * out received packets whose MAC source address matches that
	 * of the MACVLAN interface. Setting MACVLAN interface in private
	 * mode will not filter based on source MAC address.
	 */
	netlink_link_setmode(vrrp);

	return 1;
}
Exemple #7
0
static int codel_parse_opt(struct qdisc_util *qu, int argc, char **argv,
			   struct nlmsghdr *n)
{
	unsigned limit = 0;
	unsigned target = 0;
	unsigned interval = 0;
	int ecn = -1;
	struct rtattr *tail;

	while (argc > 0) {
		if (strcmp(*argv, "limit") == 0) {
			NEXT_ARG();
			if (get_unsigned(&limit, *argv, 0)) {
				fprintf(stderr, "Illegal \"limit\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "target") == 0) {
			NEXT_ARG();
			if (get_time(&target, *argv)) {
				fprintf(stderr, "Illegal \"target\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "interval") == 0) {
			NEXT_ARG();
			if (get_time(&interval, *argv)) {
				fprintf(stderr, "Illegal \"interval\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "ecn") == 0) {
			ecn = 1;
		} else if (strcmp(*argv, "noecn") == 0) {
			ecn = 0;
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	if (limit)
		addattr_l(n, 1024, TCA_CODEL_LIMIT, &limit, sizeof(limit));
	if (interval)
		addattr_l(n, 1024, TCA_CODEL_INTERVAL, &interval, sizeof(interval));
	if (target)
		addattr_l(n, 1024, TCA_CODEL_TARGET, &target, sizeof(target));
	if (ecn != -1)
		addattr_l(n, 1024, TCA_CODEL_ECN, &ecn, sizeof(ecn));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemple #8
0
static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
			  struct nlmsghdr *hdr)
{
	char *dev = NULL;
	char *name = NULL;
	char *link = NULL;
	char *type = NULL;
	int index = 0;
	int err, len;
	struct rtattr * data;
	int group;
	struct ifinfomsg *ifm, *peer_ifm;
	unsigned int ifi_flags, ifi_change;

	if (strcmp(argv[0], "peer") != 0) {
		usage();
		return -1;
	}

	ifm = NLMSG_DATA(hdr);
	ifi_flags = ifm->ifi_flags;
	ifi_change = ifm->ifi_change;
	ifm->ifi_flags = 0;
	ifm->ifi_change = 0;

	data = NLMSG_TAIL(hdr);
	addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0);

	hdr->nlmsg_len += sizeof(struct ifinfomsg);

	err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
			   &name, &type, &link, &dev, &group, &index);
	if (err < 0)
		return err;

	if (name) {
		len = strlen(name) + 1;
		if (len > IFNAMSIZ)
			invarg("\"name\" too long\n", *argv);
		addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
	}

	peer_ifm = RTA_DATA(data);
	peer_ifm->ifi_index = index;
	peer_ifm->ifi_flags = ifm->ifi_flags;
	peer_ifm->ifi_change = ifm->ifi_change;
	ifm->ifi_flags = ifi_flags;
	ifm->ifi_change = ifi_change;

	if (group != -1)
		addattr32(hdr, 1024, IFLA_GROUP, group);

	data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data;
	return argc - 1 - err;
}
static int dsmark_parse_opt(struct qdisc_util *qu, int argc, char **argv,
    struct nlmsghdr *n)
{
	struct rtattr *tail;
	__u16 ind;
	char *end;
	int dflt,set_tc_index;

	ind = set_tc_index = 0;
	dflt = -1;
	while (argc > 0) {
		if (!strcmp(*argv,"indices")) {
			NEXT_ARG();
			ind = strtoul(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"default_index") || !strcmp(*argv,
		    "default")) {
			NEXT_ARG();
			dflt = strtoul(*argv,&end,0);
			if (*end) {
				explain();
				return -1;
			}
		}
		else if (!strcmp(*argv,"set_tc_index")) {
			set_tc_index = 1;
		}
		else {
			explain();
			return -1;
		}
		argc--;
		argv++;
	}
	if (!ind) {
		explain();
		return -1;
	}
	tail = NLMSG_TAIL(n);
	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
	addattr_l(n,1024,TCA_DSMARK_INDICES,&ind,sizeof(ind));
	if (dflt != -1) {
	    __u16 tmp = dflt;

	    addattr_l(n,1024,TCA_DSMARK_DEFAULT_INDEX,&tmp,sizeof(tmp));
	}
	if (set_tc_index) addattr_l(n,1024,TCA_DSMARK_SET_TC_INDEX,NULL,0);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemple #10
0
int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
{
	if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
		fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen);
		return -1;
	}

	memcpy(NLMSG_TAIL(n), data, len);
	memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len);
	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len);
	return 0;
}
Exemple #11
0
int
addraw_l(struct nlmsghdr *n, size_t maxlen, const void *data, size_t len)
{
	size_t align_len = NLMSG_ALIGN(len);

	if (n->nlmsg_len + align_len > maxlen)
		return -1;

	memcpy(NLMSG_TAIL(n), data, len);
	memset((void *) NLMSG_TAIL(n) + len, 0, align_len - len);
	n->nlmsg_len += (uint32_t)align_len;
	return 0;
}
Exemple #12
0
static int psp_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
			       struct nlmsghdr *n)
{
	struct tc_psp_copt copt;
	struct rtattr *tail;

	memset(&copt, 0, sizeof(copt));
	copt.mode = TC_PSP_MODE_STATIC; /* default mode */

	while (argc > 0) {
		if (matches(*argv, "rate") == 0) {
			NEXT_ARG();
			if (GET_RATE(&copt.rate, *argv)) {
				explain1("rate");
				return -1;
			}
		} else if (matches(*argv, "mode") == 0) {
			NEXT_ARG();
			if (get_u32(&copt.mode, *argv, 16)) {
				explain1("mode");
				return -1;
			}
		} else if (matches(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	if (copt.mode == TC_PSP_MODE_NORMAL && copt.rate != 0) {
		fprintf(stderr, "You can not set to \"rate\" parameter "
			"in normal mode\n");
		explain1("rate");
		return -1;
	} else if (copt.mode == TC_PSP_MODE_STATIC && copt.rate == 0) {
		fprintf(stderr, "You need set to \"rate\" parameter "
			"in static target rate mode.\n");
		explain1("rate");
		return -1;
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	addattr_l(n, 1024, TCA_PSP_COPT, &copt, sizeof(copt));
	tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
	return 0;
}
Exemple #13
0
struct rtattr *addattr_nest(struct nlmsghdr *n, int type)
{
	struct rtattr *nest = NLMSG_TAIL(n);

	addattr_l(n, type, NULL, 0);
	return nest;
}
Exemple #14
0
static int psp_parse_opt(struct qdisc_util *qu, int argc, char **argv,
			 struct nlmsghdr *n)
{
	struct tc_psp_qopt qopt;
	struct rtattr *tail;

	memset(&qopt, 0, sizeof(qopt));
	qopt.ifg = 12;

	while (argc > 0) {
		if (matches(*argv, "rate") == 0) {
			NEXT_ARG();
			if (GET_RATE(&qopt.rate, *argv)) {
				explain1("rate");
				return -1;
			}
		} else if (matches(*argv, "default") == 0) {
			NEXT_ARG();
			if (get_u32(&qopt.defcls, *argv, 16)) {
				explain1("default");
				return -1;
			}
		} else if (matches(*argv, "ifg") == 0) {
			NEXT_ARG();
			if (get_u32(&qopt.ifg, *argv, 10)) {
				explain1("ifg");
				return -1;
			}
		} else if (matches(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--;
		argv++;
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	addattr_l(n, 1024, TCA_PSP_QOPT, &qopt, sizeof(qopt));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
std::string KernelNetlinkProtocol::build_vlan(uint16_t vlan_id, uint16_t link, const std::string& name)
{
    struct
    {
        nlmsghdr nl_hdr;
        ifinfomsg if_msg;
        char buf[1024];
    } req;

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

    req.nl_hdr.nlmsg_len = NLMSG_LENGTH(sizeof(req.if_msg));
    req.nl_hdr.nlmsg_type = RTM_NEWLINK;
    req.nl_hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
    req.nl_hdr.nlmsg_pid = cmd_local_addr_.nl_pid;
    req.nl_hdr.nlmsg_seq = ++seq_num;

    // physical device id, required
    addattr_32(&req.nl_hdr, sizeof(req), IFLA_LINK, link);


    if (!name.empty())
    {
        addattr_l(&req.nl_hdr, sizeof(req), IFLA_IFNAME, name.c_str(), name.size() + 1);
    }

//	if (!address.empty()) // optional vlan MAC address setting
//	{
//		addattr_l(&req.nl_hdr, sizeof(req), IFLA_ADDRESS, address.data(), address.size());
//	}

    rtattr* linkinfo = NLMSG_TAIL(&req.nl_hdr);
    addattr_l(&req.nl_hdr, sizeof(req), IFLA_LINKINFO, NULL, 0);
    addattr_l(&req.nl_hdr, sizeof(req), IFLA_INFO_KIND, "vlan", strlen("vlan"));

    rtattr* data = NLMSG_TAIL(&req.nl_hdr);
    addattr_l(&req.nl_hdr, sizeof(req), IFLA_INFO_DATA, NULL, 0);
    addattr_l(&req.nl_hdr, sizeof(req), IFLA_VLAN_ID, &vlan_id, 2);
    // not adding vlan flags

    data->rta_len = (char *) NLMSG_TAIL(&req.nl_hdr) - (char *) data;
    linkinfo->rta_len = (char *) NLMSG_TAIL(&req.nl_hdr) - (char *) linkinfo;
    assert(req.nl_hdr.nlmsg_len > 0);

    return std::string(reinterpret_cast<char*>(&req), req.nl_hdr.nlmsg_len);
}
Exemple #16
0
static int
netlink_link_setmode(vrrp_rt *vrrp)
{
    int status = 1;
    struct {
        struct nlmsghdr n;
        struct ifinfomsg ifi;
        char buf[256];
    } req;
    struct rtattr *linkinfo;
    struct rtattr *data;

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

    req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
    req.n.nlmsg_flags = NLM_F_REQUEST;
    req.n.nlmsg_type = RTM_NEWLINK;
    req.ifi.ifi_family = AF_INET;
    req.ifi.ifi_index = IF_INDEX(vrrp->xmit_ifp);

    linkinfo = NLMSG_TAIL(&req.n);
    addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
    addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)ll_kind,
              strlen(ll_kind));

    data = NLMSG_TAIL(&req.n);
    addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0);

    /*
     * In private mode, macvlan will receive frames with same MAC addr
     * as configured on the interface.
     */
#ifndef MACVLAN_MODE_VRRP
#define MACVLAN_MODE_VRRP 16
#endif
    addattr32(&req.n, sizeof(req), IFLA_MACVLAN_MODE,
              MACVLAN_MODE_VRRP);
    data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;

    linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;

    if (netlink_talk(&nl_cmd, &req.n) < 0)
        status = -1;

    return status;
}
Exemple #17
0
static int wrr_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
	int ok=0; 
	struct wrr_class_opt copt;
	struct rtattr *tail;

	copt.handle = 0;
	copt.quantum = 0;

	//printf("wrr_parse_class_opt.\n");
	while (argc > 0) {
		if (strcmp(*argv, "quantum") == 0) {
			NEXT_ARG();
			if (get_size(&copt.quantum, *argv)) {
				fprintf(stderr, "Illegal \"quantum\"\n");
				return -1;
			}
			ok++;
		}else if (strcmp(*argv, "nfmark") == 0) {
			NEXT_ARG();
			if (get_size(&copt.handle, *argv)) {
				fprintf(stderr, "Illegal \"nfmark\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "help") == 0) {
			explain2();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain2();
			return -1;
		}
		argc--; argv++;
	}

	//printf("wrr_parse_class_opt ok %d q=%d h:%x.\n",ok,copt.quantum,copt.handle);

	if (ok)
	{
		tail = NLMSG_TAIL(n);
		addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
		addattr_l(n, 2024, TCA_WRR_PARAMS, &copt, sizeof(copt));
		tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	}
	return 0;
}
Exemple #18
0
static int qdisc_htb_root(struct qdisc_opt *qopt, struct nlmsghdr *n)
{
	struct tc_htb_glob opt;
	struct rtattr *tail;

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

	opt.rate2quantum = qopt->quantum;
	opt.version = 3;
	opt.defcls = qopt->defcls;

	tail = NLMSG_TAIL(n);
	addattr_l(n, TCA_BUF_MAX, TCA_OPTIONS, NULL, 0);
	addattr_l(n, TCA_BUF_MAX, TCA_HTB_INIT, &opt, NLMSG_ALIGN(sizeof(opt)));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemple #19
0
struct rtattr *rta_begin_nested(struct link_req *req, int attr)
{
	struct rtattr *rtattr = NLMSG_TAIL(&req->nh);

	if (rta_put(req, attr, NULL, 0))
		return NULL;

	return rtattr;
}
Exemple #20
0
struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr)
{
	struct rtattr *rtattr = NLMSG_TAIL(&nlmsg->nlmsghdr);

	if (nla_put_attr(nlmsg, attr))
		return NULL;

	return rtattr;
}
Exemple #21
0
static int qdisc_htb_class(struct qdisc_opt *qopt, struct nlmsghdr *n)
{
	struct tc_htb_opt opt;
	__u32 rtab[256],ctab[256];
	int cell_log=-1,ccell_log = -1;
	unsigned mtu = conf_mtu ? conf_mtu : 1600;
	unsigned int linklayer  = LINKLAYER_ETHERNET; /* Assume ethernet */
	struct rtattr *tail;

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

	opt.rate.rate = qopt->rate;
	opt.rate.mpu = conf_mpu;
	opt.ceil.rate = qopt->rate;
	opt.ceil.mpu = conf_mpu;

	if (tc_calc_rtable(&opt.rate, rtab, cell_log, mtu, linklayer) < 0) {
		log_ppp_error("shaper: failed to calculate rate table.\n");
		return -1;
	}
	opt.buffer = tc_calc_xmittime(opt.rate.rate, qopt->buffer);

	if (tc_calc_rtable(&opt.ceil, ctab, ccell_log, mtu, linklayer) < 0) {
		log_ppp_error("shaper: failed to calculate ceil rate table.\n");
		return -1;
	}
	opt.cbuffer = tc_calc_xmittime(opt.ceil.rate, conf_cburst ? conf_cburst : qopt->buffer);

	if (qopt->quantum)
		opt.quantum = qopt->quantum;
	else if (conf_moderate_quantum) {
		unsigned int q = qopt->rate / conf_r2q;
		if (q < 1500 || q > 200000)
			opt.quantum = q < 1500 ? 1500 : 200000;
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, TCA_BUF_MAX, TCA_OPTIONS, NULL, 0);
	addattr_l(n, TCA_BUF_MAX, TCA_HTB_PARMS, &opt, sizeof(opt));
	addattr_l(n, TCA_BUF_MAX, TCA_HTB_RTAB, rtab, 1024);
	addattr_l(n, TCA_BUF_MAX, TCA_HTB_CTAB, ctab, 1024);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
std::string KernelNetlinkProtocol::build_add_link(const std::string& kind, const std::string& name, const std::string& mac, const std::string& mtu)
{
    struct
    {
        nlmsghdr nl_hdr;
        ifinfomsg if_msg;
        char buf[128];
    } req;

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

    req.nl_hdr.nlmsg_len = NLMSG_LENGTH(sizeof(req.if_msg));
    req.nl_hdr.nlmsg_type = RTM_NEWLINK;
    req.nl_hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
    req.nl_hdr.nlmsg_pid = cmd_local_addr_.nl_pid;
    req.nl_hdr.nlmsg_seq = ++seq_num;

	if (!name.empty())
	{
		addattr_l(&req.nl_hdr, sizeof(req), IFLA_IFNAME, name.c_str(), name.size() + 1);
	}

	if (!mac.empty())
	{
		addattr_l(&req.nl_hdr, sizeof(req), IFLA_ADDRESS, tnt::MacAddress(mac).raw().data(), 6);
	}

	if (!mtu.empty())
	{
		int m = std::stoi(mtu);
		addattr_l(&req.nl_hdr, sizeof(req), IFLA_MTU, &m, 4);
	}

	rtattr* linkinfo = NLMSG_TAIL(&req.nl_hdr);

    addattr_l(&req.nl_hdr, sizeof(req), IFLA_LINKINFO, NULL, 0);
    addattr_l(&req.nl_hdr, sizeof(req), IFLA_INFO_KIND, kind.data(), kind.size());

	linkinfo->rta_len = reinterpret_cast<char*>(NLMSG_TAIL(&req.nl_hdr)) - reinterpret_cast<char*>(linkinfo);
    assert(req.nl_hdr.nlmsg_len > 0);

    return std::string(reinterpret_cast<char*>(&req), req.nl_hdr.nlmsg_len);
}
Exemple #23
0
struct nlattr *
nest_start(struct nlmsghdr *nlh, unsigned short type)
{
	struct nlattr *nest = NLMSG_TAIL(nlh);

	nest->nla_type = type;
	nlh->nlmsg_len += sizeof(struct nlattr);

	return nest;
}
Exemple #24
0
int tc_action_modify(int cmd, unsigned flags, int *argc_p, char ***argv_p)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int ret = 0;

	struct rtattr *tail;
	struct {
		struct nlmsghdr         n;
		struct tcamsg           t;
		char                    buf[MAX_MSG];
	} req;

	req.t.tca_family = AF_UNSPEC;

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg));
	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
	req.n.nlmsg_type = cmd;
	tail = NLMSG_TAIL(&req.n);
	argc -=1;
	argv +=1;
	if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) {
		fprintf(stderr, "Illegal \"action\"\n");
		return -1;
	}
	tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) {
		fprintf(stderr, "We have an error talking to the kernel\n");
		ret = -1;
	}

	*argc_p = argc;
	*argv_p = argv;

	return ret;
}
Exemple #25
0
static int wrr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
	int ok=0;
	struct wrr_gopt gopt;
	struct rtattr *tail;

	//printf("wrr_parse_opt. \n");
	while (argc > 0) {
		
		if (strcmp(*argv, "queues") == 0) {
			NEXT_ARG();
			if (get_size(&gopt.total_queues, *argv)) {
				fprintf(stderr, "Illegal \"limit\"\n");
				return -1;
			}
			ok++;
		} else if (strcmp(*argv, "help") == 0) {
			explain();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain();
			return -1;
		}
		argc--; argv++;
	}

	//printf("wrr_parse_opt ok %d q=%d.\n",ok,gopt.total_queues);

	if (ok)
	{
		tail = NLMSG_TAIL(n);
		addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
		addattr_l(n, 2024, TCA_WRR_INIT, &gopt, sizeof(gopt));
		tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	}
	
	return 0;
}
Exemple #26
0
static inline int
netlink_set_interface_flags(int ifindex, const sysctl_opts_t *sys_opts)
{
	int status = 0;
	struct {
		struct nlmsghdr n;
		struct ifinfomsg ifi;
		char buf[64];
	} req;
	struct nlattr *start;
	struct nlattr *inet_start;
	struct nlattr *conf_start;
	const sysctl_opts_t *so;

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = RTM_NEWLINK;
	req.ifi.ifi_family = AF_UNSPEC;
	req.ifi.ifi_index = ifindex;

	start = nest_start(&req.n, IFLA_AF_SPEC);
	inet_start = nest_start(&req.n, AF_INET);
	conf_start = nest_start(&req.n, IFLA_INET_CONF);

	for (so = sys_opts; so->param; so++)
		addattr32(&req.n, sizeof req, so->param, so->value);

	nest_end(NLMSG_TAIL(&req.n), conf_start);
	nest_end(NLMSG_TAIL(&req.n), inet_start);
	nest_end(NLMSG_TAIL(&req.n), start);

	if (netlink_talk(&nl_cmd, &req.n) < 0)
		status = 1;

	return status;
}
Exemple #27
0
static int dsmark_parse_class_opt(struct qdisc_util *qu, int argc, char **argv,
   struct nlmsghdr *n)
{
	struct rtattr *tail;
	__u8 tmp;
	char *end;

	tail = NLMSG_TAIL(n);
	addattr_l(n,1024,TCA_OPTIONS,NULL,0);
	while (argc > 0) {
		if (!strcmp(*argv,"mask")) {
			NEXT_ARG();
			tmp = strtoul(*argv,&end,0);
			if (*end) {
				explain_class();
				return -1;
			}
			addattr_l(n,1024,TCA_DSMARK_MASK,&tmp,1);
		}
		else if (!strcmp(*argv,"value")) {
			NEXT_ARG();
			tmp = strtoul(*argv,&end,0);
			if (*end) {
				explain_class();
				return -1;
			}
			addattr_l(n,1024,TCA_DSMARK_VALUE,&tmp,1);
		}
		else {
			explain_class();
			return -1;
		}
		argc--;
		argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemple #28
0
int htb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
{
	struct tc_htb_glob opt;
	struct rtattr *tail;
	unsigned i; char *p;
	memset(&opt,0,sizeof(opt));
	opt.rate2quantum = 10;
	opt.version = 3;

	while (argc > 0) {
		if (matches(*argv, "r2q") == 0) {
		    NEXT_ARG();
		    if (get_u32(&opt.rate2quantum, *argv, 10)) {
			explain1("r2q"); return -1;
		    }
		} else if (matches(*argv, "default") == 0) {
		    NEXT_ARG();
		    if (get_u32(&opt.defcls, *argv, 16)) {
			explain1("default"); return -1;
		    }
		} else if (matches(*argv, "debug") == 0) {
		    NEXT_ARG(); p = *argv;
		    for (i=0; i<16; i++,p++) {
			if (*p<'0' || *p>'3') break;
			opt.debug |= (*p-'0')<<(2*i);
		    }
		} else {
			printk(KERN_DEBUG "[MTC] [Q_HTB] What is \"%s\"?\n", *argv);
			return -1;
		}
		argc--; argv++;
	}
	tail = NLMSG_TAIL(n);
	addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
	addattr_l(n, 2024, TCA_HTB_INIT, &opt, NLMSG_ALIGN(sizeof(opt)));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}
Exemple #29
0
static int nla_put(struct nlmsg *nlmsg, int attr, 
		   const void *data, size_t len)
{
	struct rtattr *rta;
	size_t rtalen = RTA_LENGTH(len);
	
        rta = NLMSG_TAIL(&nlmsg->nlmsghdr);
        rta->rta_type = attr;
        rta->rta_len = rtalen;
        memcpy(RTA_DATA(rta), data, len);
        nlmsg->nlmsghdr.nlmsg_len =
		NLMSG_ALIGN(nlmsg->nlmsghdr.nlmsg_len) + RTA_ALIGN(rtalen);
	return 0;
}
Exemple #30
0
static int rta_put(struct link_req *req, int attr,
		   const void *data, size_t len)
{
	struct rtattr *rta;
	size_t rtalen = RTA_LENGTH(len);

	rta = NLMSG_TAIL(&req->nh);
	rta->rta_type = attr;
	rta->rta_len = rtalen;
	memcpy(RTA_DATA(rta), data, len);
	req->nh.nlmsg_len = NLMSG_ALIGN(req->nh.nlmsg_len) + RTA_ALIGN(rtalen);

	return 0;
}