Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be403ea1 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[IPv4]: Convert FIB dumping to use new netlink api



Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4e902c57
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -591,8 +591,8 @@ int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
	struct hlist_node *node;
	int dumped = 0;

	if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
	    ((struct rtmsg*)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
	if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
	    ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED)
		return ip_rt_dump(skb, cb);

	s_h = cb->args[0];
+1 −1
Original line number Diff line number Diff line
@@ -693,7 +693,7 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
					  tb->tb_id,
					  fa->fa_type,
					  fa->fa_scope,
					  &f->fn_key,
					  f->fn_key,
					  fz->fz_order,
					  fa->fa_tos,
					  fa->fa_info,
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ extern void fib_release_info(struct fib_info *);
extern struct fib_info *fib_create_info(struct fib_config *cfg);
extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
			 u32 tb_id, u8 type, u8 scope, void *dst,
			 u32 tb_id, u8 type, u8 scope, u32 dst,
			 int dst_len, u8 tos, struct fib_info *fi,
			 unsigned int);
extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
+48 −40
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
		goto errout;

	err = fib_dump_info(skb, info->pid, seq, event, tb_id,
			    fa->fa_type, fa->fa_scope, &key, dst_len,
			    fa->fa_type, fa->fa_scope, key, dst_len,
			    fa->fa_tos, fa->fa_info, 0);
	if (err < 0) {
		kfree_skb(skb);
@@ -928,79 +928,87 @@ u32 __fib_res_prefsrc(struct fib_result *res)
	return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
}

int
fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
	      u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
		  u32 tb_id, u8 type, u8 scope, u32 dst, int dst_len, u8 tos,
		  struct fib_info *fi, unsigned int flags)
{
	struct rtmsg *rtm;
	struct nlmsghdr *nlh;
	unsigned char	 *b = skb->tail;
	struct rtmsg *rtm;

	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
	if (nlh == NULL)
		return -ENOBUFS;

	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
	rtm = NLMSG_DATA(nlh);
	rtm = nlmsg_data(nlh);
	rtm->rtm_family = AF_INET;
	rtm->rtm_dst_len = dst_len;
	rtm->rtm_src_len = 0;
	rtm->rtm_tos = tos;
	rtm->rtm_table = tb_id;
	RTA_PUT_U32(skb, RTA_TABLE, tb_id);
	NLA_PUT_U32(skb, RTA_TABLE, tb_id);
	rtm->rtm_type = type;
	rtm->rtm_flags = fi->fib_flags;
	rtm->rtm_scope = scope;
	if (rtm->rtm_dst_len)
		RTA_PUT(skb, RTA_DST, 4, dst);
	rtm->rtm_protocol = fi->fib_protocol;

	if (rtm->rtm_dst_len)
		NLA_PUT_U32(skb, RTA_DST, dst);

	if (fi->fib_priority)
		RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority);
		NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority);

	if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
		goto rtattr_failure;
		goto nla_put_failure;

	if (fi->fib_prefsrc)
		RTA_PUT(skb, RTA_PREFSRC, 4, &fi->fib_prefsrc);
		NLA_PUT_U32(skb, RTA_PREFSRC, fi->fib_prefsrc);

	if (fi->fib_nhs == 1) {
		if (fi->fib_nh->nh_gw)
			RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw);
			NLA_PUT_U32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);

		if (fi->fib_nh->nh_oif)
			RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif);
			NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
#ifdef CONFIG_NET_CLS_ROUTE
		if (fi->fib_nh[0].nh_tclassid)
			RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid);
			NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
#endif
	}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
	if (fi->fib_nhs > 1) {
		struct rtnexthop *nhp;
		struct rtattr *mp_head;
		if (skb_tailroom(skb) <= RTA_SPACE(0))
			goto rtattr_failure;
		mp_head = (struct rtattr*)skb_put(skb, RTA_SPACE(0));
		struct rtnexthop *rtnh;
		struct nlattr *mp;

		mp = nla_nest_start(skb, RTA_MULTIPATH);
		if (mp == NULL)
			goto nla_put_failure;

		for_nexthops(fi) {
			if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
				goto rtattr_failure;
			nhp = (struct rtnexthop*)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
			nhp->rtnh_flags = nh->nh_flags & 0xFF;
			nhp->rtnh_hops = nh->nh_weight-1;
			nhp->rtnh_ifindex = nh->nh_oif;
			rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
			if (rtnh == NULL)
				goto nla_put_failure;

			rtnh->rtnh_flags = nh->nh_flags & 0xFF;
			rtnh->rtnh_hops = nh->nh_weight - 1;
			rtnh->rtnh_ifindex = nh->nh_oif;

			if (nh->nh_gw)
				RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw);
				NLA_PUT_U32(skb, RTA_GATEWAY, nh->nh_gw);
#ifdef CONFIG_NET_CLS_ROUTE
			if (nh->nh_tclassid)
				RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid);
				NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
#endif
			nhp->rtnh_len = skb->tail - (unsigned char*)nhp;
			/* length of rtnetlink header + attributes */
			rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
		} endfor_nexthops(fi);
		mp_head->rta_type = RTA_MULTIPATH;
		mp_head->rta_len = skb->tail - (u8*)mp_head;

		nla_nest_end(skb, mp);
	}
#endif
	nlh->nlmsg_len = skb->tail - b;
	return skb->len;
	return nlmsg_end(skb, nlh);

nlmsg_failure:
rtattr_failure:
	skb_trim(skb, b - skb->data);
	return -1;
nla_put_failure:
	return nlmsg_cancel(skb, nlh);
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -1854,7 +1854,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
				  tb->tb_id,
				  fa->fa_type,
				  fa->fa_scope,
				  &xkey,
				  xkey,
				  plen,
				  fa->fa_tos,
				  fa->fa_info, 0) < 0) {
Loading