static int fib6_commit_metrics(struct dst_entry *dst, struct nlattr *mx, int mx_len) { struct nlattr *nla; int remaining; u32 *mp; if (dst->flags & DST_HOST) { mp = dst_metrics_write_ptr(dst); } else { mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); if (!mp) return -ENOMEM; dst_init_metrics(dst, mp, 0); } nla_for_each_attr(nla, mx, mx_len, remaining) { int type = nla_type(nla); if (type) { if (type > RTAX_MAX) return -EINVAL; mp[type - 1] = nla_get_u32(nla); } }
void br_netfilter_rtable_init(struct net_bridge *br) { struct rtable *rt = &br->fake_rtable; atomic_set(&rt->dst.__refcnt, 1); rt->dst.dev = br->dev; rt->dst.path = &rt->dst; dst_init_metrics(&rt->dst, br_dst_default_metrics, true); rt->dst.flags = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE; rt->dst.ops = &fake_dst_ops; }