Пример #1
0
static int local_service_generic(struct hostctrl *hc, int type,
                                 const struct service_id *srvid,
                                 unsigned short prefix_bits,
                                 unsigned int priority,
                                 unsigned int weight,
                                 const struct in_addr *ipaddr)
{
    struct {
        struct ctrlmsg_service cm;
        struct service_info service;
    } req;

    if (!srvid)
        return -1;

    memset(&req, 0, sizeof(req));
    req.cm.cmh.type = type;
    req.cm.cmh.xid = ++hc->xid;
    req.cm.cmh.len = CTRLMSG_SERVICE_NUM_LEN(1);
    req.cm.service[0].srvid_prefix_bits =
        (prefix_bits > SERVICE_ID_MAX_PREFIX_BITS) ?
        0 : prefix_bits;
    req.cm.service[0].priority = priority;
    req.cm.service[0].weight = weight;
    memcpy(&req.cm.service[0].srvid, srvid, sizeof(*srvid));

    if (ipaddr)
        memcpy(&req.cm.service[0].address, ipaddr, sizeof(*ipaddr));

    req.cm.service[0].if_index = -1;

    /* strncpy(req.cm.ifname, ifname, IFNAMSIZ - 1); */

    LOG_DBG("op=%d prefix_bits=%u len=%u sizeof(req)=%zu %zu %s\n",
            type, req.cm.service[0].srvid_prefix_bits,
            CTRLMSG_SERVICE_LEN(&req.cm), sizeof(req),
            CTRLMSG_SERVICE_NUM(&req.cm),
            service_id_to_str(&req.cm.service[0].srvid));

    return message_channel_send(hc->mc, &req.cm, req.cm.cmh.len);
}
Пример #2
0
static int ctrl_handle_add_service_msg(struct ctrlmsg *cm, int peer)
{
        struct ctrlmsg_service *cmr = (struct ctrlmsg_service *)cm;
        unsigned int num_res = CTRLMSG_SERVICE_NUM(cmr);
        /* TODO - flags, etc */
        unsigned int i, index = 0;
        int err = 0;

        LOG_DBG("adding %u services, msg size %u\n", 
                num_res, CTRLMSG_SERVICE_LEN(cmr));
        
        for (i = 0; i < num_res; i++) {
                struct net_device *dev = NULL;
                struct service_info *entry = &cmr->service[i];
                unsigned short prefix_bits = SERVICE_ID_MAX_PREFIX_BITS;

                if (entry->type == SERVICE_RULE_FORWARD) {
                        dev = resolve_dev(entry);
                        
                        if (!dev)
                                continue;
                }

                if (entry->srvid_prefix_bits > 0)
                        prefix_bits = entry->srvid_prefix_bits;
         
#if defined(ENABLE_DEBUG)
                {
                        char ipstr[18];
                        LOG_DBG("Adding service id: %s(%u) "
                                "@ address %s, priority %u, weight %u\n", 
                                service_id_to_str(&entry->srvid), 
                                prefix_bits, 
                                inet_ntop(AF_INET, &entry->address,
                                          ipstr, sizeof(ipstr)),
                                entry->priority, entry->weight);
                }
#endif
                err = service_add(&entry->srvid, 
                                  prefix_bits, 
                                  entry->type,
                                  entry->srvid_flags, 
                                  entry->priority, 
                                  entry->weight,
                                  &entry->address, 
                                  sizeof(entry->address),
                                  make_target(dev), GFP_KERNEL);
                if (dev)
                        dev_put(dev);

                if (err > 0) {
                        if (index < i) {
                                /* copy it over */
                                memcpy(&cmr->service[index], 
                                       entry, sizeof(*entry));
                        }
                        index++;
                } else {
                        LOG_ERR("Error adding service %s: err=%d\n", 
                                service_id_to_str(&entry->srvid), err);
                }
        }

        if (index == 0) {
                /* Just return the original request with a return value */
                cm->retval = CTRLMSG_RETVAL_NOENTRY;
        } else {
                /* Return the entries added */
                cm->retval = CTRLMSG_RETVAL_OK;
                cm->len = CTRLMSG_SERVICE_NUM_LEN(index);
        }

        ctrl_sendmsg(cm, peer, GFP_KERNEL);

        return 0;
}