void ipoe_nl_add_net(uint32_t addr, int mask)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;

	if (rth.fd == -1)
		return;

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_ADD_NET;

	mask = mask ? ~0 << (32 - mask) : 0;

	addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);
	addattr32(nlh, 1024, IPOE_ATTR_MASK, mask);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
		log_error("ipoe: nl_add_net: error talking to kernel\n");
}
Пример #2
0
static int create_tunnel(struct l2tp_parm *p)
{
	uint32_t local_attr = L2TP_ATTR_IP_SADDR;
	uint32_t peer_attr = L2TP_ATTR_IP_DADDR;

	GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION,
		     L2TP_CMD_TUNNEL_CREATE, NLM_F_REQUEST | NLM_F_ACK);

	addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id);
	addattr32(&req.n, 1024, L2TP_ATTR_PEER_CONN_ID, p->peer_tunnel_id);
	addattr8(&req.n, 1024, L2TP_ATTR_PROTO_VERSION, 3);
	addattr16(&req.n, 1024, L2TP_ATTR_ENCAP_TYPE, p->encap);

	if (p->local_ip.family == AF_INET6)
		local_attr = L2TP_ATTR_IP6_SADDR;
	addattr_l(&req.n, 1024, local_attr, &p->local_ip.data, p->local_ip.bytelen);

	if (p->peer_ip.family == AF_INET6)
		peer_attr = L2TP_ATTR_IP6_DADDR;
	addattr_l(&req.n, 1024, peer_attr, &p->peer_ip.data, p->peer_ip.bytelen);

	if (p->encap == L2TP_ENCAPTYPE_UDP) {
		addattr16(&req.n, 1024, L2TP_ATTR_UDP_SPORT, p->local_udp_port);
		addattr16(&req.n, 1024, L2TP_ATTR_UDP_DPORT, p->peer_udp_port);
	}

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

	return 0;
}
Пример #3
0
static int set_netnsid_from_name(const char *name, int nsid)
{
	struct {
		struct nlmsghdr n;
		struct rtgenmsg g;
		char            buf[1024];
	} req;
	int fd, err = 0;

	memset(&req, 0, sizeof(req));
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = RTM_NEWNSID;
	req.g.rtgen_family = AF_UNSPEC;

	fd = netns_get_fd(name);
	if (fd < 0)
		return fd;

	addattr32(&req.n, 1024, NETNSA_FD, fd);
	addattr32(&req.n, 1024, NETNSA_NSID, nsid);
	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
		err = -2;

	close(fd);
	return err;
}
Пример #4
0
static int create_session(struct l2tp_parm *p)
{
	GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION,
		     L2TP_CMD_SESSION_CREATE, NLM_F_REQUEST | NLM_F_ACK);

	addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id);
	addattr32(&req.n, 1024, L2TP_ATTR_PEER_CONN_ID, p->peer_tunnel_id);
	addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id);
	addattr32(&req.n, 1024, L2TP_ATTR_PEER_SESSION_ID, p->peer_session_id);
	addattr16(&req.n, 1024, L2TP_ATTR_PW_TYPE, p->pw_type);
	addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_TYPE, p->l2spec_type);
	addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_LEN, p->l2spec_len);

	if (p->mtu)		addattr16(&req.n, 1024, L2TP_ATTR_MTU, p->mtu);
	if (p->recv_seq)	addattr(&req.n, 1024, L2TP_ATTR_RECV_SEQ);
	if (p->send_seq)	addattr(&req.n, 1024, L2TP_ATTR_SEND_SEQ);
	if (p->lns_mode)	addattr(&req.n, 1024, L2TP_ATTR_LNS_MODE);
	if (p->data_seq)	addattr8(&req.n, 1024, L2TP_ATTR_DATA_SEQ, p->data_seq);
	if (p->reorder_timeout) addattr64(&req.n, 1024, L2TP_ATTR_RECV_TIMEOUT,
					  p->reorder_timeout);
	if (p->offset)		addattr16(&req.n, 1024, L2TP_ATTR_OFFSET, p->offset);
	if (p->cookie_len)	addattr_l(&req.n, 1024, L2TP_ATTR_COOKIE,
					  p->cookie, p->cookie_len);
	if (p->peer_cookie_len) addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE,
					  p->peer_cookie,  p->peer_cookie_len);
	if (p->ifname && p->ifname[0])
		addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname);

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

	return 0;
}
Пример #5
0
static int do_modify_nl(enum cmd c, enum macsec_nl_commands cmd, int ifindex,
			struct rxsc_desc *rxsc, struct sa_desc *sa)
{
	struct rtattr *attr_sa;

	MACSEC_GENL_REQ(req, MACSEC_BUFLEN, cmd, NLM_F_REQUEST);

	addattr32(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_IFINDEX, ifindex);
	if (rxsc) {
		struct rtattr *attr_rxsc;

		attr_rxsc = addattr_nest(&req.n, MACSEC_BUFLEN,
					 MACSEC_ATTR_RXSC_CONFIG);
		addattr64(&req.n, MACSEC_BUFLEN,
			  MACSEC_RXSC_ATTR_SCI, rxsc->sci);
		if (c != CMD_DEL && rxsc->active != 0xff)
			addattr8(&req.n, MACSEC_BUFLEN,
				 MACSEC_RXSC_ATTR_ACTIVE, rxsc->active);

		addattr_nest_end(&req.n, attr_rxsc);
	}

	if (sa->an == 0xff)
		goto talk;

	attr_sa = addattr_nest(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_SA_CONFIG);

	addattr8(&req.n, MACSEC_BUFLEN, MACSEC_SA_ATTR_AN, sa->an);

	if (c != CMD_DEL) {
		if (sa->pn)
			addattr32(&req.n, MACSEC_BUFLEN, MACSEC_SA_ATTR_PN,
				  sa->pn);

		if (sa->key_len) {
			addattr_l(&req.n, MACSEC_BUFLEN, MACSEC_SA_ATTR_KEYID,
				  sa->key_id, MACSEC_KEYID_LEN);
			addattr_l(&req.n, MACSEC_BUFLEN, MACSEC_SA_ATTR_KEY,
				  sa->key, sa->key_len);
		}

		if (sa->active != 0xff) {
			addattr8(&req.n, MACSEC_BUFLEN,
				 MACSEC_SA_ATTR_ACTIVE, sa->active);
		}
	}

	addattr_nest_end(&req.n, attr_sa);

talk:
	if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
		return -2;

	return 0;
}
Пример #6
0
static int delete_session(struct l2tp_parm *p)
{
	GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION,
		     L2TP_CMD_SESSION_DELETE, NLM_F_REQUEST | NLM_F_ACK);

	addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id);
	addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id);
	if (rtnl_talk(&genl_rth, &req.n, 0, 0, NULL) < 0)
		return -2;

	return 0;
}
Пример #7
0
int rt_restore_entry(struct rt_entry *r)
{
	struct rtnl_handle rth;

	struct {
		struct nlmsghdr n;
		struct rtmsg r;
		char buf[1024];
	} req;

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
	req.n.nlmsg_type = RTM_NEWROUTE;

	memcpy(&req.r, r->rtm, sizeof(struct rtmsg));

	if (r->src)
		addattr_l(&req.n, sizeof(req), RTA_SRC, &r->src, 4);
	if (r->psrc)
		addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &r->psrc, 4);
	if (r->dest)
		addattr_l(&req.n, sizeof(req), RTA_DST, &r->dest, 4);
	if (r->gate)
		addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &r->gate, 4);
	if (r->flow)
		addattr_l(&req.n, sizeof(req), RTA_FLOW, &r->flow, 4);

	if (r->oif)
		addattr32(&req.n, sizeof(req), RTA_OIF, r->oif);
	if (r->iif)
		addattr32(&req.n, sizeof(req), RTA_IIF, r->iif);
	if (r->prio)
		addattr32(&req.n, sizeof(req), RTA_PRIORITY, r->prio);
	if (r->metrics)
		addattr32(&req.n, sizeof(req), RTA_METRICS, r->metrics);

	if (rtnl_open(&rth, 0) < 0) {
		printf("Can not initialize netlink interface...\n");
		return -1;
	}

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
		printf("Can not talk with netlink interface...\n");
		return -1;
	}

	return 0;
}
int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr)
{
	struct rtnl_handle rth;
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	int ret = 0;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;
	union {
		uint8_t hwaddr[6];
		uint64_t u64;
	} u;

	if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) {
		log_ppp_error("ipoe: cannot open generic netlink socket\n");
		return -1;
	}

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_MODIFY;

	addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex);
	addattr32(nlh, 1024, IPOE_ATTR_PEER_ADDR, peer_addr);
	addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);

	if (hwaddr) {
		memcpy(u.hwaddr, hwaddr, 6);
		addattr_l(nlh, 1024, IPOE_ATTR_HWADDR, &u.u64, 8);
	}

	if (ifname)
		addattr_l(nlh, 1024, IPOE_ATTR_IFNAME, ifname, strlen(ifname) + 1);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) {
		log_ppp_error("ipoe: nl_create: error talking to kernel\n");
		ret = -1;
	}

	rtnl_close(&rth);

	return ret;
}
void ipoe_nl_add_interface(int ifindex)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;

	if (rth.fd == -1)
		return;

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_ADD_IF;

	addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
		log_error("ipoe: nl_add_iface: error talking to kernel\n");
}
Пример #10
0
int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
{
	int len;
	struct iplink_req req;
	char answer[16384];

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
	req.n.nlmsg_type = RTM_GETLINK;
	req.i.ifi_family = preferred_family;

	if (name) {
		len = strlen(name) + 1;
		if (len == 1)
			invarg("\"\" is not a valid device identifier\n",
				   "name");
		if (len > IFNAMSIZ)
			invarg("\"name\" too long\n", name);
		addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len);
	}
	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);

	if (rtnl_talk(&rth, &req.n, 0, 0, (struct nlmsghdr *)answer) < 0)
		return -2;

	print_linkinfo(NULL, (struct nlmsghdr *)answer, stdout);

	return 0;
}
Пример #11
0
static int ipnetns_have_nsid(void)
{
	struct {
		struct nlmsghdr n;
		struct rtgenmsg g;
		char            buf[1024];
	} req;
	int fd;

	if (have_rtnl_getnsid < 0) {
		memset(&req, 0, sizeof(req));
		req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_GETNSID;
		req.g.rtgen_family = AF_UNSPEC;

		fd = open("/proc/self/ns/net", O_RDONLY);
		if (fd < 0) {
			perror("open(\"/proc/self/ns/net\")");
			exit(1);
		}

		addattr32(&req.n, 1024, NETNSA_FD, fd);

		if (rtnl_send(&rth, &req.n, req.n.nlmsg_len) < 0) {
			perror("request send failed");
			exit(1);
		}
		rtnl_listen(&rth, ipnetns_accept_msg, NULL);
		close(fd);
	}

	return have_rtnl_getnsid;
}
Пример #12
0
int ipoe_nl_del_vlan_mon(int ifindex)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;

	if (rth.fd == -1)
		return -1;

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_DEL_VLAN_MON;

	addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) {
		log_error("ipoe: nl_del_vlan_mon: error talking to kernel\n");
		return -1;
	}

	return 0;
}
Пример #13
0
void ipoe_nl_delete(int ifindex)
{
	struct rtnl_handle rth;
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;

	if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) {
		log_ppp_error("ipoe: cannot open generic netlink socket\n");
		return;
	}

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_DELETE;

	addattr32(nlh, 128, IPOE_ATTR_IFINDEX, ifindex);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
		log_ppp_error("ipoe: nl_delete: error talking to kernel\n");

	rtnl_close(&rth);
}
Пример #14
0
void ipoe_nl_delete_nets(void)
{
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;

	if (rth.fd == -1)
		return;

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_DEL_NET;

	addattr32(nlh, 1024, IPOE_ATTR_ADDR, 0);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
		log_error("ipoe: nl_del_net: error talking to kernel\n");
}
Пример #15
0
static int macvtap_parse_opt(struct link_util *lu, int argc, char **argv,
                             struct nlmsghdr *n)
{
    while (argc > 0) {
        if (matches(*argv, "mode") == 0) {
            __u32 mode = 0;
            NEXT_ARG();

            if (strcmp(*argv, "private") == 0)
                mode = MACVLAN_MODE_PRIVATE;
            else if (strcmp(*argv, "vepa") == 0)
                mode = MACVLAN_MODE_VEPA;
            else if (strcmp(*argv, "bridge") == 0)
                mode = MACVLAN_MODE_BRIDGE;
            else if (strcmp(*argv, "passthru") == 0)
                mode = MACVLAN_MODE_PASSTHRU;
            else
                return mode_arg(*argv);

            addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
        } else if (matches(*argv, "help") == 0) {
            explain();
            return -1;
        } else {
            fprintf(stderr, "macvtap: unknown command \"%s\"?\n", *argv);
            explain();
            return -1;
        }
        argc--, argv++;
    }

    return 0;
}
static int route_mod(int cmd, int oif, uint8_t table, uint8_t proto,
		     unsigned flags, uint32_t priority,
		     const struct in6_addr *src, int src_plen,
		     const struct in6_addr *dst, int dst_plen,
		     const struct in6_addr *gateway)
{
	uint8_t buf[512];
	struct nlmsghdr *n;
	struct rtmsg *rtm;

	if (cmd == RTM_NEWROUTE && oif == 0)
		return -1;

	memset(buf, 0, sizeof(buf));
	n = (struct nlmsghdr *)buf;

	n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	n->nlmsg_flags = NLM_F_REQUEST;
	if (cmd == RTM_NEWROUTE) {
		n->nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
	}
	n->nlmsg_type = cmd;

	rtm = NLMSG_DATA(n);
	rtm->rtm_family = AF_INET6;
	rtm->rtm_dst_len = dst_plen;
	rtm->rtm_src_len = src_plen;
	rtm->rtm_table = table;
	rtm->rtm_protocol = proto;
	rtm->rtm_scope = RT_SCOPE_UNIVERSE;
	rtm->rtm_type = RTN_UNICAST;
	rtm->rtm_flags = flags;

	addattr_l(n, sizeof(buf), RTA_DST, dst, sizeof(*dst));
	if (src)
		addattr_l(n, sizeof(buf), RTA_SRC, src, sizeof(*src));
	addattr32(n, sizeof(buf), RTA_OIF, oif);
	if (gateway)
		addattr_l(n, sizeof(buf),
			  RTA_GATEWAY, gateway, sizeof(*gateway));
	if (priority)
		addattr32(n, sizeof(buf), RTA_PRIORITY, priority);
	return rtnl_route_do(n, NULL);
}
Пример #17
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;
}
Пример #18
0
/* Routing table change via netlink interface. */
int
netlink_route (int cmd, int family, void *dest, int length, void *gate,
               int index, int zebra_flags, int table)
{
    int ret;
    int bytelen;
    struct sockaddr_nl snl;

    struct
    {
        struct nlmsghdr n;
        struct rtmsg r;
        char buf[1024];
    } req;

    memset (&req, 0, sizeof req);

    bytelen = (family == AF_INET ? 4 : 16);

    req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
    req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
    req.n.nlmsg_type = cmd;
    req.r.rtm_family = family;
    req.r.rtm_table = table;
    req.r.rtm_dst_len = length;

    if (cmd == RTM_NEWROUTE)
    {
        req.r.rtm_protocol = RTPROT_ZEBRA;
        req.r.rtm_scope = RT_SCOPE_UNIVERSE;

        if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
            req.r.rtm_type = RTN_BLACKHOLE;
        else
            req.r.rtm_type = RTN_UNICAST;
    }

    if (gate)
        addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
    if (dest)
        addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
    if (index > 0)
        addattr32 (&req.n, sizeof req, RTA_OIF, index);

    /* Destination netlink address. */
    memset (&snl, 0, sizeof snl);
    snl.nl_family = AF_NETLINK;

    /* Talk to netlink socket. */
    ret = netlink_talk (&req.n, &netlink);
    if (ret < 0)
        return -1;

    return 0;
}
Пример #19
0
static int ipneigh_dump_filter(struct nlmsghdr *nlh, int reqlen)
{
	struct ndmsg *ndm = NLMSG_DATA(nlh);
	int err;

	ndm->ndm_flags = filter.ndm_flags;

	if (filter.index) {
		err = addattr32(nlh, reqlen, NDA_IFINDEX, filter.index);
		if (err)
			return err;
	}
	if (filter.master) {
		err = addattr32(nlh, reqlen, NDA_MASTER, filter.master);
		if (err)
			return err;
	}

	return 0;
}
Пример #20
0
static int delete_tunnel(struct l2tp_parm *p)
{
	GENL_REQUEST(req, 128, genl_family, 0, L2TP_GENL_VERSION,
		     L2TP_CMD_TUNNEL_DELETE, NLM_F_REQUEST | NLM_F_ACK);

	addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->tunnel_id);

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

	return 0;
}
Пример #21
0
static int get_session(struct l2tp_data *p)
{
	GENL_REQUEST(req, 128, genl_family, 0, L2TP_GENL_VERSION,
		     L2TP_CMD_SESSION_GET,
		     NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST);

	req.n.nlmsg_seq = genl_rth.dump = ++genl_rth.seq;

	if (p->config.tunnel_id && p->config.session_id) {
		addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->config.tunnel_id);
		addattr32(&req.n, 128, L2TP_ATTR_SESSION_ID, p->config.session_id);
	}

	if (rtnl_send(&genl_rth, &req, req.n.nlmsg_len) < 0)
		return -2;

	if (rtnl_dump_filter(&genl_rth, session_nlmsg, p) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	return 0;
}
Пример #22
0
static int qfq_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, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "weight") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 10)) {
				explain1("weight"); return -1;
			}
			addattr32(n, 4096, TCA_QFQ_WEIGHT, tmp);
		} else if (matches(*argv, "maxpkt") == 0) {
			NEXT_ARG();
			if (get_u32(&tmp, *argv, 10)) {
				explain1("maxpkt"); return -1;
			}
			addattr32(n, 4096, TCA_QFQ_LMAX, tmp);
		} else if (strcmp(*argv, "help") == 0) {
			explain_class();
			return -1;
		} else {
			fprintf(stderr, "What is \"%s\"?\n", *argv);
			explain_class();
			return -1;
		}
		argc--; argv++;
	}

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

	return 0;
}
Пример #23
0
int ipoe_nl_add_vlan_mon_vid(int ifindex, int vid)
{
	struct rtnl_handle rth;
	struct nlmsghdr *nlh;
	struct genlmsghdr *ghdr;
	struct {
		struct nlmsghdr n;
		char buf[1024];
	} req;
	int r = 0;

	if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) {
		log_error("ipoe: cannot open generic netlink socket\n");
		return -1;
	}

	nlh = &req.n;
	nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_type = ipoe_genl_id;

	ghdr = NLMSG_DATA(&req.n);
	ghdr->cmd = IPOE_CMD_ADD_VLAN_MON_VID;

	addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex);
	addattr32(nlh, 1024, IPOE_ATTR_ADDR, vid);

	if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) {
		log_error("ipoe: nl_add_vlan_mon_vid: error talking to kernel\n");
		r = -1;
	}

	rtnl_close(&rth);

	return r;
}
Пример #24
0
static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
			  struct nlmsghdr *n)
{
	__u32 mode = 0;
	__u16 flags = 0;

	while (argc > 0) {
		if (matches(*argv, "mode") == 0) {
			NEXT_ARG();

			if (strcmp(*argv, "private") == 0)
				mode = MACVLAN_MODE_PRIVATE;
			else if (strcmp(*argv, "vepa") == 0)
				mode = MACVLAN_MODE_VEPA;
			else if (strcmp(*argv, "bridge") == 0)
				mode = MACVLAN_MODE_BRIDGE;
			else if (strcmp(*argv, "passthru") == 0)
				mode = MACVLAN_MODE_PASSTHRU;
			else
				return mode_arg(*argv);
		} else if (matches(*argv, "nopromisc") == 0) {
			flags |= MACVLAN_FLAG_NOPROMISC;
		} else if (matches(*argv, "help") == 0) {
			explain(lu);
			return -1;
		} else {
			pfx_err(lu, "unknown option \"%s\"?", *argv);
			explain(lu);
			return -1;
		}
		argc--, argv++;
	}

	if (mode)
		addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);

	if (flags) {
		if (flags & MACVLAN_FLAG_NOPROMISC &&
		    mode != MACVLAN_MODE_PASSTHRU) {
			pfx_err(lu, "nopromisc flag only valid in passthru mode");
			explain(lu);
			return -1;
		}
		addattr16(n, 1024, IFLA_MACVLAN_FLAGS, flags);
	}
	return 0;
}
Пример #25
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;
}
Пример #26
0
static int get_netnsid_from_name(const char *name)
{
	struct {
		struct nlmsghdr n;
		struct rtgenmsg g;
		char            buf[1024];
	} req, answer;
	struct rtattr *tb[NETNSA_MAX + 1];
	struct rtgenmsg *rthdr;
	int len, fd;

	memset(&req, 0, sizeof(req));
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = RTM_GETNSID;
	req.g.rtgen_family = AF_UNSPEC;

	fd = netns_get_fd(name);
	if (fd < 0)
		return fd;

	addattr32(&req.n, 1024, NETNSA_FD, fd);
	if (rtnl_talk(&rth, &req.n, 0, 0, &answer.n) < 0) {
		close(fd);
		return -2;
	}
	close(fd);

	/* Validate message and parse attributes */
	if (answer.n.nlmsg_type == NLMSG_ERROR)
		return -1;

	rthdr = NLMSG_DATA(&answer.n);
	len = answer.n.nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
	if (len < 0)
		return -1;

	parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);

	if (tb[NETNSA_NSID])
		return rta_getattr_u32(tb[NETNSA_NSID]);

	return -1;
}
Пример #27
0
/* Add/Delete IP rule to/from a specific IP/network */
int
netlink_rule(ip_rule_t *iprule, int cmd)
{
	int status = 1;
	struct {
		struct nlmsghdr n;
		struct rtmsg r;
		char buf[1024];
	} req;

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

	req.n.nlmsg_len    = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags  = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
	req.n.nlmsg_type   = cmd ? RTM_NEWRULE : RTM_DELRULE;
	req.r.rtm_family   = IP_FAMILY(iprule->addr);
	if (iprule->table < 256)
		req.r.rtm_table = iprule->table ? iprule->table : RT_TABLE_MAIN;
	else {
		req.r.rtm_table = RT_TABLE_UNSPEC;
		addattr32(&req.n, sizeof(req), FRA_TABLE, iprule->table);
	}
	req.r.rtm_type     = RTN_UNSPEC;
	req.r.rtm_scope    = RT_SCOPE_UNIVERSE;
	req.r.rtm_flags    = 0;

	if (cmd) {
		req.r.rtm_protocol = RTPROT_BOOT;
		req.r.rtm_type     = RTN_UNICAST;
	}

	/* Set rule entry */
	if (iprule->dir == VRRP_RULE_FROM) {
		req.r.rtm_src_len = iprule->mask;
		add_addr2req(&req.n, sizeof(req), FRA_SRC, iprule->addr);
	} else if (iprule->dir == VRRP_RULE_TO) {
		req.r.rtm_dst_len = iprule->mask;
		add_addr2req(&req.n, sizeof(req), FRA_DST, iprule->addr);
	}

	if (netlink_talk(&nl_cmd, &req.n) < 0)
		status = -1;
	return status;
}
Пример #28
0
void TunManager::addRemoveTable(int ifIdx, RouterID rid, bool add) {
  // We just store default routes (one for IPv4 and one for IPv6) in each route
  // table.
  struct {
    struct nlmsghdr n;
    struct rtmsg r;
    char buf[256];
  } req;
  const folly::IPAddress addrs[] = {
    IPAddress{"0.0.0.0"},       // v4 default
    IPAddress{"::0"},           // v6 default
  };

  for (const auto& addr : addrs) {
    memset(&req, 0, sizeof(req));
    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    req.n.nlmsg_flags = NLM_F_REQUEST;
    if (add) {
      req.n.nlmsg_type = RTM_NEWROUTE;
      req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_REPLACE;
    } else {
      req.n.nlmsg_type = RTM_DELROUTE;
    }
    req.r.rtm_family = addr.family();
    req.r.rtm_table = getTableId(rid);
    req.r.rtm_scope = RT_SCOPE_NOWHERE;
    req.r.rtm_protocol = RTPROT_FBOSS;
    req.r.rtm_scope = RT_SCOPE_UNIVERSE;
    req.r.rtm_type = RTN_UNICAST;
    req.r.rtm_dst_len = 0;       // default route, /0
    addattr_l(&req.n, sizeof(req), RTA_DST, addr.bytes(), addr.byteCount());
    addattr32(&req.n, sizeof(req), RTA_OIF, ifIdx);
    auto ret = rtnl_talk(&rth_, &req.n, 0, 0, nullptr);
    sysCheckError(ret, "Failed to ", add ? "add" : "remove",
                  " default route ", addr, " @ index ", ifIdx,
                  " in table ", getTableId(rid), " for router ", rid);
    LOG(INFO) << (add ? "Added" : "Removed") << " default route " << addr
              << " @ index " << ifIdx << " in table " << getTableId(rid)
              << " for router " << rid;
  }
}
Пример #29
0
/* Request for specific interface or address information from the kernel */
static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type,
				     uint32_t filter_mask)
{
	struct {
		struct nlmsghdr n;
		struct ifinfomsg ifm;
		char buf[256];
	} req;

	/* Form the request, specifying filter (rtattr) if needed. */
	memset(&req, 0, sizeof(req));
	req.n.nlmsg_type = type;
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
	req.ifm.ifi_family = family;

	/* Include filter, if specified. */
	if (filter_mask)
		addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);

	return netlink_request(&zns->netlink_cmd, &req.n);
}
Пример #30
0
static int modify_neigh(struct xia_xid *dst, unsigned char *lladdr,
	int lladdr_len, unsigned oif, int to_add)
{
	struct {
		struct nlmsghdr 	n;
		struct rtmsg 		r;
		char   			buf[1024];
	} req;

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));

	if (to_add) {
		/* XXX Does one really needs all these flags? */
		req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
		req.n.nlmsg_type = RTM_NEWROUTE;
		req.r.rtm_scope = RT_SCOPE_LINK;
	} else {
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_DELROUTE;
		req.r.rtm_scope = RT_SCOPE_NOWHERE;
	}

	req.r.rtm_family = AF_XIA;
	req.r.rtm_table = XRTABLE_MAIN_INDEX;
	req.r.rtm_protocol = RTPROT_BOOT;
	req.r.rtm_type = RTN_UNICAST;

	req.r.rtm_dst_len = sizeof(*dst);
	addattr_l(&req.n, sizeof(req), RTA_DST, dst, sizeof(*dst));
	addattr_l(&req.n, sizeof(req), RTA_LLADDR, lladdr, lladdr_len);
	addattr32(&req.n, sizeof(req), RTA_OIF, oif);

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