示例#1
0
static int dsmark_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
	struct rtattr *tb[TCA_DSMARK_MAX+1];

	if (!opt) return 0;
	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, TCA_DSMARK_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));
	if (tb[TCA_DSMARK_MASK]) {
		if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK]))
			fprintf(stderr,"dsmark: empty mask\n");
		else fprintf(f,"mask 0x%02x ",
			    rta_getattr_u8(tb[TCA_DSMARK_MASK]));
	}
	if (tb[TCA_DSMARK_VALUE]) {
		if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE]))
			fprintf(stderr,"dsmark: empty value\n");
		else fprintf(f,"value 0x%02x ",
			    rta_getattr_u8(tb[TCA_DSMARK_VALUE]));
	}
	if (tb[TCA_DSMARK_INDICES]) {
		if (RTA_PAYLOAD(tb[TCA_DSMARK_INDICES]) < sizeof(__u16))
			fprintf(stderr,"dsmark: indices too short\n");
		else fprintf(f,"indices 0x%04x ",
			    rta_getattr_u16(tb[TCA_DSMARK_INDICES]));
	}
	if (tb[TCA_DSMARK_DEFAULT_INDEX]) {
		if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(__u16))
			fprintf(stderr,"dsmark: default_index too short\n");
		else fprintf(f,"default_index 0x%04x ",
			    rta_getattr_u16(tb[TCA_DSMARK_DEFAULT_INDEX]));
	}
	if (tb[TCA_DSMARK_SET_TC_INDEX]) fprintf(f,"set_tc_index ");
	return 0;
}
示例#2
0
文件: ipila.c 项目: hannes/iproute2
static int print_ila_mapping(const struct sockaddr_nl *who,
			     struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct genlmsghdr *ghdr;
	struct rtattr *tb[ILA_ATTR_MAX + 1];
	int len = n->nlmsg_len;

	if (n->nlmsg_type != genl_family)
		return 0;

	len -= NLMSG_LENGTH(GENL_HDRLEN);
	if (len < 0)
		return -1;

	ghdr = NLMSG_DATA(n);
	parse_rtattr(tb, ILA_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len);

	print_ila_locid(fp, ILA_ATTR_LOCATOR_MATCH, tb, ADDR_BUF_SIZE);
	print_ila_locid(fp, ILA_ATTR_LOCATOR, tb, ADDR_BUF_SIZE);

	if (tb[ILA_ATTR_IFINDEX])
		fprintf(fp, "%-16s",
			ll_index_to_name(rta_getattr_u32(
						tb[ILA_ATTR_IFINDEX])));
	else
		fprintf(fp, "%-10s ", "-");

	if (tb[ILA_ATTR_CSUM_MODE])
		fprintf(fp, "%s",
			ila_csum_mode2name(rta_getattr_u8(
						tb[ILA_ATTR_CSUM_MODE])));
	else
		fprintf(fp, "%-10s ", "-");

	if (tb[ILA_ATTR_IDENT_TYPE])
		fprintf(fp, "%s",
			ila_ident_type2name(rta_getattr_u8(
						tb[ILA_ATTR_IDENT_TYPE])));
	else
		fprintf(fp, "-");

	fprintf(fp, "\n");

	return 0;
}
static void print_slave_state(FILE *f, struct rtattr *tb)
{
	unsigned int state = rta_getattr_u8(tb);

	if (state >= sizeof(slave_states) / sizeof(slave_states[0]))
		fprintf(f, "state %d ", state);
	else
		fprintf(f, "state %s ", slave_states[state]);
}
static void print_slave_mii_status(FILE *f, struct rtattr *tb)
{
	unsigned int status = rta_getattr_u8(tb);

	if (status >= sizeof(slave_mii_status) / sizeof(slave_mii_status[0]))
		fprintf(f, "mii_status %d ", status);
	else
		fprintf(f, "mii_status %s ", slave_mii_status[status]);
}
示例#5
0
static void print_linkmode(FILE *f, struct rtattr *tb)
{
	unsigned int mode = rta_getattr_u8(tb);

	if (mode >= sizeof(link_modes) / sizeof(link_modes[0]))
		fprintf(f, "mode %d ", mode);
	else
		fprintf(f, "mode %s ", link_modes[mode]);
}
示例#6
0
文件: ipmacsec.c 项目: dtaht/tc-adv
static void print_tx_sc(const char *prefix, __u64 sci, __u8 encoding_sa,
			struct rtattr *txsc_stats, struct rtattr *secy_stats,
			struct rtattr *sa)
{
	struct rtattr *sa_attr[MACSEC_SA_ATTR_MAX + 1];
	struct rtattr *a;
	int rem;

	print_string(PRINT_FP, NULL, "%s", prefix);
	print_0xhex(PRINT_ANY, "sci",
		    "TXSC: %016llx", ntohll(sci));
	print_uint(PRINT_ANY, "encoding_sa",
		   " on SA %d\n", encoding_sa);

	print_secy_stats(prefix, secy_stats);
	print_txsc_stats(prefix, txsc_stats);

	open_json_array(PRINT_JSON, "sa_list");
	rem = RTA_PAYLOAD(sa);
	for (a = RTA_DATA(sa); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) {
		bool state;

		open_json_object(NULL);
		parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX + 1, a);
		state = rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_ACTIVE]);

		print_string(PRINT_FP, NULL, "%s", prefix);
		print_string(PRINT_FP, NULL, "%s", prefix);
		print_uint(PRINT_ANY, "an", "%d:",
			   rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_AN]));
		print_uint(PRINT_ANY, "pn", " PN %u,",
			   rta_getattr_u32(sa_attr[MACSEC_SA_ATTR_PN]));

		print_bool(PRINT_JSON, "active", NULL, state);
		print_string(PRINT_FP, NULL,
			     " state %s,", state ? "on" : "off");
		print_key(sa_attr[MACSEC_SA_ATTR_KEYID]);

		print_txsa_stats(prefix, sa_attr[MACSEC_SA_ATTR_STATS]);
		close_json_object();
	}
	close_json_array(PRINT_JSON, NULL);
}
示例#7
0
static void print_slave_state(FILE *f, struct rtattr *tb)
{
	unsigned int state = rta_getattr_u8(tb);

	if (state >= ARRAY_SIZE(slave_states))
		print_int(PRINT_ANY, "state_index", "state %d ", state);
	else
		print_string(PRINT_ANY,
			     "state",
			     "state %s ",
			     slave_states[state]);
}
示例#8
0
文件: ipmacsec.c 项目: dtaht/tc-adv
static void print_attrs(struct rtattr *attrs[])
{
	print_flag(attrs, "protect", MACSEC_SECY_ATTR_PROTECT);

	if (attrs[MACSEC_SECY_ATTR_VALIDATE]) {
		__u8 val = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_VALIDATE]);

		print_string(PRINT_ANY, "validate",
			     "validate %s ", validate_str[val]);
	}

	print_flag(attrs, "sc", MACSEC_RXSC_ATTR_ACTIVE);
	print_flag(attrs, "sa", MACSEC_SA_ATTR_ACTIVE);
	print_flag(attrs, "encrypt", MACSEC_SECY_ATTR_ENCRYPT);
	print_flag(attrs, "send_sci", MACSEC_SECY_ATTR_INC_SCI);
	print_flag(attrs, "end_station", MACSEC_SECY_ATTR_ES);
	print_flag(attrs, "scb", MACSEC_SECY_ATTR_SCB);
	print_flag(attrs, "replay", MACSEC_SECY_ATTR_REPLAY);

	if (attrs[MACSEC_SECY_ATTR_WINDOW]) {
		__u32 win = rta_getattr_u32(attrs[MACSEC_SECY_ATTR_WINDOW]);

		print_uint(PRINT_ANY, "window", "window %u ", win);
	}

	if (attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]) {
		__u64 cid = rta_getattr_u64(attrs[MACSEC_SECY_ATTR_CIPHER_SUITE]);

		print_string(PRINT_FP, NULL, "%s", _SL_);
		print_string(PRINT_ANY, "cipher_suite",
			     "    cipher suite: %s,", cs_id_to_name(cid));
	}

	if (attrs[MACSEC_SECY_ATTR_ICV_LEN]) {
		__u8 icv_len = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_ICV_LEN]);

		print_uint(PRINT_ANY, "icv_length",
		     " using ICV length %u\n", icv_len);
	}
}
static void print_encap_ip6(FILE *fp, struct rtattr *encap)
{
	struct rtattr *tb[LWTUNNEL_IP6_MAX+1];

	parse_rtattr_nested(tb, LWTUNNEL_IP6_MAX, encap);

	if (tb[LWTUNNEL_IP6_ID])
		fprintf(fp, "id %llu ", ntohll(rta_getattr_u64(tb[LWTUNNEL_IP6_ID])));

	if (tb[LWTUNNEL_IP6_SRC])
		fprintf(fp, "src %s ",
			rt_addr_n2a_rta(AF_INET6, tb[LWTUNNEL_IP6_SRC]));

	if (tb[LWTUNNEL_IP6_DST])
		fprintf(fp, "dst %s ",
			rt_addr_n2a_rta(AF_INET6, tb[LWTUNNEL_IP6_DST]));

	if (tb[LWTUNNEL_IP6_HOPLIMIT])
		fprintf(fp, "hoplimit %d ", rta_getattr_u8(tb[LWTUNNEL_IP6_HOPLIMIT]));

	if (tb[LWTUNNEL_IP6_TC])
		fprintf(fp, "tc %d ", rta_getattr_u8(tb[LWTUNNEL_IP6_TC]));
}
static void print_encap_ip(FILE *fp, struct rtattr *encap)
{
	struct rtattr *tb[LWTUNNEL_IP_MAX+1];

	parse_rtattr_nested(tb, LWTUNNEL_IP_MAX, encap);

	if (tb[LWTUNNEL_IP_ID])
		fprintf(fp, "id %llu ", ntohll(rta_getattr_u64(tb[LWTUNNEL_IP_ID])));

	if (tb[LWTUNNEL_IP_SRC])
		fprintf(fp, "src %s ",
			rt_addr_n2a_rta(AF_INET, tb[LWTUNNEL_IP_SRC]));

	if (tb[LWTUNNEL_IP_DST])
		fprintf(fp, "dst %s ",
			rt_addr_n2a_rta(AF_INET, tb[LWTUNNEL_IP_DST]));

	if (tb[LWTUNNEL_IP_TTL])
		fprintf(fp, "ttl %d ", rta_getattr_u8(tb[LWTUNNEL_IP_TTL]));

	if (tb[LWTUNNEL_IP_TOS])
		fprintf(fp, "tos %d ", rta_getattr_u8(tb[LWTUNNEL_IP_TOS]));
}
示例#11
0
static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	SPRINT_BUF(b1);
	if (!tb)
		return;

	if (tb[IFLA_BOND_SLAVE_STATE])
		print_slave_state(f, tb[IFLA_BOND_SLAVE_STATE]);

	if (tb[IFLA_BOND_SLAVE_MII_STATUS])
		print_slave_mii_status(f, tb[IFLA_BOND_SLAVE_MII_STATUS]);

	if (tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT])
		print_int(PRINT_ANY,
			  "link_failure_count",
			  "link_failure_count %d ",
			  rta_getattr_u32(tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT]));

	if (tb[IFLA_BOND_SLAVE_PERM_HWADDR])
		print_string(PRINT_ANY,
			     "perm_hwaddr",
			     "perm_hwaddr %s ",
			     ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_SLAVE_PERM_HWADDR]),
					 RTA_PAYLOAD(tb[IFLA_BOND_SLAVE_PERM_HWADDR]),
					 0, b1, sizeof(b1)));

	if (tb[IFLA_BOND_SLAVE_QUEUE_ID])
		print_int(PRINT_ANY,
			  "queue_id",
			  "queue_id %d ",
			  rta_getattr_u16(tb[IFLA_BOND_SLAVE_QUEUE_ID]));

	if (tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID])
		print_int(PRINT_ANY,
			  "ad_aggregator_id",
			  "ad_aggregator_id %d ",
			  rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID]));

	if (tb[IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE])
		print_int(PRINT_ANY,
			  "ad_actor_oper_port_state",
			  "ad_actor_oper_port_state %d ",
			  rta_getattr_u8(tb[IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE]));

	if (tb[IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE])
		print_int(PRINT_ANY,
			  "ad_partner_oper_port_state",
			  "ad_partner_oper_port_state %d ",
			  rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE]));
}
示例#12
0
static void print_slave_mii_status(FILE *f, struct rtattr *tb)
{
	unsigned int status = rta_getattr_u8(tb);

	if (status >= ARRAY_SIZE(slave_mii_status))
		print_int(PRINT_ANY,
			  "mii_status_index",
			  "mii_status %d ",
			  status);
	else
		print_string(PRINT_ANY,
			     "mii_status",
			     "mii_status %s ",
			     slave_mii_status[status]);
}
示例#13
0
文件: ipmacsec.c 项目: dtaht/tc-adv
static void print_flag(struct rtattr *attrs[], const char *desc,
		       int field)
{
	__u8 flag;

	if (!attrs[field])
		return;

	flag = rta_getattr_u8(attrs[field]);
	if (is_json_context())
		print_bool(PRINT_JSON, desc, NULL, flag);
	else {
		print_string(PRINT_FP, NULL, "%s ", desc);
		print_string(PRINT_FP, NULL, "%s ",
			     flag ? "on" : "off");
	}
}
示例#14
0
文件: ipmacsec.c 项目: dtaht/tc-adv
static __u64 getattr_u64(struct rtattr *stat)
{
	switch (RTA_PAYLOAD(stat)) {
	case sizeof(__u64):
		return rta_getattr_u64(stat);
	case sizeof(__u32):
		return rta_getattr_u32(stat);
	case sizeof(__u16):
		return rta_getattr_u16(stat);
	case sizeof(__u8):
		return rta_getattr_u8(stat);
	default:
		fprintf(stderr, "invalid attribute length %lu\n",
			RTA_PAYLOAD(stat));
		exit(-1);
	}
}
static void print_encap_ila(FILE *fp, struct rtattr *encap)
{
	struct rtattr *tb[ILA_ATTR_MAX+1];

	parse_rtattr_nested(tb, ILA_ATTR_MAX, encap);

	if (tb[ILA_ATTR_LOCATOR]) {
		char abuf[ADDR64_BUF_SIZE];

		addr64_n2a(*(__u64 *)RTA_DATA(tb[ILA_ATTR_LOCATOR]),
			   abuf, sizeof(abuf));
		fprintf(fp, " %s ", abuf);
	}

	if (tb[ILA_ATTR_CSUM_MODE])
		fprintf(fp, " csum-mode %s ",
			ila_csum_mode2name(rta_getattr_u8(tb[ILA_ATTR_CSUM_MODE])));
}
示例#16
0
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	if (!tb)
		return;

	if (tb[IFLA_BR_FORWARD_DELAY])
		fprintf(f, "forward_delay %u ",
			rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));

	if (tb[IFLA_BR_HELLO_TIME])
		fprintf(f, "hello_time %u ",
			rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));

	if (tb[IFLA_BR_MAX_AGE])
		fprintf(f, "max_age %u ",
			rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));

	if (tb[IFLA_BR_AGEING_TIME])
		fprintf(f, "ageing_time %u ",
			rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));

	if (tb[IFLA_BR_STP_STATE])
		fprintf(f, "stp_state %u ",
			rta_getattr_u32(tb[IFLA_BR_STP_STATE]));

	if (tb[IFLA_BR_PRIORITY])
		fprintf(f, "priority %u ",
			rta_getattr_u16(tb[IFLA_BR_PRIORITY]));

	if (tb[IFLA_BR_VLAN_FILTERING])
		fprintf(f, "vlan_filtering %u ",
			rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));

	if (tb[IFLA_BR_VLAN_PROTOCOL]) {
		SPRINT_BUF(b1);

		fprintf(f, "vlan_protocol %s ",
			ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
				     b1, sizeof(b1)));
	}
}
示例#17
0
static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
{
	struct rtattr *inet6_attr;
	struct rtattr *tb[IFLA_INET6_MAX + 1];

	inet6_attr = parse_rtattr_one_nested(AF_INET6, af_spec_attr);
	if (!inet6_attr)
		return;

	parse_rtattr_nested(tb, IFLA_INET6_MAX, inet6_attr);

	if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
		switch (rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE])) {
		case IN6_ADDR_GEN_MODE_EUI64:
			fprintf(fp, "addrgenmode eui64 ");
			break;
		case IN6_ADDR_GEN_MODE_NONE:
			fprintf(fp, "addrgenmode none ");
			break;
		}
	}
}
示例#18
0
文件: q_prio.c 项目: hannes/iproute2
int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
	int i;
	struct tc_prio_qopt *qopt;
	struct rtattr *tb[TCA_PRIO_MAX+1];

	if (opt == NULL)
		return 0;

	if (parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
					sizeof(*qopt)))
		return -1;

	fprintf(f, "bands %u priomap ", qopt->bands);
	for (i = 0; i <= TC_PRIO_MAX; i++)
		fprintf(f, " %d", qopt->priomap[i]);

	if (tb[TCA_PRIO_MQ])
		fprintf(f, " multiqueue: %s ",
			rta_getattr_u8(tb[TCA_PRIO_MQ]) ? "on" : "off");

	return 0;
}
示例#19
0
int print_link(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) {
	struct ndmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *ifattr[IFLA_MAX+1];
	struct rtattr *ifinfo[IFLA_INFO_MAX+1];
	struct rtattr *ifgreo[IFLA_GRE_MAX+1];
	const char *ifname;
	const char *kind;
	int link=0;
	int tunid=0;
	struct in_addr sip,dip;
	uint8_t ttl=0,tos=0;
	struct ifinfomsg *ifi;

	sip.s_addr=dip.s_addr=htonl(0);

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) {
		fprintf(stderr, "Not RTM_xxxLINK: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	ifi=(void *)r;

	parse_rtattr(ifattr, IFLA_MAX, IFLA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
	if (ifattr[IFLA_IFNAME])
		ifname=rta_getattr_str(ifattr[IFLA_IFNAME]);
	else
		ifname="";
	if (ifattr[IFLA_LINKINFO])
		parse_rtattr(ifinfo, IFLA_INFO_MAX, (void *)rta_getattr_str(ifattr[IFLA_LINKINFO]), ifattr[IFLA_LINKINFO]->rta_len);
	else
		memset(ifinfo,0,sizeof ifinfo);
	if (ifinfo[IFLA_INFO_KIND])
		kind=rta_getattr_str(ifinfo[IFLA_INFO_KIND]);
	else
		kind="";
	if (!strcmp(kind,"eoip") && ifinfo[IFLA_INFO_DATA]) {
		char ts[IFNAMSIZ],td[IFNAMSIZ];

		parse_rtattr(ifgreo, IFLA_GRE_MAX, (void *)rta_getattr_str(ifinfo[IFLA_INFO_DATA]), ifinfo[IFLA_INFO_DATA]->rta_len);
		if (ifgreo[IFLA_GRE_LINK])
			link=rta_getattr_u32(ifgreo[IFLA_GRE_LINK]);
		if (ifgreo[IFLA_GRE_TOS])
			tos=rta_getattr_u8(ifgreo[IFLA_GRE_TOS]);
		if (ifgreo[IFLA_GRE_TTL])
			ttl=rta_getattr_u8(ifgreo[IFLA_GRE_TTL]);
		if (ifgreo[IFLA_GRE_LOCAL])
			sip.s_addr=rta_getattr_u32(ifgreo[IFLA_GRE_LOCAL]);
		if (ifgreo[IFLA_GRE_REMOTE])
			dip.s_addr=rta_getattr_u32(ifgreo[IFLA_GRE_REMOTE]);
		if (ifgreo[IFLA_GRE_IKEY])
			tunid=rta_getattr_u32(ifgreo[IFLA_GRE_IKEY]);
		strcpy(ts,inet_ntoa(sip));
		strcpy(td,inet_ntoa(dip));
		printf("%d: %s@%d: link/%s %s remote %s tunnel-id %d ttl %d tos %d\n",ifi->ifi_index,ifname,link,kind,ts,td,tunid,ttl,tos);
	}

	return 0;
}
示例#20
0
static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	if (!tb)
		return;

	if (tb[IFLA_BR_FORWARD_DELAY])
		fprintf(f, "forward_delay %u ",
			rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));

	if (tb[IFLA_BR_HELLO_TIME])
		fprintf(f, "hello_time %u ",
			rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));

	if (tb[IFLA_BR_MAX_AGE])
		fprintf(f, "max_age %u ",
			rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));

	if (tb[IFLA_BR_AGEING_TIME])
		fprintf(f, "ageing_time %u ",
			rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));

	if (tb[IFLA_BR_STP_STATE])
		fprintf(f, "stp_state %u ",
			rta_getattr_u32(tb[IFLA_BR_STP_STATE]));

	if (tb[IFLA_BR_PRIORITY])
		fprintf(f, "priority %u ",
			rta_getattr_u16(tb[IFLA_BR_PRIORITY]));

	if (tb[IFLA_BR_VLAN_FILTERING])
		fprintf(f, "vlan_filtering %u ",
			rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));

	if (tb[IFLA_BR_VLAN_PROTOCOL]) {
		SPRINT_BUF(b1);

		fprintf(f, "vlan_protocol %s ",
			ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
				     b1, sizeof(b1)));
	}

	if (tb[IFLA_BR_BRIDGE_ID]) {
		char bridge_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id,
				  sizeof(bridge_id));
		fprintf(f, "bridge_id %s ", bridge_id);
	}

	if (tb[IFLA_BR_ROOT_ID]) {
		char root_id[32];

		br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id,
				  sizeof(root_id));
		fprintf(f, "designated_root %s ", root_id);
	}

	if (tb[IFLA_BR_ROOT_PORT])
		fprintf(f, "root_port %u ",
			rta_getattr_u16(tb[IFLA_BR_ROOT_PORT]));

	if (tb[IFLA_BR_ROOT_PATH_COST])
		fprintf(f, "root_path_cost %u ",
			rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE])
		fprintf(f, "topology_change %u ",
			rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE]));

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])
		fprintf(f, "topology_change_detected %u ",
			rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]));

	if (tb[IFLA_BR_HELLO_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_HELLO_TIMER]));
		fprintf(f, "hello_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_TCN_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_TCN_TIMER]));
		fprintf(f, "tcn_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]) {
		unsigned long jiffies;
		struct timeval tv;

		jiffies = rta_getattr_u64(tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]);
		__jiffies_to_tv(&tv, jiffies);
		fprintf(f, "topology_change_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_GC_TIMER]) {
		struct timeval tv;

		__jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_GC_TIMER]));
		fprintf(f, "gc_timer %4i.%.2i ", (int)tv.tv_sec,
			(int)tv.tv_usec/10000);
	}

	if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
		fprintf(f, "vlan_default_pvid %u ",
			rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]));

	if (tb[IFLA_BR_GROUP_FWD_MASK])
		fprintf(f, "group_fwd_mask %#x ",
			rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK]));

	if (tb[IFLA_BR_GROUP_ADDR]) {
		SPRINT_BUF(mac);

		fprintf(f, "group_address %s ",
			ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]),
				    RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]),
				    1 /*ARPHDR_ETHER*/, mac, sizeof(mac)));
	}

	if (tb[IFLA_BR_MCAST_SNOOPING])
		fprintf(f, "mcast_snooping %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));

	if (tb[IFLA_BR_MCAST_ROUTER])
		fprintf(f, "mcast_router %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER]));

	if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])
		fprintf(f, "mcast_query_use_ifaddr %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]));

	if (tb[IFLA_BR_MCAST_QUERIER])
		fprintf(f, "mcast_querier %u ",
			rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));

	if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
		fprintf(f, "mcast_hash_elasticity %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY]));

	if (tb[IFLA_BR_MCAST_HASH_MAX])
		fprintf(f, "mcast_hash_max %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])
		fprintf(f, "mcast_last_member_count %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])
		fprintf(f, "mcast_startup_query_count %u ",
			rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]));

	if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])
		fprintf(f, "mcast_last_member_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]));

	if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])
		fprintf(f, "mcast_membership_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERIER_INTVL])
		fprintf(f, "mcast_querier_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_INTVL])
		fprintf(f, "mcast_query_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]));

	if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])
		fprintf(f, "mcast_query_response_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]));

	if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
		fprintf(f, "mcast_startup_query_interval %llu ",
			rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]));

	if (tb[IFLA_BR_NF_CALL_IPTABLES])
		fprintf(f, "nf_call_iptables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES]));

	if (tb[IFLA_BR_NF_CALL_IP6TABLES])
		fprintf(f, "nf_call_ip6tables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]));

	if (tb[IFLA_BR_NF_CALL_ARPTABLES])
		fprintf(f, "nf_call_arptables %u ",
			rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]));
}
示例#21
0
static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
                              struct nlmsghdr *n)
{
    struct {
        struct nlmsghdr n;
        struct ifinfomsg i;
        char buf[2048];
    } req;
    struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
    struct rtattr *tb[IFLA_MAX + 1];
    struct rtattr *linkinfo[IFLA_INFO_MAX+1];
    struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
    int len;
    __u32 link = 0;
    __u32 laddr = 0;
    __u32 raddr = 0;
    __u8 ttl = 0;
    __u8 tos = 0;
    __u8 pmtudisc = 1;
    __u16 iflags = 0;
    __u8 proto = 0;
    struct in6_addr ip6rdprefix;
    __u16 ip6rdprefixlen = 0;
    __u32 ip6rdrelayprefix = 0;
    __u16 ip6rdrelayprefixlen = 0;

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

    if (!(n->nlmsg_flags & NLM_F_CREATE)) {
        memset(&req, 0, sizeof(req));

        req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
        req.n.nlmsg_flags = NLM_F_REQUEST;
        req.n.nlmsg_type = RTM_GETLINK;
        req.i.ifi_family = preferred_family;
        req.i.ifi_index = ifi->ifi_index;

        if (rtnl_talk(&rth, &req.n, 0, 0, &req.n) < 0) {
get_failed:
            fprintf(stderr,
                    "Failed to get existing tunnel info.\n");
            return -1;
        }

        len = req.n.nlmsg_len;
        len -= NLMSG_LENGTH(sizeof(*ifi));
        if (len < 0)
            goto get_failed;

        parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);

        if (!tb[IFLA_LINKINFO])
            goto get_failed;

        parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);

        if (!linkinfo[IFLA_INFO_DATA])
            goto get_failed;

        parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
                            linkinfo[IFLA_INFO_DATA]);

        if (iptuninfo[IFLA_IPTUN_LOCAL])
            laddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_LOCAL]);

        if (iptuninfo[IFLA_IPTUN_REMOTE])
            raddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_REMOTE]);

        if (iptuninfo[IFLA_IPTUN_TTL])
            ttl = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);

        if (iptuninfo[IFLA_IPTUN_TOS])
            tos = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TOS]);

        if (iptuninfo[IFLA_IPTUN_PMTUDISC])
            pmtudisc =
                rta_getattr_u8(iptuninfo[IFLA_IPTUN_PMTUDISC]);

        if (iptuninfo[IFLA_IPTUN_FLAGS])
            iflags = rta_getattr_u16(iptuninfo[IFLA_IPTUN_FLAGS]);

        if (iptuninfo[IFLA_IPTUN_LINK])
            link = rta_getattr_u32(iptuninfo[IFLA_IPTUN_LINK]);

        if (iptuninfo[IFLA_IPTUN_PROTO])
            proto = rta_getattr_u8(iptuninfo[IFLA_IPTUN_PROTO]);

        if (iptuninfo[IFLA_IPTUN_6RD_PREFIX])
            memcpy(&ip6rdprefix,
                   RTA_DATA(iptuninfo[IFLA_IPTUN_6RD_PREFIX]),
                   sizeof(laddr));

        if (iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN])
            ip6rdprefixlen =
                rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN]);

        if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX])
            ip6rdrelayprefix =
                rta_getattr_u32(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX]);

        if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN])
            ip6rdrelayprefixlen =
                rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
    }

    while (argc > 0) {
        if (strcmp(*argv, "remote") == 0) {
            NEXT_ARG();
            if (strcmp(*argv, "any"))
                raddr = get_addr32(*argv);
            else
                raddr = 0;
        } else if (strcmp(*argv, "local") == 0) {
            NEXT_ARG();
            if (strcmp(*argv, "any"))
                laddr = get_addr32(*argv);
            else
                laddr = 0;
        } else if (matches(*argv, "dev") == 0) {
            NEXT_ARG();
            link = if_nametoindex(*argv);
            if (link == 0)
                invarg("\"dev\" is invalid", *argv);
        } else if (strcmp(*argv, "ttl") == 0 ||
                   strcmp(*argv, "hoplimit") == 0) {
            NEXT_ARG();
            if (strcmp(*argv, "inherit") != 0) {
                if (get_u8(&ttl, *argv, 0))
                    invarg("invalid TTL\n", *argv);
            } else
                ttl = 0;
        } else if (strcmp(*argv, "tos") == 0 ||
                   strcmp(*argv, "tclass") == 0 ||
                   matches(*argv, "dsfield") == 0) {
            __u32 uval;
            NEXT_ARG();
            if (strcmp(*argv, "inherit") != 0) {
                if (rtnl_dsfield_a2n(&uval, *argv))
                    invarg("bad TOS value", *argv);
                tos = uval;
            } else
                tos = 1;
        } else if (strcmp(*argv, "nopmtudisc") == 0) {
            pmtudisc = 0;
        } else if (strcmp(*argv, "pmtudisc") == 0) {
            pmtudisc = 1;
        } else if (strcmp(lu->id, "sit") == 0 &&
                   strcmp(*argv, "isatap") == 0) {
            iflags |= SIT_ISATAP;
        } else if (strcmp(lu->id, "sit") == 0 &&
                   strcmp(*argv, "mode") == 0) {
            NEXT_ARG();
            if (strcmp(*argv, "ipv6/ipv4") == 0 ||
                    strcmp(*argv, "ip6ip") == 0)
                proto = IPPROTO_IPV6;
            else if (strcmp(*argv, "ipv4/ipv4") == 0 ||
                     strcmp(*argv, "ipip") == 0 ||
                     strcmp(*argv, "ip4ip4") == 0)
                proto = IPPROTO_IPIP;
            else if (strcmp(*argv, "any/ipv4") == 0 ||
                     strcmp(*argv, "any") == 0)
                proto = 0;
            else
                invarg("Cannot guess tunnel mode.", *argv);
        } else if (strcmp(*argv, "6rd-prefix") == 0) {
            inet_prefix prefix;
            NEXT_ARG();
            if (get_prefix(&prefix, *argv, AF_INET6))
                invarg("invalid 6rd_prefix\n", *argv);
            memcpy(&ip6rdprefix, prefix.data, 16);
            ip6rdprefixlen = prefix.bitlen;
        } else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
            inet_prefix prefix;
            NEXT_ARG();
            if (get_prefix(&prefix, *argv, AF_INET))
                invarg("invalid 6rd-relay_prefix\n", *argv);
            memcpy(&ip6rdrelayprefix, prefix.data, 4);
            ip6rdrelayprefixlen = prefix.bitlen;
        } else if (strcmp(*argv, "6rd-reset") == 0) {
            inet_prefix prefix;
            get_prefix(&prefix, "2002::", AF_INET6);
            memcpy(&ip6rdprefix, prefix.data, 16);
            ip6rdprefixlen = 16;
            ip6rdrelayprefix = 0;
            ip6rdrelayprefixlen = 0;
        } else
            usage(strcmp(lu->id, "sit") == 0);
        argc--, argv++;
    }

    if (ttl && pmtudisc == 0) {
        fprintf(stderr, "ttl != 0 and nopmtudisc are incompatible\n");
        exit(-1);
    }

    addattr32(n, 1024, IFLA_IPTUN_LINK, link);
    addattr32(n, 1024, IFLA_IPTUN_LOCAL, laddr);
    addattr32(n, 1024, IFLA_IPTUN_REMOTE, raddr);
    addattr8(n, 1024, IFLA_IPTUN_TTL, ttl);
    addattr8(n, 1024, IFLA_IPTUN_TOS, tos);
    addattr8(n, 1024, IFLA_IPTUN_PMTUDISC, pmtudisc);
    if (strcmp(lu->id, "sit") == 0) {
        addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
        addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
        if (ip6rdprefixlen) {
            addattr_l(n, 1024, IFLA_IPTUN_6RD_PREFIX,
                      &ip6rdprefix, sizeof(ip6rdprefix));
            addattr16(n, 1024, IFLA_IPTUN_6RD_PREFIXLEN,
                      ip6rdprefixlen);
            addattr32(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIX,
                      ip6rdrelayprefix);
            addattr16(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
                      ip6rdrelayprefixlen);
        }
    }

    return 0;
}
示例#22
0
static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
			 struct nlmsghdr *n)
{
	struct {
		struct nlmsghdr n;
		struct ifinfomsg i;
		char buf[1024];
	} req;
	struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
	struct rtattr *tb[IFLA_MAX + 1];
	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
	struct rtattr *greinfo[IFLA_GRE_MAX + 1];
	__u16 iflags = 0;
	__u16 oflags = 0;
	unsigned ikey = 0;
	unsigned okey = 0;
	struct in6_addr raddr = IN6ADDR_ANY_INIT;
	struct in6_addr laddr = IN6ADDR_ANY_INIT;
	unsigned link = 0;
	unsigned flowinfo = 0;
	unsigned flags = 0;
	__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
	__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
	int len;

	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
		memset(&req, 0, sizeof(req));

		req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_GETLINK;
		req.i.ifi_family = preferred_family;
		req.i.ifi_index = ifi->ifi_index;

		if (rtnl_talk(&rth, &req.n, 0, 0, &req.n) < 0) {
get_failed:
			fprintf(stderr,
				"Failed to get existing tunnel info.\n");
			return -1;
		}

		len = req.n.nlmsg_len;
		len -= NLMSG_LENGTH(sizeof(*ifi));
		if (len < 0)
			goto get_failed;

		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);

		if (!tb[IFLA_LINKINFO])
			goto get_failed;

		parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);

		if (!linkinfo[IFLA_INFO_DATA])
			goto get_failed;

		parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
				    linkinfo[IFLA_INFO_DATA]);

		if (greinfo[IFLA_GRE_IKEY])
			ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);

		if (greinfo[IFLA_GRE_OKEY])
			okey = rta_getattr_u32(greinfo[IFLA_GRE_OKEY]);

		if (greinfo[IFLA_GRE_IFLAGS])
			iflags = rta_getattr_u16(greinfo[IFLA_GRE_IFLAGS]);

		if (greinfo[IFLA_GRE_OFLAGS])
			oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);

		if (greinfo[IFLA_GRE_LOCAL])
			memcpy(&laddr, RTA_DATA(greinfo[IFLA_GRE_LOCAL]), sizeof(laddr));

		if (greinfo[IFLA_GRE_REMOTE])
			memcpy(&raddr, RTA_DATA(greinfo[IFLA_GRE_REMOTE]), sizeof(raddr));

		if (greinfo[IFLA_GRE_TTL])
			hop_limit = rta_getattr_u8(greinfo[IFLA_GRE_TTL]);

		if (greinfo[IFLA_GRE_LINK])
			link = rta_getattr_u32(greinfo[IFLA_GRE_LINK]);

		if (greinfo[IFLA_GRE_ENCAP_LIMIT])
			encap_limit = rta_getattr_u8(greinfo[IFLA_GRE_ENCAP_LIMIT]);

		if (greinfo[IFLA_GRE_FLOWINFO])
			flowinfo = rta_getattr_u32(greinfo[IFLA_GRE_FLOWINFO]);

		if (greinfo[IFLA_GRE_FLAGS])
			flags = rta_getattr_u32(greinfo[IFLA_GRE_FLAGS]);
	}

	while (argc > 0) {
		if (!matches(*argv, "key")) {
			unsigned uval;

			NEXT_ARG();
			iflags |= GRE_KEY;
			oflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0) < 0) {
					fprintf(stderr,
						"Invalid value for \"key\"\n");
					exit(-1);
				}
				uval = htonl(uval);
			}

			ikey = okey = uval;
		} else if (!matches(*argv, "ikey")) {
			unsigned uval;

			NEXT_ARG();
			iflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0)<0) {
					fprintf(stderr, "invalid value of \"ikey\"\n");
					exit(-1);
				}
				uval = htonl(uval);
			}
			ikey = uval;
		} else if (!matches(*argv, "okey")) {
			unsigned uval;

			NEXT_ARG();
			oflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0)<0) {
					fprintf(stderr, "invalid value of \"okey\"\n");
					exit(-1);
				}
				uval = htonl(uval);
			}
			okey = uval;
		} else if (!matches(*argv, "seq")) {
			iflags |= GRE_SEQ;
			oflags |= GRE_SEQ;
		} else if (!matches(*argv, "iseq")) {
			iflags |= GRE_SEQ;
		} else if (!matches(*argv, "oseq")) {
			oflags |= GRE_SEQ;
		} else if (!matches(*argv, "csum")) {
			iflags |= GRE_CSUM;
			oflags |= GRE_CSUM;
		} else if (!matches(*argv, "icsum")) {
			iflags |= GRE_CSUM;
		} else if (!matches(*argv, "ocsum")) {
			oflags |= GRE_CSUM;
		} else if (!matches(*argv, "remote")) {
			inet_prefix addr;
			NEXT_ARG();
			get_prefix(&addr, *argv, preferred_family);
			if (addr.family == AF_UNSPEC)
				invarg("\"remote\" address family is AF_UNSPEC", *argv);
			memcpy(&raddr, &addr.data, sizeof(raddr));
		} else if (!matches(*argv, "local")) {
			inet_prefix addr;
			NEXT_ARG();
			get_prefix(&addr, *argv, preferred_family);
			if (addr.family == AF_UNSPEC)
				invarg("\"local\" address family is AF_UNSPEC", *argv);
			memcpy(&laddr, &addr.data, sizeof(laddr));
		} else if (!matches(*argv, "dev")) {
			NEXT_ARG();
			link = if_nametoindex(*argv);
			if (link == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n",
					*argv);
				exit(-1);
			}
		} else if (!matches(*argv, "ttl") ||
			   !matches(*argv, "hoplimit")) {
			__u8 uval;
			NEXT_ARG();
			if (get_u8(&uval, *argv, 0))
				invarg("invalid TTL", *argv);
			hop_limit = uval;
		} else if (!matches(*argv, "tos") ||
			   !matches(*argv, "tclass") ||
			   !matches(*argv, "dsfield")) {
			__u8 uval;
			NEXT_ARG();
			if (strcmp(*argv, "inherit") == 0)
				flags |= IP6_TNL_F_USE_ORIG_TCLASS;
			else {
				if (get_u8(&uval, *argv, 16))
					invarg("invalid TClass", *argv);
				flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS;
				flags &= ~IP6_TNL_F_USE_ORIG_TCLASS;
			}
		} else if (strcmp(*argv, "flowlabel") == 0 ||
			   strcmp(*argv, "fl") == 0) {
			__u32 uval;
			NEXT_ARG();
			if (strcmp(*argv, "inherit") == 0)
				flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
			else {
				if (get_u32(&uval, *argv, 16))
					invarg("invalid Flowlabel", *argv);
				if (uval > 0xFFFFF)
					invarg("invalid Flowlabel", *argv);
				flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL;
				flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
			}
		} else if (strcmp(*argv, "dscp") == 0) {
			NEXT_ARG();
			if (strcmp(*argv, "inherit") != 0)
				invarg("not inherit", *argv);
			flags |= IP6_TNL_F_RCV_DSCP_COPY;
		} else
			usage();
		argc--; argv++;
	}

	addattr32(n, 1024, IFLA_GRE_IKEY, ikey);
	addattr32(n, 1024, IFLA_GRE_OKEY, okey);
	addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
	addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
	addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr));
	addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr));
	if (link)
		addattr32(n, 1024, IFLA_GRE_LINK, link);
	addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1);
	addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1);
	addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4);
	addattr_l(n, 1024, IFLA_GRE_FLAGS, &flowinfo, 4);

	return 0;
}
示例#23
0
文件: ipl2tp.c 项目: AllardJ/Tomato
static int get_response(struct nlmsghdr *n, void *arg)
{
	struct genlmsghdr *ghdr;
	struct l2tp_data *data = arg;
	struct l2tp_parm *p = &data->config;
	struct rtattr *attrs[L2TP_ATTR_MAX + 1];
	struct rtattr *nla_stats;
	int len;

	/* Validate message and parse attributes */
	if (n->nlmsg_type == NLMSG_ERROR)
		return -EBADMSG;

	ghdr = NLMSG_DATA(n);
	len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ghdr));
	if (len < 0)
		return -1;

	parse_rtattr(attrs, L2TP_ATTR_MAX, (void *)ghdr + GENL_HDRLEN, len);

	if (attrs[L2TP_ATTR_PW_TYPE])
		p->pw_type = rta_getattr_u16(attrs[L2TP_ATTR_PW_TYPE]);
	if (attrs[L2TP_ATTR_ENCAP_TYPE])
		p->encap = rta_getattr_u16(attrs[L2TP_ATTR_ENCAP_TYPE]);
	if (attrs[L2TP_ATTR_OFFSET])
		p->offset = rta_getattr_u16(attrs[L2TP_ATTR_OFFSET]);
	if (attrs[L2TP_ATTR_DATA_SEQ])
		p->data_seq = rta_getattr_u16(attrs[L2TP_ATTR_DATA_SEQ]);
	if (attrs[L2TP_ATTR_CONN_ID])
		p->tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_CONN_ID]);
	if (attrs[L2TP_ATTR_PEER_CONN_ID])
		p->peer_tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_CONN_ID]);
	if (attrs[L2TP_ATTR_SESSION_ID])
		p->session_id = rta_getattr_u32(attrs[L2TP_ATTR_SESSION_ID]);
	if (attrs[L2TP_ATTR_PEER_SESSION_ID])
		p->peer_session_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_SESSION_ID]);
	if (attrs[L2TP_ATTR_L2SPEC_TYPE])
		p->l2spec_type = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_TYPE]);
	if (attrs[L2TP_ATTR_L2SPEC_LEN])
		p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]);

	p->udp_csum = !!attrs[L2TP_ATTR_UDP_CSUM];
	if (attrs[L2TP_ATTR_COOKIE])
		memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]),
		       p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE]));

	if (attrs[L2TP_ATTR_PEER_COOKIE])
		memcpy(p->peer_cookie, RTA_DATA(attrs[L2TP_ATTR_PEER_COOKIE]),
		       p->peer_cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_PEER_COOKIE]));

	p->recv_seq = !!attrs[L2TP_ATTR_RECV_SEQ];
	p->send_seq = !!attrs[L2TP_ATTR_SEND_SEQ];

	if (attrs[L2TP_ATTR_RECV_TIMEOUT])
		p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]);
	if (attrs[L2TP_ATTR_IP_SADDR]) {
		p->local_ip.family = AF_INET;
		p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]);
		p->local_ip.bytelen = 4;
		p->local_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP_DADDR]) {
		p->peer_ip.family = AF_INET;
		p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]);
		p->peer_ip.bytelen = 4;
		p->peer_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP6_SADDR]) {
		p->local_ip.family = AF_INET6;
		memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]),
			p->local_ip.bytelen = 16);
		p->local_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP6_DADDR]) {
		p->peer_ip.family = AF_INET6;
		memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]),
			p->peer_ip.bytelen = 16);
		p->peer_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_UDP_SPORT])
		p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]);
	if (attrs[L2TP_ATTR_UDP_DPORT])
		p->peer_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_DPORT]);
	if (attrs[L2TP_ATTR_MTU])
		p->mtu = rta_getattr_u16(attrs[L2TP_ATTR_MTU]);
	if (attrs[L2TP_ATTR_IFNAME])
		p->ifname = rta_getattr_str(attrs[L2TP_ATTR_IFNAME]);

	nla_stats = attrs[L2TP_ATTR_STATS];
	if (nla_stats) {
		struct rtattr *tb[L2TP_ATTR_STATS_MAX + 1];

		parse_rtattr_nested(tb, L2TP_ATTR_STATS_MAX, nla_stats);

		if (tb[L2TP_ATTR_TX_PACKETS])
			data->stats.data_tx_packets = rta_getattr_u64(tb[L2TP_ATTR_TX_PACKETS]);
		if (tb[L2TP_ATTR_TX_BYTES])
			data->stats.data_tx_bytes = rta_getattr_u64(tb[L2TP_ATTR_TX_BYTES]);
		if (tb[L2TP_ATTR_TX_ERRORS])
			data->stats.data_tx_errors = rta_getattr_u64(tb[L2TP_ATTR_TX_ERRORS]);
		if (tb[L2TP_ATTR_RX_PACKETS])
			data->stats.data_rx_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_PACKETS]);
		if (tb[L2TP_ATTR_RX_BYTES])
			data->stats.data_rx_bytes = rta_getattr_u64(tb[L2TP_ATTR_RX_BYTES]);
		if (tb[L2TP_ATTR_RX_ERRORS])
			data->stats.data_rx_errors = rta_getattr_u64(tb[L2TP_ATTR_RX_ERRORS]);
		if (tb[L2TP_ATTR_RX_SEQ_DISCARDS])
			data->stats.data_rx_oos_discards = rta_getattr_u64(tb[L2TP_ATTR_RX_SEQ_DISCARDS]);
		if (tb[L2TP_ATTR_RX_OOS_PACKETS])
			data->stats.data_rx_oos_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_OOS_PACKETS]);
	}

	return 0;
}
示例#24
0
static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	char s1[1024];
	char s2[64];
	const char *local = "any";
	const char *remote = "any";
	unsigned iflags = 0;
	unsigned oflags = 0;

	if (!tb)
		return;

	if (tb[IFLA_GRE_REMOTE]) {
		unsigned addr = rta_getattr_u32(tb[IFLA_GRE_REMOTE]);

		if (addr)
			remote = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
	}

	fprintf(f, "remote %s ", remote);

	if (tb[IFLA_GRE_LOCAL]) {
		unsigned addr = rta_getattr_u32(tb[IFLA_GRE_LOCAL]);

		if (addr)
			local = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
	}

	fprintf(f, "local %s ", local);

	if (tb[IFLA_GRE_LINK] && rta_getattr_u32(tb[IFLA_GRE_LINK])) {
		unsigned link = rta_getattr_u32(tb[IFLA_GRE_LINK]);
		const char *n = if_indextoname(link, s2);

		if (n)
			fprintf(f, "dev %s ", n);
		else
			fprintf(f, "dev %u ", link);
	}

	if (tb[IFLA_GRE_TTL] && rta_getattr_u8(tb[IFLA_GRE_TTL]))
		fprintf(f, "ttl %d ", rta_getattr_u8(tb[IFLA_GRE_TTL]));
	else
		fprintf(f, "ttl inherit ");

	if (tb[IFLA_GRE_TOS] && rta_getattr_u8(tb[IFLA_GRE_TOS])) {
		int tos = rta_getattr_u8(tb[IFLA_GRE_TOS]);

		fputs("tos ", f);
		if (tos == 1)
			fputs("inherit ", f);
		else
			fprintf(f, "0x%x ", tos);
	}

	if (tb[IFLA_GRE_PMTUDISC] &&
	    !rta_getattr_u8(tb[IFLA_GRE_PMTUDISC]))
		fputs("nopmtudisc ", f);

	if (tb[IFLA_GRE_IFLAGS])
		iflags = rta_getattr_u16(tb[IFLA_GRE_IFLAGS]);

	if (tb[IFLA_GRE_OFLAGS])
		oflags = rta_getattr_u16(tb[IFLA_GRE_OFLAGS]);

	if ((iflags & GRE_KEY) && tb[IFLA_GRE_IKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_IKEY]), s2, sizeof(s2));
		fprintf(f, "ikey %s ", s2);
	}

	if ((oflags & GRE_KEY) && tb[IFLA_GRE_OKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_OKEY]), s2, sizeof(s2));
		fprintf(f, "okey %s ", s2);
	}

	if (iflags & GRE_SEQ)
		fputs("iseq ", f);
	if (oflags & GRE_SEQ)
		fputs("oseq ", f);
	if (iflags & GRE_CSUM)
		fputs("icsum ", f);
	if (oflags & GRE_CSUM)
		fputs("ocsum ", f);

	if (tb[IFLA_GRE_ENCAP_TYPE] &&
	    *(__u16 *)RTA_DATA(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) {
		__u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]);
		__u16 flags = rta_getattr_u16(tb[IFLA_GRE_ENCAP_FLAGS]);
		__u16 sport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_SPORT]);
		__u16 dport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_DPORT]);

		fputs("encap ", f);
		switch (type) {
		case TUNNEL_ENCAP_FOU:
			fputs("fou ", f);
			break;
		case TUNNEL_ENCAP_GUE:
			fputs("gue ", f);
			break;
		default:
			fputs("unknown ", f);
			break;
		}

		if (sport == 0)
			fputs("encap-sport auto ", f);
		else
			fprintf(f, "encap-sport %u", ntohs(sport));

		fprintf(f, "encap-dport %u ", ntohs(dport));

		if (flags & TUNNEL_ENCAP_FLAG_CSUM)
			fputs("encap-csum ", f);
		else
			fputs("noencap-csum ", f);

		if (flags & TUNNEL_ENCAP_FLAG_CSUM6)
			fputs("encap-csum6 ", f);
		else
			fputs("noencap-csum6 ", f);

		if (flags & TUNNEL_ENCAP_FLAG_REMCSUM)
			fputs("encap-remcsum ", f);
		else
			fputs("noencap-remcsum ", f);
	}
}
示例#25
0
static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	char s1[1024];
	char s2[64];
	const char *local = "any";
	const char *remote = "any";
	unsigned iflags = 0;
	unsigned oflags = 0;
	unsigned flags = 0;
	unsigned flowinfo = 0;
	struct in6_addr in6_addr_any = IN6ADDR_ANY_INIT;

	if (!tb)
		return;

	if (tb[IFLA_GRE_FLAGS])
		flags = rta_getattr_u32(tb[IFLA_GRE_FLAGS]);

	if (tb[IFLA_GRE_FLOWINFO])
		flags = rta_getattr_u32(tb[IFLA_GRE_FLOWINFO]);

	if (tb[IFLA_GRE_REMOTE]) {
		struct in6_addr addr;
		memcpy(&addr, RTA_DATA(tb[IFLA_GRE_REMOTE]), sizeof(addr));

		if (memcmp(&addr, &in6_addr_any, sizeof(addr)))
			remote = format_host(AF_INET6, sizeof(addr), &addr, s1, sizeof(s1));
	}

	fprintf(f, "remote %s ", remote);

	if (tb[IFLA_GRE_LOCAL]) {
		struct in6_addr addr;
		memcpy(&addr, RTA_DATA(tb[IFLA_GRE_LOCAL]), sizeof(addr));

		if (memcmp(&addr, &in6_addr_any, sizeof(addr)))
			local = format_host(AF_INET6, sizeof(addr), &addr, s1, sizeof(s1));
	}

	fprintf(f, "local %s ", local);

	if (tb[IFLA_GRE_LINK] && rta_getattr_u32(tb[IFLA_GRE_LINK])) {
		unsigned link = rta_getattr_u32(tb[IFLA_GRE_LINK]);
		const char *n = if_indextoname(link, s2);

		if (n)
			fprintf(f, "dev %s ", n);
		else
			fprintf(f, "dev %u ", link);
	}

	if (tb[IFLA_GRE_TTL] && rta_getattr_u8(tb[IFLA_GRE_TTL]))
		fprintf(f, "hoplimit %d ", rta_getattr_u8(tb[IFLA_GRE_TTL]));

	if (flags & IP6_TNL_F_IGN_ENCAP_LIMIT)
		fprintf(f, "encaplimit none ");
	else if (tb[IFLA_GRE_ENCAP_LIMIT]) {
		int encap_limit = rta_getattr_u8(tb[IFLA_GRE_ENCAP_LIMIT]);

		fprintf(f, "encaplimit %d ", encap_limit);
	}

	if (flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
		fprintf(f, "flowlabel inherit ");
	else
		fprintf(f, "flowlabel 0x%05x ", ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL));

	if (flags & IP6_TNL_F_RCV_DSCP_COPY)
		fprintf(f, "dscp inherit ");

	if (tb[IFLA_GRE_IFLAGS])
		iflags = rta_getattr_u16(tb[IFLA_GRE_IFLAGS]);

	if (tb[IFLA_GRE_OFLAGS])
		oflags = rta_getattr_u16(tb[IFLA_GRE_OFLAGS]);

	if ((iflags & GRE_KEY) && tb[IFLA_GRE_IKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_IKEY]), s2, sizeof(s2));
		fprintf(f, "ikey %s ", s2);
	}

	if ((oflags & GRE_KEY) && tb[IFLA_GRE_OKEY]) {
		inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_OKEY]), s2, sizeof(s2));
		fprintf(f, "okey %s ", s2);
	}

	if (iflags & GRE_SEQ)
		fputs("iseq ", f);
	if (oflags & GRE_SEQ)
		fputs("oseq ", f);
	if (iflags & GRE_CSUM)
		fputs("icsum ", f);
	if (oflags & GRE_CSUM)
		fputs("ocsum ", f);
}
示例#26
0
static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	unsigned ifindex;

	if (!tb)
		return;

	if (tb[IFLA_BOND_MODE]) {
		const char *mode = get_name(mode_tbl,
			rta_getattr_u8(tb[IFLA_BOND_MODE]));
		fprintf(f, "mode %s ", mode);
	}

	if (tb[IFLA_BOND_ACTIVE_SLAVE] &&
	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) {
		char buf[IFNAMSIZ];
		const char *n = if_indextoname(ifindex, buf);

		if (n)
			fprintf(f, "active_slave %s ", n);
		else
			fprintf(f, "active_slave %u ", ifindex);
	}

	if (tb[IFLA_BOND_MIIMON])
		fprintf(f, "miimon %u ", rta_getattr_u32(tb[IFLA_BOND_MIIMON]));

	if (tb[IFLA_BOND_UPDELAY])
		fprintf(f, "updelay %u ", rta_getattr_u32(tb[IFLA_BOND_UPDELAY]));

	if (tb[IFLA_BOND_DOWNDELAY])
		fprintf(f, "downdelay %u ",
			rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY]));

	if (tb[IFLA_BOND_USE_CARRIER])
		fprintf(f, "use_carrier %u ",
			rta_getattr_u8(tb[IFLA_BOND_USE_CARRIER]));

	if (tb[IFLA_BOND_ARP_INTERVAL])
		fprintf(f, "arp_interval %u ",
			rta_getattr_u32(tb[IFLA_BOND_ARP_INTERVAL]));

	if (tb[IFLA_BOND_ARP_IP_TARGET]) {
		struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1];
		char buf[INET_ADDRSTRLEN];
		int i;

		parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS,
			tb[IFLA_BOND_ARP_IP_TARGET]);

		if (iptb[0])
			fprintf(f, "arp_ip_target ");

		for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
			if (iptb[i])
				fprintf(f, "%s",
					rt_addr_n2a(AF_INET,
						    RTA_PAYLOAD(iptb[i]),
						    RTA_DATA(iptb[i]),
						    buf,
						    INET_ADDRSTRLEN));
			if (i < BOND_MAX_ARP_TARGETS-1 && iptb[i+1])
				fprintf(f, ",");
		}

		if (iptb[0])
			fprintf(f, " ");
	}

	if (tb[IFLA_BOND_ARP_VALIDATE]) {
		const char *arp_validate = get_name(arp_validate_tbl,
			rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE]));
		fprintf(f, "arp_validate %s ", arp_validate);
	}

	if (tb[IFLA_BOND_ARP_ALL_TARGETS]) {
		const char *arp_all_targets = get_name(arp_all_targets_tbl,
			rta_getattr_u32(tb[IFLA_BOND_ARP_ALL_TARGETS]));
		fprintf(f, "arp_all_targets %s ", arp_all_targets);
	}

	if (tb[IFLA_BOND_PRIMARY] &&
	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_PRIMARY]))) {
		char buf[IFNAMSIZ];
		const char *n = if_indextoname(ifindex, buf);

		if (n)
			fprintf(f, "primary %s ", n);
		else
			fprintf(f, "primary %u ", ifindex);
	}

	if (tb[IFLA_BOND_PRIMARY_RESELECT]) {
		const char *primary_reselect = get_name(primary_reselect_tbl,
			rta_getattr_u8(tb[IFLA_BOND_PRIMARY_RESELECT]));
		fprintf(f, "primary_reselect %s ", primary_reselect);
	}

	if (tb[IFLA_BOND_FAIL_OVER_MAC]) {
		const char *fail_over_mac = get_name(fail_over_mac_tbl,
			rta_getattr_u8(tb[IFLA_BOND_FAIL_OVER_MAC]));
		fprintf(f, "fail_over_mac %s ", fail_over_mac);
	}

	if (tb[IFLA_BOND_XMIT_HASH_POLICY]) {
		const char *xmit_hash_policy = get_name(xmit_hash_policy_tbl,
			rta_getattr_u8(tb[IFLA_BOND_XMIT_HASH_POLICY]));
		fprintf(f, "xmit_hash_policy %s ", xmit_hash_policy);
	}

	if (tb[IFLA_BOND_RESEND_IGMP])
		fprintf(f, "resend_igmp %u ",
			rta_getattr_u32(tb[IFLA_BOND_RESEND_IGMP]));

	if (tb[IFLA_BOND_NUM_PEER_NOTIF])
		fprintf(f, "num_grat_arp %u ",
			rta_getattr_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]));

	if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
		fprintf(f, "all_slaves_active %u ",
			rta_getattr_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]));

	if (tb[IFLA_BOND_MIN_LINKS])
		fprintf(f, "min_links %u ",
			rta_getattr_u32(tb[IFLA_BOND_MIN_LINKS]));

	if (tb[IFLA_BOND_LP_INTERVAL])
		fprintf(f, "lp_interval %u ",
			rta_getattr_u32(tb[IFLA_BOND_LP_INTERVAL]));

	if (tb[IFLA_BOND_PACKETS_PER_SLAVE])
		fprintf(f, "packets_per_slave %u ",
			rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]));

	if (tb[IFLA_BOND_AD_LACP_RATE]) {
		const char *lacp_rate = get_name(lacp_rate_tbl,
			rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE]));
		fprintf(f, "lacp_rate %s ", lacp_rate);
	}

	if (tb[IFLA_BOND_AD_SELECT]) {
		const char *ad_select = get_name(ad_select_tbl,
			rta_getattr_u8(tb[IFLA_BOND_AD_SELECT]));
		fprintf(f, "ad_select %s ", ad_select);
	}

	if (tb[IFLA_BOND_AD_INFO]) {
		struct rtattr *adtb[IFLA_BOND_AD_INFO_MAX + 1];

		parse_rtattr_nested(adtb, IFLA_BOND_AD_INFO_MAX,
			tb[IFLA_BOND_AD_INFO]);

		if (adtb[IFLA_BOND_AD_INFO_AGGREGATOR])
			fprintf(f, "ad_aggregator %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_AGGREGATOR]));

		if (adtb[IFLA_BOND_AD_INFO_NUM_PORTS])
			fprintf(f, "ad_num_ports %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_NUM_PORTS]));

		if (adtb[IFLA_BOND_AD_INFO_ACTOR_KEY])
			fprintf(f, "ad_actor_key %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_ACTOR_KEY]));

		if (adtb[IFLA_BOND_AD_INFO_PARTNER_KEY])
			fprintf(f, "ad_partner_key %d ",
			  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_PARTNER_KEY]));

		if (adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]) {
			unsigned char *p =
				RTA_DATA(adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]);
			SPRINT_BUF(b);
			fprintf(f, "ad_partner_mac %s ",
				ll_addr_n2a(p, ETH_ALEN, 0, b, sizeof(b)));
		}
	}

	if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]) {
		fprintf(f, "ad_actor_sys_prio %u ",
			rta_getattr_u16(tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]));
	}

	if (tb[IFLA_BOND_AD_USER_PORT_KEY]) {
		fprintf(f, "ad_user_port_key %u ",
			rta_getattr_u16(tb[IFLA_BOND_AD_USER_PORT_KEY]));
	}

	if (tb[IFLA_BOND_AD_ACTOR_SYSTEM]) {
		/* We assume the l2 address is an Ethernet MAC address */
		SPRINT_BUF(b1);
		fprintf(f, "ad_actor_system %s ",
			ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
				    RTA_PAYLOAD(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
				    1 /*ARPHDR_ETHER*/, b1, sizeof(b1)));
	}

	if (tb[IFLA_BOND_TLB_DYNAMIC_LB]) {
		fprintf(f, "tlb_dynamic_lb %u ",
			rta_getattr_u8(tb[IFLA_BOND_TLB_DYNAMIC_LB]));
	}
}
示例#27
0
static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
			 struct nlmsghdr *n)
{
	struct {
		struct nlmsghdr n;
		struct ifinfomsg i;
		char buf[16384];
	} req;
	struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
	struct rtattr *tb[IFLA_MAX + 1];
	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
	struct rtattr *greinfo[IFLA_GRE_MAX + 1];
	__u16 iflags = 0;
	__u16 oflags = 0;
	unsigned ikey = 0;
	unsigned okey = 0;
	unsigned saddr = 0;
	unsigned daddr = 0;
	unsigned link = 0;
	__u8 pmtudisc = 1;
	__u8 ttl = 0;
	__u8 tos = 0;
	int len;
	__u16 encaptype = 0;
	__u16 encapflags = 0;
	__u16 encapsport = 0;
	__u16 encapdport = 0;

	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
		memset(&req, 0, sizeof(req));

		req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_GETLINK;
		req.i.ifi_family = preferred_family;
		req.i.ifi_index = ifi->ifi_index;

		if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
get_failed:
			fprintf(stderr,
				"Failed to get existing tunnel info.\n");
			return -1;
		}

		len = req.n.nlmsg_len;
		len -= NLMSG_LENGTH(sizeof(*ifi));
		if (len < 0)
			goto get_failed;

		parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len);

		if (!tb[IFLA_LINKINFO])
			goto get_failed;

		parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);

		if (!linkinfo[IFLA_INFO_DATA])
			goto get_failed;

		parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
				    linkinfo[IFLA_INFO_DATA]);

		if (greinfo[IFLA_GRE_IKEY])
			ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);

		if (greinfo[IFLA_GRE_OKEY])
			okey = rta_getattr_u32(greinfo[IFLA_GRE_OKEY]);

		if (greinfo[IFLA_GRE_IFLAGS])
			iflags = rta_getattr_u16(greinfo[IFLA_GRE_IFLAGS]);

		if (greinfo[IFLA_GRE_OFLAGS])
			oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);

		if (greinfo[IFLA_GRE_LOCAL])
			saddr = rta_getattr_u32(greinfo[IFLA_GRE_LOCAL]);

		if (greinfo[IFLA_GRE_REMOTE])
			daddr = rta_getattr_u32(greinfo[IFLA_GRE_REMOTE]);

		if (greinfo[IFLA_GRE_PMTUDISC])
			pmtudisc = rta_getattr_u8(
				greinfo[IFLA_GRE_PMTUDISC]);

		if (greinfo[IFLA_GRE_TTL])
			ttl = rta_getattr_u8(greinfo[IFLA_GRE_TTL]);

		if (greinfo[IFLA_GRE_TOS])
			tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]);

		if (greinfo[IFLA_GRE_LINK])
			link = rta_getattr_u8(greinfo[IFLA_GRE_LINK]);

		if (greinfo[IFLA_GRE_ENCAP_TYPE])
			encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]);
		if (greinfo[IFLA_GRE_ENCAP_FLAGS])
			encapflags = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_FLAGS]);
		if (greinfo[IFLA_GRE_ENCAP_SPORT])
			encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]);
		if (greinfo[IFLA_GRE_ENCAP_DPORT])
			encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]);
	}

	while (argc > 0) {
		if (!matches(*argv, "key")) {
			unsigned uval;

			NEXT_ARG();
			iflags |= GRE_KEY;
			oflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0) < 0) {
					fprintf(stderr,
						"Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}

			ikey = okey = uval;
		} else if (!matches(*argv, "ikey")) {
			unsigned uval;

			NEXT_ARG();
			iflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0)<0) {
					fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}
			ikey = uval;
		} else if (!matches(*argv, "okey")) {
			unsigned uval;

			NEXT_ARG();
			oflags |= GRE_KEY;
			if (strchr(*argv, '.'))
				uval = get_addr32(*argv);
			else {
				if (get_unsigned(&uval, *argv, 0)<0) {
					fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv);
					exit(-1);
				}
				uval = htonl(uval);
			}
			okey = uval;
		} else if (!matches(*argv, "seq")) {
			iflags |= GRE_SEQ;
			oflags |= GRE_SEQ;
		} else if (!matches(*argv, "iseq")) {
			iflags |= GRE_SEQ;
		} else if (!matches(*argv, "oseq")) {
			oflags |= GRE_SEQ;
		} else if (!matches(*argv, "csum")) {
			iflags |= GRE_CSUM;
			oflags |= GRE_CSUM;
		} else if (!matches(*argv, "icsum")) {
			iflags |= GRE_CSUM;
		} else if (!matches(*argv, "ocsum")) {
			oflags |= GRE_CSUM;
		} else if (!matches(*argv, "nopmtudisc")) {
			pmtudisc = 0;
		} else if (!matches(*argv, "pmtudisc")) {
			pmtudisc = 1;
		} else if (!matches(*argv, "remote")) {
			NEXT_ARG();
			if (strcmp(*argv, "any"))
				daddr = get_addr32(*argv);
		} else if (!matches(*argv, "local")) {
			NEXT_ARG();
			if (strcmp(*argv, "any"))
				saddr = get_addr32(*argv);
		} else if (!matches(*argv, "dev")) {
			NEXT_ARG();
			link = if_nametoindex(*argv);
			if (link == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n",
					*argv);
				exit(-1);
			}
		} else if (!matches(*argv, "ttl") ||
			   !matches(*argv, "hoplimit")) {
			unsigned uval;

			NEXT_ARG();
			if (strcmp(*argv, "inherit") != 0) {
				if (get_unsigned(&uval, *argv, 0))
					invarg("invalid TTL\n", *argv);
				if (uval > 255)
					invarg("TTL must be <= 255\n", *argv);
				ttl = uval;
			}
		} else if (!matches(*argv, "tos") ||
			   !matches(*argv, "tclass") ||
			   !matches(*argv, "dsfield")) {
			__u32 uval;

			NEXT_ARG();
			if (strcmp(*argv, "inherit") != 0) {
				if (rtnl_dsfield_a2n(&uval, *argv))
					invarg("bad TOS value", *argv);
				tos = uval;
			} else
				tos = 1;
		} else if (strcmp(*argv, "noencap") == 0) {
			encaptype = TUNNEL_ENCAP_NONE;
		} else if (strcmp(*argv, "encap") == 0) {
			NEXT_ARG();
			if (strcmp(*argv, "fou") == 0)
				encaptype = TUNNEL_ENCAP_FOU;
			else if (strcmp(*argv, "gue") == 0)
				encaptype = TUNNEL_ENCAP_GUE;
			else if (strcmp(*argv, "none") == 0)
				encaptype = TUNNEL_ENCAP_NONE;
			else
				invarg("Invalid encap type.", *argv);
		} else if (strcmp(*argv, "encap-sport") == 0) {
			NEXT_ARG();
			if (strcmp(*argv, "auto") == 0)
				encapsport = 0;
			else if (get_u16(&encapsport, *argv, 0))
				invarg("Invalid source port.", *argv);
		} else if (strcmp(*argv, "encap-dport") == 0) {
			NEXT_ARG();
			if (get_u16(&encapdport, *argv, 0))
				invarg("Invalid destination port.", *argv);
		} else if (strcmp(*argv, "encap-csum") == 0) {
			encapflags |= TUNNEL_ENCAP_FLAG_CSUM;
		} else if (strcmp(*argv, "noencap-csum") == 0) {
			encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM;
		} else if (strcmp(*argv, "encap-udp6-csum") == 0) {
			encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
		} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
			encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6;
		} else if (strcmp(*argv, "encap-remcsum") == 0) {
			encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
		} else if (strcmp(*argv, "noencap-remcsum") == 0) {
			encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM;
		} else
			usage();
		argc--; argv++;
	}

	if (!ikey && IN_MULTICAST(ntohl(daddr))) {
		ikey = daddr;
		iflags |= GRE_KEY;
	}
	if (!okey && IN_MULTICAST(ntohl(daddr))) {
		okey = daddr;
		oflags |= GRE_KEY;
	}
	if (IN_MULTICAST(ntohl(daddr)) && !saddr) {
		fprintf(stderr, "A broadcast tunnel requires a source address.\n");
		return -1;
	}

	addattr32(n, 1024, IFLA_GRE_IKEY, ikey);
	addattr32(n, 1024, IFLA_GRE_OKEY, okey);
	addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
	addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
	addattr_l(n, 1024, IFLA_GRE_LOCAL, &saddr, 4);
	addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4);
	addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
	if (link)
		addattr32(n, 1024, IFLA_GRE_LINK, link);
	addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1);
	addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1);

	addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype);
	addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags);
	addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport));
	addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport));

	return 0;
}
示例#28
0
static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
    char s1[1024];
    char s2[64];
    const char *local = "any";
    const char *remote = "any";

    if (!tb)
        return;

    if (tb[IFLA_IPTUN_REMOTE]) {
        unsigned addr = rta_getattr_u32(tb[IFLA_IPTUN_REMOTE]);

        if (addr)
            remote = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
    }

    fprintf(f, "remote %s ", remote);

    if (tb[IFLA_IPTUN_LOCAL]) {
        unsigned addr = rta_getattr_u32(tb[IFLA_IPTUN_LOCAL]);

        if (addr)
            local = format_host(AF_INET, 4, &addr, s1, sizeof(s1));
    }

    fprintf(f, "local %s ", local);

    if (tb[IFLA_IPTUN_LINK] && rta_getattr_u32(tb[IFLA_IPTUN_LINK])) {
        unsigned link = rta_getattr_u32(tb[IFLA_IPTUN_LINK]);
        const char *n = if_indextoname(link, s2);

        if (n)
            fprintf(f, "dev %s ", n);
        else
            fprintf(f, "dev %u ", link);
    }

    if (tb[IFLA_IPTUN_TTL] && rta_getattr_u8(tb[IFLA_IPTUN_TTL]))
        fprintf(f, "ttl %d ", rta_getattr_u8(tb[IFLA_IPTUN_TTL]));
    else
        fprintf(f, "ttl inherit ");

    if (tb[IFLA_IPTUN_TOS] && rta_getattr_u8(tb[IFLA_IPTUN_TOS])) {
        int tos = rta_getattr_u8(tb[IFLA_IPTUN_TOS]);

        fputs("tos ", f);
        if (tos == 1)
            fputs("inherit ", f);
        else
            fprintf(f, "0x%x ", tos);
    }

    if (tb[IFLA_IPTUN_PMTUDISC] && rta_getattr_u8(tb[IFLA_IPTUN_PMTUDISC]))
        fprintf(f, "pmtudisc ");
    else
        fprintf(f, "nopmtudisc ");

    if (tb[IFLA_IPTUN_FLAGS]) {
        __u16 iflags = rta_getattr_u16(tb[IFLA_IPTUN_FLAGS]);

        if (iflags & SIT_ISATAP)
            fprintf(f, "isatap ");
    }

    if (tb[IFLA_IPTUN_6RD_PREFIXLEN] &&
            *(__u16 *)RTA_DATA(tb[IFLA_IPTUN_6RD_PREFIXLEN])) {
        __u16 prefixlen = rta_getattr_u16(tb[IFLA_IPTUN_6RD_PREFIXLEN]);
        __u16 relayprefixlen =
            rta_getattr_u16(tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
        __u32 relayprefix =
            rta_getattr_u32(tb[IFLA_IPTUN_6RD_RELAY_PREFIX]);

        printf("6rd-prefix %s/%u ",
               inet_ntop(AF_INET6, RTA_DATA(tb[IFLA_IPTUN_6RD_PREFIX]),
                         s1, sizeof(s1)),
               prefixlen);
        if (relayprefix) {
            printf("6rd-relay_prefix %s/%u ",
                   format_host(AF_INET, 4, &relayprefix, s1,
                               sizeof(s1)),
                   relayprefixlen);
        }
    }
}
示例#29
0
int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (filter.group != -1 && group != filter.group)
			return -1;
	}

	if (tb[IFLA_MASTER]) {
		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
		if (filter.master > 0 && master != filter.master)
			return -1;
	}
	else if (filter.master > 0)
		return -1;

	if (filter.kind) {
		if (tb[IFLA_LINKINFO]) {
			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);

			if (strcmp(kind, filter.kind))
				return -1;
		} else {
			return -1;
		}
	}

	if (n->nlmsg_type == RTM_DELLINK)
		fprintf(fp, "Deleted ");

	fprintf(fp, "%d: ", ifi->ifi_index);
	color_fprintf(fp, COLOR_IFNAME, "%s",
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			if (tb[IFLA_LINK_NETNSID])
				fprintf(fp, "@if%d: ", iflink);
			else {
				fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
				m_flag = ll_index_to_flags(iflink);
				m_flag = !(m_flag & IFF_UP);
			}
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_PHYS_PORT_ID]) {
		SPRINT_BUF(b1);
		fprintf(fp, "portid %s ",
			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
				      RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
				      b1, sizeof(b1)));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (tb[IFLA_GROUP]) {
		SPRINT_BUF(b1);
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
	}

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET || show_details) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			color_fprintf(fp, COLOR_MAC, "%s",
					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						ifi->ifi_type,
						b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (tb[IFLA_LINK_NETNSID]) {
		int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]);

		if (id >= 0)
			fprintf(fp, " link-netnsid %d", id);
		else
			fprintf(fp, " link-netnsid unknown");
	}

	if (tb[IFLA_PROMISCUITY] && show_details)
		fprintf(fp, " promiscuity %u ",
			*(int*)RTA_DATA(tb[IFLA_PROMISCUITY]));

	if (tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_AF_SPEC] && show_details)
		print_af_spec(fp, tb[IFLA_AF_SPEC]);

	if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
		fprintf(fp, "%s    alias %s", _SL_,
			rta_getattr_str(tb[IFLA_IFALIAS]));
	}

	if (do_link && show_stats) {
		fprintf(fp, "%s", _SL_);
		__print_link_stats(fp, tb);
	}

	if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 1;
}
示例#30
0
int print_neigh(struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct ndmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[NDA_MAX+1];
	static int logit = 1;
	__u8 protocol = 0;

	if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH &&
	    n->nlmsg_type != RTM_GETNEIGH) {
		fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);

		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH)
		return 0;

	if (filter.family && filter.family != r->ndm_family)
		return 0;
	if (filter.index && filter.index != r->ndm_ifindex)
		return 0;
	if (!(filter.state&r->ndm_state) &&
	    !(r->ndm_flags & NTF_PROXY) &&
	    !(r->ndm_flags & NTF_EXT_LEARNED) &&
	    (r->ndm_state || !(filter.state&0x100)) &&
	    (r->ndm_family != AF_DECnet))
		return 0;

	if (filter.master && !(n->nlmsg_flags & NLM_F_DUMP_FILTERED)) {
		if (logit) {
			logit = 0;
			fprintf(fp,
				"\nWARNING: Kernel does not support filtering by master device\n\n");
		}
	}

	parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));

	if (inet_addr_match_rta(&filter.pfx, tb[NDA_DST]))
		return 0;

	if (tb[NDA_PROTOCOL])
		protocol = rta_getattr_u8(tb[NDA_PROTOCOL]);

	if (filter.protocol && filter.protocol != protocol)
		return 0;

	if (filter.unused_only && tb[NDA_CACHEINFO]) {
		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);

		if (ci->ndm_refcnt)
			return 0;
	}

	if (filter.flushb) {
		struct nlmsghdr *fn;

		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
			if (flush_update())
				return -1;
		}
		fn = (struct nlmsghdr *)(filter.flushb + NLMSG_ALIGN(filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELNEIGH;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++rth.seq;
		filter.flushp = (((char *)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed++;
		if (show_stats < 2)
			return 0;
	}

	open_json_object(NULL);
	if (n->nlmsg_type == RTM_DELNEIGH)
		print_bool(PRINT_ANY, "deleted", "Deleted ", true);
	else if (n->nlmsg_type == RTM_GETNEIGH)
		print_null(PRINT_ANY, "miss", "%s ", "miss");

	if (tb[NDA_DST]) {
		const char *dst;
		int family = r->ndm_family;

		if (family == AF_BRIDGE) {
			if (RTA_PAYLOAD(tb[NDA_DST]) == sizeof(struct in6_addr))
				family = AF_INET6;
			else
				family = AF_INET;
		}

		dst = format_host_rta(family, tb[NDA_DST]);
		print_color_string(PRINT_ANY,
				   ifa_family_color(family),
				   "dst", "%s ", dst);
	}

	if (!filter.index && r->ndm_ifindex) {
		if (!is_json_context())
			fprintf(fp, "dev ");

		print_color_string(PRINT_ANY, COLOR_IFNAME,
				   "dev", "%s ",
				   ll_index_to_name(r->ndm_ifindex));
	}

	if (tb[NDA_LLADDR]) {
		const char *lladdr;
		SPRINT_BUF(b1);

		lladdr = ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]),
				     RTA_PAYLOAD(tb[NDA_LLADDR]),
				     ll_index_to_type(r->ndm_ifindex),
				     b1, sizeof(b1));

		if (!is_json_context())
			fprintf(fp, "lladdr ");

		print_color_string(PRINT_ANY, COLOR_MAC,
				   "lladdr", "%s", lladdr);
	}

	if (r->ndm_flags & NTF_ROUTER)
		print_null(PRINT_ANY, "router", " %s", "router");

	if (r->ndm_flags & NTF_PROXY)
		print_null(PRINT_ANY, "proxy", " %s", "proxy");

	if (r->ndm_flags & NTF_EXT_LEARNED)
		print_null(PRINT_ANY, "extern_learn", " %s ", "extern_learn");

	if (show_stats) {
		if (tb[NDA_CACHEINFO])
			print_cacheinfo(RTA_DATA(tb[NDA_CACHEINFO]));

		if (tb[NDA_PROBES])
			print_uint(PRINT_ANY, "probes", " probes %u",
				   rta_getattr_u32(tb[NDA_PROBES]));
	}

	if (r->ndm_state)
		print_neigh_state(r->ndm_state);

	if (protocol) {
		SPRINT_BUF(b1);

		print_string(PRINT_ANY, "protocol", " proto %s ",
			     rtnl_rtprot_n2a(protocol, b1, sizeof(b1)));
	}

	print_string(PRINT_FP, NULL, "\n", "");
	close_json_object();
	fflush(stdout);

	return 0;
}