예제 #1
0
static void rtcfg_conn_check_heartbeat(struct rtcfg_connection *conn)
{
    u64                 timeout;
    struct rtcfg_device *rtcfg_dev;


    timeout = device[conn->ifindex].spec.srv.heartbeat_timeout;
    if (!timeout)
        return;

    if (rtdm_clock_read() >= conn->last_frame + timeout) {
        rtcfg_dev = &device[conn->ifindex];

        rtcfg_dev->stations_found--;
        rtcfg_dev->stations_ready--;
        rtcfg_dev->spec.srv.clients_configured--;

        rtcfg_send_dead_station(conn);

        rtcfg_next_conn_state(conn, RTCFG_CONN_DEAD);
        conn->cfg_offs = 0;
        conn->flags    = 0;

#ifdef CONFIG_RTNET_RTIPV4
        if ((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) {
            struct rtnet_device *rtdev = rtdev_get_by_index(conn->ifindex);

            rt_ip_route_del_host(conn->addr.ip_addr, rtdev);

            if (rtdev == NULL)
                return;

            if (!(conn->addr_type & FLAG_ASSIGN_ADDR_BY_MAC))
                /* MAC address yet unknown -> use broadcast address */
                memcpy(conn->mac_addr, rtdev->broadcast, MAX_ADDR_LEN);

            rtdev_dereference(rtdev);
        }
#endif /* CONFIG_RTNET_RTIPV4 */
    }
}
예제 #2
0
파일: route.c 프로젝트: hiddeate2m/rtnet
/***
 *  rt_ip_route_del_all - deletes all routes associated with a specified device
 */
void rt_ip_route_del_all(struct rtnet_device *rtdev)
{
    rtdm_lockctx_t      context;
    struct host_route   *host_rt;
    struct host_route   **last_host_ptr;
    unsigned int        key;
    u32                 ip;


    for (key = 0; key < HOST_HASH_TBL_SIZE; key++) {
      host_start_over:
        last_host_ptr = &host_hash_tbl[key];

        rtdm_lock_get_irqsave(&host_table_lock, context);

        host_rt = host_hash_tbl[key];
        while (host_rt != NULL) {
            if (host_rt->dest_host.rtdev == rtdev) {
                *last_host_ptr = host_rt->next;

                rt_free_host_route(host_rt);

                rtdm_lock_put_irqrestore(&host_table_lock, context);

                goto host_start_over;
            }

            last_host_ptr = &host_rt->next;
            host_rt = host_rt->next;
        }

        rtdm_lock_put_irqrestore(&host_table_lock, context);
    }

    if ((ip = rtdev->local_ip) != 0)
        rt_ip_route_del_host(ip, rtdev);
}
static void rtcfg_client_recv_dead_station(int ifindex, struct rtskb *rtskb)
{
    struct rtcfg_frm_dead_station *dead_station_frm;
    struct rtcfg_device           *rtcfg_dev = &device[ifindex];
    u32                           i;


    dead_station_frm = (struct rtcfg_frm_dead_station *)rtskb->data;

    if (rtskb->len < sizeof(struct rtcfg_frm_dead_station)) {
        rtos_res_unlock(&rtcfg_dev->dev_lock);
        RTCFG_DEBUG(1, "RTcfg: received invalid dead station frame\n");
        kfree_rtskb(rtskb);
        return;
    }

    switch (dead_station_frm->addr_type) {
#ifdef CONFIG_RTNET_RTIPV4
        case RTCFG_ADDR_IP: {
            u32 ip;

            if (rtskb->len < sizeof(struct rtcfg_frm_dead_station) +
                    RTCFG_ADDRSIZE_IP) {
                rtos_res_unlock(&rtcfg_dev->dev_lock);
                RTCFG_DEBUG(1, "RTcfg: received invalid dead station frame\n");
                kfree_rtskb(rtskb);
                return;
            }

            ip = *(u32 *)dead_station_frm->logical_addr;

            /* only delete remote IPs from routing table */
            if (rtskb->rtdev->local_ip != ip)
                rt_ip_route_del_host(ip);

            dead_station_frm = (struct rtcfg_frm_dead_station *)
                (((u8 *)dead_station_frm) + RTCFG_ADDRSIZE_IP);

            break;
        }
#endif /* CONFIG_RTNET_RTIPV4 */

        case RTCFG_ADDR_MAC:
            /* nothing to do */
            break;

        default:
            rtos_res_unlock(&rtcfg_dev->dev_lock);
            RTCFG_DEBUG(1, "RTcfg: unknown addr_type %d in %s()\n",
                        dead_station_frm->addr_type, __FUNCTION__);
            kfree_rtskb(rtskb);
            return;
    }

    for (i = 0; i < rtcfg_dev->stations_found; i++)
        /* Ethernet-specific! */
        if (memcmp(rtcfg_dev->spec.clt.station_addr_list[i].mac_addr,
                   dead_station_frm->physical_addr, ETH_ALEN) == 0) {
            if ((rtcfg_dev->spec.clt.station_addr_list[i].flags &
                 RTCFG_FLAG_READY) != 0)
                rtcfg_dev->stations_ready--;

            rtcfg_dev->stations_found--;
            memmove(&rtcfg_dev->spec.clt.station_addr_list[i],
                    &rtcfg_dev->spec.clt.station_addr_list[i+1],
                    sizeof(struct rtcfg_station) *
                    (rtcfg_dev->stations_found - i));

            if (rtcfg_dev->state == RTCFG_MAIN_CLIENT_ALL_KNOWN)
                rtcfg_next_main_state(ifindex, RTCFG_MAIN_CLIENT_ANNOUNCED);
            break;
        }

    rtos_res_unlock(&rtcfg_dev->dev_lock);

    kfree_rtskb(rtskb);
}