[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6b6ddf10-5350-f21e-6eac-04f8e19d4fb3@gmail.com>
Date: Wed, 29 Sep 2021 21:33:47 -0600
From: David Ahern <dsahern@...il.com>
To: Nikolay Aleksandrov <razor@...ckwall.org>, netdev@...r.kernel.org
Cc: roopa@...dia.com, donaldsharp72@...il.com, idosch@...sch.org,
Nikolay Aleksandrov <nikolay@...dia.com>
Subject: Re: [RFC iproute2-next 03/11] ip: nexthop: add nh struct and a helper
to parse nhmsg into it
On 9/29/21 9:28 AM, Nikolay Aleksandrov wrote:
> @@ -328,6 +336,93 @@ static void print_nh_res_bucket(FILE *fp, const struct rtattr *res_bucket_attr)
> close_json_object();
> }
>
> +static void ipnh_destroy_entry(struct nh_entry *nhe)
> +{
> + if (nhe->nh_encap)
> + free(nhe->nh_encap);
> + if (nhe->nh_groups)
> + free(nhe->nh_groups);
> +}
> +
> +/* parse nhmsg into nexthop entry struct which must be destroyed by
> + * ipnh_destroy_enty when it's not needed anymore
> + */
I'd rather not have 2 functions interpreting the attributes. You should
be able to get print_nexthop to use the parse function and then print
using the nh_entry.
> +static int ipnh_parse_nhmsg(FILE *fp, const struct nhmsg *nhm, int len,
> + struct nh_entry *nhe)
> +{
> + struct rtattr *tb[NHA_MAX+1];
> + int err = 0;
> +
> + memset(nhe, 0, sizeof(*nhe));
> + parse_rtattr_flags(tb, NHA_MAX, RTM_NHA(nhm), len, NLA_F_NESTED);
> +
> + if (tb[NHA_ID])
> + nhe->nh_id = rta_getattr_u32(tb[NHA_ID]);
> +
> + if (tb[NHA_OIF])
> + nhe->nh_oif = rta_getattr_u32(tb[NHA_OIF]);
> +
> + if (tb[NHA_GROUP_TYPE])
> + nhe->nh_grp_type = rta_getattr_u16(tb[NHA_GROUP_TYPE]);
> +
> + if (tb[NHA_GATEWAY]) {
> + if (RTA_PAYLOAD(tb[NHA_GATEWAY]) > sizeof(nhe->nh_gateway)) {
> + fprintf(fp, "<nexthop id %u invalid gateway length %lu>\n",
> + nhe->nh_id, RTA_PAYLOAD(tb[NHA_GATEWAY]));
> + err = EINVAL;
> + goto out_err;
> + }
> + nhe->nh_gateway_len = RTA_PAYLOAD(tb[NHA_GATEWAY]);
> + memcpy(&nhe->nh_gateway, RTA_DATA(tb[NHA_GATEWAY]),
> + RTA_PAYLOAD(tb[NHA_GATEWAY]));
> + }
> +
> + if (tb[NHA_ENCAP]) {
> + nhe->nh_encap = malloc(RTA_LENGTH(RTA_PAYLOAD(tb[NHA_ENCAP])));
> + if (!nhe->nh_encap) {
> + err = ENOMEM;
> + goto out_err;
> + }
> + memcpy(nhe->nh_encap, tb[NHA_ENCAP],
> + RTA_LENGTH(RTA_PAYLOAD(tb[NHA_ENCAP])));
> + memcpy(&nhe->nh_encap_type, tb[NHA_ENCAP_TYPE],
> + sizeof(nhe->nh_encap_type));
> + }
> +
> + if (tb[NHA_GROUP]) {
> + if (!__valid_nh_group_attr(tb[NHA_GROUP])) {
> + fprintf(fp, "<nexthop id %u invalid nexthop group>",
> + nhe->nh_id);
> + err = EINVAL;
> + goto out_err;
> + }
> +
> + nhe->nh_groups = malloc(RTA_PAYLOAD(tb[NHA_GROUP]));
> + if (!nhe->nh_groups) {
> + err = ENOMEM;
> + goto out_err;
> + }
> + nhe->nh_groups_cnt = RTA_PAYLOAD(tb[NHA_GROUP]) /
> + sizeof(struct nexthop_grp);
> + memcpy(nhe->nh_groups, RTA_DATA(tb[NHA_GROUP]),
> + RTA_PAYLOAD(tb[NHA_GROUP]));
> + }
> +
> + nhe->nh_blackhole = !!tb[NHA_BLACKHOLE];
> + nhe->nh_fdb = !!tb[NHA_FDB];
> +
> + nhe->nh_family = nhm->nh_family;
> + nhe->nh_protocol = nhm->nh_protocol;
> + nhe->nh_scope = nhm->nh_scope;
> + nhe->nh_flags = nhm->nh_flags;
> +
> + return 0;
> +
> +out_err:
> + ipnh_destroy_entry(nhe);
> + return err;
> +}
> +
Powered by blists - more mailing lists