/*
 *===========================================================================
 *                    ipnet_rtnetlink_ip6_addr_event
 *===========================================================================
 * Description: Status of a network interface has changed, create a IFINFO
 *              event on NETLNK..
 * Parameters:  netif - The interface.
 * Returns:     -
 *
 */
IP_STATIC void
ipnet_rtnetlink_route_event(struct Ipnet_route_entry_struct *rt, int event)
{
    Ipcom_pkt               *pkt    = IP_NULL;
    Ipnet_netlink_mem_t     mem;
    int                     ret     = -1;
    int                     group;

    if (!ipnet_netlink_pkt_alloc(&pkt, IP_NULL, IP_TRUE, &mem, 512))
        return;

    /* Must explicitly switch to the correct VR here */
    pkt->vr_index = mem.vr = IPNET_ROUTE_GET_VR(rt->head);

#ifdef IPCOM_USE_INET
    if (IPNET_ROUTE_GET_FAMILY(rt->head) == IP_AF_INET)
    {
        ret = ipnet_rtnetlink_ip4_route_fill_info (&mem,
                                                   rt,
                                                   0,
                                                   event,
                                                   0);
        group = IP_RTNLGRP_IPV4_ROUTE;
    }
#endif
#ifdef IPCOM_USE_INET6
    if (IPNET_ROUTE_GET_FAMILY(rt->head) == IP_AF_INET6)
    {
        ret = ipnet_rtnetlink_ip6_route_fill_info (&mem,
                                                   rt,
                                                   0,
                                                   event,
                                                   0);
        group = IP_RTNLGRP_IPV6_ROUTE;
    }
#endif

    if (ret < 0)
        ipcom_pkt_free(pkt);
    else
    {
        pkt->end += ret;

        /* We're done; do report this pkt */
        ipnet_rtnetlink_broadcast(pkt, group);
    }
}
/*
 *===========================================================================
 *                    ipnet_netlink_dump
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_rtnetlink_do(Ipnet_rtnetlink_do_t       do_it,
                   int                        family,
                   Ipnet_socket               *sock,
                   struct Ip_nlmsghdr         *nlmsg,
                   Ip_bool                    non_blocking,
                   struct Ip_rtattr           **rta)
{
    Ipcom_pkt               *pkt    = IP_NULL;
    Ipnet_netlink_mem_t     mem;
    int                     ret;

    /* Is it a 'get'? */
    if (((nlmsg->nlmsg_type - IP_RTM_BASE) & 0x3) == 2)
    {
        /**/
        if (!ipnet_netlink_pkt_alloc(&pkt, sock, non_blocking, &mem, 512))
            return 0;
    }
    else
    {
        /**/
        ipnet_netlink_pkt_mem(IP_NULL, sock, &mem);
    }

    /* */
    ret = (*do_it) (&mem, nlmsg, rta, family);

    /* */
    if (pkt != IP_NULL && ret > 0)
    {
        pkt->end += ret;
        ipnet_netlink_pkt_queue(&pkt, sock);
    }

    if (pkt)
        ipcom_pkt_free(pkt);
    return ret < 0? ret : 0;
}