+static int
+api_ip_mroute_add_del (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ip_mroute_add_del_t *mp;
+ f64 timeout;
+ u32 sw_if_index = ~0, vrf_id = 0;
+ u8 is_ipv6 = 0;
+ u8 is_local = 0;
+ u8 create_vrf_if_needed = 0;
+ u8 is_add = 1;
+ u8 address_set = 0;
+ u32 grp_address_length = 0;
+ ip4_address_t v4_grp_address, v4_src_address;
+ ip6_address_t v6_grp_address, v6_src_address;
+ mfib_itf_flags_t iflags = 0;
+ mfib_entry_flags_t eflags = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "sw_if_index %d", &sw_if_index))
+ ;
+ else if (unformat (i, "%U %U",
+ unformat_ip4_address, &v4_src_address,
+ unformat_ip4_address, &v4_grp_address))
+ {
+ grp_address_length = 64;
+ address_set = 1;
+ is_ipv6 = 0;
+ }
+ else if (unformat (i, "%U %U",
+ unformat_ip6_address, &v6_src_address,
+ unformat_ip6_address, &v6_grp_address))
+ {
+ grp_address_length = 256;
+ address_set = 1;
+ is_ipv6 = 1;
+ }
+ else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
+ {
+ memset (&v4_src_address, 0, sizeof (v4_src_address));
+ grp_address_length = 32;
+ address_set = 1;
+ is_ipv6 = 0;
+ }
+ else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
+ {
+ memset (&v6_src_address, 0, sizeof (v6_src_address));
+ grp_address_length = 128;
+ address_set = 1;
+ is_ipv6 = 1;
+ }
+ else if (unformat (i, "/%d", &grp_address_length))
+ ;
+ else if (unformat (i, "local"))
+ {
+ is_local = 1;
+ }
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "add"))
+ is_add = 1;
+ else if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "create-vrf"))
+ create_vrf_if_needed = 1;
+ else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
+ ;
+ else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
+ ;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (address_set == 0)
+ {
+ errmsg ("missing addresses\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (IP_MROUTE_ADD_DEL, ip_mroute_add_del);
+
+ mp->next_hop_sw_if_index = ntohl (sw_if_index);
+ mp->table_id = ntohl (vrf_id);
+ mp->create_vrf_if_needed = create_vrf_if_needed;
+
+ mp->is_add = is_add;
+ mp->is_ipv6 = is_ipv6;
+ mp->is_local = is_local;
+ mp->itf_flags = ntohl (iflags);
+ mp->entry_flags = ntohl (eflags);
+ mp->grp_address_length = grp_address_length;
+ mp->grp_address_length = ntohs (mp->grp_address_length);
+
+ if (is_ipv6)
+ {
+ clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
+ clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
+ }
+ else
+ {
+ clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
+ clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
+
+ }
+
+ /* send it... */
+ S;
+ /* Wait for a reply... */
+ W;
+
+ /* Return the good/bad news */
+ return (vam->retval);
+}
+